From 02454f5bf395c2b3e714cf78e350187f8d7c99ae Mon Sep 17 00:00:00 2001
From: Julian Rother <julian@cccv.de>
Date: Sat, 4 Sep 2021 21:24:11 +0200
Subject: [PATCH] Display per-client-customizable message on login page

---
 uffd/default_config.cfg                      |   1 +
 uffd/oauth2/models.py                        |   9 +++++-
 uffd/oauth2/views.py                         |   3 +-
 uffd/translations/de/LC_MESSAGES/messages.mo | Bin 30889 -> 31076 bytes
 uffd/translations/de/LC_MESSAGES/messages.po |  32 ++++++++++++-------
 5 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/uffd/default_config.cfg b/uffd/default_config.cfg
index 6a27760b..e7ee0d62 100644
--- a/uffd/default_config.cfg
+++ b/uffd/default_config.cfg
@@ -95,6 +95,7 @@ OAUTH2_CLIENTS={
 	# You can optionally restrict access to users with a certain group. Set 'required_group' to the name of an LDAP group name or a list of groups.
 	# ... 'required_group': 'test_access_group' ... only allows users with group "test_access_group" access
 	# ... 'required_group': ['groupa', ['groupb', 'groupc']] ... allows users with group "groupa" as well as users with both "groupb" and "groupc" access
+	# Set 'login_message' (or suffixed with a language code like 'login_message_de') to display a custom message on the login form.
 }
 
 API_CLIENTS={
diff --git a/uffd/oauth2/models.py b/uffd/oauth2/models.py
index 450edd9a..5e27c5d7 100644
--- a/uffd/oauth2/models.py
+++ b/uffd/oauth2/models.py
@@ -1,4 +1,5 @@
 from flask import current_app
+from flask_babel import get_locale, gettext as _
 from sqlalchemy import Column, Integer, String, DateTime, Text
 
 from uffd.ldapalchemy.dbutils import DBRelationship
@@ -7,7 +8,7 @@ from uffd.user.models import User
 from uffd.session.models import DeviceLoginInitiation, DeviceLoginType
 
 class OAuth2Client:
-	def __init__(self, client_id, client_secret, redirect_uris, required_group=None, logout_urls=None):
+	def __init__(self, client_id, client_secret, redirect_uris, required_group=None, logout_urls=None, **kwargs):
 		self.client_id = client_id
 		self.client_secret = client_secret
 		# We only support the Authorization Code Flow for confidential (server-side) clients
@@ -21,6 +22,12 @@ class OAuth2Client:
 				self.logout_urls.append(['GET', url])
 			else:
 				self.logout_urls.append(url)
+		self.kwargs = kwargs
+
+	@property
+	def login_message(self):
+		return self.kwargs.get('login_message_' + get_locale().language,
+		                       self.kwargs.pop('login_message', _('You need to login to access this service')))
 
 	@classmethod
 	def from_id(cls, client_id):
diff --git a/uffd/oauth2/views.py b/uffd/oauth2/views.py
index cb8037c9..898d3d9b 100644
--- a/uffd/oauth2/views.py
+++ b/uffd/oauth2/views.py
@@ -164,12 +164,13 @@ def authorize():
 		del session['devicelogin_secret']
 		del session['devicelogin_confirmation']
 		if not initiation or initiation.expired or not confirmation:
-			flash('Device login failed')
+			flash(_('Device login failed'))
 			return redirect(url_for('session.login', ref=request.full_path, devicelogin=True))
 		credentials['user'] = confirmation.user
 		db.session.delete(initiation)
 		db.session.commit()
 	else:
+		flash(client.login_message)
 		return redirect(url_for('session.login', ref=request.full_path, devicelogin=True))
 
 	# Here we would normally ask the user, if he wants to give the requesting
diff --git a/uffd/translations/de/LC_MESSAGES/messages.mo b/uffd/translations/de/LC_MESSAGES/messages.mo
index e58966921aed2726349395182b5de736f144f297..8732d8a30f74045b143df675da5ec4687b98356f 100644
GIT binary patch
delta 5064
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

delta 4911
zcmaFziE-se#`=3gEK?a67#MUI85m?37#M0eK|BP$BgDYK&%nTNSBQZ@n1O-etq=nP
z8v_Faqc8)54+8@OhcE*J4+8^3s4xQq7Xt%B5|p0{<yQ$aFz_-kFtiFYFt9T)FiaL^
zU=U$oV3;k;z@W&$P|vVIn1R8bfq~(YFav`j0|SGQ2m?bQ0|SGL2t?yH5e9~61_p*B
zA`A@685kH8L>U;|85kH&h%zwLGB7X*h%qoIF)%Rni7_y^F)%P}6k}kJWME+UA;!QU
z1~N|^;sH%@1_lcT1_n!Uh(n9SK_01RV5kK%7#Lch3cJM_7#u(@6lY*yWnf^q1En8{
zLmc=5s!mFRfkBpmfk8`xfkBjkfx$z9fkB#qfgw(UfkBXgfuTx*fq{d8fuTnN;*hBl
zkPuuW!N9=Bz`$@of`Ng%o`HekyadEWx1k!INq}6&!0;Yw@HYua5c5bfFmN+4Fi1*5
zf>2cwB5nnx-6a_qEEyOWLL?#j`=H`eCBZ?>ut*Z(pd(Q6vyu!9^&pqul4M{|XJBCX
zAj!ZW#lXNIA;rLu!oa{_ECun|3@M0<*FovMQVa|V3=9lsq!<{iL1{t?5`~)53=EkJ
z3=Emlkhs1q4YBaHG{iwqq!}0l7#J8{OGBdMk2FI)*hf4v3=GU5i)A1|C?mtbAjiPK
zU?BssAY2BL7ADI;3|c4yanK4G28OE)3=G?47#J!T7#MnG85kxqFfg#mLCl#U2T{L8
zj)6g$fq`MS9K_=LauEIR<?0~<|KuQvh)<q@VKV~*gP}Y`{HZ*|Ctu|uiR!OB1A{mN
z1B18%Brf$8AU<-2@<S9LxhO*cVsWbiB+7cA@-q}57Ozo&M9J=Y1xV1{Re)F|s|eAk
zs>r~g4a$~^kVF`v2ysB1A_D^p0|P^aA_D^`r`9S$qM}`qfkBmlfnkLrB;?L1GBCJ+
zqDB!CwMI&i5QtKOm{+F+NptlrN)QG8N)Q9KD={$0gYvr)#KONy4B-4OuFSxo!N9;E
zrwp;sT^Zt#3}r|n%vFYjSd}s)&2%X<Fz7NcFf4$oKc@`w`FmxENB=2<9Z=7}rUKC@
zr~(#XP*i~gnT`s?hZZUf4EhWV3{EN#3yV}37(y8s7|NmQ&#FMu&J7iaL+(K7mnx8`
z`KH3aAjH7Hz^)1j0V!38xpt}`kJd9Vc&IWks4y@vWT-;2Rj(=o!xRPvhDE9j3>z63
z7|himsrV(7{-g#m__rD)4e+QlFld4bCUr<Y_k!{h)gd0~R);ujx;iAPm#8x^q%$xu
zJORmr^1qJ;BuFAOAO<FAK!U17gMlHRfq|h}gMp!qfq~((1|%0$X+j*-p$V~Yq9#Oq
zg(d@oEdv9?Hcd#BebI!3>~BqokGZuV=89@T(uj%{14F$Q0|SGz7DPdw7Q~<mD8Ee$
zl2|5aK?;^>T9ESLf)*q#yw-w5iHJ7DLP>1~h6qqdXhVEnsm;J30V?~oAt5kN8xq2+
zwILojpv_PZE(%XV72MEfV3@(c!0;5RpiT$kpmrTdkWbZt7_dwSV&QHbNSZmM1Bv6a
zI*<@~paZF#zUx5B1s7e2!}jVjFic`#U=Y)T=wGQ<4=K|(=rJ&~GB7Ya(qmwl07?t`
zkktQE9}*?P1`G^~85kJU4Iruiv;hNy0RscW8v{t(%NjyL$lVZ9IW-zW^q(|@sDEt8
zz~IQhz`$YzsaxEPAc?WP-Ut$etBoK*y}<~QeYP1fFuVm7u||+eW|uKEl^a7s;*K#S
zF5enMeDcSbfgz89fq~hCfx&};fuYERfx!z@;+a6w7Mm#pgAD@%1D`1*D!ff0_SHw2
zLgFgU6jCB(nL=FFV+u(m8%!Y<oHvE|=o*y&!4#63znd~JM1gXN8Kjz?1f}1ZL4w-L
zoPi+~RGyeKFqnbTngs(x45)UrU|?_s)&JKmASIowB?H4T1_lOCONdVdtRVGyy%hsP
z2?GPeF)IcJV+IBWYio$l^Q|F4T4xO@x(`@0FsLywFg&&f8_d9E11Zn~Y#?<(nGFL&
zDFXw;BpXN(&S48Gpz0YI6l@t7A{iJM{A?K*5<x{Ml;*O77?5Mfz;Fbl(T;%u)Km($
zha}3k_K*<yZ4U`SQ3r@ciVlz{wRM1`awi8!BK3A)U|?ckU<h-7L`fuw2Ic=m2S`56
zbYNiUWn^HebbzF0b|*;UlX8L>q~`<)I&&vT8kph)v3RKy#6cUKAQtU+g6Kcx1c~Fj
zPLMS9*olDwl-++iK|HMD%)n6Z%)r1<=ghzm$H2gF$QhEo6kQk?k{K8n%v=~4)-W(I
z%yNN5g}W;QLlLN{<q9d18QmBdf<d*V8^q_WZV-zWx<MSU-Hn04l!1ZalpDlhpmrOm
z(&Bc9gn+0!Lp``bAnOjXK+heLI!oOl8k*c8iLBQhQbeD1hs5<KC@ty%DUd8YAWg1d
z4@hE7^?-y(4phF%1LCo%9+0%N3QF(vsE3q%Cp;iQe8~e+f8T~0_`?I@ATCdc0pgwz
zz7CYO^n~PhH&2L<`aB^HndS*8A69rmqUa`+e(DJ+pgwvsFzA6=&-GrA{B7<9sdPfU
zK(!JB!z(XH+;e$DTrB6!z@Wpxz@Y05N%c|Qkf5LA4QT~`@P>p~o)5%<l|B#$wfR8I
z>GOd^$s!*}THERaDNpK;`arVHNgq&lU|{&*!@v*%s^@(nJ}LHv7}V+uNp!uw3=FRr
z7#QaHGB8v!FferbF)*wK6+Hfsl61X4#K#Z)A^H8SKg42{0El_!0gw>)3;>sm^$fuQ
z3=D@D7#K<dATBcxgeY(igoI3BAS6-c2SVbyH4tLpf<Q>aWpf}TsBZ^CLW(B{LQ4lh
z)N2JnLcleMfx(D@fgv)8fgu3YEDr+NSI@w3Hwfb5w?UBV^Jfsm0p`JwMCTaH0B&-n
z1w+zEb}%FnmIOl_Fg+NO8}<i7a?$%>1_nP+c@hHlA;a7dh`xOx5POb?Kyt<95C#TN
z{lmZ+3W-~bP>7FHLm?WPLm`QzClq4A?of!&UPI|$p^$9H83swTs$mQaR-l$r7$hod
z!yrMvIt-FF_Co0sQ1Q!Q3=H+4w%*e)h)Y?+Awi`U4rz8<g+qK^77i(Rs>2~ce<K`{
zcwUD?9P~aMQqTW`%8N%pidd}(NIStP0+J}RBOoDK5dm@F+z5txa3Ae-1OvlLQ1u(Z
zz;FN*H<1t*`$j=RA|eW6abgrC`;<gMLZ&+kl6ZGTL8{e<Q4j|yMT6p&fx$2uQX4u(
zL+X&OXh<Ud9}Oud1Y+tT0^%_c7i+{YF!V4mFgV08Fsx%>U^p8C3BsCKh!6T=A&F{s
zEX1O1u?!4O3=9lMV<BmVBMwqd2*pA4smDPaY#9fs<O1R#)o@K5#DhEQ;~<IR2vp!g
z9K>a};~-J+C=L?0a`6ldCZO6c9%4}el&*?rV8~@)U}%YlnDZ$fQfd8*hlGGi0wiio
z5+K>wHvtlop$QQA`iukyhE<>rMFOPAR8EBWz%UV_(Jc{D%f%-`vSDQ+#Ap495Q`Qj
zLgMszA|#ExNn~J{1**oAAO+KtBuJAkDH-Ci-^q}~&XmHyFcVb&>!&~(3MW$_*(xR#
z614THkaD3f6;f*jra^i%HEED0*TFOf22kboI*oxLh=GAYKOK^Ln$jT_EJ$Zy@CHR;
zIs=0zsMnkU$^Xe2ki<JJ1C+Sy85m||KzueogMmSWk%3`r1|-#<%7iHVoCz`bdnQDk
zXci<bXlF4nWP>`XSquzz3=9lQvLF^c&Vt0PZZ-o$AV@wN5~5w%ki<Mc8xmD3vKbgO
zLG}NZY)ERpmkr6!yg3jHG;<)?(kusJV0aFsvPsH;RKu%sAl+@*Tu3XoJ(q!D18C$X
z4^j|q%!Aab0{ILKRSXOa;rS2;UCM`qs7e6?L;WWP1_u8ENYluv5Ym?0QOLm1!N9;E
zTm(sUbBZ8wez6Er9X~FDBueFCNK`l!LmZY>49VA<iXkEPpcov-4F8HD9-C1DQNN`G
z;(>c54E5kjB(M}BaJm#?uw5Ag!)FEthUhX#cig`m;sE9fNcI!0fP|1i1*DN`TLFqo
z28NglNYExi>0GFIWd$VY>nb3*puGZ;sQW86{}O6v+dNhBwDRUo+jY!b7P`g;3P#3O
WMn;<*9WyyLAM;Gt-ke|hl^FoZL`=H?

diff --git a/uffd/translations/de/LC_MESSAGES/messages.po b/uffd/translations/de/LC_MESSAGES/messages.po
index bae852dd..89805c8f 100644
--- a/uffd/translations/de/LC_MESSAGES/messages.po
+++ b/uffd/translations/de/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PROJECT VERSION\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2021-08-30 23:22+0200\n"
+"POT-Creation-Date: 2021-09-04 21:18+0200\n"
 "PO-Revision-Date: 2021-05-25 21:18+0200\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language: de\n"
@@ -700,8 +700,12 @@ msgstr "Sekunden"
 msgid "Verify and complete setup"
 msgstr "Verifiziere und beende das Setup"
 
-#: uffd/oauth2/views.py:95 uffd/selfservice/views.py:76
-#: uffd/session/views.py:93
+#: uffd/oauth2/models.py:30
+msgid "You need to login to access this service"
+msgstr "Du musst dich anmelden, um auf diesen Dienst zugreifen zu können"
+
+#: uffd/oauth2/views.py:146 uffd/selfservice/views.py:76
+#: uffd/session/views.py:95
 #, python-format
 msgid ""
 "We received too many requests from your ip address/network! Please wait "
@@ -710,10 +714,14 @@ msgstr ""
 "Wir haben zu viele Anfragen von deiner IP-Adresses bzw. aus deinem "
 "Netzwerk empfangen! Bitte warte mindestens %(delay)s."
 
-#: uffd/oauth2/views.py:103
+#: uffd/oauth2/views.py:154
 msgid "Device login is currently not available. Try again later!"
 msgstr "Geräte-Login ist gerade nicht verfügbar. Versuche es später nochmal!"
 
+#: uffd/oauth2/views.py:167
+msgid "Device login failed"
+msgstr "Gerätelogin fehlgeschlagen"
+
 #: uffd/oauth2/templates/oauth2/logout.html:10 uffd/templates/base.html:99
 msgid "Logout"
 msgstr "Abmelden"
@@ -757,7 +765,7 @@ msgstr ""
 "versuchen?"
 
 #: uffd/role/views.py:44 uffd/rolemod/views.py:36 uffd/rolemod/views.py:45
-#: uffd/rolemod/views.py:60 uffd/session/views.py:130
+#: uffd/rolemod/views.py:60 uffd/session/views.py:132
 #: uffd/user/views_group.py:14 uffd/user/views_user.py:25
 msgid "Access denied"
 msgstr "Zugriff verweigert"
@@ -1163,7 +1171,7 @@ msgstr "Kein Zugriff"
 msgid "Close"
 msgstr "Schließen"
 
-#: uffd/session/views.py:91
+#: uffd/session/views.py:93
 #, python-format
 msgid ""
 "We received too many invalid login attempts for this user! Please wait at"
@@ -1172,27 +1180,27 @@ msgstr ""
 "Wir haben zu viele fehlgeschlagene Anmeldeversuche für diesen Account "
 "erhalten! Bitte warte mindestens %(delay)s."
 
-#: uffd/session/views.py:99
+#: uffd/session/views.py:101
 msgid "Login name or password is wrong"
 msgstr "Der Anmeldename oder das Passwort ist falsch"
 
-#: uffd/session/views.py:102
+#: uffd/session/views.py:104
 msgid "You do not have access to this service"
 msgstr "Du hast keinen Zugriff auf diesen Service"
 
-#: uffd/session/views.py:114 uffd/session/views.py:125
+#: uffd/session/views.py:116 uffd/session/views.py:127
 msgid "You need to login first"
 msgstr "Du musst dich erst anmelden"
 
-#: uffd/session/views.py:147 uffd/session/views.py:157
+#: uffd/session/views.py:149 uffd/session/views.py:159
 msgid "Initiation code is no longer valid"
 msgstr "Startcode ist nicht mehr gültig"
 
-#: uffd/session/views.py:161
+#: uffd/session/views.py:163
 msgid "Invalid confirmation code"
 msgstr "Ungültiger Bestätigungscode"
 
-#: uffd/session/views.py:173 uffd/session/views.py:184
+#: uffd/session/views.py:175 uffd/session/views.py:186
 msgid "Invalid initiation code"
 msgstr "Ungültiger Startcode"
 
-- 
GitLab