-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Snap: A Haskell Web Framework: project starter executable and glue code library -- -- Snap Framework project starter executable and glue code library @package snap @version 0.7 -- | This module includes the machinery necessary to use hint to load -- action code dynamically. It includes a Template Haskell function to -- gather the necessary compile-time information about code location, -- compiler arguments, etc, and bind that information into the calls to -- the dynamic loader. module Snap.Loader.Devel -- | This function derives all the information necessary to use the -- interpreter from the compile-time environment, and compiles it in to -- the generated code. -- -- This could be considered a TH wrapper around a function -- --
-- loadSnap :: Typeable a => IO a -> (a -> IO (Snap (), IO ())) -- -> [String] -> IO (a, Snap (), IO ()) ---- -- with a magical implementation. The [String] argument is a list of -- directories to watch for updates to trigger a reloading. Directories -- containing code should be automatically picked up by this splice. -- -- The generated splice executes the initialiser once, sets up the -- interpreter for the load function, and returns the initializer's -- result along with the interpreter's proxy handler and cleanup actions. -- The behavior of the proxy actions will change to reflect changes in -- the watched files, reinterpreting the load function as needed and -- applying it to the initializer result. -- -- This will handle reloading the application successfully in most cases. -- The cases in which it is certain to fail are those involving changing -- the types of the initializer or the load function, or changing the -- compiler options required, such as by changing/adding dependencies in -- the project's .cabal file. In those cases, a full recompile will be -- needed. loadSnapTH :: Q Exp -> Name -> [String] -> Q Exp module Snap.Loader.Prod -- | This function provides a non-magical type-compatible loader for the -- one in Snap.Loader.Devel, allowing switching one import to provide -- production-mode compilation. -- -- This could be considered a TH wrapper around a function -- --
-- loadSnap :: Typeable a => IO a -> (a -> IO (Snap (), IO ())) -- -> [String] -> IO (a, Snap (), IO ()) ---- -- The third argument is unused, and only present for type-compatibility -- with Snap.Loader.Devel loadSnapTH :: Q Exp -> Name -> [String] -> Q Exp -- | Snaplets allow you to build web applications out of composable parts. -- This allows you to build self-contained units and glue them together -- to make your overall application. -- -- A snaplet has a few moving parts, some user-defined and some provided -- by the snaplet API: -- --
-- fooInit :: SnapletInit b Foo -- fooInit = makeSnaplet "foo" "An example snaplet" Nothing $ do -- -- Your initializer code here -- return $ Foo 42 ---- -- Note that you're writing your initializer code in the Initializer -- monad, and makeSnaplet converts it into an opaque SnapletInit type. -- This allows us to use the type system to ensure that the API is used -- correctly. makeSnaplet :: Text -> Text -> Maybe (IO FilePath) -> Initializer b v v -> SnapletInit b v -- | Runs another snaplet's initializer and returns the initialized Snaplet -- value. Calling an initializer with nestSnaplet gives the nested -- snaplet access to the same base state that the current snaplet has. -- This makes it possible for the child snaplet to make use of -- functionality provided by sibling snaplets. nestSnaplet :: ByteString -> (Lens v (Snaplet v1)) -> SnapletInit b v1 -> Initializer b v (Snaplet v1) -- | Runs another snaplet's initializer and returns the initialized Snaplet -- value. The difference between this and nestSnaplet is the first type -- parameter in the third argument. The "v1 v1" makes the child snaplet -- think that it is top-level, which means that it will not be able to -- use functionality provided by snaplets included above it in the -- snaplet tree. This strongly isolates the child snaplet, and allows you -- to eliminate the b type variable. The embedded snaplet can still get -- functionality from other snaplets, but only if it nests or embeds the -- snaplet itself. embedSnaplet :: ByteString -> (Lens v (Snaplet v1)) -> SnapletInit v1 v1 -> Initializer b v (Snaplet v1) -- | Sets a snaplet's name. All snaplets have a default name set by the -- snaplet author. This function allows you to override that name. You -- will have to do this if you have more than one instance of the same -- kind of snaplet because snaplet names must be unique. This function -- must immediately surround the snaplet's initializer. For example: -- --
-- fooState <- nestSnaplet "fooA" $ nameSnaplet "myFoo" $ fooInit --nameSnaplet :: Text -> SnapletInit b v -> SnapletInit b v -- | Attaches an unload handler to the snaplet. The unload handler will be -- called when the server shuts down, or is reloaded. onUnload :: IO () -> Initializer b v () -- | Adds an IO action that modifies the current snaplet state to be run at -- the end of initialization on the state that was created. This makes it -- easier to allow one snaplet's state to be modified by another -- snaplet's initializer. A good example of this is when a snaplet has -- templates that define its views. The Heist snaplet provides the -- addTemplates function which allows other snaplets to set up -- their own templates. addTemplates is implemented using this -- function. addPostInitHook :: (v -> IO v) -> Initializer b v () -- | Variant of addPostInitHook for when you have things wrapped in a -- Snaplet. addPostInitHookBase :: (Snaplet b -> IO (Snaplet b)) -> Initializer b v () -- | Initializers should use this function for all informational or error -- messages to be displayed to the user. On application startup they will -- be sent to the console. When executed from the reloader, they will be -- sent back to the user in the HTTP response. printInfo :: Text -> Initializer b v () -- | Adds routing to the current Handler. The new routes are merged -- with the main routing section and take precedence over existing -- routing that was previously defined. addRoutes :: [(ByteString, Handler b v ())] -> Initializer b v () -- | Wraps the snaplet's routing. This can be used to provide a snaplet -- that does per-request setup and cleanup, but then dispatches to the -- rest of the application. wrapHandlers :: (Handler b v () -> Handler b v ()) -> Initializer b v () -- | Snaplet infrastructure is available during runtime request processing -- through the Handler monad. There aren't very many standalone functions -- to read about here, but this is deceptive. The key is in the type -- class instances. Handler is an instance of MonadSnap, which -- means it is the monad you will use to write all your application -- routes. It also has a MonadSnaplet instance, which gives you -- all the functionality described above. data Handler b v a -- | Handler that reloads the site. reloadSite :: Handler b v () -- | Given a Snaplet initializer, produce the set of messages generated -- during initialization, a snap handler, and a cleanup action. runSnaplet :: SnapletInit b b -> IO (Text, Snap (), IO ()) -- | Given a configuration and a snap handler, complete it and produce the -- completed configuration as well as a new toplevel handler with things -- like compression and a 500 handler set up. combineConfig :: Config Snap a -> Snap () -> IO (Config Snap a, Snap ()) -- | Serves a top-level snaplet as a web application. Reads command-line -- arguments. FIXME: document this. serveSnaplet :: Config Snap a -> SnapletInit b b -> IO () -- | The Heist snaplet makes it easy to add Heist to your application and -- use it in other snaplets. module Snap.Snaplet.Heist -- | The state for the Heist snaplet. To use the Heist snaplet in your app -- include this in your application state and use heistInit to -- initialize it. The type parameter b will typically be the base state -- type for your application. data Heist b -- | A single snaplet should never need more than one instance of Heist as -- a subsnaplet. This type class allows you to make it easy for other -- snaplets to get the lens that identifies the heist snaplet. Here's an -- example of how the heist snaplet might be declared: -- --
-- data App = App { _heist :: Snaplet (Heist App) }
-- mkLabels [''App]
--
-- instance HasHeist App where heistLens = subSnaplet heist
--
-- appInit = makeSnaplet "app" "" Nothing $ do
-- h <- nestSnaplet "heist" heist $ heistInit "templates"
-- addSplices myAppSplices
-- return $ App h
--
class HasHeist b
heistLens :: HasHeist b => Lens (Snaplet b) (Snaplet (Heist b))
-- | The Initializer for Heist. This function is a
-- convenience wrapper around heistInit' that uses the default
-- emptyTemplateState from Heist and sets up routes for all the
-- templates.
heistInit :: FilePath -> SnapletInit b (Heist b)
-- | A lower level Initializer for Heist. This initializer
-- requires you to specify the initial TemplateState. It also does not
-- add any routes for templates, allowing you complete control over which
-- templates get routed.
heistInit' :: FilePath -> TemplateState (Handler b b) -> SnapletInit b (Heist b)
-- | Adds templates to the Heist TemplateState. Other snaplets should use
-- this function to add their own templates. The templates are
-- automatically read from the templates directory in the current
-- snaplet's filesystem root.
addTemplates :: HasHeist b => ByteString -> Initializer b v ()
-- | Adds templates to the Heist TemplateState, and lets you specify where
-- they are found in the filesystem.
addTemplatesAt :: HasHeist b => ByteString -> FilePath -> Initializer b v ()
-- | More general function allowing arbitrary TemplateState modification.
-- Without this function you wouldn't be able to bind more complicated
-- splices like the cache tag.
modifyHeistTS :: HasHeist b => (TemplateState (Handler b b) -> TemplateState (Handler b b)) -> Initializer b v ()
-- | Runs a function on with the Heist snaplet's TemplateState.
withHeistTS :: HasHeist b => (TemplateState (Handler b b) -> a) -> Handler b v a
-- | Allows snaplets to add splices.
addSplices :: HasHeist b => [(Text, SnapletSplice b v)] -> Initializer b v ()
-- | Renders a template as text/html. If the given template is not found,
-- this returns empty.
render :: HasHeist b => ByteString -> Handler b v ()
-- | Renders a template as the given content type. If the given template is
-- not found, this returns empty.
renderAs :: HasHeist b => ByteString -> ByteString -> Handler b v ()
-- | Analogous to fileServe. If the template specified in the
-- request path is not found, it returns empty.
heistServe :: HasHeist b => Handler b v ()
-- | Analogous to fileServeSingle. If the given template is not
-- found, this throws an error.
heistServeSingle :: HasHeist b => ByteString -> Handler b v ()
-- | Runs a handler with a modified TemplateState. You might want to
-- use this if you had a set of splices which were customised for a
-- specific action. To do that you would do:
--
-- -- heistLocal (bindSplices mySplices) handlerThatNeedsSplices --heistLocal :: HasHeist b => (TemplateState (Handler b b) -> TemplateState (Handler b b)) -> Handler b v a -> Handler b v a -- | Runs an action with additional splices bound into the Heist -- TemplateState. withSplices :: HasHeist b => [(Text, SnapletSplice b v)] -> Handler b v a -> Handler b v a -- | Renders a template with a given set of splices. This is syntax sugar -- for a common combination of heistLocal, bindSplices, and render. renderWithSplices :: HasHeist b => ByteString -> [(Text, SnapletSplice b v)] -> Handler b v () -- | Monad for working with Heist's API from within a snaplet. data SnapletHeist b v a -- | Type alias for convenience. type SnapletSplice b v = SnapletHeist b v Template -- | Lifts a HeistT action into SnapletHeist. Use this with all the -- functions from the Heist API. liftHeist :: HeistT (Handler b b) a -> SnapletHeist b v a -- | Lifts a Handler into SnapletHeist. liftHandler :: Handler b v a -> SnapletHeist b v a -- | Lifts a (Handler b b) into SnapletHeist. liftAppHandler :: Handler b b a -> SnapletHeist b v a -- | Common idiom for the combination of liftHandler and withTop. liftWith :: (Lens (Snaplet b) (Snaplet v')) -> Handler b v' a -> SnapletHeist b v a -- | SnapletSplices version of bindSplices. bindSnapletSplices :: (Lens (Snaplet b) (Snaplet v)) -> [(Text, SnapletSplice b v)] -> TemplateState (Handler b b) -> TemplateState (Handler b b) -- | Clears data stored by the cache tag. The cache tag automatically -- reloads its data when the specified TTL expires, but sometimes you may -- want to trigger a manual reload. This function lets you do that. clearHeistCache :: Heist b -> IO () module Snap.Snaplet.Session -- | Any Haskell record that is a member of the ISessionManager -- typeclass can be stuffed inside a SessionManager to enable all -- session-related functionality. data SessionManager -- | Wrap around a handler, committing any changes in the session at the -- end withSession :: (Lens b (Snaplet SessionManager)) -> Handler b v a -> Handler b v a -- | Commit changes to session within the current request cycle commitSession :: Handler b SessionManager () -- | Set a key-value pair in the current session setInSession :: Text -> Text -> Handler b SessionManager () -- | Get a key from the current session getFromSession :: Text -> Handler b SessionManager (Maybe Text) -- | Remove a key from the current session deleteFromSession :: Text -> Handler b SessionManager () -- | Returns a CSRF Token unique to the current session csrfToken :: Handler b SessionManager Text -- | Return session contents as an association list sessionToList :: Handler b SessionManager [(Text, Text)] -- | Deletes the session cookie, effectively resetting the session resetSession :: Handler b SessionManager () -- | Touch the session so the timeout gets refreshed touchSession :: Handler b SessionManager () -- | This module contains all the central authentication functionality. -- -- It exports a number of high-level functions to be used directly in -- your application handlers. -- -- We also export a number of mid-level functions that should be helpful -- when you are integrating with another way of confirming the -- authentication of login requests. module Snap.Snaplet.Auth -- | Create a new user from just a username and password -- -- May throw a DuplicateLogin if given username is not unique createUser :: Text -> ByteString -> Handler b (AuthManager b) AuthUser -- | Check whether a user with the given username exists. usernameExists :: Text -> Handler b (AuthManager b) Bool -- | Create or update a given user -- -- May throw a BackendError if something goes wrong. saveUser :: AuthUser -> Handler b (AuthManager b) AuthUser -- | Destroy the given user -- -- May throw a BackendError if something goes wrong. destroyUser :: AuthUser -> Handler b (AuthManager b) () -- | Lookup a user by her username, check given password and perform login loginByUsername :: ByteString -> Password -> Bool -> Handler b (AuthManager b) (Either AuthFailure AuthUser) -- | Remember user from the remember token if possible and perform login loginByRememberToken :: Handler b (AuthManager b) (Maybe AuthUser) -- | Login and persist the given AuthUser in the active session -- -- Meant to be used if you have other means of being sure that the person -- is who she says she is. forceLogin :: AuthUser -> Handler b (AuthManager b) (Either AuthFailure AuthUser) -- | Logout the active user logout :: Handler b (AuthManager b) () -- | Return the current user; trying to remember from cookie if possible. currentUser :: Handler b (AuthManager b) (Maybe AuthUser) -- | Convenience wrapper around rememberUser that returns a bool -- result isLoggedIn :: Handler b (AuthManager b) Bool -- | Mutate an AuthUser, marking successful authentication -- -- This will save the user to the backend. markAuthSuccess :: AuthUser -> Handler b (AuthManager b) AuthUser -- | Mutate an AuthUser, marking failed authentication -- -- This will save the user to the backend. markAuthFail :: AuthUser -> Handler b (AuthManager b) AuthUser -- | Authenticate and log the user into the current session if successful. -- -- This is a mid-level function exposed to allow roll-your-own ways of -- looking up a user from the database. -- -- This function will: -- --
-- asMinPasswdLen = 8 -- asRememberCookieName = "_remember" -- asRememberPeriod = Just (2*7*24*60*60) = 2 weeks -- asLockout = Nothing -- asSiteKey = "site_key.txt" --defAuthSettings :: AuthSettings -- | Type representing the concept of a User in your application. data AuthUser AuthUser :: Maybe UserId -> Text -> Maybe Password -> Maybe UTCTime -> Maybe UTCTime -> Maybe Text -> Int -> Int -> Maybe UTCTime -> Maybe UTCTime -> Maybe UTCTime -> Maybe ByteString -> Maybe ByteString -> Maybe UTCTime -> Maybe UTCTime -> [Role] -> HashMap Text Value -> AuthUser userId :: AuthUser -> Maybe UserId userLogin :: AuthUser -> Text userPassword :: AuthUser -> Maybe Password userActivatedAt :: AuthUser -> Maybe UTCTime userSuspendedAt :: AuthUser -> Maybe UTCTime userRememberToken :: AuthUser -> Maybe Text userLoginCount :: AuthUser -> Int userFailedLoginCount :: AuthUser -> Int userLockedOutUntil :: AuthUser -> Maybe UTCTime userCurrentLoginAt :: AuthUser -> Maybe UTCTime userLastLoginAt :: AuthUser -> Maybe UTCTime userCurrentLoginIp :: AuthUser -> Maybe ByteString userLastLoginIp :: AuthUser -> Maybe ByteString userCreatedAt :: AuthUser -> Maybe UTCTime userUpdatedAt :: AuthUser -> Maybe UTCTime userRoles :: AuthUser -> [Role] userMeta :: AuthUser -> HashMap Text Value -- | Default AuthUser that has all empty values. defAuthUser :: AuthUser -- | Internal representation of a User. By convention, we demand -- that the application is able to directly fetch a User using -- this identifier. -- -- Think of this type as a secure, authenticated user. You should -- normally never see this type unless a user has been authenticated. newtype UserId UserId :: Text -> UserId unUid :: UserId -> Text -- | Password is clear when supplied by the user and encrypted later when -- returned from the db. data Password ClearText :: ByteString -> Password Encrypted :: ByteString -> Password -- | Authentication failures indicate what went wrong during -- authentication. They may provide useful information to the developer, -- although it is generally not advisable to show the user the exact -- details about why login failed. data AuthFailure UserNotFound :: AuthFailure IncorrectPassword :: AuthFailure PasswordMissing :: AuthFailure -- | Locked out until given time LockedOut :: UTCTime -> AuthFailure AuthError :: String -> AuthFailure data BackendError DuplicateLogin :: BackendError BackendError :: String -> BackendError -- | This will be replaced by a role-based permission system. data Role Role :: ByteString -> Role -- | Run a function on the backend, and return the result. -- -- This uses an existential type so that the backend type doesn't -- escape AuthManager. The reason that the type is Handler b -- (AuthManager v) a and not a is because anything that uses the backend -- will return an IO something, which you can liftIO, or a Handler b -- (AuthManager v) a if it uses other handler things. withBackend :: (forall r. IAuthBackend r => r -> Handler b (AuthManager v) a) -> Handler b (AuthManager v) a encryptPassword :: Password -> IO Password checkPassword :: Password -> Password -> Bool -- | Check password for a given user. -- -- Returns Nothing if check is successful and an -- IncorrectPassword error otherwise authenticatePassword :: AuthUser -> Password -> Maybe AuthFailure -- | Set a new password for the given user. Given password should be -- clear-text; it will be encrypted into a Encrypted. setPassword :: AuthUser -> ByteString -> IO AuthUser -- | Register a new user by specifying login and password Param -- fields registerUser :: ByteString -> ByteString -> Handler b (AuthManager b) AuthUser -- | A MonadSnap handler that processes a login form. -- -- The request paremeters are passed to performLogin loginUser :: ByteString -> ByteString -> Maybe ByteString -> (AuthFailure -> Handler b (AuthManager b) ()) -> Handler b (AuthManager b) () -> Handler b (AuthManager b) () -- | Simple handler to log the user out. Deletes user from session. logoutUser :: Handler b (AuthManager b) () -> Handler b (AuthManager b) () -- | Require that an authenticated AuthUser is present in the -- current session. -- -- This function has no DB cost - only checks to see if a user_id is -- present in the current session. requireUser :: Lens b (Snaplet (AuthManager b)) -> Handler b v a -> Handler b v a -> Handler b v a -- | Add all standard auth splices to a Heist-enabled application. -- -- This adds the following splices: <ifLoggedIn> -- <ifLoggedOut> addAuthSplices :: HasHeist b => Lens b (Snaplet (AuthManager b)) -> Initializer b v () -- | A splice that can be used to check for existence of a user. If a user -- is present, this will run the contents of the node. -- --
-- <ifLoggedIn> Show this when there is a logged in user </ifLoggedIn> --ifLoggedIn :: Lens b (Snaplet (AuthManager b)) -> SnapletSplice b v -- | A splice that can be used to check for absence of a user. If a user is -- not present, this will run the contents of the node. -- --
-- <ifLoggedOut> Show this when there is a logged in user </ifLoggedOut> --ifLoggedOut :: Lens b (Snaplet (AuthManager b)) -> SnapletSplice b v module Snap.Snaplet.Auth.Backends.JsonFile -- | Initialize a JSON file backed AuthManager initJsonFileAuthManager :: AuthSettings -> Lens b (Snaplet SessionManager) -> FilePath -> SnapletInit b (AuthManager b) -- | Load/create a datafile into memory cache and return the manager. -- -- This data type can be used by itself for batch/non-handler processing. mkJsonAuthMgr :: FilePath -> IO JsonFileAuthManager instance FromJSON Password instance ToJSON Password instance FromJSON AuthUser instance ToJSON AuthUser instance FromJSON UserCache instance ToJSON UserCache instance IAuthBackend JsonFileAuthManager instance FromJSON UserIdCache instance ToJSON UserIdCache module Snap.Snaplet.Session.Backends.CookieSession -- | Initialize a cookie-backed session, returning a SessionManager -- to be stuffed inside your application's state. This -- SessionManager will enable the use of all session storage -- functionality defined in Snap.Snaplet.Session initCookieSessionManager :: FilePath -> ByteString -> Maybe Int -> SnapletInit b SessionManager instance Typeable CookieSessionManager instance Eq CookieSession instance Show CookieSession instance Show CookieSessionManager instance Eq Payload instance Show Payload instance Ord Payload instance Serialize Payload instance ISessionManager CookieSessionManager instance (Serialize k, Serialize v, Hashable k, Eq k) => Serialize (HashMap k v) instance Serialize CookieSession -- | This module provides convenience exports of the modules most commonly -- used when developing with the Snap Framework. For documentation about -- Snaplets, see Snap.Snaplet. For the core web server API, see -- Snap.Core. module Snap