PyOTP's totp.verify defaults to the valid_window of zero, which means
it will reject valid codes, if submitted just past the 30 sec window.
It also means, users will run into authentication issues very quickly
if their phones time-sync isn't perfect.
Therefore valid_window should at the very least be 1 or more, settting
it higher trades security for robustness, especially with regard to
time desync issues.
Resolves the following issue, which occurs with force_otp enabled
and OAuth authentication sources:
File "/srv/powerdnsadmin/powerdnsadmin/models/user.py", line 481, in update_profile
"utf-8") if self.plain_text_password else user.password
AttributeError: 'User' object has no attribute 'plain_text_password'
As vermin [0] confirms, the codebase has long moved beyond supporting
python v2 (which is not a bad thing). This removes the last explicit py2
piece of code.
And in case anyone wonders, vermin currently reports the minium version
to be v3.6.
[0] https://pypi.org/project/vermin/
If the 'otp_force' and 'otp_field_enabled' basic settings are both enabled, automatically enable 2FA for the user after login or signup, if needed, by setting a new OTP secret. Redirect the user to a welcome page for scanning the QR code.
Also show the secret key in ASCII form on the user profile page for easier copying into other applications.
The order of account names returned by User.get_accounts() affects the
order account names are displyed in on /domain/add if the current user
neither has the Administrator role nor the Operator role and the
`allow_user_create_domain` setting is enabled at the same time.
If the current user does have the Administrator or Operator role,
routes.domain.add() already returns accounts ordered by name, so this
change makes it consistent.