Safe Haskell | None |
---|---|
Language | Haskell2010 |
- newtype ActionState = ActionState {
- fromActionState :: (Pool Connection, MVar ChaChaDRG, ThentosConfig)
- newtype Action e s a = Action {
- fromAction :: ReaderT ActionState (EitherT (ThentosError e) (StateT s (LIO DCLabel))) a
- data ActionError e
- = ActionErrorThentos (ThentosError e)
- | ActionErrorAnyLabel AnyLabelError
- | ActionErrorUnknown SomeException
- runAction :: (Show e, Typeable e) => s -> ActionState -> Action e s a -> IO (a, s)
- runActionWithPrivs :: (Show e, Typeable e) => [CNF] -> s -> ActionState -> Action e s a -> IO (a, s)
- runActionWithClearance :: (Show e, Typeable e) => DCLabel -> s -> ActionState -> Action e s a -> IO (a, s)
- runActionAsAgent :: (Show e, Typeable e) => Agent -> s -> ActionState -> Action e s a -> IO (a, s)
- runActionInThentosSession :: (Show e, Typeable e) => ThentosSessionToken -> s -> ActionState -> Action e s a -> IO (a, s)
- runActionE :: forall s e a. (Show e, Typeable e) => s -> ActionState -> Action e s a -> IO (Either (ActionError e) a, s)
- runActionWithPrivsE :: (Show e, Typeable e) => [CNF] -> s -> ActionState -> Action e s a -> IO (Either (ActionError e) a, s)
- runActionWithClearanceE :: (Show e, Typeable e) => DCLabel -> s -> ActionState -> Action e s a -> IO (Either (ActionError e) a, s)
- runActionAsAgentE :: (Show e, Typeable e) => Agent -> s -> ActionState -> Action e s a -> IO (Either (ActionError e) a, s)
- runActionInThentosSessionE :: (Show e, Typeable e) => ThentosSessionToken -> s -> ActionState -> Action e s a -> IO (Either (ActionError e) a, s)
- grantAccessRights'P :: [CNF] -> Action e s ()
- accessRightsByAgent'P :: Agent -> Action e s [CNF]
- accessRightsByThentosSession'P :: ThentosSessionToken -> Action e s [CNF]
- query'P :: ThentosQuery e v -> Action e s v
- getConfig'P :: Action e s ThentosConfig
- getCurrentTime'P :: Action e s Timestamp
- genRandomBytes'P :: Int -> Action e s SBS
- makeUserFromFormData'P :: UserFormData -> Action e s User
- hashUserPass'P :: UserPass -> Action e s (HashedSecret UserPass)
- hashServiceKey'P :: ServiceKey -> Action e s (HashedSecret ServiceKey)
- sendMail'P :: SmtpConfig -> Maybe UserName -> UserEmail -> ST -> ST -> Action e s ()
- renderTextTemplate'P :: ST -> MuContext IO -> Action e s LT
- logger'P :: Priority -> String -> Action e s ()
- logIfError'P :: forall m l e v f s. (m ~ Action f s, Monad m, MonadLIO l m, MonadError e m, Show e, Show f) => m v -> m v
- taintMsg :: String -> DCLabel -> Action e s ()
- guardWriteMsg :: String -> DCLabel -> Action e s ()
types
newtype ActionState
ActionState | |
|
Generic ActionState | |
MonadReader ActionState (Action e s) | |
MonadReader ActionState (UnsafeAction e s) | |
type Rep ActionState |
newtype Action e s a
The Action
monad transformer stack. It contains:
LIO
as a base monad.- A state of polymorphic type (for use e.g. by the frontend handlers to store cookies etc.)
- The option of throwing
ThentosError e
. (Not 'ActionError e', which contains authorization errors that must not be catchable from inside anAction
.) - An
ActionState
in a reader. The state can be used by actions for calls toLIO
, which will have authorized effect. Since it is contained in a reader, actions do not have the power to corrupt it.
Action | |
|
data ActionError e
Errors known by runActionE
, runAction
, ....
The MonadError
instance of newtype Action
lets you throw and catch errors from *within* the
Action
, i.e., at construction time). These are errors are handled in the ActionErrorThentos
constructor. Label errors and other (possibly async) exceptions are caught (if possible) in
runActionE
and its friends and maintained in other ActionError
constructors.
ActionErrorThentos (ThentosError e) | |
ActionErrorAnyLabel AnyLabelError | |
ActionErrorUnknown SomeException |
Show e => Show (ActionError e) | |
(Show e, Typeable * e) => Exception (ActionError e) |
running actions
runAction :: (Show e, Typeable e) => s -> ActionState -> Action e s a -> IO (a, s)
Call runActionE
and throw Left
values.
runActionWithPrivs :: (Show e, Typeable e) => [CNF] -> s -> ActionState -> Action e s a -> IO (a, s)
runActionWithClearance :: (Show e, Typeable e) => DCLabel -> s -> ActionState -> Action e s a -> IO (a, s)
runActionAsAgent :: (Show e, Typeable e) => Agent -> s -> ActionState -> Action e s a -> IO (a, s)
runActionInThentosSession :: (Show e, Typeable e) => ThentosSessionToken -> s -> ActionState -> Action e s a -> IO (a, s)
runActionE :: forall s e a. (Show e, Typeable e) => s -> ActionState -> Action e s a -> IO (Either (ActionError e) a, s)
Call an action with no access rights. Catch all errors. Initial LIO state is not
dcDefaultState
, but LIOState dcBottom dcBottom
: Only actions that require no clearance can be
executed, and the label has not been guarded by any action yet.
Updates to the polymorphic state inside the action are effective in the result if there are no
exceptions or if a ThentosError
is thrown, but NOT if any other exceptions (such as
AnyLabelError
) are thrown.
runActionWithPrivsE :: (Show e, Typeable e) => [CNF] -> s -> ActionState -> Action e s a -> IO (Either (ActionError e) a, s)
runActionWithClearanceE :: (Show e, Typeable e) => DCLabel -> s -> ActionState -> Action e s a -> IO (Either (ActionError e) a, s)
runActionAsAgentE :: (Show e, Typeable e) => Agent -> s -> ActionState -> Action e s a -> IO (Either (ActionError e) a, s)
runActionInThentosSessionE :: (Show e, Typeable e) => ThentosSessionToken -> s -> ActionState -> Action e s a -> IO (Either (ActionError e) a, s)
labels, privileges and access rights.
grantAccessRights'P :: [CNF] -> Action e s ()
In order to execute an Action
, certain access rights need to be granted. A set of access
rights is a list of ToCNF
instances that are used to update the current clearance in the
LIOState
in the LIO
monad underlying Action
.
To execute an Action
with the access rights of UserId
u
and BasicRole
r
:
>>>
grantAccessRights'P [toCNF u, toCNF r]
Or, to grant just r
:
>>>
grantAccessRights'P [r]
Adding more access rights must increase access, so for a list ars
of access rights, the
constructed clearance level c
must satisfy:
>>>
and [ (ar %% ar) `canFlowTo` c | ar <- ars ]
Therefore, c
is defined as the least upper bound (join) of the labels constructed from
individual access rights:
>>>
c = foldl' (lub) dcBottom [ ar %% ar | ar <- ars ]
accessRightsByAgent'P :: Agent -> Action e s [CNF]
Construct a DCLabel
from agent's roles.
accessRightsByThentosSession'P :: ThentosSessionToken -> Action e s [CNF]
TCB business
query'P :: ThentosQuery e v -> Action e s v
getConfig'P :: Action e s ThentosConfig
getCurrentTime'P :: Action e s Timestamp
genRandomBytes'P :: Int -> Action e s SBS
A relative of cprgGenerate
from crypto-random that lives in
Action
.
makeUserFromFormData'P :: UserFormData -> Action e s User
hashUserPass'P :: UserPass -> Action e s (HashedSecret UserPass)
hashServiceKey'P :: ServiceKey -> Action e s (HashedSecret ServiceKey)
sendMail'P :: SmtpConfig -> Maybe UserName -> UserEmail -> ST -> ST -> Action e s ()
renderTextTemplate'P :: ST -> MuContext IO -> Action e s LT
Render a Hastache template for plain-text output (none of the characters in context variables will be escaped).
logIfError'P :: forall m l e v f s. (m ~ Action f s, Monad m, MonadLIO l m, MonadError e m, Show e, Show f) => m v -> m v
(This type signature could be greatly simplified, but that would also make it less explanatory.)
better label errors
taintMsg :: String -> DCLabel -> Action e s ()
Call taint
, but log a more informative error in case of fail.
guardWriteMsg :: String -> DCLabel -> Action e s ()