Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a09cbb-87c6-7900-a145-4ce53ba9f1a6
27 lines
1.4 KiB
Python
27 lines
1.4 KiB
Python
"""Provider enrollment hook: password-only self-service cannot replace an active factor.
|
|
|
|
Loaded explicitly by provider configuration, so a missing module fails startup.
|
|
Pending setup can be regenerated/confirmed; active-factor replacement goes through
|
|
fresh-MFA audited recovery. Admin actions retain their existing provider policies.
|
|
"""
|
|
def check(request, action):
|
|
from flask import g
|
|
from privacyidea.lib.error import PolicyError
|
|
from privacyidea.lib.user import User
|
|
from privacyidea.lib.token import get_tokens
|
|
|
|
principal = g.logged_in_user
|
|
if principal.get('role') != 'user':
|
|
return True
|
|
user = User(principal.get('username', ''), principal.get('realm', ''))
|
|
if user.is_empty() or action != 'init':
|
|
raise PolicyError('Use the account recovery process to replace an active authenticator.')
|
|
tokens = get_tokens(user=user, active=True)
|
|
if any(token.token.rollout_state not in {'verify', 'clientwait', 'pending'} for token in tokens):
|
|
raise PolicyError('An active authenticator already exists. Use the account recovery process to replace it.')
|
|
serial = request.all_data.get('serial')
|
|
if serial:
|
|
matches = [token for token in tokens if token.token.serial == serial]
|
|
if len(matches) != 1 or matches[0].token.rollout_state != 'verify':
|
|
raise PolicyError('Only your unfinished authenticator setup can be confirmed or regenerated.')
|
|
return True
|