# © 2021 Florian Kantelberg - initOS GmbH # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import json import logging from unittest.mock import MagicMock from odoo.tests import TransactionCase from odoo.tools import mute_logger from odoo.addons.website.tools import MockRequest from ..controllers import main _logger = logging.getLogger(__name__) class TestController(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() cls.controller = main.Controller() cls.user = cls.env["res.users"].create( {"login": "test", "email": "test@test", "name": "test"} ) cls.user.inbox_token = "42" cls.user.keys.current = False cls.key = cls.env["res.users.key"].create( { "user_id": cls.user.id, "public": "a public key", "salt": "42", "iv": "2424", "iterations": 4000, "private": "24", "current": True, } ) cls.inbox = cls.env["vault.inbox"].create( { "user_id": cls.user.id, "name": "Inbox", "key": "4", "iv": "1", "secret": "old secret", "secret_file": "old file", "accesses": 100, } ) @mute_logger("odoo.sql_db") def test_vault_inbox(self): def return_context(template, context): self.assertEqual(template, "vault.inbox") return json.dumps(context) def load(response): return json.loads(response.data) with MockRequest(self.env) as request_mock: request_mock.render = return_context response = load(self.controller.vault_inbox("")) self.assertIn("error", response) response = load(self.controller.vault_inbox(self.user.inbox_token)) self.assertNotIn("error", response) self.assertEqual(response["public"], self.user.active_key.public) # Try to eliminate each error step by step request_mock.httprequest.method = "POST" request_mock.params = {} response = load(self.controller.vault_inbox(self.user.inbox_token)) self.assertIn("error", response) request_mock.params["name"] = "test" response = load(self.controller.vault_inbox(self.user.inbox_token)) self.assertIn("error", response) request_mock.params.update( {"encrypted": "secret", "encrypted_file": "file"} ) response = load(self.controller.vault_inbox(self.user.inbox_token)) self.assertIn("error", response) request_mock.params["filename"] = "filename" response = load(self.controller.vault_inbox(self.user.inbox_token)) self.assertIn("error", response) self.assertEqual(self.inbox.secret, "old secret") self.assertEqual(self.inbox.secret_file, b"old file") # Store something successfully request_mock.params.update({"iv": "iv", "key": "key"}) response = load(self.controller.vault_inbox(self.inbox.token)) self.assertNotIn("error", response) self.assertEqual(self.inbox.secret, "secret") self.assertEqual(self.inbox.secret_file, b"file") # Test a duplicate inbox self.inbox.copy().token = self.inbox.token response = load(self.controller.vault_inbox(self.inbox.token)) self.assertIn("error", response) def raise_error(*args, **kwargs): raise TypeError() # Catch internal errors try: request_mock.httprequest.remote_addr = "127.0.0.1" self.env["vault.inbox"]._patch_method("store_in_inbox", raise_error) response = load(self.controller.vault_inbox(self.user.inbox_token)) finally: self.env["vault.inbox"]._revert_method("store_in_inbox") self.assertIn("error", response) @mute_logger("odoo.sql_db") def test_vault_public(self): with MockRequest(self.env): no_key = self.env["res.users"].create( {"login": "keyless", "email": "test@test", "name": "test"} ) response = self.controller.vault_public(user_id=no_key.id) self.assertEqual(response, {}) response = self.controller.vault_public(user_id=self.user.id) self.assertEqual(response["public_key"], self.key.public) @mute_logger("odoo.sql_db") def test_vault_replace(self): with MockRequest(self.env): vault = self.env["vault"].create({"name": "Vault"}) right = vault.right_ids[:1] entry = self.env["vault.entry"].create( {"name": "Test Entry", "vault_id": vault.id} ) field = self.env["vault.field"].create( {"entry_id": entry.id, "name": "Test", "value": "hello"} ) file = self.env["vault.file"].create( {"entry_id": entry.id, "name": "Test", "value": b"hello"} ) right.write({"key": "invalid"}) self.controller.vault_replace(None) self.assertEqual(field.value, "hello") self.assertEqual(file.value, b"hello") vault.reencrypt_required = True self.controller.vault_replace( [ {"model": field._name, "id": field.id, "value": "test"}, {"model": file._name, "id": file.id, "value": "test"}, {"model": right._name, "id": right.id, "key": "changed"}, ] ) self.assertEqual(field.value, "test") self.assertEqual(file.value, b"test") self.assertEqual(right.key, "changed") self.assertFalse(vault.reencrypt_required) @mute_logger("odoo.sql_db") def test_vault_store( self, ): with MockRequest(self.env): mock = MagicMock() try: self.env["res.users.key"]._patch_method("store", mock) self.controller.vault_store_keys() mock.assert_called_once() finally: self.env["res.users.key"]._revert_method("store") @mute_logger("odoo.sql_db") def test_vault_keys_get(self): with MockRequest(self.env): mock = MagicMock() try: self.env["res.users"]._patch_method("get_vault_keys", mock) self.controller.vault_get_keys() mock.assert_called_once() finally: self.env["res.users"]._revert_method("get_vault_keys") @mute_logger("odoo.sql_db") def test_vault_right_keys(self): with MockRequest(self.env): self.assertFalse(self.controller.vault_get_right_keys()) # New vault with user as owner and only right vault = self.env["vault"].create({"name": "Vault"}) response = self.controller.vault_get_right_keys() self.assertEqual(response, {vault.uuid: vault.right_ids.key}) @mute_logger("odoo.sql_db") def test_vault_store_right_key(self): with MockRequest(self.env): vault = self.env["vault"].create({"name": "Vault"}) self.controller.vault_store_right_keys(None) self.controller.vault_store_right_keys({vault.uuid: "new key"}) self.assertEqual(vault.right_ids.key, "new key") @mute_logger("odoo.sql_db") def test_vault_inbox_keys(self): with MockRequest(self.env): self.assertFalse(self.controller.vault_get_inbox()) inbox = self.inbox.copy({"user_id": self.env.uid}) response = self.controller.vault_get_inbox() self.assertEqual(response, {inbox.token: inbox.key}) @mute_logger("odoo.sql_db") def test_vault_store_inbox_key(self): with MockRequest(self.env): inbox = self.inbox.copy({"user_id": self.env.uid}) inbox.user_id = self.env.user self.controller.vault_store_inbox(None) self.controller.vault_store_inbox({inbox.token: "new key"}) self.assertEqual(inbox.key, "new key")