ID and SSH pub key can be set by the user

This commit is contained in:
Filip Gralinski 2015-11-10 21:35:42 +01:00
parent 8e9e32b676
commit 8c7e9f4a13
5 changed files with 62 additions and 8 deletions

View File

@ -173,6 +173,8 @@ instance YesodAuth App where
, userPassword = Nothing , userPassword = Nothing
, userName = Nothing , userName = Nothing
, userIsAdmin = False , userIsAdmin = False
, userLocalId = Nothing
, userSshPubKey = Nothing
} }
-- You can add other plugins like BrowserID, email or OAuth here -- You can add other plugins like BrowserID, email or OAuth here

View File

@ -7,11 +7,13 @@ import Yesod.Form.Bootstrap3 (BootstrapFormLayout (..), renderBootstrap3,
import Handler.Shared import Handler.Shared
import Handler.Extract import Handler.Extract
import Text.Regex.TDFA
getYourAccountR :: Handler Html getYourAccountR :: Handler Html
getYourAccountR = do getYourAccountR = do
userId <- requireAuthId userId <- requireAuthId
user <- runDB $ get404 userId user <- runDB $ get404 userId
(formWidget, formEnctype) <- generateFormPost (yourAccountForm $ userName user) (formWidget, formEnctype) <- generateFormPost (yourAccountForm (userName user) (userLocalId user) (userSshPubKey user))
let submission = Nothing :: Maybe (Import.FileInfo, Text) let submission = Nothing :: Maybe (Import.FileInfo, Text)
handlerName = "getYourAccountR" :: Text handlerName = "getYourAccountR" :: Text
defaultLayout $ do defaultLayout $ do
@ -21,22 +23,67 @@ getYourAccountR = do
postYourAccountR :: Handler Html postYourAccountR :: Handler Html
postYourAccountR = do postYourAccountR = do
((result, formWidget), formEnctype) <- runFormPost (yourAccountForm Nothing) ((result, formWidget), formEnctype) <- runFormPost (yourAccountForm Nothing Nothing Nothing)
let handlerName = "postYourAccountR" :: Text let handlerName = "postYourAccountR" :: Text
accountData = case result of accountData = case result of
FormSuccess res -> Just res FormSuccess res -> Just res
_ -> Nothing _ -> Nothing
Just (name, aboutMe) = accountData Just (name, localId, sshPubKey) = accountData
userId <- requireAuthId userId <- requireAuthId
runDB $ update userId [UserName =. name] updateUserAccount userId name localId sshPubKey
user <- runDB $ get404 userId user <- runDB $ get404 userId
defaultLayout $ do defaultLayout $ do
aDomId <- newIdent aDomId <- newIdent
setTitle "Your account" setTitle "Your account"
$(widgetFile "your-account") $(widgetFile "your-account")
yourAccountForm :: Maybe Text -> Maybe Text -> Maybe Text -> Form (Maybe Text, Maybe Text, Maybe Text)
yourAccountForm :: Maybe Text -> Form (Maybe Text, Maybe Text) yourAccountForm maybeName maybeLocalId maybeSshPubKey = renderBootstrap3 BootstrapBasicForm $ (,,)
yourAccountForm maybeName = renderBootstrap3 BootstrapBasicForm $ (,)
<$> aopt textField (fieldSettingsLabel MsgAccountName) (Just maybeName) <$> aopt textField (fieldSettingsLabel MsgAccountName) (Just maybeName)
<*> aopt textField (fieldSettingsLabel MsgAboutMe) Nothing <*> aopt textField (fieldSettingsLabel MsgId) (Just maybeLocalId)
<*> aopt textField (fieldSettingsLabel MsgSshPubKey) (Just maybeSshPubKey)
localIdRegexp = makeRegexOpts defaultCompOpt{newSyntax=True} defaultExecOpt ("\\`[a-z][-a-z0-9]{0,31}\\'" ::String)
unwantedLocalIds :: [Text]
unwantedLocalIds = ["git",
"gitolite",
"admin",
"root",
"filipg"]
isLocalIdAcceptable :: Text -> Bool
isLocalIdAcceptable localId =
match localIdRegexp (unpack localId) && not (localId `elem` unwantedLocalIds)
updateUserAccount :: Key User -> Maybe Text -> Maybe Text -> Maybe Text -> Handler ()
updateUserAccount userId name maybeLocalId maybeSshPubKey = do
updateJustName userId name
updateLocalIdAndPubKey userId maybeLocalId maybeSshPubKey
updateLocalIdAndPubKey :: Key User -> Maybe Text -> Maybe Text -> Handler ()
updateLocalIdAndPubKey userId (Just localId) maybeSshPubKey = do
if isLocalIdAcceptable localId
then
do
otherTheSame <- runDB $ selectFirst [UserLocalId ==. (Just localId), UserId !=. userId] []
case otherTheSame of
Just _ -> do
setMessage $ toHtml ("ID already used" :: Text)
Nothing -> do
user <- runDB $ get404 userId
case userLocalId user of
Just prevLocalId -> do
unless (prevLocalId == localId) $ setMessage $ toHtml ("only the administrator can change your ID" :: Text)
Nothing -> do
runDB $ update userId [UserLocalId =. (Just localId), UserSshPubKey =. maybeSshPubKey]
else
setMessage $ toHtml ("unexpected ID (use only lower-case letters, digits and hyphens, start with a letter)" :: Text)
updateLocalIdAndPubKey _ Nothing (Just _) = do
setMessage $ toHtml ("SSH public key cannot be added without an ID" :: Text)
updateLocalIdAndPubKey _ Nothing Nothing = return ()
updateJustName :: Key User -> Maybe Text -> Handler ()
updateJustName userId name = runDB $ update userId [UserName =. name]

View File

@ -4,6 +4,8 @@ User
UniqueUser ident UniqueUser ident
name Text Maybe name Text Maybe
isAdmin Bool default=True isAdmin Bool default=True
localId Text Maybe
sshPubKey Text Maybe
deriving Typeable deriving Typeable
Email Email
email Text email Text

View File

@ -112,6 +112,7 @@ library
, geval , geval
, filepath , filepath
, yesod-table , yesod-table
, regex-tdfa
executable gonito executable gonito
if flag(library-only) if flag(library-only)

View File

@ -16,3 +16,5 @@ SubmissionDescription: Submission description
YourAccount: your account YourAccount: your account
AboutMe: about me AboutMe: about me
AccountName: name AccountName: name
Id: ID
SshPubKey: your SSH public key