diff --git a/config/settings.yml b/config/settings.yml index 2809c54ba..e714cd3e9 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -32,6 +32,18 @@ mail-support: email: "_env:MAILSUPPORT:uni2work@ifi.lmu.de" mail-retain-sent: 31470547 +legal-external: + - language: "en" + imprint: "https://www.fraport.com/en/tools/imprint.html" + data-protection: "https://www.fraport.com/en/our-group/data-protection-statement.html" + terms-of-use: "https://www.fraport.com/en/tools/legal-information.html" + payments: "https://www.fraport.com/de/geschaeftsfelder/service/geschaeftspartner/richtlinien-und-zahlungsbedingungen.html" + - language: "de" + imprint: "https://www.fraport.com/de/tools/impressum.html" + data-protection: "https://www.fraport.com/de/konzern/datenschutz.html" + terms-of-use: "https://www.fraport.com/de/tools/disclaimer.html" + payments: "https://www.fraport.com/de/geschaeftsfelder/service/geschaeftspartner/richtlinien-und-zahlungsbedingungen.html" + job-workers: "_env:JOB_WORKERS:10" job-flush-interval: "_env:JOB_FLUSH:30" job-cron-interval: "_env:CRON_INTERVAL:60" diff --git a/messages/uniworx/categories/info/de-de-formal.msg b/messages/uniworx/categories/info/de-de-formal.msg index 4844e9c56..d317cdb5b 100644 --- a/messages/uniworx/categories/info/de-de-formal.msg +++ b/messages/uniworx/categories/info/de-de-formal.msg @@ -3,6 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-or-later HeadingLegal: Rechtliche Informationen +InfoSupervisorTitle: Hinweise für Ansprechpartner InfoLecturerTitle: Hinweise für Veranstalter:innen InfoLecturerCourses: Veranstaltungen InfoLecturerExercises: Übungsbetrieb diff --git a/messages/uniworx/categories/info/en-eu.msg b/messages/uniworx/categories/info/en-eu.msg index 77d52d870..e39baf4cc 100644 --- a/messages/uniworx/categories/info/en-eu.msg +++ b/messages/uniworx/categories/info/en-eu.msg @@ -3,6 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-or-later HeadingLegal: Legal +InfoSupervisorTitle: Information for Supervisors InfoLecturerTitle: Information for lecturers InfoLecturerCourses: Courses InfoLecturerExercises: Course Exercises diff --git a/messages/uniworx/utils/navigation/menu/de-de-formal.msg b/messages/uniworx/utils/navigation/menu/de-de-formal.msg index b3005b8d3..e5aee3da3 100644 --- a/messages/uniworx/utils/navigation/menu/de-de-formal.msg +++ b/messages/uniworx/utils/navigation/menu/de-de-formal.msg @@ -21,6 +21,7 @@ MenuDataProt: Datenschutzerklärung MenuTermsUse: Nutzungsbedingungen MenuCopyright: Urheberrecht MenuImprint: Impressum +MenuPayments: Zahlungsbedingungen MenuInstance: Instanz-Identifikation MenuHealth: Instanz-Zustand diff --git a/messages/uniworx/utils/navigation/menu/en-eu.msg b/messages/uniworx/utils/navigation/menu/en-eu.msg index d65d8bc65..b70a400fd 100644 --- a/messages/uniworx/utils/navigation/menu/en-eu.msg +++ b/messages/uniworx/utils/navigation/menu/en-eu.msg @@ -21,6 +21,7 @@ MenuDataProt: Data protection MenuTermsUse: Terms of use MenuCopyright: Copyright MenuImprint: Imprint +MenuPayments: Payment Terms MenuInstance: Instance identification MenuHealth: Instance health diff --git a/routes b/routes index 86f96547c..b08f5ccbc 100644 --- a/routes +++ b/routes @@ -79,10 +79,15 @@ /instance InstanceR GET !free /info InfoR GET !free /info/lecturer InfoLecturerR GET !free +/info/supervisor InfoSupervisorR GET !free /info/legal LegalR GET !free /info/allocation InfoAllocationR GET !free /info/glossary GlossaryR GET !free /info/faq FaqR GET !free +/info/terms-of-use TermsOfUseR GET !free +/info/payments PaymentsR GET !free +/imprint ImprintR GET !free +/data-protection DataProtectionR GET !free /version VersionR GET !free /status StatusR GET !free diff --git a/src/Application.hs b/src/Application.hs index fcc9dc91b..6ae224457 100644 --- a/src/Application.hs +++ b/src/Application.hs @@ -370,6 +370,8 @@ makeFoundation appSettings''@AppSettings{..} = do } return . Just $ mkAvsQuery avsServer avsAuth avsEnv + when (null appLegalExternal) $ $logErrorS "Legal" "Configuration of external legal links is missing." + $logDebugS "Runtime configuration" $ tshowCrop appSettings' let foundation = mkFoundation appSettings' sqlPool smtpPool ldapPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appMemcachedLocal appUploadCache appVerpSecret appAuthKey appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery diff --git a/src/Foundation/Navigation.hs b/src/Foundation/Navigation.hs index ae285ae5c..317f9080f 100644 --- a/src/Foundation/Navigation.hs +++ b/src/Foundation/Navigation.hs @@ -47,7 +47,7 @@ import Yesod.Core.Types (HandlerContents) type Breadcrumb = (Text, Maybe (Route UniWorX)) - + -- Define breadcrumbs. i18nCrumb :: forall msg m. (RenderMessage UniWorX msg, MonadHandler m, HandlerSite m ~ UniWorX) @@ -117,7 +117,7 @@ breadcrumb AdminLdapR = i18nCrumb MsgMenuLdap $ Just AdminR breadcrumb PrintCenterR = i18nCrumb MsgMenuApc Nothing breadcrumb PrintSendR = i18nCrumb MsgMenuPrintSend $ Just PrintCenterR -breadcrumb PrintDownloadR{} = i18nCrumb MsgMenuPrintDownload $ Just PrintCenterR +breadcrumb PrintDownloadR{} = i18nCrumb MsgMenuPrintDownload $ Just PrintCenterR breadcrumb PrintAckR{} = i18nCrumb MsgMenuPrintSend $ Just PrintCenterR -- never displayed breadcrumb PrintAckDirectR{}= i18nCrumb MsgMenuPrintSend $ Just PrintCenterR -- never displayed @@ -134,12 +134,18 @@ breadcrumb (ExamOfficeR EOFieldsR) = i18nCrumb MsgMenuExamOfficeFields . Just $ breadcrumb (ExamOfficeR EOUsersR) = i18nCrumb MsgMenuExamOfficeUsers . Just $ ExamOfficeR EOExamsR breadcrumb (ExamOfficeR EOUsersInviteR) = i18nCrumb MsgBreadcrumbExamOfficeUserInvite Nothing -breadcrumb InfoR = i18nCrumb MsgMenuInformation Nothing -breadcrumb InfoLecturerR = i18nCrumb MsgInfoLecturerTitle $ Just InfoR -breadcrumb LegalR = i18nCrumb MsgMenuLegal $ Just InfoR +breadcrumb InfoR = i18nCrumb MsgMenuInformation Nothing +breadcrumb InfoLecturerR = i18nCrumb MsgInfoLecturerTitle $ Just InfoR +breadcrumb InfoSupervisorR = i18nCrumb MsgInfoSupervisorTitle $ Just InfoR +breadcrumb LegalR = i18nCrumb MsgMenuLegal $ Just InfoR +breadcrumb ImprintR = i18nCrumb MsgMenuImprint $ Just LegalR +breadcrumb DataProtectionR = i18nCrumb MsgMenuDataProt $ Just LegalR +breadcrumb TermsOfUseR = i18nCrumb MsgMenuTermsUse $ Just LegalR +breadcrumb PaymentsR = i18nCrumb MsgMenuPayments $ Just LegalR + breadcrumb InfoAllocationR = i18nCrumb MsgBreadcrumbAllocationInfo $ Just InfoR -breadcrumb VersionR = i18nCrumb MsgMenuVersion $ Just InfoR -breadcrumb FaqR = i18nCrumb MsgBreadcrumbFaq $ Just InfoR +breadcrumb VersionR = i18nCrumb MsgMenuVersion $ Just InfoR +breadcrumb FaqR = i18nCrumb MsgBreadcrumbFaq $ Just InfoR breadcrumb HelpR = i18nCrumb MsgMenuHelp Nothing @@ -150,21 +156,21 @@ breadcrumb InstanceR = i18nCrumb MsgMenuInstance Nothing breadcrumb StatusR = i18nCrumb MsgMenuHealth Nothing -- never displayed breadcrumb QualificationAllR = i18nCrumb MsgMenuQualifications Nothing -breadcrumb (QualificationSchoolR ssh ) = useRunDB . maybeT (i18nCrumb MsgBreadcrumbSchool . Just $ SchoolListR) $ do -- redirect only, used in other breadcrumbs - guardM . lift . existsBy . UniqueSchoolShorthand $ unSchoolKey ssh +breadcrumb (QualificationSchoolR ssh ) = useRunDB . maybeT (i18nCrumb MsgBreadcrumbSchool . Just $ SchoolListR) $ do -- redirect only, used in other breadcrumbs + guardM . lift . existsBy . UniqueSchoolShorthand $ unSchoolKey ssh return (CI.original $ unSchoolKey ssh, Just QualificationAllR) breadcrumb (QualificationR ssh qsh) =useRunDB . maybeT (i18nCrumb MsgBreadcrumbCourse . Just $ QualificationSchoolR ssh) $ do - guardM . lift . existsBy $ SchoolQualificationShort ssh qsh + guardM . lift . existsBy $ SchoolQualificationShort ssh qsh return (CI.original qsh, Just $ QualificationSchoolR ssh) breadcrumb LmsAllR = i18nCrumb MsgMenuLms Nothing -breadcrumb (LmsSchoolR ssh ) = useRunDB . maybeT (i18nCrumb MsgBreadcrumbSchool . Just $ SchoolListR) $ do -- redirect only, used in other breadcrumbs - guardM . lift . existsBy . UniqueSchoolShorthand $ unSchoolKey ssh +breadcrumb (LmsSchoolR ssh ) = useRunDB . maybeT (i18nCrumb MsgBreadcrumbSchool . Just $ SchoolListR) $ do -- redirect only, used in other breadcrumbs + guardM . lift . existsBy . UniqueSchoolShorthand $ unSchoolKey ssh return (CI.original $ unSchoolKey ssh, Just LmsAllR) breadcrumb (LmsR ssh qsh) =useRunDB . maybeT (i18nCrumb MsgBreadcrumbCourse . Just $ LmsSchoolR ssh) $ do - guardM . lift . existsBy $ SchoolQualificationShort ssh qsh + guardM . lift . existsBy $ SchoolQualificationShort ssh qsh return (CI.original qsh, Just $ LmsSchoolR ssh) -breadcrumb (LmsEditR ssh qsh) = i18nCrumb MsgMenuLmsEdit $ Just $ LmsR ssh qsh +breadcrumb (LmsEditR ssh qsh) = i18nCrumb MsgMenuLmsEdit $ Just $ LmsR ssh qsh breadcrumb (LmsUsersR ssh qsh) = i18nCrumb MsgMenuLmsUsers $ Just $ LmsR ssh qsh breadcrumb (LmsUsersDirectR ssh qsh) = i18nCrumb MsgMenuLmsUsers $ Just $ LmsUsersR ssh qsh -- never displayed, TypedContent breadcrumb (LmsUserlistR ssh qsh) = i18nCrumb MsgMenuLmsUserlist $ Just $ LmsR ssh qsh @@ -543,7 +549,7 @@ navLinkAccess NavLink{..} = case navAccess' of authCtx <- getAuthContext memcachedBy (Just . Right $ 2 * diffMinute) (NavCacheRouteAccess authCtx nt route) . useRunDB $ bool hasWriteAccessTo hasReadAccessTo (is _NavTypeLink nt) route - + defaultLinks :: ( MonadHandler m , HandlerSite m ~ UniWorX -- , MonadThrow m @@ -629,7 +635,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the } , return $ NavFooter NavLink { navLabel = MsgMenuDataProt - , navRoute = LegalR :#: ("data-protection" :: Text) + , navRoute = DataProtectionR , navAccess' = NavAccessTrue , navType = NavTypeLink { navModal = False } , navQuick' = mempty @@ -653,7 +659,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the } , return $ NavFooter NavLink { navLabel = MsgMenuImprint - , navRoute = LegalR :#: ("imprint" :: Text) -- neue Route, dort redirect "http://" + , navRoute = ImprintR , navAccess' = NavAccessTrue , navType = NavTypeLink { navModal = False } , navQuick' = mempty @@ -762,7 +768,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the , navQuick' = mempty , navForceActive = False } - } + } , return NavHeaderContainer { navHeaderRole = NavHeaderPrimary , navLabel = SomeMessage MsgMenuAdminHeading @@ -839,7 +845,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the , navType = NavTypeLink { navModal = False } , navQuick' = mempty , navForceActive = False - } + } ] } , return NavHeaderContainer @@ -1418,7 +1424,7 @@ pageActions (ForProfileR cID) = return } , navChildren = [] } - ] + ] pageActions TermShowR = do participantsSecondary <- pageQuickActions NavQuickViewPageActionSecondary ParticipantsListR return @@ -2034,7 +2040,7 @@ pageActions (CSheetR tid ssh csh shn SShowR) = do { navLink = NavLink { navLabel = MsgMenuSheetPersonalisedFiles , navRoute = CSheetR tid ssh csh shn SPersonalFilesR - , navAccess' = NavAccessDB $ + , navAccess' = NavAccessDB $ let onlyPersonalised = fmap (maybe False $ not . E.unValue) . E.selectMaybe . E.from $ \(sheet `E.InnerJoin` course) -> do E.on $ sheet E.^. SheetCourse E.==. course E.^. CourseId E.where_$ sheet E.^. SheetName E.==. E.val shn @@ -2093,7 +2099,7 @@ pageActions (CSheetR tid ssh csh shn SSubsR) = return { navLink = NavLink { navLabel = MsgMenuSubmissionNew , navRoute = CSheetR tid ssh csh shn SubmissionNewR - , navAccess' = NavAccessDB $ + , navAccess' = NavAccessDB $ let submissionAccess = hasWriteAccessTo $ CSheetR tid ssh csh shn SSubsR hasNoSubmission = maybeT (return False) $ do uid <- MaybeT $ liftHandler maybeAuthId @@ -2494,31 +2500,31 @@ pageActions ParticipantsListR = return , navChildren = [] } ] -pageActions (LmsR sid qsh) = return - [ NavPageActionPrimary +pageActions (LmsR sid qsh) = return + [ NavPageActionPrimary { navLink = defNavLink MsgMenuLmsUsers $ LmsUsersR sid qsh - , navChildren = - [ defNavLink MsgMenuLmsDirectDownload $ LmsUsersDirectR sid qsh + , navChildren = + [ defNavLink MsgMenuLmsDirectDownload $ LmsUsersDirectR sid qsh ] } - , NavPageActionPrimary + , NavPageActionPrimary { navLink = defNavLink MsgMenuLmsUserlist $ LmsUserlistR sid qsh - , navChildren = - [ defNavLink MsgMenuLmsUpload $ LmsUserlistUploadR sid qsh - , defNavLink MsgMenuLmsDirectUpload $ LmsUserlistDirectR sid qsh + , navChildren = + [ defNavLink MsgMenuLmsUpload $ LmsUserlistUploadR sid qsh + , defNavLink MsgMenuLmsDirectUpload $ LmsUserlistDirectR sid qsh ] } - , NavPageActionPrimary + , NavPageActionPrimary { navLink = defNavLink MsgMenuLmsResult $ LmsResultR sid qsh - , navChildren = - [ defNavLink MsgMenuLmsUpload $ LmsResultUploadR sid qsh - , defNavLink MsgMenuLmsDirectUpload $ LmsResultDirectR sid qsh + , navChildren = + [ defNavLink MsgMenuLmsUpload $ LmsResultUploadR sid qsh + , defNavLink MsgMenuLmsDirectUpload $ LmsResultDirectR sid qsh ] } - , NavPageActionSecondary { + , NavPageActionSecondary { navLink = defNavLink MsgMenuLmsEdit $ LmsEditR sid qsh } - , NavPageActionSecondary { + , NavPageActionSecondary { navLink = defNavLink MsgMenuLmsFake $ LmsFakeR sid qsh } ] @@ -2536,14 +2542,14 @@ pageActions ApiDocsR = return } ] pageActions PrintCenterR = do - openDays <- useRunDB $ Ex.select $ do + openDays <- useRunDB $ Ex.select $ do pj <- Ex.from $ Ex.table @PrintJob - let pjDay = E.day $ pj Ex.^. PrintJobCreated + let pjDay = E.day $ pj Ex.^. PrintJobCreated Ex.where_ $ Ex.isNothing (pj Ex.^. PrintJobAcknowledged) Ex.orderBy [ Ex.asc pjDay ] pure (pjDay, pj Ex.^. PrintJobId) - - let dayMap = Map.fromListWith (<>) (openDays <&> (\(Ex.unValue -> pjDay, Ex.unValue -> pjId) -> (pjDay, Set.singleton pjId))) + + let dayMap = Map.fromListWith (<>) (openDays <&> (\(Ex.unValue -> pjDay, Ex.unValue -> pjId) -> (pjDay, Set.singleton pjId))) toDayAck (d, pjIds) = do dtxt <- formatTime SelFormatDate d let n = Set.size pjIds @@ -2551,7 +2557,7 @@ pageActions PrintCenterR = do msg = "#" <> tshow n <> ", " <> dtxt return NavPageActionPrimary { navLink = NavLink - { navLabel = SomeMessage msg + { navLabel = SomeMessage msg , navRoute = PrintAckR d n h , navAccess' = NavAccessTrue , navType = NavTypeLink { navModal = True } @@ -2571,7 +2577,7 @@ pageActions PrintCenterR = do } } dayLinks <- mapM toDayAck $ Map.toAscList dayMap - return $ manualSend : take 9 dayLinks + return $ manualSend : take 9 dayLinks pageActions _ = return [] diff --git a/src/Foundation/SiteLayout.hs b/src/Foundation/SiteLayout.hs index faa1fe3ef..249ee5840 100644 --- a/src/Foundation/SiteLayout.hs +++ b/src/Foundation/SiteLayout.hs @@ -422,7 +422,7 @@ siteLayout' overrideHeading widget = do -> let route = navRoute' ident = navIdent in $(widgetFile "widgets/footer/link") - _other -> error "not implemented" + _other -> error "Treatment of this kind of Nav is not implemented." navContainerItemWidget :: (Nav, Text, Maybe Text, [(NavLink, Text, Text)]) -> (NavLink, Text, Text) diff --git a/src/Handler/Info.hs b/src/Handler/Info.hs index 4b06ab0f5..af12815cb 100644 --- a/src/Handler/Info.hs +++ b/src/Handler/Info.hs @@ -20,9 +20,25 @@ import Development.GitRev import Auth.LDAP (ADError(..), ADInvalidCredentials(..), CampusMessage(..)) -import Yesod.Auth.Message(AuthMessage(..)) - +import Yesod.Auth.Message(AuthMessage(..)) + +pickLegalExternalLang :: Handler LegalExternal +pickLegalExternalLang = do + langMap <- $cachedHereBinary ("legal_external"::Text) makeMapLegalExternal + availLangs <- case nonEmpty' (Map.keys langMap) of + Just ls -> pure ls + Nothing -> $logErrorS "Legal" "Configuration of external legal links is missing." >> notFound + lang <- selectLanguage availLangs + return $ langMap ! lang + where + makeMapLegalExternal :: Handler (Map Lang LegalExternal) + makeMapLegalExternal = do + legExs <- getsYesod $ view _appLegalExternal + return $ Set.foldl' (\acc le -> Map.singleton (externalLanguage le) le <> acc) mempty legExs + -- return $ Map.fromAscList [(externalLanguage le,le) | le <- Set.toAscList legExs] + + -- | Versionsgeschichte getVersionR :: Handler TypedContent getVersionR = selectRep $ do @@ -31,9 +47,32 @@ getVersionR = selectRep $ do provideRep getInfoR +getImprintR :: Handler Html +getImprintR = do + le <- pickLegalExternalLang + redirect $ externalImprint le + +getDataProtectionR :: Handler Html +getDataProtectionR = do + le <- pickLegalExternalLang + redirect $ externalDataProtection le + +getPaymentsR :: Handler Html +getPaymentsR = do + le <- pickLegalExternalLang + redirect $ externalPayments le + +getTermsOfUseR :: Handler Html +getTermsOfUseR = do + le <- pickLegalExternalLang + redirect $ externalTermsOfUse le + +getInfoSupervisorR :: Handler Html +getInfoSupervisorR = error "TODO" + -- | Datenschutzerklaerung und Aufbewahrungspflichten, Nutzungsbedingungen, Urheberrecht, Impressum getLegalR :: Handler Html -getLegalR = +getLegalR = do siteLayoutMsg MsgHeadingLegal $ do setTitleI MsgLegalHeading let dataProtection = $(i18nWidgetFile "data-protection") diff --git a/src/Settings.hs b/src/Settings.hs index 270fb2039..7d1274058 100644 --- a/src/Settings.hs +++ b/src/Settings.hs @@ -246,6 +246,8 @@ data AppSettings = AppSettings , appCommunicationAttachmentsMaxSize :: Maybe Natural , appFileChunkingParams :: FastCDCParameters + + , appLegalExternal :: Set LegalExternal } deriving Show @@ -412,6 +414,17 @@ data SettingBotMitigation deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable) deriving anyclass (Universe, Finite) +data LegalExternal = LegalExternal + { externalLanguage :: Lang + , externalImprint :: Text + , externalDataProtection :: Text + , externalTermsOfUse :: Text + , externalPayments :: Text + } + deriving (Eq, Ord, Read, Show, Generic, Typeable) +makeLenses_ ''LegalExternal + + nullaryPathPiece ''ApprootScope $ camelToPathPiece' 1 pathPieceJSON ''ApprootScope pathPieceJSONKey ''ApprootScope @@ -585,6 +598,14 @@ instance FromJSON ServerSessionSettings where , ServerSession.setPersistentCookies <$> persistentCookies ]) +instance FromJSON LegalExternal where + parseJSON = withObject "LegalExternal" $ \o -> do + externalLanguage <- o .: "language" + externalImprint <- o .: "imprint" + externalDataProtection <- o .: "data-protection" + externalTermsOfUse<- o .: "terms-of-use" + externalPayments <- o .: "payments" + return LegalExternal{..} instance FromJSON AppSettings where parseJSON = withObject "AppSettings" $ \o -> do @@ -779,6 +800,8 @@ instance FromJSON AppSettings where appCommunicationAttachmentsMaxSize <- o .:? "communication-attachments-max-size" + appLegalExternal <- o .: "legal-external" + return AppSettings{..} where isValidARCConf ARCConf{..} = arccMaximumWeight > 0 diff --git a/templates/i18n/copyright/de-de-formal.hamlet b/templates/i18n/copyright/de-de-formal.hamlet index f0e9eaf1a..c207c7e30 100644 --- a/templates/i18n/copyright/de-de-formal.hamlet +++ b/templates/i18n/copyright/de-de-formal.hamlet @@ -1,14 +1,19 @@ $newline never -$# SPDX-FileCopyrightText: 2022 Sarah Vaupel +$# SPDX-FileCopyrightText: 2022 Sarah Vaupel ,Steffen Jost $# $# SPDX-License-Identifier: AGPL-3.0-or-later -

- Durch das Einstellen von Inhalten in Uni2work erklären Sie, dass Sie das Recht besitzen, # - die so veröffentlichten Inhalte an alle zugriffsberechtigten Personen zu verbreiten.

- Im Zuge dessen gewähren Sie allen zugriffsberechtigten Personen das Recht, die Inhalte herunterzuladen und # - für persönliche Zwecke zu nutzen, sowie für der Lehre innerhalb dieses konkreten Kurses dienliche Zwecke # - einzusetzen. + Zusätzlich zu den Nutzungsbedingungen und Nutzungspflichten der Fraport AG gilt: +