Prevent non-admins from creating Manager or Admin accounts

Client-side, I'm not exposing the role option to users. Server-side, I'm
asserting that requests to create Manager and Admin accounts are attempted by
users with a session tied to an admin account.
This commit is contained in:
William Carroll 2020-08-01 11:48:55 +01:00
parent a3732300e1
commit 83f4f8e9d6
2 changed files with 29 additions and 14 deletions

View file

@ -16,6 +16,7 @@ type SessionCookie = Header' '[Required] "Cookie" T.SessionCookie
type API =
-- accounts: Create
"accounts"
:> Header "Cookie" T.SessionCookie
:> ReqBody '[JSON] T.CreateAccountRequest
:> Post '[JSON] NoContent
:<|> "verify"

View file

@ -77,20 +77,34 @@ server config@T.Config{..} = createAccount
adminsOnly cookie = adminsAnd cookie (const True)
-- TODO(wpcarro): Handle failed CONSTRAINTs instead of sending 500s
createAccount :: T.CreateAccountRequest -> Handler NoContent
createAccount T.CreateAccountRequest{..} = do
secretUUID <- liftIO $ T.RegistrationSecret <$> Random.randomIO
liftIO $ PendingAccounts.create dbFile
secretUUID
createAccountRequestUsername
createAccountRequestPassword
createAccountRequestRole
createAccountRequestEmail
liftIO $ sendVerifyEmail config mailgunAPIKey
createAccountRequestUsername
createAccountRequestEmail
secretUUID
pure NoContent
createAccount :: Maybe T.SessionCookie
-> T.CreateAccountRequest
-> Handler NoContent
createAccount mCookie T.CreateAccountRequest{..} =
case (mCookie, createAccountRequestRole) of
(_, T.RegularUser) ->
doCreateAccount
(Nothing, T.Manager) ->
throwError err401 { errBody = "Only admins can create Manager accounts" }
(Nothing, T.Admin) ->
throwError err401 { errBody = "Only admins can create Admin accounts" }
(Just cookie, _) ->
adminsOnly cookie doCreateAccount
where
doCreateAccount :: Handler NoContent
doCreateAccount = do
secretUUID <- liftIO $ T.RegistrationSecret <$> Random.randomIO
liftIO $ PendingAccounts.create dbFile
secretUUID
createAccountRequestUsername
createAccountRequestPassword
createAccountRequestRole
createAccountRequestEmail
liftIO $ sendVerifyEmail config mailgunAPIKey
createAccountRequestUsername
createAccountRequestEmail
secretUUID
pure NoContent
verifyAccount :: Text -> Text -> Handler NoContent
verifyAccount username secret = do