diff --git a/CHANGELOG.md b/CHANGELOG.md index c0a7de2f3..fcd5469a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,28 @@ 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. +## [26.6.6](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v26.6.5...v26.6.6) (2022-12-12) + +## [26.6.5](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v26.6.4...v26.6.5) (2022-12-05) + +## [26.6.4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v26.6.3...v26.6.4) (2022-12-02) + +## [26.6.3](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v26.6.2...v26.6.3) (2022-11-30) + + +### Bug Fixes + +* **avs:** normalize internal personal numbers between LDAP and AVS ([b20008d](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/b20008d3bcb730ff76a76ce2928364e6ce9e7c35)) + +## [26.6.2](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v26.6.1...v26.6.2) (2022-11-29) + +## [26.6.1](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v26.6.0...v26.6.1) (2022-11-28) + + +### Bug Fixes + +* **lms:** filtering qualifications by supervisor works properly now ([15f7a75](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/15f7a7576ab48a362a479f43034510b4e80bb1b2)) + ## [26.6.0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v26.5.14...v26.6.0) (2022-11-18) diff --git a/config/settings.yml b/config/settings.yml index 1052e0b59..8b5c96e54 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -276,6 +276,7 @@ user-defaults: show-sex: false exam-office-get-synced: true exam-office-get-labels: true + prefers-postal: true instance-id: "_env:INSTANCE_ID:instance" diff --git a/messages/uniworx/categories/admin/de-de-formal.msg b/messages/uniworx/categories/admin/de-de-formal.msg index d11cce147..0a02c699e 100644 --- a/messages/uniworx/categories/admin/de-de-formal.msg +++ b/messages/uniworx/categories/admin/de-de-formal.msg @@ -79,7 +79,7 @@ StudyFeatureInferenceNoNameConflicts: Keine Konflikte beobachtet StudyFeatureInferenceNameConflictsHeading: Studiengangseinträge mit beobachteten Konflikten AdminHeading !ident-ok: Administration -AdminPageEmpty: Diese Seite soll eine Übersichtsseite für Administrator:innen werden. Aktuell finden sich hier nur Links zu wichtigen Administrator-Funktionalitäten. + BearerTokenImpersonate: Auftreten als BearerTokenImpersonateNone: Keine Änderung BearerTokenImpersonateSingle: Einzelner Benutzer/Einzelne Benutzerin @@ -94,3 +94,22 @@ BearerTokenArchiveName !ident-ok: tokens.zip TestDownloadDirect: Direkte Generierung TestDownloadInTransaction: Generierung während Datenbank-Transaktion TestDownloadFromDatabase: Generierung während Download aus Datenbank + +ProblemsHeading: Problemübersicht +ProblemsHeadingDrivers: Fahrberechtigungen +ProblemsAvsProblem: Synchronisation mit AVS/MoBaKo komplett fehlgeschlagen +ProblemsDriverSynch n@Int: #{tshow n} Diskrepanzen zwischen AVS und FRADrive +ProblemsDriverSynch0: Alle Sperrungen von Fahrberechtigungen sind im AVS eingetragen +ProblemsDriverSynch1: Alle gültigen Vorfeld-Fahrberechtigungen 'F' sind im AVS eingetragen +ProblemsDriverSynch2: Alle gültigen Rollfeld-Fahrberechtigungen 'R' sind im AVS eingetragen +ProblemsRDriversHaveFs: Alle Inhaber einer Rollfeld-Fahrberechtigung besitzen auch eine gültige Vorfeld-Fahrberechtigung +ProblemsDriversHaveAvsIds: Alle Inhaber einer Fahrberechtigung konnten einer AVS Identifikationsnummer zugeordnet werden +ProblemsHeadingUsers: Allgemein +ProblemsUsersAreReachable: Für alle Benutzer ist eine E-Mail oder postalische Adresse bekannt +ProblemsNoStalePrintJobs n@Integer: Alle Briefversandaufträge der vergangenen #{show n} Tage wurden von der Druckerei bestätigt +ProblemsUnreachableHeading: Unerreichbare Benutzer +ProblemsUnreachableBody: Benutzer ohne E-Mail oder Postadresse, welche z.B. bei ablaufenden Berechtigungen nicht benachrichtigt werden können: +ProblemsRWithoutFHeading: Fahrer mit R ohne F +ProblemsRWithoutFBody: Diese Fahrer sind wegen einer ungültigen Vorfeld-Fahrberechtigung komplett gesperrt, obwohl eine gültige Rollfeld-Fahrberechtigung besteht: +ProblemsNoAvsIdHeading: Fahrer ohne AVS-Id +ProblemsNoAvsIdBody: Fahrer mit gültiger Fahrberechtigung in FRADrive, welche trotzdem nicht fahren dürfen, da die Fahrberechtigung aufgrund einer unbekannten AVS Id nicht an die Ausweisstelle übermittelt werden konnte: \ No newline at end of file diff --git a/messages/uniworx/categories/admin/en-eu.msg b/messages/uniworx/categories/admin/en-eu.msg index 25d9dcff0..1f346e598 100644 --- a/messages/uniworx/categories/admin/en-eu.msg +++ b/messages/uniworx/categories/admin/en-eu.msg @@ -79,7 +79,6 @@ StudyFeatureInferenceNoNameConflicts: No observed conflicts StudyFeatureInferenceNameConflictsHeading: Fields of study with observed conflicts AdminHeading: Administration -AdminPageEmpty: This page shall provide an overview for administrators in the future. For now there are only links to important administrator-functions. BearerTokenImpersonate: Impersonate BearerTokenImpersonateNone: No one @@ -95,3 +94,22 @@ BearerTokenArchiveName: tokens.zip TestDownloadDirect: Direct generation TestDownloadInTransaction: Generate during database transaction TestDownloadFromDatabase: Generate while streaming from database + +ProblemsHeading: Overview Problems +ProblemsHeadingDrivers: Driving Licences +ProblemsAvsProblem: Synchronisation with AVS/MoBaKo failed entirely +ProblemsDriverSynch n: #{tshow n} mismatches between AVS and FRADrive +ProblemsDriverSynch0: All revocations of driving licences were successfully registered with AVS +ProblemsDriverSynch1: All valid apron driving licences 'F' were successfully registered with AVS +ProblemsDriverSynch2: All valid maneuvering area driving licences 'R' were successfully registered with AVS +ProblemsRDriversHaveFs: All driving licence 'R' holders also have a valid 'F' licence +ProblemsDriversHaveAvsIds: All driving licence holder could be matched with their AVS id +ProblemsHeadingUsers: Miscellaneous +ProblemsUsersAreReachable: Either Email or postal address is known for all users +ProblemsNoStalePrintJobs n: All requests for letter mailing within the last #{show n} days were acknowledged as printed by the airport printing center +ProblemsUnreachableHeading: Unreachable Users +ProblemsUnreachableBody: Users without Email nor postal address, who thus cannot be notified about expiring qualifications: +ProblemsRWithoutFHeading: Drivers having 'R' but not 'F' +ProblemsRWithoutFBody: Drivers without apron driving licence are prohibited from driving, even if they own a valid maneuvering driving licence: +ProblemsNoAvsIdHeading: Drivers without AVS id +ProblemsNoAvsIdBody: Drivers having a valid apron driving licence within FRADrive only, but who may not drive since a missing AVS id prevents communication of the driving licence to AVS: \ No newline at end of file diff --git a/messages/uniworx/categories/authorization/de-de-formal.msg b/messages/uniworx/categories/authorization/de-de-formal.msg index 9cc17e6a8..a5e4e744c 100644 --- a/messages/uniworx/categories/authorization/de-de-formal.msg +++ b/messages/uniworx/categories/authorization/de-de-formal.msg @@ -28,7 +28,6 @@ UnauthorizedExamExamOffice: Es existieren keine Prüfungsergebnisse für Nutzer: UnauthorizedSchoolExamOffice: Sie sind nicht mit Prüfungsverwaltung für dieses Institut beauftragt. UnauthorizedSystemExamOffice: Sie sind nicht mit systemweiter Prüfungsverwaltung beauftragt. UnauthorizedSystemPrinter: Sie sind nicht mit systemweitem Druck und Briefversand beauftragt. -UnauthorizedSystemSap: Sie sind nicht mit der systemweitem SAP Schnittstellenverwaltung beauftragt. UnauthorizedExternalExamExamOffice: Es existieren keine Prüfungsergebnisse für Nutzer:innen, für die Sie mit der Prüfungsverwaltung beauftragt sind. UnauthorizedEvaluation: Sie sind nicht mit der Kursumfragenverwaltung beauftragt. UnauthorizedSchoolLecturer: Sie sind nicht als Veranstalter:in für dieses Institut eingetragen. diff --git a/messages/uniworx/categories/authorization/en-eu.msg b/messages/uniworx/categories/authorization/en-eu.msg index 337b0f33d..489a2e6ca 100644 --- a/messages/uniworx/categories/authorization/en-eu.msg +++ b/messages/uniworx/categories/authorization/en-eu.msg @@ -29,7 +29,6 @@ UnauthorizedExamExamOffice: You are not part of the appropriate exam office for UnauthorizedSchoolExamOffice: You are not part of an exam office for this school. UnauthorizedSystemExamOffice: You are not charged with system wide exam administration. UnauthorizedSystemPrinter: You are not charged with system wide letter printing. -UnauthorizedSystemSap: You are not charged with system wide SAP administration. UnauthorizedExternalExamExamOffice: You are not part of the appropriate exam office for any of the participants of this exam. UnauthorizedSchoolLecturer: You are no lecturer for this department. UnauthorizedLecturer: You are no administrator for this course. diff --git a/messages/uniworx/categories/avs/de-de-formal.msg b/messages/uniworx/categories/avs/de-de-formal.msg index ff4428e24..169fd2987 100644 --- a/messages/uniworx/categories/avs/de-de-formal.msg +++ b/messages/uniworx/categories/avs/de-de-formal.msg @@ -10,4 +10,6 @@ AvsLastName: Nachname AvsInternalPersonalNo: Personalnummer (nur Fraport AG) AvsVersionNo: Versionsnummer AvsQueryEmpty: Bitte mindestens ein Anfragefeld ausfüllen! -AvsQueryStatusInvalid t@Text: Nur numerische IDs eingeben, durch Komma getrennt! Erhalten: #{show t} \ No newline at end of file +AvsQueryStatusInvalid t@Text: Nur numerische IDs eingeben, durch Komma getrennt! Erhalten: #{show t} +AvsLicence: Fahrberechtigung +AvsPersonNoNotId: AVS Personennummer dient zur menschlichen Kommunikation mit der Ausweisstelle und darf nicht verwechselt werden mit der maschinell verwendeten AVS Personen Id \ No newline at end of file diff --git a/messages/uniworx/categories/avs/en-eu.msg b/messages/uniworx/categories/avs/en-eu.msg index 831a371df..3ee9a293e 100644 --- a/messages/uniworx/categories/avs/en-eu.msg +++ b/messages/uniworx/categories/avs/en-eu.msg @@ -10,4 +10,6 @@ AvsLastName: Last name AvsInternalPersonalNo: Personnel number (Fraport AG only) AvsVersionNo: Version number AvsQueryEmpty: At least one query field must be filled! -AvsQueryStatusInvalid t: Numeric IDs only, comma seperated! #{show t} \ No newline at end of file +AvsQueryStatusInvalid t: Numeric IDs only, comma seperated! #{show t} +AvsLicence: Driving Licence +AvsPersonNoNotId: AVS person number is used in human communication only and must not be mistaken for the AVS personen id used in machine communications \ No newline at end of file diff --git a/messages/uniworx/categories/model_types/de-de-formal.msg b/messages/uniworx/categories/model_types/de-de-formal.msg index be3831b8a..8d7aa361c 100644 --- a/messages/uniworx/categories/model_types/de-de-formal.msg +++ b/messages/uniworx/categories/model_types/de-de-formal.msg @@ -18,5 +18,4 @@ BothSubmissions: Abgabe direkt in Uni2work oder extern mit Pseudonym SystemExamOffice: Prüfungsverwaltung SystemFaculty: Fakultätsmitglied SystemStudent: Student:in -SystemPrinter: Drucker:in -SystemSap: SAP Verwalter:in +SystemPrinter: Drucker:in \ No newline at end of file diff --git a/messages/uniworx/categories/model_types/en-eu.msg b/messages/uniworx/categories/model_types/en-eu.msg index eafba769a..fe2c2418f 100644 --- a/messages/uniworx/categories/model_types/en-eu.msg +++ b/messages/uniworx/categories/model_types/en-eu.msg @@ -18,5 +18,4 @@ BothSubmissions: Submission either directly in Uni2work or externally via pseudo SystemExamOffice: Exam office SystemFaculty: Faculty member SystemStudent: Student -SystemPrinter: Printing staff -SystemSap: SAP Administrator \ No newline at end of file +SystemPrinter: Printing staff \ No newline at end of file diff --git a/messages/uniworx/categories/qualification/en-eu.msg b/messages/uniworx/categories/qualification/en-eu.msg index 51aa90ba7..2e15e3c97 100644 --- a/messages/uniworx/categories/qualification/en-eu.msg +++ b/messages/uniworx/categories/qualification/en-eu.msg @@ -14,9 +14,9 @@ TableQualificationCountActive: Active TableQualificationCountActiveTooltip: Number of currently valid qualification holders TableQualificationCountTotal: Total TableQualificationIsAvsLicence: AVS Driving License -TableQualificationIsAvsLicenceTooltip: Is this Qualification synchronized with AVS? Only applies to qualification holders having an AVS PersonID. +TableQualificationIsAvsLicenceTooltip: Under which name is this qualification synchronized with AVS, if any? Only applies to qualification holders having an AVS PersonID. TableQualificationSapExport: Sent to SAP -TableQualificationSapExportTooltip: Is this Qualification transmitted to SAP? Only applies to qualification holder having a Fraport Personnelnumber. +TableQualificationSapExportTooltip: Is this qualification transmitted to SAP? Only applies to qualification holder having a Fraport AG personnel number. LmsQualificationValidUntil: Valid until TableQualificationLastRefresh: Last renewed TableQualificationFirstHeld: First held diff --git a/messages/uniworx/categories/settings/auth_settings/de-de-formal.msg b/messages/uniworx/categories/settings/auth_settings/de-de-formal.msg index a786899f6..f91e260cf 100644 --- a/messages/uniworx/categories/settings/auth_settings/de-de-formal.msg +++ b/messages/uniworx/categories/settings/auth_settings/de-de-formal.msg @@ -14,7 +14,6 @@ AuthTagAdmin: Nutzer:in ist Administrator:in AuthTagExamOffice: Nutzer:in ist mit Prüfungsverwaltung beauftragt AuthTagSystemExamOffice: Nutzer:in ist mit systemweiter Prüfungsverwaltung beauftragt AuthTagSystemPrinter: Nutzer:in ist mit systemweiten Druck von Briefen beauftragt -AuthTagSystemSap: Nutzer:in ist mit systemweiter SAP Schnittstellen-Administration beauftragt AuthTagEvaluation: Nutzer:in ist mit Kursumfragenverwaltung beauftragt AuthTagToken: Nutzer:in präsentiert Authorisierungs-Token AuthTagNoEscalation: Nutzer-Rechte werden nicht auf fremde Institute ausgeweitet diff --git a/messages/uniworx/categories/settings/auth_settings/en-eu.msg b/messages/uniworx/categories/settings/auth_settings/en-eu.msg index c9b57afd7..5a27d7360 100644 --- a/messages/uniworx/categories/settings/auth_settings/en-eu.msg +++ b/messages/uniworx/categories/settings/auth_settings/en-eu.msg @@ -14,7 +14,6 @@ AuthTagAdmin: User is administrator AuthTagExamOffice: User is part of an exam office AuthTagSystemExamOffice: User is charged with system wide exam administration AuthTagSystemPrinter: User is responsible for system wide letter printing -AuthTagSystemSap: User is responsible for system wide SAP interface administration AuthTagEvaluation: User is charged with course evaluation AuthTagToken: User is presenting an authorisation-token AuthTagNoEscalation: User permissions are not being expanded to other departments diff --git a/messages/uniworx/categories/settings/personal_settings/de-de-formal.msg b/messages/uniworx/categories/settings/personal_settings/de-de-formal.msg index 06b915786..147d89ded 100644 --- a/messages/uniworx/categories/settings/personal_settings/de-de-formal.msg +++ b/messages/uniworx/categories/settings/personal_settings/de-de-formal.msg @@ -27,7 +27,11 @@ ProfileCorrectorRemark: Die oberhalb angezeigte Tabelle zeigt nur prinzipielle E ProfileCorrections: Auflistung aller zugewiesenen Korrekturen Remarks: Hinweise +ProfileSupervisor: Übergeordnete Ansprechpartner +ProfileSupervisee: Ist Ansprechpartner für + UserTelephone: Telefon UserMobile: Mobiltelefon +Company: Firmenzugehörigkeit CompanyPersonalNumber: Personalnummer (nur Fraport AG) CompanyDepartment: Abteilung \ No newline at end of file diff --git a/messages/uniworx/categories/settings/personal_settings/en-eu.msg b/messages/uniworx/categories/settings/personal_settings/en-eu.msg index e39556769..cc3c63c19 100644 --- a/messages/uniworx/categories/settings/personal_settings/en-eu.msg +++ b/messages/uniworx/categories/settings/personal_settings/en-eu.msg @@ -27,7 +27,11 @@ ProfileCorrectorRemark: The table above only shows registration as a corrector i ProfileCorrections: List of all assigned corrections Remarks: Remarks +ProfileSupervisor: Supervised by +ProfileSupervisee: Supervises + UserTelephone: Phone UserMobile: Mobile +Company: Company affilitaion CompanyPersonalNumber: Personnel number (Fraport AG only) CompanyDepartment: Department \ No newline at end of file diff --git a/messages/uniworx/categories/term/de-de-formal.msg b/messages/uniworx/categories/term/de-de-formal.msg index 9166aaf30..8a93e5698 100644 --- a/messages/uniworx/categories/term/de-de-formal.msg +++ b/messages/uniworx/categories/term/de-de-formal.msg @@ -28,7 +28,7 @@ TermLectureStartTooltip: Muss am oder nach dem Beginn liegen TermLectureEndTooltip: Muss am oder vor dem Ende liegen TermActive: Aktiv TermActiveTooltip: Zeitraum in dem Lehrende Kurse anlegen dürfen; kann auf angegebene Lehrende eingeschränkt werden -TermActiveForPlaceholder: Email (optional) +TermActiveForPlaceholder: E-Mail (optional) NumCourses num@Int64: #{num} #{pluralDE num "Kurs" "Kurse"} TermsHeading: Semesterübersicht TermEditHeading: Semester editieren/anlegen diff --git a/messages/uniworx/categories/term/en-eu.msg b/messages/uniworx/categories/term/en-eu.msg index 4491e0ef4..7880cc072 100644 --- a/messages/uniworx/categories/term/en-eu.msg +++ b/messages/uniworx/categories/term/en-eu.msg @@ -28,7 +28,7 @@ TermLectureStartTooltip: Must be on or after starting day TermLectureEndTooltip: Must be before or on ending day TermActive: Active TermActiveTooltip: Timeframe when lecturers may add courses; maybe restricted for specified lecturers -TermActiveForPlaceholder: E-Mail (optional) +TermActiveForPlaceholder: Email (optional) NumCourses num: #{num} #{pluralEN num "course" "courses"} TermsHeading: Semesters TermEditHeading: Edit semester diff --git a/messages/uniworx/categories/user/de-de-formal.msg b/messages/uniworx/categories/user/de-de-formal.msg index 6777920d1..e5572b77d 100644 --- a/messages/uniworx/categories/user/de-de-formal.msg +++ b/messages/uniworx/categories/user/de-de-formal.msg @@ -13,7 +13,7 @@ AdminUserAuth: Authentifizierung AdminUserMatriculation: Matrikelnummer AdminUserSex: Geschlecht AdminUserTelephone: Telefonnummer -AdminUserMobile: Mobiltelefonmummer +AdminUserMobile: Mobiltelefonnummer AdminUserFPersonalNumber: Personalnummer (nur Fraport AG) AdminUserFDepartment: Abteilung AdminUserPostAddress: Postalische Anschrift diff --git a/messages/uniworx/utils/table_column/de-de-formal.msg b/messages/uniworx/utils/table_column/de-de-formal.msg index 23b111979..024a150dc 100644 --- a/messages/uniworx/utils/table_column/de-de-formal.msg +++ b/messages/uniworx/utils/table_column/de-de-formal.msg @@ -72,3 +72,5 @@ TableExamOfficeLabel: Label-Name TableExamOfficeLabelStatus: Label-Farbe TableExamOfficeLabelPriority: Label-Priorität TableQualifications: Qualifikationen +TableCompany: Firma +TableSupervisor: Ansprechpartner diff --git a/messages/uniworx/utils/table_column/en-eu.msg b/messages/uniworx/utils/table_column/en-eu.msg index f00b57ea0..1367d7bb1 100644 --- a/messages/uniworx/utils/table_column/en-eu.msg +++ b/messages/uniworx/utils/table_column/en-eu.msg @@ -72,3 +72,5 @@ TableExamOfficeLabel: Label name TableExamOfficeLabelStatus: Label colour TableExamOfficeLabelPriority: Label priority TableQualifications: Qualifications +TableCompany: Company +TableSupervisor: Supervisor diff --git a/models/avs.model b/models/avs.model index a1a7d87c7..5bb75e315 100644 --- a/models/avs.model +++ b/models/avs.model @@ -14,8 +14,9 @@ UserAvs - personId AvsPersonId -- unique identifier for user throughout avs + personId AvsPersonId -- unique identifier for user throughout avs; newtype for Int user UserId + noPerson Int default=0 -- only needed for manual communication with personnel from Ausweisverwaltungsstelle UniqueUserAvsUser user UniqueUserAvsId personId deriving Generic diff --git a/models/lms.model b/models/lms.model index 0084425f9..12d543000 100644 --- a/models/lms.model +++ b/models/lms.model @@ -15,8 +15,8 @@ Qualification -- elearningOnly Bool -- successful E-learing automatically increases validity. NO! -- refreshInvitation StoredMarkup -- hard-coded I18N-MSGs used instead, but displayed on qualification page NO! -- expiryNotification StoredMarkup Maybe -- configurable user-profile-notifcations are used instead NO! - avsLicence AvsLicence Maybe -- if set, is synchronized to Avs as a driving licence - sapId Text Maybe -- if set, all QualificationUsers with userCompanyPersonalNumber are transmitted via SAP interface under this id + avsLicence AvsLicence Maybe -- if set, valid QualificationUsers are synchronized to AVS as a driving licence + sapId Text Maybe -- if set, valid QualificationUsers with userCompanyPersonalNumber are transmitted via SAP interface under this id SchoolQualificationShort school shorthand -- must be unique per school and shorthand SchoolQualificationName school name -- must be unique per school and name -- across all schools, only one qualification may be a driving licence: diff --git a/nix/docker/demo-version.json b/nix/docker/demo-version.json index 10ad06c7c..2250f5914 100644 --- a/nix/docker/demo-version.json +++ b/nix/docker/demo-version.json @@ -1,3 +1,3 @@ { - "version": "26.6.0" + "version": "26.6.6" } diff --git a/nix/docker/version.json b/nix/docker/version.json index 10ad06c7c..2250f5914 100644 --- a/nix/docker/version.json +++ b/nix/docker/version.json @@ -1,3 +1,3 @@ { - "version": "26.6.0" + "version": "26.6.6" } diff --git a/package-lock.json b/package-lock.json index 85e41e099..221774807 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "uni2work", - "version": "26.6.0", + "version": "26.6.6", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index ee81377b5..b65b3f85e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uni2work", - "version": "26.6.0", + "version": "26.6.6", "description": "", "keywords": [], "author": "", diff --git a/package.yaml b/package.yaml index 762b9fd12..f560dc507 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: uniworx -version: 26.6.0 +version: 26.6.6 dependencies: - base - yesod diff --git a/resources/FAG_UKM-MI_Pictogram-Library-Manual_RZ.pdf b/resources/FAG_UKM-MI_Pictogram-Library-Manual_RZ.pdf new file mode 100644 index 000000000..b317194eb Binary files /dev/null and b/resources/FAG_UKM-MI_Pictogram-Library-Manual_RZ.pdf differ diff --git a/resources/FraportIcons.zip b/resources/FraportIcons.zip new file mode 100644 index 000000000..71bff9649 Binary files /dev/null and b/resources/FraportIcons.zip differ diff --git a/resources/fraport_icons_übersicht_2018-11-15.pdf b/resources/fraport_icons_übersicht_2018-11-15.pdf new file mode 100644 index 000000000..070759eb4 Binary files /dev/null and b/resources/fraport_icons_übersicht_2018-11-15.pdf differ diff --git a/routes b/routes index fb359922f..98cb723a6 100644 --- a/routes +++ b/routes @@ -68,6 +68,9 @@ /admin/crontab AdminCrontabR GET /admin/avs AdminAvsR GET POST /admin/ldap AdminLdapR GET POST +/admin/problems/no-contact ProblemUnreachableR GET +/admin/problems/no-avs-id ProblemWithoutAvsId GET +/admin/problems/r-without-f ProblemFbutNoR GET /print PrintCenterR GET POST !system-printer /print/acknowledge/#Day/#Int/#Int PrintAckR GET POST !system-printer @@ -102,8 +105,8 @@ /user/lang LangR POST !free /user/storage-key StorageKeyR POST !free -/for/#CryptoUUIDUser/user ForProfileR GET POST !supervisor -/for/#CryptoUUIDUser/user/profile ForProfileDataR GET !supervisor +/for/#CryptoUUIDUser/user ForProfileR GET POST !supervisor !self +/for/#CryptoUUIDUser/user/profile ForProfileDataR GET !supervisor !self /exam-office ExamOfficeR !exam-office: @@ -254,12 +257,12 @@ -- !/*{CI FilePath} CryptoFileNameDispatchR GET !free -- Disabled until preliminary check for valid cID exists -- for users -/qualification QualificationAllR GET !free -- TODO repurpose -/qualification/#SchoolId QualificationSchoolR GET !free -- TODO repurpose +/qualification QualificationAllR GET -- TODO repurpose +/qualification/#SchoolId QualificationSchoolR GET -- TODO repurpose /qualification/#SchoolId/#QualificationShorthand QualificationR GET -- TODO repurpose -- SAP export -/qualifications/sap/direct QualificationSAPDirectR GET !system-sap +/qualifications/sap/direct QualificationSAPDirectR GET !token -- OSIS CSV Export Demo /lms LmsAllR GET POST !free -- TODO verify that this is ok /lms/#SchoolId LmsSchoolR GET !free -- TODO verify that this is ok diff --git a/src/Auth/LDAP.hs b/src/Auth/LDAP.hs index 23c1eb341..fc225edf4 100644 --- a/src/Auth/LDAP.hs +++ b/src/Auth/LDAP.hs @@ -146,7 +146,7 @@ campusUserReTest' :: (MonadMask m, MonadLogger m, MonadUnliftIO m) => Failover ( campusUserReTest' pool doTest mode User{userIdent} = runMaybeT . catchIfMaybeT (is _CampusUserNoResult) $ campusUserReTest pool doTest mode (Creds apLdap (CI.original userIdent) []) -campusUser :: (MonadUnliftIO m, MonadMask m, MonadLogger m) => Failover (LdapConf, LdapPool) -> FailoverMode -> Creds site -> m (Ldap.AttrList []) +campusUser :: (MonadMask m, MonadUnliftIO m, MonadLogger m) => Failover (LdapConf, LdapPool) -> FailoverMode -> Creds site -> m (Ldap.AttrList []) campusUser pool mode creds = throwLeft =<< campusUserWith withLdapFailover pool mode creds campusUser' :: (MonadMask m, MonadUnliftIO m, MonadLogger m) => Failover (LdapConf, LdapPool) -> FailoverMode -> User -> m (Maybe (Ldap.AttrList [])) diff --git a/src/Data/Time/Clock/Instances.hs b/src/Data/Time/Clock/Instances.hs index 84f23db4f..d08b8e6c4 100644 --- a/src/Data/Time/Clock/Instances.hs +++ b/src/Data/Time/Clock/Instances.hs @@ -99,7 +99,7 @@ instance PersistField CalendarDiffDays where coerceICcd :: Integer -> CDDdb coerceICcd = fromIntegral - -- placement in Utils impossivle due to cyclic dependencies + -- placement in Utils impossible due to cyclic dependencies -- Data.Tuple.Extra is not yet a dependency -- both = join (***) is still too cryptic for me both :: (a -> b) -> (a, a) -> (b, b) diff --git a/src/Database/Esqueleto/Utils.hs b/src/Database/Esqueleto/Utils.hs index 2d823de2b..128307869 100644 --- a/src/Database/Esqueleto/Utils.hs +++ b/src/Database/Esqueleto/Utils.hs @@ -7,7 +7,7 @@ module Database.Esqueleto.Utils ( true, false - , justVal, justValList + , justVal, justValList, toValues , isJust, alt , isInfixOf, hasInfix , strConcat, substring @@ -50,7 +50,9 @@ import Data.Universe import qualified Data.Set as Set import qualified Data.List as List import qualified Data.Foldable as F +import Data.List.NonEmpty (NonEmpty(..)) import qualified Database.Esqueleto.Legacy as E +import qualified Database.Esqueleto.Experimental as Ex import qualified Database.Esqueleto.PostgreSQL as E import qualified Database.Esqueleto.Internal.Internal as E import Database.Esqueleto.Utils.TH @@ -97,10 +99,15 @@ false = E.val False -- infinity = unsafeSqlValue "'infinity'" justVal :: PersistField typ => typ -> E.SqlExpr (E.Value (Maybe typ)) -justVal = E.val . Just +-- justVal = E.val . Just +justVal = E.just . E.val justValList :: PersistField typ => [typ] -> E.SqlExpr (E.ValueList (Maybe typ)) -justValList = E.valList . map Just +-- justValList = E.valList . map Just +justValList = E.justList . E.valList + +toValues :: PersistField typ => NonEmpty typ -> Ex.From (Ex.SqlExpr (Ex.Value typ)) -- E.From invalid here, requires Esqueleto.Experimental +toValues = E.values . fmap Ex.val infixl 4 =?. (=?.) :: PersistField typ => E.SqlExpr (E.Value typ) -> E.SqlExpr (E.Value (Maybe typ)) -> E.SqlExpr (E.Value Bool) diff --git a/src/Foundation/Authorization.hs b/src/Foundation/Authorization.hs index 8edec626a..7b27f7cf6 100644 --- a/src/Foundation/Authorization.hs +++ b/src/Foundation/Authorization.hs @@ -568,15 +568,6 @@ tagAccessPredicate AuthSystemPrinter = cacheAPSystemFunction SystemPrinter (Just isPrinter <- lift $ exists [UserSystemFunctionUser ==. authId, UserSystemFunctionFunction ==. SystemPrinter, UserSystemFunctionIsOptOut ==. False] guardMExceptT isPrinter $ unauthorizedI MsgUnauthorizedSystemPrinter return Authorized -tagAccessPredicate AuthSystemSap = cacheAPSystemFunction SystemSap (Just $ Right diffHour) $ \mAuthId' _ _ sapList -> if - | maybe True (`Set.notMember` sapList) mAuthId' -> Right $ if - | is _Nothing mAuthId' -> return AuthenticationRequired - | otherwise -> unauthorizedI MsgUnauthorizedSystemSap - | otherwise -> Left $ APDB $ \_ _ mAuthId _ _ -> $cachedHereBinary mAuthId . exceptT return return $ do - authId <- maybeExceptT AuthenticationRequired $ return mAuthId - isPrinter <- lift $ exists [UserSystemFunctionUser ==. authId, UserSystemFunctionFunction ==. SystemSap, UserSystemFunctionIsOptOut ==. False] - guardMExceptT isPrinter $ unauthorizedI MsgUnauthorizedSystemSap - return Authorized tagAccessPredicate AuthStudent = cacheAPSystemFunction SystemStudent (Just $ Right diffHour) $ \mAuthId' _ _ studentList -> if | maybe True (`Set.notMember` studentList) mAuthId' -> Right $ if | is _Nothing mAuthId' -> return AuthenticationRequired @@ -1505,6 +1496,8 @@ tagAccessPredicate AuthSelf = APDB $ \_ _ mAuthId route _ -> exceptT return retu UserNotificationR cID -> return $ Left cID UserPasswordR cID -> return $ Left cID CourseR _ _ _ (CUserR cID) -> return $ Left cID + ForProfileR cID -> return $ Left cID + ForProfileDataR cID -> return $ Left cID _other -> throwError =<< $unsupportedAuthPredicate AuthSelf route referencedUser <- case referencedUser' of Right uid -> return uid diff --git a/src/Foundation/Navigation.hs b/src/Foundation/Navigation.hs index 3c4bcb72e..8d548dc43 100644 --- a/src/Foundation/Navigation.hs +++ b/src/Foundation/Navigation.hs @@ -106,14 +106,17 @@ breadcrumb (UserPasswordR cID) = useRunDB $ do breadcrumb AdminNewFunctionaryInviteR = i18nCrumb MsgMenuLecturerInvite $ Just UsersR breadcrumb AdminFunctionaryInviteR = i18nCrumb MsgBreadcrumbFunctionaryInvite Nothing -breadcrumb AdminR = i18nCrumb MsgAdminHeading Nothing -breadcrumb AdminTestR = i18nCrumb MsgMenuAdminTest $ Just AdminR -breadcrumb AdminTestPdfR = i18nCrumb MsgMenuAdminTest $ Just AdminTestR -breadcrumb AdminErrMsgR = i18nCrumb MsgMenuAdminErrMsg $ Just AdminR -breadcrumb AdminTokensR = i18nCrumb MsgMenuAdminTokens $ Just AdminR -breadcrumb AdminCrontabR = i18nCrumb MsgBreadcrumbAdminCrontab $ Just AdminR -breadcrumb AdminAvsR = i18nCrumb MsgMenuAvs $ Just AdminR -breadcrumb AdminLdapR = i18nCrumb MsgMenuLdap $ Just AdminR +breadcrumb AdminR = i18nCrumb MsgAdminHeading Nothing +breadcrumb AdminTestR = i18nCrumb MsgMenuAdminTest $ Just AdminR +breadcrumb AdminTestPdfR = i18nCrumb MsgMenuAdminTest $ Just AdminTestR +breadcrumb AdminErrMsgR = i18nCrumb MsgMenuAdminErrMsg $ Just AdminR +breadcrumb AdminTokensR = i18nCrumb MsgMenuAdminTokens $ Just AdminR +breadcrumb AdminCrontabR = i18nCrumb MsgBreadcrumbAdminCrontab $ Just AdminR +breadcrumb AdminAvsR = i18nCrumb MsgMenuAvs $ Just AdminR +breadcrumb AdminLdapR = i18nCrumb MsgMenuLdap $ Just AdminR +breadcrumb ProblemUnreachableR = i18nCrumb MsgProblemsUnreachableHeading $Just AdminR +breadcrumb ProblemWithoutAvsId = i18nCrumb MsgProblemsNoAvsIdHeading $ Just AdminR +breadcrumb ProblemFbutNoR = i18nCrumb MsgProblemsRWithoutFHeading $ Just AdminR breadcrumb PrintCenterR = i18nCrumb MsgMenuApc Nothing breadcrumb PrintSendR = i18nCrumb MsgMenuPrintSend $ Just PrintCenterR @@ -732,6 +735,14 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the , navIcon = IconMenuAdmin , navChildren = [ NavLink + { navLabel = MsgProblemsHeading + , navRoute = AdminR + , navAccess' = NavAccessTrue + , navType = NavTypeLink { navModal = False } + , navQuick' = mempty + , navForceActive = False + } + , NavLink { navLabel = MsgMenuUsers , navRoute = UsersR , navAccess' = NavAccessTrue diff --git a/src/Foundation/Yesod/Auth.hs b/src/Foundation/Yesod/Auth.hs index 9d4bbb1f2..7d2c4be8a 100644 --- a/src/Foundation/Yesod/Auth.hs +++ b/src/Foundation/Yesod/Auth.hs @@ -4,7 +4,8 @@ module Foundation.Yesod.Auth ( authenticate - , upsertCampusUser, upsertCampusUserByCn + , ldapLookupAndUpsert + , upsertCampusUser , decodeUserTest , CampusUserConversionException(..) , campusUserFailoverMode, updateUserLanguage @@ -106,10 +107,10 @@ authenticate creds@Creds{..} = liftHandler . runDB . withReaderT projectBackend | not isDummy -> res <$ update uid [ UserLastAuthentication =. Just now ] _other -> return res - $logDebugS "auth" $ tshow Creds{..} - UniWorX{..} <- getYesod + $logDebugS "auth" $ tshow Creds{..} + ldapPool' <- getsYesod $ view _appLdapPool - flip catches excHandlers $ case appLdapPool of + flip catches excHandlers $ case ldapPool' of Just ldapPool | Just upsertMode' <- upsertMode -> do ldapData <- campusUser ldapPool campusUserFailoverMode Creds{..} @@ -152,14 +153,25 @@ _upsertCampusUserMode mMode cs@Creds{..} defaultOther = apHash +ldapLookupAndUpsert :: forall m. (MonadHandler m, HandlerSite m ~ UniWorX, MonadMask m, MonadUnliftIO m) => Text -> SqlPersistT m (Entity User) +ldapLookupAndUpsert ident = + getsYesod (view _appLdapPool) >>= \case + Nothing -> throwM $ CampusUserLdapError $ LdapHostNotResolved "No LDAP configuration in Foundation." + Just ldapPool -> + campusUser'' ldapPool campusUserFailoverMode ident >>= \case + Nothing -> throwM CampusUserNoResult + Just ldapResponse -> upsertCampusUser UpsertCampusUserGuessUser ldapResponse + +{- THIS FUNCION JUST DECODES, BUT IT DOES NOT QUERY LDAP! upsertCampusUserByCn :: forall m. ( MonadHandler m, HandlerSite m ~ UniWorX , MonadThrow m ) => Text -> SqlPersistT m (Entity User) upsertCampusUserByCn persNo = upsertCampusUser UpsertCampusUserGuessUser [(ldapPrimaryKey,[Text.encodeUtf8 persNo])] +-} - +-- | Upsert User DB according to given LDAP data (does not query LDAP itself) upsertCampusUser :: forall m. ( MonadHandler m, HandlerSite m ~ UniWorX , MonadThrow m @@ -208,7 +220,7 @@ decodeUserTest mbIdent ldapData = do decodeUser :: (MonadThrow m) => UTCTime -> UserDefaultConf -> UpsertCampusUserMode -> Ldap.AttrList [] -> m (User,_) -decodeUser now UserDefaultConf{..} upsertMode ldapData = do +decodeUser now UserDefaultConf{..} upsertMode ldapData = do let userTelephone = decodeLdap ldapUserTelephone userMobile = decodeLdap ldapUserMobile @@ -279,7 +291,7 @@ decodeUser now UserDefaultConf{..} upsertMode ldapData = do , userMatrikelnummer = Nothing -- not known from LDAP, must be derived from REST interface to AVS TODO , userPostAddress = Nothing -- not known from LDAP, must be derived from REST interface to AVS TODO , userPinPassword = Nothing -- must be derived via AVS - , userPrefersPostal = False + , userPrefersPostal = userDefaultPrefersPostal , .. } userUpdate = [ diff --git a/src/Handler/Admin.hs b/src/Handler/Admin.hs index e627fbec3..5215d16b5 100644 --- a/src/Handler/Admin.hs +++ b/src/Handler/Admin.hs @@ -8,6 +8,22 @@ module Handler.Admin import Import +-- import Data.Either +import qualified Data.Set as Set +-- import qualified Data.Text.Lazy.Encoding as LBS + +-- import qualified Control.Monad.Catch as Catch +-- import Servant.Client (ClientError(..), ResponseF(..)) +-- import Text.Blaze.Html (preEscapedToHtml) + +import Database.Esqueleto.Experimental ((:&)(..)) +import qualified Database.Esqueleto.Experimental as E +import qualified Database.Esqueleto.Utils as E + +import Handler.Utils.DateTime +import Handler.Utils.Avs +import Handler.Utils.Widgets + import Handler.Admin.Test as Handler.Admin import Handler.Admin.ErrorMessage as Handler.Admin import Handler.Admin.Tokens as Handler.Admin @@ -15,8 +31,188 @@ import Handler.Admin.Crontab as Handler.Admin import Handler.Admin.Avs as Handler.Admin import Handler.Admin.Ldap as Handler.Admin + getAdminR :: Handler Html -getAdminR = - siteLayoutMsg MsgAdminHeading $ do - setTitleI MsgAdminHeading - i18n MsgAdminPageEmpty +getAdminR = do + now <- liftIO getCurrentTime + let nowaday = utctDay now + cutOffPrintDays = 7 + cutOffPrintJob = addLocalDays (-cutOffPrintDays) now + (usersAreReachable, driversHaveAvsIds, rDriversHaveFs, noStalePrintJobs) <- runDB $ (,,,) + <$> areAllUsersReachable + <*> allDriversHaveAvsId nowaday + <*> allRDriversHaveFs nowaday + <*> (not <$> exists [PrintJobAcknowledged ==. Nothing, PrintJobCreated <=. cutOffPrintJob]) + diffLics <- try retrieveDifferingLicences <&> \case + -- (Left (UnsupportedContentType "text/html" resp)) -> Left $ text2widget "Html received" + (Left e) -> Left $ text2widget $ tshow (e :: SomeException) + (Right (to0, to1, to2)) -> Right (Set.size to0, Set.size to1, Set.size to2) + -- let procDiffLics (to0, to1, to2) = Right (Set.size to0, Set.size to1, Set.size to2) + -- diffLics <- (procDiffLics <$> retrieveDifferingLicences) `catches` + -- [ Catch.Handler (\case (UnsupportedContentType "text/html;charset=utf-8" Response{responseBody}) + -- -> return $ Left $ toWidget $ preEscapedToHtml $ fromRight "Response UTF8-decoding error" $ LBS.decodeUtf8' responseBody + -- ex -> return $ Left $ text2widget $ tshow ex) + -- , Catch.Handler (\(ex::SomeException) -> return $ Left $ text2widget $ tshow ex) + -- ] + + -- we abuse messageTooltip for colored icons here + msgSuccessTooltip <- messageI Success MsgMessageSuccess + msgWarningTooltip <- messageI Warning MsgMessageWarning + msgErrorTooltip <- messageI Error MsgMessageError + + let flagError = messageTooltip . bool msgErrorTooltip msgSuccessTooltip + flagWarning = messageTooltip . bool msgWarningTooltip msgSuccessTooltip + flagNonZero :: Int -> Widget + flagNonZero n | n <= 0 = flagError True + | otherwise = messageTooltip =<< handlerToWidget (messageI Error (MsgProblemsDriverSynch n)) + + siteLayoutMsg MsgProblemsHeading $ do + setTitleI MsgProblemsHeading + $(widgetFile "admin-problems") + + +getProblemUnreachableR :: Handler Html +getProblemUnreachableR = do + unreachables <- runDB $ E.select retrieveUnreachableUsers + siteLayoutMsg MsgProblemsUnreachableHeading $ do + setTitleI MsgProblemsUnreachableHeading + [whamlet| +
+ _{MsgProblemsUnreachableBody} +