diff --git a/fusion_plating/fusion_plating_shopfloor/models/res_users.py b/fusion_plating/fusion_plating_shopfloor/models/res_users.py index 0e470982..9710afb3 100644 --- a/fusion_plating/fusion_plating_shopfloor/models/res_users.py +++ b/fusion_plating/fusion_plating_shopfloor/models/res_users.py @@ -139,3 +139,50 @@ class ResUsers(models.Model): 'name': 'Set Tablet PIN', 'target': 'new', } + + def _check_credentials(self, credential, env): + """Custom auth manager: accept `type='fp_tablet_pin'` credential. + + Validates the PIN hash, that the user is active, and that they hold + at least one shop-branch plating role. On success, returns the auth + info dict Odoo's session expects. On failure, raises AccessDenied + so the standard auth chain returns a 401. + + See docs/superpowers/specs/2026-05-24-tablet-pin-session-redesign-design.md + Section 2 — Auth path. + """ + from odoo.exceptions import AccessDenied + if isinstance(credential, dict) and credential.get('type') == 'fp_tablet_pin': + login = credential.get('login') + pin = credential.get('pin') + if not login or not pin: + raise AccessDenied() + user_sudo = self.sudo().search([('login', '=', login)], limit=1) + if not user_sudo or not user_sudo.active: + raise AccessDenied() + # Must hold a shop-branch role (otherwise they can't operate the tablet) + shop_branch_xmlids = ( + 'fusion_plating.group_fp_technician', + 'fusion_plating.group_fp_shop_manager_v2', + 'fusion_plating.group_fp_manager', + 'fusion_plating.group_fp_quality_manager', + 'fusion_plating.group_fp_owner', + ) + shop_branch_ids = { + g.id for g in ( + self.env.ref(x, raise_if_not_found=False) + for x in shop_branch_xmlids + ) if g + } + user_group_ids = set(user_sudo.group_ids.ids) + if not (shop_branch_ids & user_group_ids): + raise AccessDenied() + # Verify the PIN hash. verify_tablet_pin already exists. + if not user_sudo.verify_tablet_pin(pin): + raise AccessDenied() + return { + 'uid': user_sudo.id, + 'auth_method': 'fp_tablet_pin', + 'mfa': 'default', + } + return super()._check_credentials(credential, env)