dev:web: refactor permission checking
This commit is contained in:
parent
24ce9b5be1
commit
2ba321885d
@ -16,7 +16,7 @@
|
|||||||
module Hledger.Web.Foundation where
|
module Hledger.Web.Foundation where
|
||||||
|
|
||||||
import Control.Applicative ((<|>))
|
import Control.Applicative ((<|>))
|
||||||
import Control.Monad (join, when)
|
import Control.Monad (join, when, unless)
|
||||||
-- import Control.Monad.Except (runExceptT) -- now re-exported by Hledger
|
-- import Control.Monad.Except (runExceptT) -- now re-exported by Hledger
|
||||||
import qualified Data.ByteString.Char8 as BC
|
import qualified Data.ByteString.Char8 as BC
|
||||||
import Data.Traversable (for)
|
import Data.Traversable (for)
|
||||||
@ -283,3 +283,11 @@ getCurrentJournal jref opts d = do
|
|||||||
liftIO . writeIORef jref $ filterJournalTransactions depthlessinitialq j'
|
liftIO . writeIORef jref $ filterJournalTransactions depthlessinitialq j'
|
||||||
return (j',Nothing)
|
return (j',Nothing)
|
||||||
Right (_, False) -> return (j, Nothing)
|
Right (_, False) -> return (j, Nothing)
|
||||||
|
|
||||||
|
-- | In a request handler, check for the given permission
|
||||||
|
-- and fail with a message if it's not present.
|
||||||
|
require :: Permission -> Handler ()
|
||||||
|
require p = do
|
||||||
|
VD{perms} <- getViewData
|
||||||
|
unless (p `elem` perms) $ permissionDenied $
|
||||||
|
"Missing the '" <> T.pack (showPermission p) <> "' permission"
|
||||||
|
|||||||
@ -30,8 +30,8 @@ getAddR = do
|
|||||||
postAddR :: Handler ()
|
postAddR :: Handler ()
|
||||||
postAddR = do
|
postAddR = do
|
||||||
checkServerSideUiEnabled
|
checkServerSideUiEnabled
|
||||||
VD{perms, j, today} <- getViewData
|
VD{j, today} <- getViewData
|
||||||
when (AddPermission `notElem` perms) (permissionDenied "Missing the 'add' permission")
|
require AddPermission
|
||||||
|
|
||||||
((res, view), enctype) <- runFormPost $ addForm j today
|
((res, view), enctype) <- runFormPost $ addForm j today
|
||||||
case res of
|
case res of
|
||||||
@ -59,8 +59,8 @@ postAddR = do
|
|||||||
-- The web form handler above should probably use PUT as well.
|
-- The web form handler above should probably use PUT as well.
|
||||||
putAddR :: Handler RepJson
|
putAddR :: Handler RepJson
|
||||||
putAddR = do
|
putAddR = do
|
||||||
VD{perms, j, opts} <- getViewData
|
VD{j, opts} <- getViewData
|
||||||
when (AddPermission `notElem` perms) (permissionDenied "Missing the 'add' permission")
|
require AddPermission
|
||||||
|
|
||||||
(r :: Result Transaction) <- parseCheckJsonBody
|
(r :: Result Transaction) <- parseCheckJsonBody
|
||||||
case r of
|
case r of
|
||||||
|
|||||||
@ -31,8 +31,8 @@ getEditR f = do
|
|||||||
postEditR :: FilePath -> Handler ()
|
postEditR :: FilePath -> Handler ()
|
||||||
postEditR f = do
|
postEditR f = do
|
||||||
checkServerSideUiEnabled
|
checkServerSideUiEnabled
|
||||||
VD {perms, j} <- getViewData
|
VD {j} <- getViewData
|
||||||
when (EditPermission `notElem` perms) (permissionDenied "Missing the 'edit' permission")
|
require EditPermission
|
||||||
|
|
||||||
(f', txt) <- journalFile404 f j
|
(f', txt) <- journalFile404 f j
|
||||||
((res, view), enctype) <- runFormPost (editForm f' txt)
|
((res, view), enctype) <- runFormPost (editForm f' txt)
|
||||||
|
|||||||
@ -21,7 +21,7 @@ getJournalR :: Handler Html
|
|||||||
getJournalR = do
|
getJournalR = do
|
||||||
checkServerSideUiEnabled
|
checkServerSideUiEnabled
|
||||||
VD{perms, j, q, opts, qparam, qopts, today} <- getViewData
|
VD{perms, j, q, opts, qparam, qopts, today} <- getViewData
|
||||||
when (ViewPermission `notElem` perms) (permissionDenied "Missing the 'view' permission")
|
require ViewPermission
|
||||||
let title = case inAccount qopts of
|
let title = case inAccount qopts of
|
||||||
Nothing -> "General Journal"
|
Nothing -> "General Journal"
|
||||||
Just (a, inclsubs) -> "Transactions in " <> a <> if inclsubs then "" else " (excluding subaccounts)"
|
Just (a, inclsubs) -> "Transactions in " <> a <> if inclsubs then "" else " (excluding subaccounts)"
|
||||||
|
|||||||
@ -38,8 +38,8 @@ getRootR = do
|
|||||||
getManageR :: Handler Html
|
getManageR :: Handler Html
|
||||||
getManageR = do
|
getManageR = do
|
||||||
checkServerSideUiEnabled
|
checkServerSideUiEnabled
|
||||||
VD{perms, j} <- getViewData
|
VD{j} <- getViewData
|
||||||
when (EditPermission `notElem` perms) (permissionDenied "Missing the 'edit' permission")
|
require EditPermission
|
||||||
defaultLayout $ do
|
defaultLayout $ do
|
||||||
setTitle "Edit journal"
|
setTitle "Edit journal"
|
||||||
$(widgetFile "manage")
|
$(widgetFile "manage")
|
||||||
@ -47,8 +47,8 @@ getManageR = do
|
|||||||
getDownloadR :: FilePath -> Handler TypedContent
|
getDownloadR :: FilePath -> Handler TypedContent
|
||||||
getDownloadR f = do
|
getDownloadR f = do
|
||||||
checkServerSideUiEnabled
|
checkServerSideUiEnabled
|
||||||
VD{perms, j} <- getViewData
|
VD{j} <- getViewData
|
||||||
when (EditPermission `notElem` perms) (permissionDenied "Missing the 'edit' permission")
|
require EditPermission
|
||||||
(f', txt) <- journalFile404 f j
|
(f', txt) <- journalFile404 f j
|
||||||
addHeader "Content-Disposition" ("attachment; filename=\"" <> T.pack f' <> "\"")
|
addHeader "Content-Disposition" ("attachment; filename=\"" <> T.pack f' <> "\"")
|
||||||
sendResponse ("text/plain" :: ByteString, toContent txt)
|
sendResponse ("text/plain" :: ByteString, toContent txt)
|
||||||
@ -57,50 +57,46 @@ getDownloadR f = do
|
|||||||
|
|
||||||
getVersionR :: Handler TypedContent
|
getVersionR :: Handler TypedContent
|
||||||
getVersionR = do
|
getVersionR = do
|
||||||
VD{perms} <- getViewData
|
require ViewPermission
|
||||||
when (ViewPermission `notElem` perms) (permissionDenied "Missing the 'view' permission")
|
selectRep $ provideJson $ packageversion
|
||||||
selectRep $ do
|
|
||||||
provideJson $ packageversion
|
|
||||||
|
|
||||||
getAccountnamesR :: Handler TypedContent
|
getAccountnamesR :: Handler TypedContent
|
||||||
getAccountnamesR = do
|
getAccountnamesR = do
|
||||||
VD{perms, j} <- getViewData
|
VD{j} <- getViewData
|
||||||
when (ViewPermission `notElem` perms) (permissionDenied "Missing the 'view' permission")
|
require ViewPermission
|
||||||
selectRep $ do
|
selectRep $ provideJson $ journalAccountNames j
|
||||||
provideJson $ journalAccountNames j
|
|
||||||
|
|
||||||
getTransactionsR :: Handler TypedContent
|
getTransactionsR :: Handler TypedContent
|
||||||
getTransactionsR = do
|
getTransactionsR = do
|
||||||
VD{perms, j} <- getViewData
|
VD{j} <- getViewData
|
||||||
when (ViewPermission `notElem` perms) (permissionDenied "Missing the 'view' permission")
|
require ViewPermission
|
||||||
selectRep $ do
|
selectRep $ provideJson $ jtxns j
|
||||||
provideJson $ jtxns j
|
|
||||||
|
|
||||||
getPricesR :: Handler TypedContent
|
getPricesR :: Handler TypedContent
|
||||||
getPricesR = do
|
getPricesR = do
|
||||||
VD{perms, j} <- getViewData
|
VD{j} <- getViewData
|
||||||
when (ViewPermission `notElem` perms) (permissionDenied "Missing the 'view' permission")
|
require ViewPermission
|
||||||
selectRep $ do
|
selectRep $
|
||||||
provideJson $ map priceDirectiveToMarketPrice $ jpricedirectives j
|
provideJson $ map priceDirectiveToMarketPrice $ jpricedirectives j
|
||||||
|
|
||||||
getCommoditiesR :: Handler TypedContent
|
getCommoditiesR :: Handler TypedContent
|
||||||
getCommoditiesR = do
|
getCommoditiesR = do
|
||||||
VD{perms, j} <- getViewData
|
VD{j} <- getViewData
|
||||||
when (ViewPermission `notElem` perms) (permissionDenied "Missing the 'view' permission")
|
require ViewPermission
|
||||||
selectRep $ do
|
selectRep $ do
|
||||||
provideJson $ (M.keys . jinferredcommodities) j
|
provideJson $ (M.keys . jinferredcommodities) j
|
||||||
|
|
||||||
getAccountsR :: Handler TypedContent
|
getAccountsR :: Handler TypedContent
|
||||||
getAccountsR = do
|
getAccountsR = do
|
||||||
VD{perms, j} <- getViewData
|
VD{j} <- getViewData
|
||||||
when (ViewPermission `notElem` perms) (permissionDenied "Missing the 'view' permission")
|
require ViewPermission
|
||||||
selectRep $ do
|
selectRep $ do
|
||||||
provideJson $ flattenAccounts $ mapAccounts (accountSetDeclarationInfo j) $ ledgerRootAccount $ ledgerFromJournal Any j
|
provideJson $ flattenAccounts $ mapAccounts (accountSetDeclarationInfo j) $ ledgerRootAccount $ ledgerFromJournal Any j
|
||||||
|
|
||||||
getAccounttransactionsR :: Text -> Handler TypedContent
|
getAccounttransactionsR :: Text -> Handler TypedContent
|
||||||
getAccounttransactionsR a = do
|
getAccounttransactionsR a = do
|
||||||
VD{perms, j} <- getViewData
|
VD{j} <- getViewData
|
||||||
when (ViewPermission `notElem` perms) (permissionDenied "Missing the 'view' permission")
|
require ViewPermission
|
||||||
let
|
let
|
||||||
rspec = defreportspec
|
rspec = defreportspec
|
||||||
thisacctq = Acct $ accountNameToAccountRegex a -- includes subs
|
thisacctq = Acct $ accountNameToAccountRegex a -- includes subs
|
||||||
|
|||||||
@ -27,7 +27,7 @@ getRegisterR :: Handler Html
|
|||||||
getRegisterR = do
|
getRegisterR = do
|
||||||
checkServerSideUiEnabled
|
checkServerSideUiEnabled
|
||||||
VD{perms, j, q, opts, qparam, qopts, today} <- getViewData
|
VD{perms, j, q, opts, qparam, qopts, today} <- getViewData
|
||||||
when (ViewPermission `notElem` perms) (permissionDenied "Missing the 'view' permission")
|
require ViewPermission
|
||||||
|
|
||||||
let (a,inclsubs) = fromMaybe ("all accounts",True) $ inAccount qopts
|
let (a,inclsubs) = fromMaybe ("all accounts",True) $ inAccount qopts
|
||||||
s1 = if inclsubs then "" else " (excluding subaccounts)"
|
s1 = if inclsubs then "" else " (excluding subaccounts)"
|
||||||
|
|||||||
@ -35,8 +35,8 @@ getUploadR f = do
|
|||||||
postUploadR :: FilePath -> Handler ()
|
postUploadR :: FilePath -> Handler ()
|
||||||
postUploadR f = do
|
postUploadR f = do
|
||||||
checkServerSideUiEnabled
|
checkServerSideUiEnabled
|
||||||
VD {perms, j} <- getViewData
|
VD {j} <- getViewData
|
||||||
when (EditPermission `notElem` perms) (permissionDenied "Missing the 'edit' permission")
|
require EditPermission
|
||||||
|
|
||||||
(f', _) <- journalFile404 f j
|
(f', _) <- journalFile404 f j
|
||||||
((res, view), enctype) <- runFormPost (uploadForm f')
|
((res, view), enctype) <- runFormPost (uploadForm f')
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import Safe (lastMay)
|
|||||||
import Hledger.Cli hiding (packageversion, progname, prognameandversion)
|
import Hledger.Cli hiding (packageversion, progname, prognameandversion)
|
||||||
import Hledger.Web.Settings (defhost, defport, defbaseurl)
|
import Hledger.Web.Settings (defhost, defport, defbaseurl)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
import Data.Char (toLower)
|
||||||
|
|
||||||
-- cf Hledger.Cli.Version
|
-- cf Hledger.Cli.Version
|
||||||
|
|
||||||
@ -193,6 +194,10 @@ parsePermission "add" = Right AddPermission
|
|||||||
parsePermission "edit" = Right EditPermission
|
parsePermission "edit" = Right EditPermission
|
||||||
parsePermission x = Left $ T.pack $ BC.unpack x
|
parsePermission x = Left $ T.pack $ BC.unpack x
|
||||||
|
|
||||||
|
-- | Convert to the lower case permission name.
|
||||||
|
showPermission :: Permission -> String
|
||||||
|
showPermission p = map toLower $ reverse $ drop 10 $ reverse $ show p
|
||||||
|
|
||||||
-- | For the --allow option: how much access to allow to hledger-web users ?
|
-- | For the --allow option: how much access to allow to hledger-web users ?
|
||||||
data AccessLevel =
|
data AccessLevel =
|
||||||
ViewAccess -- ^ view permission only
|
ViewAccess -- ^ view permission only
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user