Merge branch 'master' into exam-office
This commit is contained in:
commit
99b25cfbc6
18
CHANGELOG.md
18
CHANGELOG.md
@ -2,6 +2,24 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [6.7.0](https://gitlab.cip.ifi.lmu.de/jost/UniWorX/compare/v6.6.0...v6.7.0) (2019-09-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datepicker:** increase datepicker z-index in modals ([593a6a7](https://gitlab.cip.ifi.lmu.de/jost/UniWorX/commit/593a6a7))
|
||||
* **datepicker:** quickfix to fix datepicker position in modals ([3f9454a](https://gitlab.cip.ifi.lmu.de/jost/UniWorX/commit/3f9454a))
|
||||
* **submission-users:** properly delete old invitations ([91c926b](https://gitlab.cip.ifi.lmu.de/jost/UniWorX/commit/91c926b))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **admin-users:** allow adding users ([67f1201](https://gitlab.cip.ifi.lmu.de/jost/UniWorX/commit/67f1201))
|
||||
* **health:** timeout all health checks ([33338cd](https://gitlab.cip.ifi.lmu.de/jost/UniWorX/commit/33338cd))
|
||||
* **invitations:** additional explanation for new users ([bb9c34f](https://gitlab.cip.ifi.lmu.de/jost/UniWorX/commit/bb9c34f))
|
||||
|
||||
|
||||
|
||||
## [6.6.0](https://gitlab.cip.ifi.lmu.de/jost/UniWorX/compare/v6.5.0...v6.6.0) (2019-09-09)
|
||||
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import { Utility } from '../../core/utility';
|
||||
import moment from 'moment';
|
||||
|
||||
const KEYCODE_ESCAPE = 27;
|
||||
const Z_INDEX_MODAL = 9999;
|
||||
|
||||
// INTERNAL (Uni2work specific) formats for formatting dates and/or times
|
||||
const FORM_DATE_FORMAT = {
|
||||
@ -139,6 +140,16 @@ export class Datepicker {
|
||||
// initialize tail.datetime (datepicker) instance
|
||||
this.datepickerInstance = datetime(this._element, { ...datepickerGlobalConfig, ...datepickerConfig });
|
||||
|
||||
// append the datepicker element (dt) to the form
|
||||
this._element.form.appendChild(this.datepickerInstance.dt);
|
||||
|
||||
// if the input element is in any open modal, increase the z-index of the datepicker and set its position to fixed to avoid repositioning on page scroll
|
||||
// FIXME: instead of setting the position to fixed, use absolute and reposition (decrease left)
|
||||
if (this._element.closest('.modal--open')) {
|
||||
this.datepickerInstance.dt.style.zIndex = Z_INDEX_MODAL;
|
||||
this.datepickerInstance.dt.style.position = 'fixed';
|
||||
}
|
||||
|
||||
// register this datepicker instance with the formID of the given element in the datepicker collection
|
||||
const formID = this._element.form.id;
|
||||
const elemID = this._element.id;
|
||||
|
||||
@ -789,9 +789,9 @@ MailUserRightsIntro name@Text email@UserEmail: #{name} <#{email}> hat folgende U
|
||||
MailNoLecturerRights: Sie haben derzeit keine Dozenten-Rechte.
|
||||
MailLecturerRights n@Int: Als Dozent dürfen Sie Veranstaltungen innerhalb #{pluralDE n "Ihres Instituts" "Ihrer Institute"} anlegen.
|
||||
|
||||
MailSubjectUserAuthModeUpdate: Änderung Ihres Uni2work-Anmeldemodus
|
||||
UserAuthModePWHashChangedToLDAP: Sie melden sich nun mit Ihrer Campus-Kennung an
|
||||
UserAuthModeLDAPChangedToPWHash: Sie melden sich nun mit einer Uni2work-internen Kennung an
|
||||
MailSubjectUserAuthModeUpdate: Ihr Uni2work-Login
|
||||
UserAuthModePWHashChangedToLDAP: Sie können sich nun mit Ihrer Campus-Kennung in Uni2work einloggen
|
||||
UserAuthModeLDAPChangedToPWHash: Sie können sich nun mit einer Uni2work-internen Kennung in Uni2work einloggen
|
||||
NewPasswordLinkTip: Das Passwort Ihrer Uni2work-internen Kennung können Sie auf der folgenden Seite setzen:
|
||||
NewPasswordLink: Neues Passwort setzen
|
||||
AuthPWHashTip: Sie müssen nun das mit "Uni2work-Login" beschriftete Login-Formular verwenden. Stellen Sie bitte sicher, dass Sie ein Passwort gesetzt haben, bevor Sie versuchen sich anzumelden.
|
||||
@ -804,6 +804,8 @@ MailSubjectSupportCustom customSubject@Text: [Support] #{customSubject}
|
||||
CommCourseSubject: Kursmitteilung
|
||||
MailSubjectLecturerInvitation tid@TermId ssh@SchoolId csh@CourseShorthand: [#{tid}-#{ssh}-#{csh}] Einladung zum Kursverwalter
|
||||
InvitationAcceptDecline: Einladung annehmen/ablehnen
|
||||
InvitationFromTip displayName@Text: Sie erhalten diese Einladung, weil #{displayName} ihren Versand in Uni2work ausgelöst hat.
|
||||
InvitationUniWorXTip: Uni2work ist ein webbasiertes Lehrverwaltungssystem der LMU München.
|
||||
|
||||
MailSubjectParticipantInvitation tid@TermId ssh@SchoolId csh@CourseShorthand: [#{tid}-#{ssh}-#{csh}] Einladung zum Kursteilname
|
||||
|
||||
@ -1010,6 +1012,7 @@ MenuCourseApplications: Bewerbungen
|
||||
MenuTermShow: Semester
|
||||
MenuSubmissionDelete: Abgabe löschen
|
||||
MenuUsers: Benutzer
|
||||
MenuUserAdd: Benutzer anlegen
|
||||
MenuUserNotifications: Benachrichtigungs-Einstellungen
|
||||
MenuUserPassword: Passwort
|
||||
MenuAdminTest: Admin-Demo
|
||||
@ -1692,4 +1695,16 @@ ExamOfficeFieldForced: Forcierte Einsicht
|
||||
InvalidExamOfficeFieldMode parseErr@Text: Konnte „#{parseErr}“ nicht interpretieren
|
||||
|
||||
LdapIdentification: Campus-Kennung
|
||||
LdapIdentificationOrEmail: Campus-Kennung/E-Mail Addresse
|
||||
LdapIdentificationOrEmail: Campus-Kennung/E-Mail Addresse
|
||||
AdminUserTitle: Titel
|
||||
AdminUserFirstName: Vorname
|
||||
AdminUserSurname: Nachname
|
||||
AdminUserDisplayName: Anzeige-Name
|
||||
AdminUserEmail: E-Mail Addresse
|
||||
AdminUserIdent: Identifikation
|
||||
AdminUserAuth: Authentifizierung
|
||||
AdminUserMatriculation: Matrikelnummer
|
||||
AuthKindLDAP: Campus-Kennung
|
||||
AuthKindPWHash: Uni2work-Kennung
|
||||
UserAdded: Benutzer erfolgreich angelegt
|
||||
UserCollision: Benutzer konnte wegen Eindeutigkeit nicht angelegt werden
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "uni2work",
|
||||
"version": "6.6.0",
|
||||
"version": "6.7.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "uni2work",
|
||||
"version": "6.6.0",
|
||||
"version": "6.7.0",
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
name: uniworx
|
||||
version: 6.6.0
|
||||
version: 6.7.0
|
||||
|
||||
dependencies:
|
||||
# Due to a bug in GHC 8.0.1, we block its usage
|
||||
|
||||
1
routes
1
routes
@ -51,6 +51,7 @@
|
||||
/users/#CryptoUUIDUser/password UserPasswordR GET POST !selfANDis-pw-hash
|
||||
!/users/functionary-invite/new AdminNewFunctionaryInviteR GET POST
|
||||
!/users/functionary-invite AdminFunctionaryInviteR GET POST
|
||||
!/users/add AdminUserAddR GET POST
|
||||
/admin AdminR GET
|
||||
/admin/features AdminFeaturesR GET POST
|
||||
/admin/test AdminTestR GET POST
|
||||
|
||||
@ -1773,6 +1773,7 @@ instance YesodBreadcrumbs UniWorX where
|
||||
breadcrumb (AuthR _) = return ("Login" , Just HomeR)
|
||||
breadcrumb HomeR = return ("Uni2work" , Nothing)
|
||||
breadcrumb UsersR = return ("Benutzer" , Just AdminR)
|
||||
breadcrumb AdminUserAddR = return ("Benutzer anlegen", Just UsersR)
|
||||
breadcrumb (AdminUserR _) = return ("Users" , Just UsersR)
|
||||
breadcrumb AdminR = return ("Administration", Nothing)
|
||||
breadcrumb AdminFeaturesR = return ("Test" , Just AdminR)
|
||||
@ -2148,6 +2149,14 @@ pageActions (UsersR) =
|
||||
, menuItemModal = True
|
||||
, menuItemAccessCallback' = return True
|
||||
}
|
||||
, MenuItem
|
||||
{ menuItemType = PageActionPrime
|
||||
, menuItemLabel = MsgMenuUserAdd
|
||||
, menuItemIcon = Nothing
|
||||
, menuItemRoute = SomeRoute AdminUserAddR
|
||||
, menuItemModal = True
|
||||
, menuItemAccessCallback' = return True
|
||||
}
|
||||
]
|
||||
pageActions (AdminUserR cID) =
|
||||
[ MenuItem
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||
|
||||
module Handler.Users where
|
||||
module Handler.Users
|
||||
( module Handler.Users
|
||||
) where
|
||||
|
||||
import Import
|
||||
|
||||
@ -30,6 +32,8 @@ import qualified Data.ByteString.Base64 as Base64
|
||||
import Text.Hamlet (ihamlet)
|
||||
import Data.Aeson hiding (Result(..))
|
||||
|
||||
import Handler.Users.Add as Handler.Users
|
||||
|
||||
|
||||
hijackUserForm :: Form ()
|
||||
hijackUserForm csrf = do
|
||||
|
||||
108
src/Handler/Users/Add.hs
Normal file
108
src/Handler/Users/Add.hs
Normal file
@ -0,0 +1,108 @@
|
||||
module Handler.Users.Add
|
||||
( AuthenticationKind(..)
|
||||
, classifyAuth, mkAuthMode
|
||||
, AdminUserForm(..), adminUserForm
|
||||
, getAdminUserAddR, postAdminUserAddR
|
||||
) where
|
||||
|
||||
|
||||
import Import
|
||||
import Handler.Utils
|
||||
import Jobs
|
||||
|
||||
|
||||
data AdminUserForm = AdminUserForm
|
||||
{ aufTitle :: Maybe Text
|
||||
, aufFirstName :: Text
|
||||
, aufSurname :: UserSurname
|
||||
, aufDisplayName :: UserDisplayName
|
||||
, aufMatriculation :: Maybe UserMatriculation
|
||||
, aufEmail :: UserEmail
|
||||
, aufIdent :: UserIdent
|
||||
, aufAuth :: AuthenticationKind
|
||||
}
|
||||
|
||||
data AuthenticationKind = AuthKindLDAP | AuthKindPWHash
|
||||
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)
|
||||
instance Universe AuthenticationKind
|
||||
instance Finite AuthenticationKind
|
||||
embedRenderMessage ''UniWorX ''AuthenticationKind id
|
||||
nullaryPathPiece ''AuthenticationKind $ camelToPathPiece' 2
|
||||
|
||||
classifyAuth :: AuthenticationMode -> AuthenticationKind
|
||||
classifyAuth AuthLDAP = AuthKindLDAP
|
||||
classifyAuth AuthPWHash{} = AuthKindPWHash
|
||||
|
||||
mkAuthMode :: AuthenticationKind -> AuthenticationMode
|
||||
mkAuthMode AuthKindLDAP = AuthLDAP
|
||||
mkAuthMode AuthKindPWHash = AuthPWHash ""
|
||||
|
||||
adminUserForm :: Maybe AdminUserForm -> Form AdminUserForm
|
||||
adminUserForm template = renderAForm FormStandard
|
||||
$ AdminUserForm
|
||||
<$> aopt (textField & cfStrip) (fslI MsgAdminUserTitle) (aufTitle <$> template)
|
||||
<*> areq (textField & cfStrip) (fslI MsgAdminUserFirstName) (aufFirstName <$> template)
|
||||
<*> areq (textField & cfStrip) (fslI MsgAdminUserSurname) (aufSurname <$> template)
|
||||
<*> areq (textField & cfStrip) (fslI MsgAdminUserDisplayName) (aufDisplayName <$> template)
|
||||
<*> aopt (textField & cfStrip) (fslI MsgAdminUserMatriculation) (aufMatriculation <$> template)
|
||||
<*> areq (emailField & cfCI) (fslI MsgAdminUserEmail) (aufEmail <$> template)
|
||||
<*> areq (textField & cfStrip & cfCI) (fslI MsgAdminUserIdent) (aufIdent <$> template)
|
||||
<*> areq (selectField optionsFinite) (fslI MsgAdminUserAuth) (aufAuth <$> template <|> Just AuthKindLDAP)
|
||||
|
||||
|
||||
getAdminUserAddR, postAdminUserAddR :: Handler Html
|
||||
getAdminUserAddR = postAdminUserAddR
|
||||
postAdminUserAddR = do
|
||||
((userRes, userView), userEnctype) <- runFormPost $ adminUserForm Nothing
|
||||
|
||||
formResult userRes $ \AdminUserForm{..} -> do
|
||||
now <- liftIO getCurrentTime
|
||||
UserDefaultConf{..} <- getsYesod $ view _appUserDefaults
|
||||
|
||||
let
|
||||
newUser@User{..} = User
|
||||
{ userIdent = aufIdent
|
||||
, userMaxFavourites = userDefaultMaxFavourites
|
||||
, userTheme = userDefaultTheme
|
||||
, userDateTimeFormat = userDefaultDateTimeFormat
|
||||
, userDateFormat = userDefaultDateFormat
|
||||
, userTimeFormat = userDefaultTimeFormat
|
||||
, userDownloadFiles = userDefaultDownloadFiles
|
||||
, userWarningDays = userDefaultWarningDays
|
||||
, userNotificationSettings = def
|
||||
, userMailLanguages = def
|
||||
, userTokensIssuedAfter = Nothing
|
||||
, userCreated = now
|
||||
, userLastLdapSynchronisation = Nothing
|
||||
, userLastAuthentication = Nothing
|
||||
, userEmail = aufEmail
|
||||
, userDisplayName = aufDisplayName
|
||||
, userFirstName = aufFirstName
|
||||
, userSurname = aufSurname
|
||||
, userTitle = aufTitle
|
||||
, userMatrikelnummer = aufMatriculation
|
||||
, userAuthentication = mkAuthMode aufAuth
|
||||
}
|
||||
|
||||
didInsert <- runDBJobs . runMaybeT $ do
|
||||
uid <- MaybeT $ insertUnique newUser
|
||||
lift . queueDBJob $ JobSynchroniseLdapUser uid
|
||||
lift . queueDBJob . JobQueueNotification $ NotificationUserAuthModeUpdate uid userAuthentication
|
||||
when (aufAuth == AuthKindPWHash) $
|
||||
lift . queueDBJob $ JobSendPasswordReset uid
|
||||
return uid
|
||||
|
||||
case didInsert of
|
||||
Just uid -> do
|
||||
addMessageI Success MsgUserAdded
|
||||
cID <- encrypt uid
|
||||
redirect $ AdminUserR cID
|
||||
Nothing ->
|
||||
addMessageI Error MsgUserCollision
|
||||
|
||||
siteLayoutMsg MsgMenuUserAdd $ do
|
||||
setTitleI MsgMenuUserAdd
|
||||
wrapForm userView def
|
||||
{ formAction = Just $ SomeRoute AdminUserAddR
|
||||
, formEncoding = userEnctype
|
||||
}
|
||||
@ -6,6 +6,8 @@ module Jobs.Handler.SendNotification.UserAuthModeUpdate
|
||||
|
||||
import Import
|
||||
|
||||
import Auth.PWHash (PWHashMessage(..))
|
||||
|
||||
import Handler.Utils.Mail
|
||||
import Jobs.Handler.SendNotification.Utils
|
||||
|
||||
@ -18,8 +20,8 @@ dispatchNotificationUserAuthModeUpdate nUser _nOriginalAuthMode jRecipient = us
|
||||
replaceMailHeader "Auto-Submitted" $ Just "auto-generated"
|
||||
setSubjectI MsgMailSubjectUserAuthModeUpdate
|
||||
|
||||
editNotifications <- mkEditNotifications jRecipient
|
||||
editNotifications <- ihamletSomeMessage <$> mkEditNotifications jRecipient
|
||||
|
||||
addAlternatives $
|
||||
providePreferredAlternative ($(ihamletFile "templates/mail/userAuthModeUpdate.hamlet") :: HtmlUrlI18n UniWorXMessage (Route UniWorX))
|
||||
providePreferredAlternative ($(ihamletFile "templates/mail/userAuthModeUpdate.hamlet") :: HtmlUrlI18n (SomeMessage UniWorX) (Route UniWorX))
|
||||
|
||||
|
||||
@ -9,3 +9,7 @@ $newline never
|
||||
<p>
|
||||
<a href=#{jInvitationUrl}>
|
||||
_{MsgInvitationAcceptDecline}
|
||||
<p>
|
||||
_{MsgInvitationFromTip (userDisplayName jInviter')}
|
||||
<p>
|
||||
_{MsgInvitationUniWorXTip}
|
||||
|
||||
@ -13,13 +13,18 @@ $newline never
|
||||
<h1>
|
||||
$case userAuthentication
|
||||
$of AuthLDAP
|
||||
_{MsgUserAuthModePWHashChangedToLDAP}
|
||||
_{SomeMessage MsgUserAuthModePWHashChangedToLDAP}
|
||||
$of AuthPWHash _
|
||||
_{MsgUserAuthModeLDAPChangedToPWHash}
|
||||
_{SomeMessage MsgUserAuthModeLDAPChangedToPWHash}
|
||||
$if is _AuthPWHash userAuthentication
|
||||
<p>
|
||||
_{MsgAuthPWHashTip}
|
||||
<p>
|
||||
_{MsgPasswordResetEmailIncoming}
|
||||
_{SomeMessage MsgAuthPWHashTip}
|
||||
<dd>
|
||||
<dt>_{SomeMessage MsgPWHashIdent}
|
||||
<dd style="font-family: monospace">#{userIdent}
|
||||
<dt>_{SomeMessage MsgPWHashPassword}
|
||||
<dd>
|
||||
_{SomeMessage MsgPasswordResetEmailIncoming}
|
||||
|
||||
^{editNotifications}
|
||||
$if is _Just userLastAuthentication
|
||||
^{editNotifications}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user