# Copyright 2024 360ERP () # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) import json from uuid import uuid4 from odoo.tests import HttpCase, tagged from odoo.tools import mute_logger @tagged("post_install", "-at_install") class TestImpersonateLogin(HttpCase): @classmethod def setUpClass(cls): super().setUpClass() cls.admin_user = cls.env.ref("base.user_admin") cls.demo_user = cls.env.ref("base.user_demo") def _impersonate_user(self, user): response = self.url_open( "/web/dataset/call_button", data=json.dumps( { "params": { "model": "res.users", "method": "impersonate_login", "args": [user.id], "kwargs": {}, }, } ), headers={"Content-Type": "application/json"}, ) self.assertEqual(response.status_code, 200) return response.json() def _action_impersonate_login(self): response = self.url_open( "/web/dataset/call_button", data=json.dumps( { "params": { "model": "res.users", "method": "action_impersonate_login", "args": [], "kwargs": {}, }, } ), headers={"Content-Type": "application/json"}, ) self.assertEqual(response.status_code, 200) return response.json() def _get_session_info(self): response = self.url_open( "/web/session/get_session_info", data=json.dumps(dict(jsonrpc="2.0", method="call", id=str(uuid4()))), headers={"Content-Type": "application/json"}, ) self.assertEqual(response.status_code, 200) return response.json() def test_01_admin_impersonates_user_demo(self): """Admin user impersonates Demo user""" # Login as admin self.authenticate(user="admin", password="admin") self.assertEqual(self.session.uid, self.admin_user.id) # Check get_session_info() data = self._get_session_info() result = data["result"] self.assertEqual(result["username"], self.admin_user.login) self.assertTrue(result["is_system"]) self.assertTrue(result["is_admin"]) self.assertTrue(result["is_impersonate_user"]) self.assertFalse(result["impersonate_from_uid"]) # Switch Login button data = self._action_impersonate_login() result = data["result"] self.assertEqual(result["target"], "new") # Impersonate demo user data = self._impersonate_user(self.demo_user) result = data["result"] self.assertEqual(result["tag"], "reload") # Check get_session_info() data = self._get_session_info() result = data["result"] self.assertEqual(result["username"], self.demo_user.login) self.assertFalse(result["is_system"]) self.assertFalse(result["is_admin"]) self.assertFalse(result["is_impersonate_user"]) self.assertEqual(result["impersonate_from_uid"], self.admin_user.id) # Check impersonate log log1 = self.env["impersonate.log"].search([], order="id desc", limit=1) self.assertTrue(log1.date_start) self.assertFalse(log1.date_end) # Impersonate demo user again: error with mute_logger("odoo.http"): data = self._impersonate_user(self.demo_user) result = data["error"] self.assertEqual( result["data"]["message"], "You are already Logged as another user." ) # Back to original user data = self._impersonate_user(self.admin_user) result = data["result"] self.assertEqual(result["tag"], "reload") # Check get_session_info() data = self._get_session_info() result = data["result"] self.assertEqual(result["username"], self.admin_user.login) self.assertTrue(result["is_system"]) self.assertTrue(result["is_admin"]) self.assertTrue(result["is_impersonate_user"]) self.assertFalse(result["impersonate_from_uid"]) # Check impersonate log log2 = self.env["impersonate.log"].search([], order="id desc", limit=1) self.assertEqual(log1, log2) self.assertTrue(log1.date_start) self.assertTrue(log1.date_end) def test_02_user_demo_impersonates_admin(self): """Demo user impersonates Admin user""" # Login as demo user self.authenticate(user="demo", password="demo") self.assertEqual(self.session.uid, self.demo_user.id) # Check get_session_info() data = self._get_session_info() result = data["result"] self.assertFalse(result["is_impersonate_user"]) self.assertFalse(result["impersonate_from_uid"]) # Impersonate demo user: is already current user self.demo_user.groups_id += self.env.ref( "impersonate_login.group_impersonate_login" ) with mute_logger("odoo.http"): data = self._impersonate_user(self.demo_user) result = data["error"] self.assertEqual(result["data"]["message"], "It's you.") # Impersonate admin user data = self._impersonate_user(self.admin_user) result = data["result"] self.assertEqual(result["tag"], "reload") # Check get_session_info() data = self._get_session_info() result = data["result"] self.assertEqual(result["username"], self.admin_user.login) self.assertTrue(result["is_system"]) self.assertTrue(result["is_admin"]) self.assertTrue(result["is_impersonate_user"]) self.assertEqual(result["impersonate_from_uid"], self.demo_user.id) # Impersonate admin user again: error with mute_logger("odoo.http"): data = self._impersonate_user(self.admin_user) result = data["error"] self.assertEqual( result["data"]["message"], "You are already Logged as another user." ) # Back to original user data = self._impersonate_user(self.demo_user) result = data["result"] self.assertEqual(result["tag"], "reload") # Check get_session_info() data = self._get_session_info() result = data["result"] self.assertEqual(result["username"], self.demo_user.login) self.assertFalse(result["is_system"]) self.assertFalse(result["is_admin"]) self.assertTrue(result["is_impersonate_user"]) self.assertFalse(result["impersonate_from_uid"]) def test_03_create_uid(self): """Check the create_uid of records created during an impersonated session""" # Login as admin self.authenticate(user="admin", password="admin") # Impersonate demo user and create a contact self._impersonate_user(self.demo_user) response = self.url_open( "/web/dataset/call_kw/res.partner/create", data=json.dumps( { "params": { "model": "res.partner", "method": "create", "args": [ { "name": "Contact123", }, ], "kwargs": {}, }, } ), headers={"Content-Type": "application/json"}, ) self.assertEqual(response.status_code, 200) data = response.json() contact_id = data["result"] contact = self.env["res.partner"].browse(contact_id) self.assertEqual(contact.name, "Contact123") self.assertEqual(contact.create_uid, self.admin_user) def test_04_write_uid(self): """Check the write_uid of records created during an impersonated session""" # Login as admin self.authenticate(user="admin", password="admin") # Create a contact contact = self.env["res.partner"].create({"name": "ContactABC"}) # Impersonate demo user and modify a contact self._impersonate_user(self.demo_user) response = self.url_open( "/web/dataset/call_kw/res.partner/write", data=json.dumps( { "params": { "model": "res.partner", "method": "write", "args": [ [contact.id], { "ref": "abc", }, ], "kwargs": {}, }, } ), headers={"Content-Type": "application/json"}, ) self.assertEqual(response.status_code, 200) data = response.json() result = data["result"] self.assertEqual(result, True) self.assertEqual(contact.ref, "abc") self.assertEqual(contact.write_uid, self.admin_user)