module IHP.Controller.AccessDenied ( accessDeniedWhen , accessDeniedUnless , handleAccessDeniedFound , buildAccessDeniedResponse , renderAccessDenied ) where import IHP.Prelude hiding (displayException) import IHP.Controller.RequestContext import Network.HTTP.Types (status403) import Network.Wai import Network.HTTP.Types.Header import qualified Text.Blaze.Html.Renderer.Utf8 as Blaze import qualified Data.ByteString.Lazy as LBS import IHP.HSX.QQ (hsx) import qualified System.Directory as Directory import IHP.Controller.Context import IHP.Controller.Response (respondAndExit) -- | Stops the action execution with an access denied message (403) when the access condition is True. -- -- __Example:__ Checking a user is the author of a blog post. -- -- > action EditPostAction { postId } = do -- > post <- fetch postId -- > accessDeniedWhen (post.authorId /= currentUserId) -- > -- > renderHtml EditView { .. } -- -- This will throw an error and prevent the view from being rendered when the current user is not the author of the post. accessDeniedWhen :: (?context :: ControllerContext) => Bool -> IO () accessDeniedWhen condition = when condition renderAccessDenied -- | Stops the action execution with an access denied message (403) when the access condition is False. -- -- __Example:__ Checking a user is the author of a blog post. -- -- > action EditPostAction { postId } = do -- > post <- fetch postId -- > accessDeniedUnless (post.authorId == currentUserId) -- > -- > renderHtml EditView { .. } -- -- This will throw an error and prevent the view from being rendered when the current user is not the author of the post. accessDeniedUnless :: (?context :: ControllerContext) => Bool -> IO () accessDeniedUnless condition = unless condition renderAccessDenied -- | Renders a 403 access denied response. If a static/403.html exists, that is rendered instead of the IHP access denied page. handleAccessDeniedFound :: Request -> Respond -> IO ResponseReceived handleAccessDeniedFound request respond = do response <- buildAccessDeniedResponse respond response buildAccessDeniedResponse :: IO Response buildAccessDeniedResponse = do hasCustomAccessDenied <- Directory.doesFileExist "static/403.html" if hasCustomAccessDenied then customAccessDeniedResponse else pure defaultAccessDeniedResponse -- | The default IHP 403 not found page defaultAccessDeniedResponse :: Response defaultAccessDeniedResponse = responseBuilder status403 [(hContentType, "text/html")] $ Blaze.renderHtmlBuilder [hsx|
Access denied