@@ -90,6 +90,7 @@ def __init__(self, tenant, mail, app):
90
90
self .post_param_login = config .get ('post_param_login' , False )
91
91
self .max_login_attempts = config .get ('max_login_attempts' , 20 )
92
92
self .totp_enabled = config .get ('totp_enabled' , False )
93
+ self .totp_enabled_for_admin = config .get ('totp_enabled_for_admin' , False )
93
94
self .totp_issuer_name = config .get ('totp_issuer_name' , 'QWC Services' )
94
95
95
96
db_engine = DatabaseEngine ()
@@ -200,7 +201,7 @@ def login(self):
200
201
# add initial password history entry if missing
201
202
self .create_password_history (db_session , user )
202
203
203
- if self .totp_enabled :
204
+ if self .__totp_is_enabled ( user ) :
204
205
session ['login_uid' ] = user .id
205
206
session ['target_url' ] = target_url
206
207
if user .totp_secret :
@@ -254,6 +255,12 @@ def verify_login(self):
254
255
abort (401 )
255
256
abort (401 )
256
257
258
+ def __totp_is_enabled (self , user ):
259
+ """ Returns whether totp is enabled for the specified user
260
+ :param user User: The user
261
+ """
262
+ return self .totp_enabled or (user and user .name == self .DEFAULT_ADMIN_USER and self .totp_enabled_for_admin )
263
+
257
264
def verify (self ):
258
265
"""Handle submit of form for TOTP verification token."""
259
266
# create session for ConfigDB
@@ -267,7 +274,7 @@ def __verify(self, db_session, submit=True):
267
274
:param bool submit: Whether form was submitted
268
275
(False if shown after login form)
269
276
"""
270
- if not self . totp_enabled or 'login_uid' not in session :
277
+ if 'login_uid' not in session :
271
278
self .logger .warning ("TOTP not enabled or not in login process" )
272
279
return redirect (url_for ('login' ))
273
280
@@ -276,6 +283,10 @@ def __verify(self, db_session, submit=True):
276
283
self .logger .warning ("user not found" )
277
284
return redirect (url_for ('login' ))
278
285
286
+ if not self .__totp_is_enabled (user ):
287
+ self .logger .warning ("TOTP not enabled or not in login process" )
288
+ return redirect (url_for ('login' ))
289
+
279
290
form = VerifyForm (meta = wft_locales ())
280
291
form .logo = self .login_logo
281
292
form .background = self .login_background
@@ -323,7 +334,7 @@ def __setup_totp(self, db_session, submit=True):
323
334
:param bool submit: Whether form was submitted
324
335
(False if shown after login form)
325
336
"""
326
- if not self . totp_enabled or 'login_uid' not in session :
337
+ if 'login_uid' not in session :
327
338
self .logger .warning ("TOTP not enabled or not in login process" )
328
339
return redirect (url_for ('login' ))
329
340
@@ -332,6 +343,10 @@ def __setup_totp(self, db_session, submit=True):
332
343
# user not found
333
344
return redirect (url_for ('login' ))
334
345
346
+ if not self .__totp_is_enabled (user ):
347
+ self .logger .warning ("TOTP not enabled or not in login process" )
348
+ return redirect (url_for ('login' ))
349
+
335
350
totp_secret = session .get ('totp_secret' , None )
336
351
if totp_secret is None :
337
352
# generate new secret
@@ -386,7 +401,7 @@ def __setup_totp(self, db_session, submit=True):
386
401
387
402
def qrcode (self ):
388
403
"""Return TOTP QR code."""
389
- if not self . totp_enabled or 'login_uid' not in session :
404
+ if 'login_uid' not in session :
390
405
self .logger .warning ("TOTP not enabled or not in login process" )
391
406
abort (404 )
392
407
@@ -412,6 +427,10 @@ def qrcode(self):
412
427
# user not found
413
428
abort (404 )
414
429
430
+ if not self .__totp_is_enabled (user ):
431
+ self .logger .warning ("TOTP not enabled or not in login process" )
432
+ return redirect (url_for ('login' ))
433
+
415
434
# generate TOTP URI
416
435
email = user .email or user .name
417
436
uri = pyotp .totp .TOTP (totp_secret ).provisioning_uri (
@@ -687,7 +706,7 @@ def __user_is_authorized(self, user, password):
687
706
elif user .check_password (password ):
688
707
# valid credentials
689
708
if user .failed_sign_in_count < self .max_login_attempts :
690
- if not self .totp_enabled :
709
+ if not self .__totp_is_enabled ( user ) :
691
710
# update last sign in timestamp and reset failed attempts
692
711
# counter
693
712
user .last_sign_in_at = datetime .datetime .now (datetime .UTC )
0 commit comments