Skip to content

Commit

Permalink
[IMP] auth_oauth_multi_token: make it compatible with odoo.sh "login as"
Browse files Browse the repository at this point in the history
  • Loading branch information
CRogos authored and kobros-tech committed Feb 4, 2025
1 parent 873af5f commit e6c6427
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 24 deletions.
55 changes: 34 additions & 21 deletions auth_oauth_multi_token/models/res_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@

from odoo import api, exceptions, fields, models

from odoo.addons import base

base.models.res_users.USER_PRIVATE_FIELDS.append("oauth_master_uuid")


class ResUsers(models.Model):
_inherit = "res.users"
Expand All @@ -24,60 +20,77 @@ def _generate_oauth_master_uuid(self):
readonly=True,
groups="base.group_system",
)

oauth_access_max_token = fields.Integer(
string="Max Number of Simultaneous Connections", default=10, required=True
)
oauth_master_uuid = fields.Char(

# use the oauth_access_token field as oauth_master_uuid
oauth_access_token = fields.Char(
string="Master UUID",
copy=False,
readonly=True,
required=True,
default=lambda self: self._generate_oauth_master_uuid(),
)

@property
def multi_token_model(self):
return self.env["auth.oauth.multi.token"]

@api.model
def _generate_signup_values(self, provider, validation, params):
"""Because access_token was replace in
_auth_oauth_signin we need to replace it here."""
res = super()._generate_signup_values(provider, validation, params)
res["oauth_access_token"] = params["access_token_multi"]
return res

@api.model
def _auth_oauth_signin(self, provider, validation, params):
"""Override to handle sign-in with multi token."""
res = super()._auth_oauth_signin(provider, validation, params)
params["access_token_multi"] = params["access_token"]

oauth_uid = validation["user_id"]
# Lookup for user by oauth uid and provider
oauth_uid = validation["user_id"]
user = self.search(
[("oauth_uid", "=", oauth_uid), ("oauth_provider_id", "=", provider)]
)

# Because access_token is automatically written to the user,
# we need to replace this by the existing oauth_access_token
params["access_token"] = user.oauth_access_token
res = super()._auth_oauth_signin(provider, validation, params)

if not user:
raise exceptions.AccessDenied()

Check warning on line 63 in auth_oauth_multi_token/models/res_users.py

View check run for this annotation

Codecov / codecov/patch

auth_oauth_multi_token/models/res_users.py#L63

Added line #L63 was not covered by tests
user.ensure_one()
# user found and unique: create a token
self.multi_token_model.create(
{"user_id": user.id, "oauth_access_token": params["access_token"]}
{"user_id": user.id, "oauth_access_token": params["access_token_multi"]}
)
return res

def action_oauth_clear_token(self):
"""Inactivate current user tokens."""
self.mapped("oauth_access_token_ids")._oauth_clear_token()
for res in self:
res.oauth_access_token = False
res.oauth_master_uuid = self._generate_oauth_master_uuid()
res.oauth_access_token = self._generate_oauth_master_uuid()

@api.model
def _check_credentials(self, password, env):
"""Override to check credentials against multi tokens."""
try:
return super()._check_credentials(password, env)
except exceptions.AccessDenied:
res = self.multi_token_model.sudo().search(
[("user_id", "=", self.env.uid), ("oauth_access_token", "=", password)]
passwd_allowed = (
env["interactive"] or not self.env.user._rpc_api_keys_only()
)
if not res:
raise
if passwd_allowed and self.env.user.active:
res = self.multi_token_model.sudo().search(
[
("user_id", "=", self.env.uid),
("oauth_access_token", "=", password),
]
)
if res:
return

Check warning on line 94 in auth_oauth_multi_token/models/res_users.py

View check run for this annotation

Codecov / codecov/patch

auth_oauth_multi_token/models/res_users.py#L94

Added line #L94 was not covered by tests

def _get_session_token_fields(self):
res = super()._get_session_token_fields()
res.remove("oauth_access_token")
return res | {"oauth_master_uuid"}
raise
8 changes: 5 additions & 3 deletions auth_oauth_multi_token/tests/test_multi_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,12 @@ def test_access_multi_token(self):
len(self.user.oauth_access_token_ids), self.user.oauth_access_max_token
)

def test_remove_oauth_access_token(self):
def test_oauth_access_token_odoo_sh(self):
# do not change the _get_session_token_fields
# result to stay compatible with odoo.sh
res = self.user._get_session_token_fields()
self.assertFalse("oauth_access_token" in res)
self.assertTrue("oauth_master_uuid" in res)
self.assertTrue("oauth_access_token" in res)
self.assertFalse("oauth_master_uuid" in res)

def test_action_oauth_clear_token(self):
self.user.action_oauth_clear_token()
Expand Down

0 comments on commit e6c6427

Please sign in to comment.