merge master

This commit is contained in:
SJost 2019-02-28 11:12:39 +01:00
commit d51608a1bf
13 changed files with 96 additions and 40 deletions

View File

@ -626,12 +626,12 @@ MenuCorrectionsCreate: Abgaben registrieren
MenuCorrectionsGrade: Abgaben bewerten MenuCorrectionsGrade: Abgaben bewerten
MenuAuthPreds: Authorisierungseinstellungen MenuAuthPreds: Authorisierungseinstellungen
AuthPredsInfo: Um eigene Veranstaltungen aus Sicht der Teilnehmer anzusehen, können Veranstalter und Korrektoren hier die Prüfung ihrer erweiterten Berechtigungen temporär deaktivieren. Abgewählte Prädikate werden nicht geprüft um Zugriffe zu gewähren, welche andernfalls nicht erlaubt wären. Diese Einstellungen gelten nur temporär bis Ihre Sitzung abgelaufen ist (d.h. bis ihr Browser-Cookie abgelaufen ist). AuthPredsInfo: Um eigene Veranstaltungen aus Sicht der Teilnehmer anzusehen, können Veranstalter und Korrektoren hier die Prüfung ihrer erweiterten Berechtigungen temporär deaktivieren. Abgewählte Prädikate schlagen immer fehl. Abgewählte Prädikate werden also nicht geprüft um Zugriffe zu gewähren, welche andernfalls nicht erlaubt wären. Diese Einstellungen gelten nur temporär bis Ihre Sitzung abgelaufen ist, d.h. bis ihr Browser-Cookie abgelaufen ist. Durch Abwahl von Prädikaten kann man sich höchstens temporär aussperren.
AuthPredsActive: Aktive Authorisierungsprädikate AuthPredsActive: Aktive Authorisierungsprädikate
AuthPredsActiveChanged: Authorisierungseinstellungen für aktuelle Sitzung gespeichert AuthPredsActiveChanged: Authorisierungseinstellungen für aktuelle Sitzung gespeichert
AuthTagFree: Seite ist universell zugänglich AuthTagFree: Seite ist universell zugänglich
AuthTagAdmin: Nutzer ist Administrator AuthTagAdmin: Nutzer ist Administrator
AuthTagNoEscalation: Nutzer-Rechte werden nicht erweitert AuthTagNoEscalation: Nutzer-Rechte werden nicht auf fremde Institute ausgeweitet
AuthTagDeprecated: Seite ist nicht überholt AuthTagDeprecated: Seite ist nicht überholt
AuthTagDevelopment: Seite ist nicht in Entwicklung AuthTagDevelopment: Seite ist nicht in Entwicklung
AuthTagLecturer: Nutzer ist Dozent AuthTagLecturer: Nutzer ist Dozent
@ -646,7 +646,7 @@ AuthTagOwner: Nutzer ist Besitzer
AuthTagRated: Korrektur ist bewertet AuthTagRated: Korrektur ist bewertet
AuthTagUserSubmissions: Abgaben erfolgen durch Kursteilnehmer AuthTagUserSubmissions: Abgaben erfolgen durch Kursteilnehmer
AuthTagCorrectorSubmissions: Abgaben erfolgen durch Korrektoren AuthTagCorrectorSubmissions: Abgaben erfolgen durch Korrektoren
AuthTagAuthentication: Authentifizierung erfüllt Anforderungen AuthTagAuthentication: Nutzer ist angemeldet, falls erforderlich
AuthTagRead: Zugriff ist nur lesend AuthTagRead: Zugriff ist nur lesend
AuthTagWrite: Zugriff ist i.A. schreibend AuthTagWrite: Zugriff ist i.A. schreibend

View File

@ -1,3 +1,4 @@
-- Some comments needes
User json User json
ident (CI Text) ident (CI Text)
authentication AuthenticationMode authentication AuthenticationMode
@ -24,7 +25,7 @@ UserLecturer
user UserId user UserId
school SchoolId school SchoolId
UniqueSchoolLecturer user school UniqueSchoolLecturer user school
StudyFeatures StudyFeatures -- Abschluss, Studiengang, Haupt/Nebenfachh und Fachsemester
user UserId user UserId
degree StudyDegreeId degree StudyDegreeId
field StudyTermsId field StudyTermsId
@ -34,12 +35,12 @@ StudyFeatures
valid Bool default=true valid Bool default=true
UniqueStudyFeatures user degree field type semester UniqueStudyFeatures user degree field type semester
-- UniqueUserSubject user degree field -- There exists a counterexample -- UniqueUserSubject user degree field -- There exists a counterexample
StudyDegree StudyDegree -- Studienabschluss
key Int key Int
shorthand Text Maybe shorthand Text Maybe
name Text Maybe name Text Maybe
Primary key Primary key
StudyTerms StudyTerms -- Studiengang
key Int key Int
shorthand Text Maybe shorthand Text Maybe
name Text Maybe name Text Maybe

View File

@ -13,7 +13,7 @@ import Handler.Utils.Course
import Handler.Utils.Delete import Handler.Utils.Delete
-- import Data.Time -- import Data.Time
import qualified Data.Text as T -- import qualified Data.Text as T
import Data.Function ((&)) import Data.Function ((&))
-- import Yesod.Form.Bootstrap3 -- import Yesod.Form.Bootstrap3
@ -282,9 +282,9 @@ getCShowR tid ssh csh = do
lecturers <- lift . E.select $ E.from $ \(lecturer `E.InnerJoin` user) -> do lecturers <- lift . E.select $ E.from $ \(lecturer `E.InnerJoin` user) -> do
E.on $ lecturer E.^. LecturerUser E.==. user E.^. UserId E.on $ lecturer E.^. LecturerUser E.==. user E.^. UserId
E.where_ $ lecturer E.^. LecturerCourse E.==. E.val cid E.where_ $ lecturer E.^. LecturerCourse E.==. E.val cid
return $ user E.^. UserDisplayName return $ (user E.^. UserDisplayName, user E.^. UserSurname, user E.^. UserEmail)
return (course,schoolName,participants,registration,lecturers)
return (course,schoolName,participants,registration,map E.unValue lecturers)
mRegFrom <- traverse (formatTime SelFormatDateTime) $ courseRegisterFrom course mRegFrom <- traverse (formatTime SelFormatDateTime) $ courseRegisterFrom course
mRegTo <- traverse (formatTime SelFormatDateTime) $ courseRegisterTo course mRegTo <- traverse (formatTime SelFormatDateTime) $ courseRegisterTo course
mDereg <- traverse (formatTime SelFormatDateTime) $ courseDeregisterUntil course mDereg <- traverse (formatTime SelFormatDateTime) $ courseDeregisterUntil course
@ -633,7 +633,7 @@ validateCourse CourseForm{..} =
type UserTableExpr = (E.SqlExpr (Entity User) `E.InnerJoin` E.SqlExpr (Entity CourseParticipant)) `E.LeftOuterJoin` E.SqlExpr (Maybe (Entity CourseUserNote)) type UserTableExpr = (E.SqlExpr (Entity User) `E.InnerJoin` E.SqlExpr (Entity CourseParticipant)) `E.LeftOuterJoin` E.SqlExpr (Maybe (Entity CourseUserNote))
type UserTableWhere = UserTableExpr -> E.SqlExpr (E.Value Bool) type UserTableWhere = UserTableExpr -> E.SqlExpr (E.Value Bool)
type UserTableData = DBRow (Entity User, E.Value UTCTime, E.Value (Maybe CourseUserNoteId)) type UserTableData = DBRow (Entity User, UTCTime, Maybe CourseUserNoteId)
forceUserTableType :: (UserTableExpr -> a) -> (UserTableExpr -> a) forceUserTableType :: (UserTableExpr -> a) -> (UserTableExpr -> a)
forceUserTableType = id forceUserTableType = id
@ -656,10 +656,10 @@ instance HasUser UserTableData where
hasUser = _dbrOutput . _1 . _entityVal hasUser = _dbrOutput . _1 . _entityVal
_userTableRegistration :: Lens' UserTableData UTCTime _userTableRegistration :: Lens' UserTableData UTCTime
_userTableRegistration = _dbrOutput . _2 . _unValue _userTableRegistration = _dbrOutput . _2
_userTableNote :: Lens' UserTableData (Maybe CourseUserNoteId) _userTableNote :: Lens' UserTableData (Maybe CourseUserNoteId)
_userTableNote = _dbrOutput . _3 . _unValue _userTableNote = _dbrOutput . _3
-- default Where-Clause -- default Where-Clause
courseIs :: CourseId -> UserTableWhere courseIs :: CourseId -> UserTableWhere
@ -669,7 +669,7 @@ courseIs cid ((_user `E.InnerJoin` participant) `E.LeftOuterJoin` _note) = parti
colUserComment :: IsDBTable m c => TermId -> SchoolId -> CourseShorthand -> Colonnade Sortable UserTableData (DBCell m c) colUserComment :: IsDBTable m c => TermId -> SchoolId -> CourseShorthand -> Colonnade Sortable UserTableData (DBCell m c)
colUserComment tid ssh csh = colUserComment tid ssh csh =
sortable (Just "course-user-note") (i18nCell MsgCourseUserNote) sortable (Just "course-user-note") (i18nCell MsgCourseUserNote)
$ \DBRow{ dbrOutput=(Entity uid _, _, E.Value mbNoteKey) } -> $ \DBRow{ dbrOutput=(Entity uid _, _, mbNoteKey) } ->
maybeEmpty mbNoteKey $ const $ maybeEmpty mbNoteKey $ const $
anchorCellM (courseLink <$> encrypt uid) (toWidget $ hasComment True) anchorCellM (courseLink <$> encrypt uid) (toWidget $ hasComment True)
where where
@ -694,7 +694,7 @@ makeCourseUserTable whereClause colChoices psValidator =
dbtStyle = def dbtStyle = def
dbtSQLQuery = userTableQuery whereClause dbtSQLQuery = userTableQuery whereClause
dbtRowKey ((user `E.InnerJoin` _participant) `E.LeftOuterJoin` _note) = user E.^. UserId dbtRowKey ((user `E.InnerJoin` _participant) `E.LeftOuterJoin` _note) = user E.^. UserId
dbtProj = return -- . dbrOutput -- NOT SURE dbtProj = traverse $ \(user, E.Value registrationTime , E.Value userNoteId) -> return (user, registrationTime, userNoteId)
dbtColonnade = colChoices dbtColonnade = colChoices
dbtSorting = Map.fromList [] -- TODO dbtSorting = Map.fromList [] -- TODO
dbtFilter = Map.fromList [] -- TODO dbtFilter = Map.fromList [] -- TODO

View File

@ -192,7 +192,7 @@ getImpressumR :: Handler Html
getImpressumR = -- do getImpressumR = -- do
siteLayoutMsg' MsgMenuImpressum $ do siteLayoutMsg' MsgMenuImpressum $ do
setTitleI MsgImpressumHeading setTitleI MsgImpressumHeading
$(widgetFile "impressum") $(i18nWidgetFile "imprint")
-- | Hinweise zu Datenschutz und Aufbewahrungspflichten -- | Hinweise zu Datenschutz und Aufbewahrungspflichten
@ -200,7 +200,7 @@ getDataProtR :: Handler Html
getDataProtR = -- do getDataProtR = -- do
siteLayoutMsg' MsgMenuDataProt $ do siteLayoutMsg' MsgMenuDataProt $ do
setTitleI MsgDataProtHeading setTitleI MsgDataProtHeading
$(widgetFile "data-protection-de") $(i18nWidgetFile "data-protection")
-- | Allgemeine Informationen -- | Allgemeine Informationen
@ -280,8 +280,7 @@ getInfoLecturerR :: Handler Html
getInfoLecturerR = getInfoLecturerR =
siteLayoutMsg' MsgInfoLecturerTitle $ do siteLayoutMsg' MsgInfoLecturerTitle $ do
setTitleI MsgInfoLecturerTitle setTitleI MsgInfoLecturerTitle
-- TODO: Translation. This is simply too much for a simple message and too akwward to cut into bits. Create i18nWidgetFile tool. $(i18nWidgetFile "info-lecturer")
$(widgetFile "infoLecturer")
getAuthPredsR, postAuthPredsR :: Handler Html getAuthPredsR, postAuthPredsR :: Handler Html

View File

@ -7,6 +7,13 @@ import Import
import qualified Data.Text as T import qualified Data.Text as T
-- import qualified Data.Set (Set) -- import qualified Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.CaseInsensitive (CI, original)
-- import qualified Data.CaseInsensitive as CI
import Language.Haskell.TH (Q, Exp)
-- import Language.Haskell.TH.Datatype
import Text.Hamlet (shamletFile)
import Handler.Utils.DateTime as Handler.Utils import Handler.Utils.DateTime as Handler.Utils
import Handler.Utils.Form as Handler.Utils import Handler.Utils.Form as Handler.Utils
@ -36,9 +43,16 @@ tidFromText = fmap TermKey . maybeRight . termFromText
simpleLink :: Widget -> Route UniWorX -> Widget simpleLink :: Widget -> Route UniWorX -> Widget
simpleLink lbl url = [whamlet|<a href=@{url}>^{lbl}|] simpleLink lbl url = [whamlet|<a href=@{url}>^{lbl}|]
-- | toWidget-Version of @nameHtml@, for convenience
nameWidget :: Text -> Text -> Widget nameWidget :: Text -> Text -> Widget
nameWidget displayName surname = toWidget $ nameHtml displayName surname nameWidget displayName surname = toWidget $ nameHtml displayName surname
-- | toWidget-Version of @nameEmailHtml@, for convenience
nameEmailWidget :: (CI Text) -> Text -> Text -> Widget
nameEmailWidget email displayName surname = toWidget $ nameEmailHtml email displayName surname
-- | Show user's displayName, highlighting the surname if possible.
-- Otherwise appends the surname in parenthesis
nameHtml :: Text -> Text -> Html nameHtml :: Text -> Text -> Html
nameHtml displayName surname nameHtml displayName surname
| null surname = toHtml displayName | null surname = toHtml displayName
@ -56,6 +70,21 @@ nameHtml displayName surname
|] |]
[] -> error "Data.Text.splitOn returned empty list in violation of specification." [] -> error "Data.Text.splitOn returned empty list in violation of specification."
-- | Like nameHtml just show a users displayname with hightlighted surname,
-- but also wrap the name with a mailto-link
nameEmailHtml :: (CI Text) -> Text -> Text -> Html
nameEmailHtml email displayName surname =
wrapMailto email $ nameHtml displayName surname
-- | Wrap mailto around given Html using single hamlet-file for consistency
wrapMailto :: (CI Text) -> Html -> Html
wrapMailto (original -> email) linkText
| null email = linkText
| otherwise = $(shamletFile "templates/widgets/link-email.hamlet")
-- | Just show an email address in a standard way, for convenience inside hamlet files.
mailtoHtml :: (CI Text) -> Html
mailtoHtml email = wrapMailto email $ toHtml email
warnTermDays :: TermId -> [Maybe UTCTime] -> DB () warnTermDays :: TermId -> [Maybe UTCTime] -> DB ()
warnTermDays tid times = do warnTermDays tid times = do
@ -70,3 +99,12 @@ warnTermDays tid times = do
forM_ outoflecture $ warnI MsgDayIsOutOfLecture forM_ outoflecture $ warnI MsgDayIsOutOfLecture
forM_ outoftermdays $ warnI MsgDayIsOutOfTerm forM_ outoftermdays $ warnI MsgDayIsOutOfTerm
-- | Add language dependent template files
-- For large files which are translated as a whole.
-- Argument musst be a directory under templates,
-- which contains a file for each language,
-- eg. /templates/imprint/de.hamlet and /templates/imprint/en.hamlet
i18nWidgetFile :: FilePath -> Q Exp
i18nWidgetFile =
-- TODO write code to distinguish languages here
widgetFile . (</> "de")

View File

@ -65,7 +65,8 @@ userCell :: IsDBTable m a => Text -> Text -> DBCell m a
userCell displayName surname = cell $ nameWidget displayName surname userCell displayName surname = cell $ nameWidget displayName surname
emailCell :: IsDBTable m a => CI Text -> DBCell m a emailCell :: IsDBTable m a => CI Text -> DBCell m a
emailCell userEmail = cell $(widgetFile "widgets/link-email") emailCell email = cell $(widgetFile "widgets/link-email")
where linkText= toWgt email
cellHasUser :: (IsDBTable m c, HasUser a) => a -> DBCell m c cellHasUser :: (IsDBTable m c, HasUser a) => a -> DBCell m c
cellHasUser = liftA2 userCell (view _userDisplayName) (view _userSurname) cellHasUser = liftA2 userCell (view _userDisplayName) (view _userSurname)

View File

@ -1,5 +1,6 @@
<p> <p>
<a href="mailto:#{userEmail}">#{userEmail} $# Does not use link-email.hamlet, but should
^{mailtoHtml userEmail}
<form method=post action=@{AdminUserR uuid} enctype=#{formEnctype}> <form method=post action=@{AdminUserR uuid} enctype=#{formEnctype}>
^{formWidget} ^{formWidget}
^{submitButtonView} ^{submitButtonView}

View File

@ -18,7 +18,9 @@
<dt .deflist__dt>_{MsgLecturerFor} <dt .deflist__dt>_{MsgLecturerFor}
<dd .deflist__dd> <dd .deflist__dd>
<div> <div>
#{T.intercalate ", " lecturers} <ul .list--inline .list--comma-separated>
$forall (E.Value displayname, E.Value surname, E.Value email) <- lecturers
<li>^{nameEmailWidget email displayname surname}
$maybe link <- courseLinkExternal course $maybe link <- courseLinkExternal course
<dt .deflist__dt>Website <dt .deflist__dt>Website

View File

@ -73,7 +73,7 @@
<h4>Welche Daten werden erhoben <h4>Welche Daten werden erhoben
Der Webserver protokolliert Der Webserver protokolliert
<ul> <ul>
<li>Pseudonymisierte IP-Adresse des Webclients des Nutzers dieses Dienstes <li>IP-Adresse des Webclients des Nutzers dieses Dienstes
<li>Datum und Uhrzeit des Abrufs eines Elementes der Webseite <li>Datum und Uhrzeit des Abrufs eines Elementes der Webseite
<li>Adresse des abgerufenen Elementes <li>Adresse des abgerufenen Elementes
<li>übertragene Datenmenge <li>übertragene Datenmenge

View File

@ -10,5 +10,4 @@
bitten um Ihr Verständnis. bitten um Ihr Verständnis.
<p> <p>
Bitte melden Sie etwaige Probleme an # Bitte melden Sie etwaige Probleme an #
<a href="mailto:jost@tcs.ifi.lmu.de"> ^{mailtoHtml "jost@tcs.ifi.lmu.de"}
jost@tcs.ifi.lmu.de

View File

@ -9,9 +9,7 @@ $newline never
<li>Akademischer Rat <li>Akademischer Rat
<li>Oettingenstraße 67 <li>Oettingenstraße 67
<li>D-80538 München <li>D-80538 München
<li>E-Mail: # <li>E-Mail: ^{mailtoHtml "jost@tcs.ifi.lmu.de"}
<a href="mailto:jost@tcs.ifi.lmu.de">
jost@tcs.ifi.lmu.de
<li>Web: # <li>Web: #
<a href="https://www.tcs.ifi.lmu.de/mitarbeiter/steffen-jost"> <a href="https://www.tcs.ifi.lmu.de/mitarbeiter/steffen-jost">
https://www.tcs.ifi.lmu.de/mitarbeiter/steffen-jost https://www.tcs.ifi.lmu.de/mitarbeiter/steffen-jost
@ -24,9 +22,7 @@ $newline never
<li>Leiter Rechnerbetriebsgruppe <li>Leiter Rechnerbetriebsgruppe
<li>Oettingenstraße 67 <li>Oettingenstraße 67
<li>D-80538 München <li>D-80538 München
<li>E-Mail: # <li>E-Mail: ^{mailtoHtml "rbg@ifi.lmu.de"}
<a href="mailto:rbg@ifi.lmu.de">
rbg@ifi.lmu.de
<li>Web: # <li>Web: #
<a href="https://www.rz.ifi.lmu.de/rbg/"> <a href="https://www.rz.ifi.lmu.de/rbg/">
https://www.rz.ifi.lmu.de/rbg/ https://www.rz.ifi.lmu.de/rbg/
@ -41,7 +37,7 @@ $newline never
<ul style="list-style-type: none"> <ul style="list-style-type: none">
<li>Oettingenstraße 67 <li>Oettingenstraße 67
<li>D-80538 München <li>D-80538 München
<li>E-Mail: rbg@ifi.lmu.de <li>E-Mail: ^{mailtoHtml "rbg@ifi.lmu.de"}
<li>Web: https://www.rz.ifi.lmu.de/rbg/ <li>Web: https://www.rz.ifi.lmu.de/rbg/
<li>Telefon: +49 (0) 89 / 2180 - 9198 <li>Telefon: +49 (0) 89 / 2180 - 9198
<p> <p>
@ -68,9 +64,7 @@ $newline never
<li>Geschwister-Scholl-Platz 1 <li>Geschwister-Scholl-Platz 1
<li>80539 München< <li>80539 München<
<li>Telefon: +49 (0) 89 / 2180 - 0 <li>Telefon: +49 (0) 89 / 2180 - 0
<li>E-Mail: # <li>E-Mail: ^{mailtoHtml "praesidium@lmu.de"}
<a href="mailto:praesidium@lmu.de">
praesidium@lmu.de
<li>Web: # <li>Web: #
<a href="https://www.lmu.de/"> <a href="https://www.lmu.de/">
https://www.lmu.de/ https://www.lmu.de/

View File

@ -135,9 +135,29 @@ hier die wichtigsten Neuerungen.
<dt .deflist__dt> Papierabgaben <dt .deflist__dt> Papierabgaben
<dd .deflist__dd> <dd .deflist__dd>
Abgaben in anderer Form (z.B. Papierabgaben) Externe Abgaben Form (z.B. Papierabgaben)
können mit Hilfe von Tokens verwaltet werden. können mit Pseudonymen verwaltet werden:
Korrekturen können elektronisch zurückgegeben werden. <ul>
<li>
Übungsblatt mit Abgabe-Modus
<i>Abgabe extern mit Pseudonym
anlegen
<li>
Studierende können sich auf
der Seite des Übungsblattes ein
Pseudonym generieren und ihre Abgabe
damit markieren.
<p>
Für jedes Übungsblatt müssen sich die
Studierenden ein neues Pseudonym
erstellen, damit eine anonyme Korrektur
gewährleistet werden kann.
<li>
Korrektoren bekommen die externen Abgaben
ausgehändigt.
Anhand der Pseudonyme werden
in Uni2work Abgaben angelegt,
welche wie üblich korrigiert werden können.
<section> <section>
<h2>Klausuren <h2>Klausuren

View File

@ -1,2 +1,3 @@
<a href="mailto:#{userEmail}"> $# Used for all mailto-link, and used as both as shamlet and whamlet at once.
#{userEmail} <a href="mailto:#{email}">
^{linkText}