From 09f6ae5b95bbcfec8a8e60c62d7e6c72d1826c31 Mon Sep 17 00:00:00 2001 From: David Beguin Date: Wed, 23 Jun 2021 13:09:26 +0000 Subject: [PATCH] [MOV] auth_top: reorganise module to set content in proper place This commit juste moves the different part of code (class, views, data) in the correct file where they belong. Task-2487630 Part-of: odoo/odoo#71142 --- addons/auth_totp/__init__.py | 1 + addons/auth_totp/__manifest__.py | 4 +- addons/auth_totp/data/ir_action_data.xml | 40 ++++ addons/auth_totp/data/mail_templates_data.xml | 4 +- addons/auth_totp/models/__init__.py | 3 + addons/auth_totp/models/res_users.py | 120 +--------- addons/auth_totp/models/totp.py | 56 +++++ addons/auth_totp/views/res_users_views.xml | 115 +++++++++ addons/auth_totp/views/user_preferences.xml | 220 ------------------ addons/auth_totp/wizard/__init__.py | 4 + addons/auth_totp/wizard/auth_totp_wizard.py | 74 ++++++ .../wizard/auth_totp_wizard_views.xml | 76 ++++++ 12 files changed, 380 insertions(+), 337 deletions(-) create mode 100644 addons/auth_totp/data/ir_action_data.xml create mode 100644 addons/auth_totp/models/totp.py create mode 100644 addons/auth_totp/views/res_users_views.xml delete mode 100644 addons/auth_totp/views/user_preferences.xml create mode 100644 addons/auth_totp/wizard/__init__.py create mode 100644 addons/auth_totp/wizard/auth_totp_wizard.py create mode 100644 addons/auth_totp/wizard/auth_totp_wizard_views.xml diff --git a/addons/auth_totp/__init__.py b/addons/auth_totp/__init__.py index 9e5827f90ee..cec04a5b0e2 100644 --- a/addons/auth_totp/__init__.py +++ b/addons/auth_totp/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- from . import controllers from . import models +from . import wizard diff --git a/addons/auth_totp/__manifest__.py b/addons/auth_totp/__manifest__.py index 7005abfb8b6..05ad46b63c3 100644 --- a/addons/auth_totp/__manifest__.py +++ b/addons/auth_totp/__manifest__.py @@ -18,10 +18,12 @@ can setup API keys to replace their main password. 'category': 'Extra Tools', 'auto_install': True, 'data': [ + 'data/ir_action_data.xml', 'data/mail_templates_data.xml', 'security/security.xml', - 'views/user_preferences.xml', + 'views/res_users_views.xml', 'views/templates.xml', + 'wizard/auth_totp_wizard_views.xml', ], 'assets': { 'web.assets_tests': [ diff --git a/addons/auth_totp/data/ir_action_data.xml b/addons/auth_totp/data/ir_action_data.xml new file mode 100644 index 00000000000..9543556ed08 --- /dev/null +++ b/addons/auth_totp/data/ir_action_data.xml @@ -0,0 +1,40 @@ + + + + + Invite to use two-factor authentication + + + list + code + + action = records.action_totp_invite() + + + + + + + Disable two-factor authentication + + + list + code + + action = records.action_totp_disable() + + + + + + + Open two-factor authentication configuration + + code + +user = env.user +action = user.action_open_my_account_settings() + + + + diff --git a/addons/auth_totp/data/mail_templates_data.xml b/addons/auth_totp/data/mail_templates_data.xml index a17c9b105e1..1e31d764915 100644 --- a/addons/auth_totp/data/mail_templates_data.xml +++ b/addons/auth_totp/data/mail_templates_data.xml @@ -13,7 +13,9 @@

Dear ${object.partner_id.name}

${user.name} requested you activate two-factor authentication to protect your account.

- Two-factor Authentication ("2FA") is a system of double authentication. The first one is done with your password and the second one with a code you get from a dedicated mobile app. Popular ones include Authy, Google Authenticator or the Microsoft Authenticator. + Two-factor Authentication ("2FA") is a system of double authentication. + The first one is done with your password and the second one with a code you get from a dedicated mobile app. + Popular ones include Authy, Google Authenticator or the Microsoft Authenticator.

Q", counter) - mac = hmac.new(secret, msg=C, digestmod=ALGORITHM).digest() - # the data offset is the last nibble of the hash - offset = mac[-1] & 0xF - # code is the 4 bytes at the offset interpreted as a 31b big-endian uint - # (31b to avoid sign concerns). This effectively limits digits to 9 and - # hard-limits it to 10: each digit is normally worth 3.32 bits but the - # 10th is only worth 1.1 (9 digits encode 29.9 bits). - code = struct.unpack_from('>I', mac, offset)[0] & 0x7FFFFFFF - r = code % (10 ** DIGITS) - # NOTE: use text / bytes instead of int? - return r diff --git a/addons/auth_totp/models/totp.py b/addons/auth_totp/models/totp.py new file mode 100644 index 00000000000..642fb8fcc81 --- /dev/null +++ b/addons/auth_totp/models/totp.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import hmac +import struct +import time + +# 160 bits, as recommended by HOTP RFC 4226, section 4, R6. +# Google Auth uses 80 bits by default but supports 160. +TOTP_SECRET_SIZE = 160 + +# The algorithm (and key URI format) allows customising these parameters but +# google authenticator doesn't support it +# https://github.com/google/google-authenticator/wiki/Key-Uri-Format +ALGORITHM = 'sha1' +DIGITS = 6 +TIMESTEP = 30 + +class TOTP: + def __init__(self, key): + self._key = key + + def match(self, code, t=None, window=TIMESTEP): + """ + :param code: authenticator code to check against this key + :param int t: current timestamp (seconds) + :param int window: fuzz window to account for slow fingers, network + latency, desynchronised clocks, ..., every code + valid between t-window an t+window is considered + valid + """ + if t is None: + t = time.time() + + low = int((t - window) / TIMESTEP) + high = int((t + window) / TIMESTEP) + 1 + + return next(( + counter for counter in range(low, high) + if hotp(self._key, counter) == code + ), None) + +def hotp(secret, counter): + # C is the 64b counter encoded in big-endian + C = struct.pack(">Q", counter) + mac = hmac.new(secret, msg=C, digestmod=ALGORITHM).digest() + # the data offset is the last nibble of the hash + offset = mac[-1] & 0xF + # code is the 4 bytes at the offset interpreted as a 31b big-endian uint + # (31b to avoid sign concerns). This effectively limits digits to 9 and + # hard-limits it to 10: each digit is normally worth 3.32 bits but the + # 10th is only worth 1.1 (9 digits encode 29.9 bits). + code = struct.unpack_from('>I', mac, offset)[0] & 0x7FFFFFFF + r = code % (10 ** DIGITS) + # NOTE: use text / bytes instead of int? + return r diff --git a/addons/auth_totp/views/res_users_views.xml b/addons/auth_totp/views/res_users_views.xml new file mode 100644 index 00000000000..43d116ae405 --- /dev/null +++ b/addons/auth_totp/views/res_users_views.xml @@ -0,0 +1,115 @@ + + + + res.users.view.search.inherit.auth.totp + res.users + + + + + + + + + + + + + user form: add totp status + res.users + + + + + + + +

+
Two-factor Authentication +
+ + + +
+ +
+ + Two-factor Authentication ("2FA") is a system of double authentication. + The first one is done with your password and the second one with a code you get from a dedicated mobile app. + Popular ones include Authy, Google Authenticator or the Microsoft Authenticator. +
Learn More + + Your account is protected! +
+ + + + + + + + users preference: totp + res.users + + + + + +
+
Two-factor Authentication +
+ + Two-factor Authentication ("2FA") is a system of double authentication. + The first one is done with your password and the second one with a code you get from a dedicated mobile app. + Popular ones include Authy, Google Authenticator or the Microsoft Authenticator. + Learn More + + Your account is protected! +
+
+
+
+
+ + + + users preference: Account Security + res.users + + primary + +
+ 0 + 0 + 0 +
+

+ + +
+
+ $0 +
+ + +
+

+ +

+
+
+ +