-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Another Haskell web framework for rapid development
--
-- This toolbox provides everything you need to get a quick start into
-- web hacking with haskell:
--
--
-- - fast routing
-- - middleware
-- - json
-- - sessions
-- - cookies
-- - database helper
-- - csrf-protection
--
--
-- A tutorial is available at spock.li
@package Spock
@version 0.12.0.0
module Web.Spock.Internal.SessionVault
class (Eq (SessionKey s), Hashable (SessionKey s)) => IsSession s where type SessionKey s :: * where {
type family SessionKey s :: *;
}
getSessionKey :: IsSession s => s -> SessionKey s
newtype SessionVault s
SessionVault :: Map (SessionKey s) s -> SessionVault s
[unSessionVault] :: SessionVault s -> Map (SessionKey s) s
-- | Create a new session vault
newSessionVault :: STM (SessionVault s)
-- | Load a session
loadSession :: IsSession s => SessionKey s -> SessionVault s -> STM (Maybe s)
-- | Store a session, overwriting any previous values
storeSession :: IsSession s => s -> SessionVault s -> STM ()
-- | Removea session
deleteSession :: IsSession s => SessionKey s -> SessionVault s -> STM ()
-- | Get all sessions as list
toList :: SessionVault s -> STM [s]
-- | Remove all sessions that do not match the predicate
filterSessions :: IsSession s => (s -> Bool) -> SessionVault s -> STM ()
-- | Perform action on all sessions
mapSessions :: IsSession s => (s -> STM s) -> SessionVault s -> STM ()
newStmSessionStore' :: IO (SessionStore (Session conn sess st) STM)
newStmSessionStore :: IO (SessionStoreInstance (Session conn sess st))
instance Web.Spock.Internal.SessionVault.IsSession (Web.Spock.Internal.Types.Session conn sess st)
module Web.Spock.Internal.SessionManager
createSessionManager :: MonadIO m => SessionCfg conn sess st -> SessionIf m -> IO (SessionManager m conn sess st)
withSessionManager :: MonadIO m => SessionCfg conn sess st -> SessionIf m -> (SessionManager m conn sess st -> IO a) -> IO a
type SessionId = Text
data Session conn sess st
Session :: !SessionId -> !Text -> !UTCTime -> !sess -> Session conn sess st
[sess_id] :: Session conn sess st -> !SessionId
[sess_csrfToken] :: Session conn sess st -> !Text
[sess_validUntil] :: Session conn sess st -> !UTCTime
[sess_data] :: Session conn sess st -> !sess
data SessionManager m conn sess st
SessionManager :: m SessionId -> m Text -> m () -> m sess -> (sess -> m ()) -> (forall a. (sess -> (sess, a)) -> m a) -> ((forall n. Monad n => sess -> n sess) -> m ()) -> (MonadIO m => m ()) -> Middleware -> IO () -> SessionManager m conn sess st
[sm_getSessionId] :: SessionManager m conn sess st -> m SessionId
[sm_getCsrfToken] :: SessionManager m conn sess st -> m Text
[sm_regenerateSessionId] :: SessionManager m conn sess st -> m ()
[sm_readSession] :: SessionManager m conn sess st -> m sess
[sm_writeSession] :: SessionManager m conn sess st -> sess -> m ()
[sm_modifySession] :: SessionManager m conn sess st -> forall a. (sess -> (sess, a)) -> m a
[sm_mapSessions] :: SessionManager m conn sess st -> (forall n. Monad n => sess -> n sess) -> m ()
[sm_clearAllSessions] :: SessionManager m conn sess st -> MonadIO m => m ()
[sm_middleware] :: SessionManager m conn sess st -> Middleware
[sm_closeSessionManager] :: SessionManager m conn sess st -> IO ()
data SessionIf m
SessionIf :: (forall a. Key a -> m (Maybe a)) -> ((Vault -> Vault) -> m ()) -> (MultiHeader -> ByteString -> m ()) -> IO (Key SessionId) -> SessionIf m
[si_queryVault] :: SessionIf m -> forall a. Key a -> m (Maybe a)
[si_modifyVault] :: SessionIf m -> (Vault -> Vault) -> m ()
[si_setRawMultiHeader] :: SessionIf m -> MultiHeader -> ByteString -> m ()
[si_vaultKey] :: SessionIf m -> IO (Key SessionId)
module Web.Spock.SessionActions
type SessionId = Text
-- | Regenerate the users sessionId. This preserves all stored data. Call
-- this prior to logging in a user to prevent session fixation attacks.
sessionRegenerateId :: SpockActionCtx ctx conn sess st ()
-- | Get the current users sessionId. Note that this ID should only be
-- shown to it's owner as otherwise sessions can be hijacked.
getSessionId :: SpockActionCtx ctx conn sess st SessionId
-- | Read the stored session
readSession :: SpockActionCtx ctx conn sess st sess
-- | Write to the current session. Note that all data is stored on the
-- server. The user only reciedes a sessionId to be identified.
writeSession :: forall sess ctx conn st. sess -> SpockActionCtx ctx conn sess st ()
-- | Modify the stored session
modifySession :: (sess -> sess) -> SpockActionCtx ctx conn sess st ()
-- | Modify the stored session and return a value
modifySession' :: (sess -> (sess, a)) -> SpockActionCtx ctx conn sess st a
-- | Modify the stored session and return the new value after modification
modifyReadSession :: (sess -> sess) -> SpockActionCtx ctx conn sess st sess
-- | Apply a transformation to all sessions. Be careful with this, as this
-- may cause many STM transaction retries.
mapAllSessions :: (forall m. Monad m => sess -> m sess) -> SpockActionCtx ctx conn sess st ()
-- | Globally delete all existing sessions. This is useful for example if
-- you want to require all users to relogin
clearAllSessions :: SpockActionCtx ctx conn sess st ()
module Web.Spock.Config
-- | Spock configuration, use defaultSpockCfg and change single
-- values if needed
data SpockCfg conn sess st
SpockCfg :: st -> PoolOrConn conn -> SessionCfg conn sess st -> Maybe Word64 -> (Status -> ActionCtxT () IO ()) -> Bool -> Text -> Text -> SpockCfg conn sess st
-- | initial application global state
[spc_initialState] :: SpockCfg conn sess st -> st
-- | See PoolOrConn
[spc_database] :: SpockCfg conn sess st -> PoolOrConn conn
-- | See SessionCfg
[spc_sessionCfg] :: SpockCfg conn sess st -> SessionCfg conn sess st
-- | Maximum request size in bytes. Nothing means no limit. Defaults
-- to 5 MB in defaultSpockCfg.
[spc_maxRequestSize] :: SpockCfg conn sess st -> Maybe Word64
-- | Custom error handlers for implicit errors such as not matching routes
-- or exceptions during a request handler run.
[spc_errorHandler] :: SpockCfg conn sess st -> Status -> ActionCtxT () IO ()
-- | When set to true, all non GET request will require either an
-- HTTP-Header spc_csrfHeaderName or a POST-Parameter
-- spc_csrfPostName to be set to the value aquired by
-- getCsrfToken
[spc_csrfProtection] :: SpockCfg conn sess st -> Bool
-- | see spc_csrfHeaderName
[spc_csrfHeaderName] :: SpockCfg conn sess st -> Text
-- | see spc_csrfPostName
[spc_csrfPostName] :: SpockCfg conn sess st -> Text
-- | Spock configuration with reasonable defaults such as a basic error
-- page and 5MB request body limit. IMPORTANT: CSRF Protection is turned
-- off by default for now to not break any existing Spock applications.
-- Consider turning it on manually as it will become the default in the
-- future.
defaultSpockCfg :: sess -> PoolOrConn conn -> st -> IO (SpockCfg conn sess st)
-- | You can feed Spock with either a connection pool, or instructions on
-- how to build a connection pool. See ConnBuilder
data PoolOrConn a
[PCPool] :: Pool a -> PoolOrConn a
[PCConn] :: ConnBuilder a -> PoolOrConn a
[PCNoDatabase] :: PoolOrConn ()
-- | The ConnBuilder instructs Spock how to create or close a database
-- connection.
data ConnBuilder a
ConnBuilder :: IO a -> (a -> IO ()) -> PoolCfg -> ConnBuilder a
[cb_createConn] :: ConnBuilder a -> IO a
[cb_destroyConn] :: ConnBuilder a -> a -> IO ()
[cb_poolConfiguration] :: ConnBuilder a -> PoolCfg
-- | If Spock should take care of connection pooling, you need to configure
-- it depending on what you need.
data PoolCfg
PoolCfg :: Int -> Int -> NominalDiffTime -> PoolCfg
[pc_stripes] :: PoolCfg -> Int
[pc_resPerStripe] :: PoolCfg -> Int
[pc_keepOpenTime] :: PoolCfg -> NominalDiffTime
-- | Session configuration with reasonable defaults and an stm based
-- session store
defaultSessionCfg :: a -> IO (SessionCfg conn a st)
-- | Configuration for the session manager
data SessionCfg conn a st
SessionCfg :: Text -> NominalDiffTime -> Int -> Bool -> a -> SessionStoreInstance (Session conn a st) -> NominalDiffTime -> SessionHooks a -> SessionCfg conn a st
-- | name of the client side cookie
[sc_cookieName] :: SessionCfg conn a st -> Text
-- | how long shoud a client session live
[sc_sessionTTL] :: SessionCfg conn a st -> NominalDiffTime
-- | entropy of the session id sent to the client
[sc_sessionIdEntropy] :: SessionCfg conn a st -> Int
-- | if this is true, every page reload will renew the session time to live
-- counter
[sc_sessionExpandTTL] :: SessionCfg conn a st -> Bool
-- | initial session for visitors
[sc_emptySession] :: SessionCfg conn a st -> a
-- | storage interface for sessions
[sc_store] :: SessionCfg conn a st -> SessionStoreInstance (Session conn a st)
-- | how often should the session manager check for dangeling dead sessions
[sc_housekeepingInterval] :: SessionCfg conn a st -> NominalDiffTime
-- | hooks into the session manager
[sc_hooks] :: SessionCfg conn a st -> SessionHooks a
-- | NOP session hooks
defaultSessionHooks :: SessionHooks a
-- | Hook into the session manager to trigger custom behavior
data SessionHooks a
SessionHooks :: (HashMap SessionId a -> IO ()) -> SessionHooks a
[sh_removed] :: SessionHooks a -> HashMap SessionId a -> IO ()
data SessionStore sess tx
SessionStore :: (forall a. tx a -> IO a) -> (SessionId -> tx (Maybe sess)) -> (SessionId -> tx ()) -> (sess -> tx ()) -> tx [sess] -> ((sess -> Bool) -> tx ()) -> ((sess -> tx sess) -> tx ()) -> SessionStore sess tx
[ss_runTx] :: SessionStore sess tx -> forall a. tx a -> IO a
[ss_loadSession] :: SessionStore sess tx -> SessionId -> tx (Maybe sess)
[ss_deleteSession] :: SessionStore sess tx -> SessionId -> tx ()
[ss_storeSession] :: SessionStore sess tx -> sess -> tx ()
[ss_toList] :: SessionStore sess tx -> tx [sess]
[ss_filterSessions] :: SessionStore sess tx -> (sess -> Bool) -> tx ()
[ss_mapSessions] :: SessionStore sess tx -> (sess -> tx sess) -> tx ()
data SessionStoreInstance sess
[SessionStoreInstance] :: forall sess tx. (Monad tx, Functor tx, Applicative tx) => SessionStore sess tx -> SessionStoreInstance sess
newStmSessionStore :: IO (SessionStoreInstance (Session conn sess st))
module Web.Spock
-- | Run a Spock application. Basically just a wrapper around run.
runSpock :: Port -> IO Middleware -> IO ()
-- | Like runSpock, but does not display the banner "Spock is
-- running on port XXX" on stdout.
runSpockNoBanner :: Port -> IO Middleware -> IO ()
-- | Convert a middleware to an application. All failing requests will
-- result in a 404 page
spockAsApp :: IO Middleware -> IO Application
-- | Create a spock application using a given db storageLayer and an
-- initial state. Spock works with database libraries that already
-- implement connection pooling and with those that don't come with it
-- out of the box. For more see the PoolOrConn type. Use
-- runSpock to run the app or spockAsApp to create a
-- Wai.Application
spock :: forall conn sess st. SpockCfg conn sess st -> SpockM conn sess st () -> IO Middleware
type SpockM conn sess st = SpockCtxM () conn sess st
type SpockCtxM ctx conn sess st = SpockCtxT ctx (WebStateM conn sess st)
data Path (as :: [*]) (pathState :: PathState) :: [*] -> PathState -> *
-- | The root of a path piece. Use to define a handler for "/"
root :: Path ([] *) Open
type Var a = Path ((:) * a ([] *)) Open
-- | A route parameter
var :: (Typeable * a, FromHttpApiData a) => Path ((:) * a ([] *)) Open
-- | A static route piece
static :: String -> Path ([] *) Open
-- | Combine two path components
(/>) :: Path as Open -> Path bs ps -> Path (Append as bs) ps
-- | Matches the rest of the route. Should be the last part of the path.
wildcard :: Path ((:) * Text ([] *)) Closed
-- | Render a route applying path pieces
renderRoute :: AllHave ToHttpApiData as => Path as Open -> HVectElim as Text
-- | Define a subcomponent. Usage example:
--
--
-- subcomponent "site" $
-- do get "home" homeHandler
-- get ("misc" <//> var) $ -- ...
-- subcomponent "admin" $
-- do get "home" adminHomeHandler
--
--
-- The request /site/home will be routed to homeHandler and the request
-- /admin/home will be routed to adminHomeHandler
subcomponent :: (RouteM t, Monad m) => Path ([] *) Open -> t ctx m () -> t ctx m ()
-- | Specify an action that will be run before all subroutes. It can modify
-- the requests current context
prehook :: (RouteM t, MonadIO m) => ActionCtxT ctx m ctx' -> t ctx' m () -> t ctx m ()
type RouteSpec xs ps ctx conn sess st = Path xs ps -> HVectElim xs (SpockActionCtx ctx conn sess st ()) -> SpockCtxM ctx conn sess st ()
-- | Specify an action that will be run when the HTTP verb GET and
-- the given route match
get :: HasRep xs => RouteSpec xs ps ctx conn sess st
-- | Specify an action that will be run when the HTTP verb POST and
-- the given route match
post :: HasRep xs => RouteSpec xs ps ctx conn sess st
-- | Specify an action that will be run when the HTTP verb 'GET'/'POST' and
-- the given route match
getpost :: HasRep xs => RouteSpec xs ps ctx conn sess st
-- | Specify an action that will be run when the HTTP verb HEAD and
-- the given route match
head :: HasRep xs => RouteSpec xs ps ctx conn sess st
-- | Specify an action that will be run when the HTTP verb PUT and
-- the given route match
put :: HasRep xs => RouteSpec xs ps ctx conn sess st
-- | Specify an action that will be run when the HTTP verb DELETE
-- and the given route match
delete :: HasRep xs => RouteSpec xs ps ctx conn sess st
-- | Specify an action that will be run when the HTTP verb PATCH and
-- the given route match
patch :: HasRep xs => RouteSpec xs ps ctx conn sess st
-- | Specify an action that will be run when a standard HTTP verb and the
-- given route match
hookRoute :: HasRep xs => StdMethod -> RouteSpec xs ps ctx conn sess st
-- | Specify an action that will be run when a custom HTTP verb and the
-- given route match
hookRouteCustom :: HasRep xs => Text -> RouteSpec xs ps ctx conn sess st
-- | Specify an action that will be run when a standard HTTP verb matches
-- but no defined route matches. The full path is passed as an argument
hookAny :: StdMethod -> ([Text] -> SpockActionCtx ctx conn sess st ()) -> SpockCtxM ctx conn sess st ()
-- | Specify an action that will be run when a custom HTTP verb matches but
-- no defined route matches. The full path is passed as an argument
hookAnyCustom :: Text -> ([Text] -> SpockActionCtx ctx conn sess st ()) -> SpockCtxM ctx conn sess st ()
-- | HTTP standard method (as defined by RFC 2616, and PATCH which is
-- defined by RFC 5789).
data StdMethod :: *
GET :: StdMethod
POST :: StdMethod
HEAD :: StdMethod
PUT :: StdMethod
DELETE :: StdMethod
TRACE :: StdMethod
CONNECT :: StdMethod
OPTIONS :: StdMethod
PATCH :: StdMethod
-- | Hook wai middleware into Spock
middleware :: (RouteM t, Monad m) => Middleware -> t ctx m ()
-- | The SpockAction is a specialisation of SpockActionCtx
-- with a '()' context.
type SpockAction conn sess st = SpockActionCtx () conn sess st
-- | The SpockActionCtx is the monad of all route-actions. You have
-- access to the context of the request and database, session and state
-- of your application.
type SpockActionCtx ctx conn sess st = ActionCtxT ctx (WebStateM conn sess st)
class HasSpock m where type SpockConn m :: * type SpockState m :: * type SpockSession m :: * where {
type family SpockConn m :: *;
type family SpockState m :: *;
type family SpockSession m :: *;
}
-- | Give you access to a database connectin from the connection pool. The
-- connection is released back to the pool once the function terminates.
runQuery :: HasSpock m => (SpockConn m -> IO a) -> m a
-- | Read the application's state. If you wish to have mutable state, you
-- could use a TVar from the STM packge.
getState :: HasSpock m => m (SpockState m)
-- | Get the session manager
getSessMgr :: HasSpock m => m (SpockSessionManager (SpockConn m) (SpockSession m) (SpockState m))
-- | Get the Spock configuration
getSpockCfg :: HasSpock m => m (SpockCfg (SpockConn m) (SpockSession m) (SpockState m))
data SessionManager m conn sess st
-- | Get the CSRF token for the current user. This token must be sent on
-- all non GET requests via a post parameter or HTTP-Header if
-- spc_csrfProtection is turned on. See configuration
-- SpockCfg documentation for more information
getCsrfToken :: SpockActionCtx ctx conn sess st Text
-- | Get the CSRF token sent by the client. You should not need to call
-- this manually if spc_csrfProtection is turned on.
getClientCsrfToken :: SpockActionCtx ctx conn sess st (Maybe Text)
-- | Check that the client sent a valid CSRF token. You should not need to
-- call this manually in non GET requests if spc_csrfProtection is
-- turned on.
csrfCheck :: SpockActionCtx ctx conn sess st ()
type WebStateM conn sess st = WebStateT conn sess st (ResourceT IO)
data WebStateT conn sess st m a
data WebState conn sess st
-- | Read the heart of Spock. This is useful if you want to construct your
-- own monads that work with runQuery and getState using
-- runSpockIO
getSpockHeart :: MonadTrans t => t (WebStateM conn sess st) (WebState conn sess st)
-- | Run an action inside of Spocks core monad. This allows you to use
-- runQuery and getState
runSpockIO :: WebState conn sess st -> WebStateM conn sess st a -> IO a
-- | Read the connection pool of Spock. This is useful if you want to
-- construct your own monads that work with runQuery and
-- getState using runSpockIO
getSpockPool :: MonadTrans t => t (WebStateM conn sess st) (Pool conn)