mirror of
https://github.com/bringout/oca-server-auth.git
synced 2026-04-19 09:51:59 +02:00
Initial commit: OCA Server Auth packages (29 packages)
This commit is contained in:
commit
3ed80311c4
1325 changed files with 127292 additions and 0 deletions
11
odoo-bringout-oca-server-auth-vault/vault/tests/__init__.py
Normal file
11
odoo-bringout-oca-server-auth-vault/vault/tests/__init__.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# © 2021 Florian Kantelberg - initOS GmbH
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import (
|
||||
test_controller,
|
||||
test_log,
|
||||
test_rights,
|
||||
test_user,
|
||||
test_vault,
|
||||
test_widgets,
|
||||
)
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
# © 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")
|
||||
115
odoo-bringout-oca-server-auth-vault/vault/tests/test_inbox.py
Normal file
115
odoo-bringout-oca-server-auth-vault/vault/tests/test_inbox.py
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
# © 2021 Florian Kantelberg - initOS GmbH
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from uuid import uuid4
|
||||
|
||||
from odoo.tests import TransactionCase
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestShare(TransactionCase):
|
||||
def test_user_inbox(self):
|
||||
user = self.env["res.users"].create(
|
||||
{"login": "test", "email": "test@test", "name": "test"}
|
||||
)
|
||||
|
||||
user.action_new_inbox_token()
|
||||
|
||||
model = self.env["res.users"]
|
||||
token = user.inbox_token
|
||||
|
||||
self.assertEqual(user, model.find_user_of_inbox(token))
|
||||
self.assertIn(token, user.inbox_link)
|
||||
|
||||
user.inbox_enabled = False
|
||||
self.assertEqual(model, model.find_user_of_inbox(token))
|
||||
|
||||
user.action_new_inbox_token()
|
||||
self.assertNotEqual(user.inbox_token, token)
|
||||
|
||||
def test_inbox(self):
|
||||
model = self.env["vault.inbox"]
|
||||
user = self.env.user
|
||||
vals = {
|
||||
"name": f"Inbox {user.name}",
|
||||
"secret": "secret",
|
||||
"iv": "iv",
|
||||
"user": user,
|
||||
"key": "key",
|
||||
"secret_file": "",
|
||||
"filename": "",
|
||||
}
|
||||
|
||||
# Should create a new inbox for the user
|
||||
inbox = model.store_in_inbox(**vals)
|
||||
self.assertEqual(inbox.secret, "secret")
|
||||
self.assertEqual(inbox.accesses, 0)
|
||||
self.assertIn(inbox.token, inbox.inbox_link)
|
||||
|
||||
# No change because of no accesses left
|
||||
vals["secret"] = "new secret"
|
||||
inbox.store_in_inbox(**vals)
|
||||
self.assertEqual(inbox.secret, "secret")
|
||||
self.assertEqual(inbox.accesses, 0)
|
||||
|
||||
# Change expected because 5 accesses left
|
||||
inbox.accesses = 5
|
||||
inbox.store_in_inbox(**vals)
|
||||
self.assertEqual(inbox.secret, "new secret")
|
||||
self.assertEqual(inbox.accesses, 4)
|
||||
|
||||
# No change because expired
|
||||
vals["secret"] = "newer secret"
|
||||
inbox.expiration = datetime(1970, 1, 1)
|
||||
inbox.store_in_inbox(**vals)
|
||||
self.assertEqual(inbox.secret, "new secret")
|
||||
self.assertEqual(inbox.accesses, 4)
|
||||
|
||||
# Search for shares
|
||||
self.assertEqual(inbox, model.find_inbox(inbox.token))
|
||||
self.assertEqual(model, model.find_inbox(uuid4()))
|
||||
|
||||
def test_send_wizard(self):
|
||||
user = self.env.user
|
||||
wiz = self.env["vault.send.wizard"].create(
|
||||
{
|
||||
"name": uuid4(),
|
||||
"iv": "iv",
|
||||
"key_user": "key",
|
||||
"key": "k",
|
||||
"secret": uuid4(),
|
||||
"user_id": user.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create a new inbox
|
||||
wiz.action_send()
|
||||
self.assertTrue(self.env["vault.inbox"].search([("name", "=", wiz.name)]))
|
||||
|
||||
def test_store_wizard(self):
|
||||
vault = self.env["vault"].create({"name": "Vault"})
|
||||
|
||||
entry = self.env["vault.entry"].create({"vault_id": vault.id, "name": "Entry"})
|
||||
|
||||
wiz = self.env["vault.store.wizard"].create(
|
||||
{
|
||||
"vault_id": vault.id,
|
||||
"entry_id": entry.id,
|
||||
"name": uuid4(),
|
||||
"iv": "iv",
|
||||
"key": "k",
|
||||
"secret": uuid4(),
|
||||
"secret_temporary": "temp",
|
||||
"model": "vault.field",
|
||||
}
|
||||
)
|
||||
|
||||
vault.right_ids.write({"key": uuid4()})
|
||||
self.assertEqual(wiz.master_key, vault.right_ids.key)
|
||||
|
||||
wiz.action_store()
|
||||
|
||||
self.assertEqual(wiz.name, entry.field_ids.name)
|
||||
41
odoo-bringout-oca-server-auth-vault/vault/tests/test_log.py
Normal file
41
odoo-bringout-oca-server-auth-vault/vault/tests/test_log.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# © 2021 Florian Kantelberg - initOS GmbH
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
|
||||
from odoo.tests import TransactionCase
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestLog(TransactionCase):
|
||||
def test_not_implemeneted(self):
|
||||
with self.assertRaises(NotImplementedError):
|
||||
self.env["vault.abstract"].log_entry("test")
|
||||
|
||||
with self.assertRaises(NotImplementedError):
|
||||
self.env["vault.abstract"].log_info("test")
|
||||
|
||||
with self.assertRaises(NotImplementedError):
|
||||
self.env["vault.abstract"].log_warn("test")
|
||||
|
||||
with self.assertRaises(NotImplementedError):
|
||||
self.env["vault.abstract"].log_error("test")
|
||||
|
||||
def test_log_created(self):
|
||||
vault = self.env["vault"].create({"name": "Vault"})
|
||||
entry = self.env["vault.entry"].create({"vault_id": vault.id, "name": "Entry"})
|
||||
|
||||
vault.log_ids.unlink()
|
||||
|
||||
vault.log_info("info")
|
||||
self.assertEqual(vault.log_ids.mapped("state"), ["info"])
|
||||
self.assertEqual(entry.log_ids.mapped("state"), [])
|
||||
|
||||
entry.log_warn("warn")
|
||||
self.assertEqual(vault.log_ids.mapped("state"), ["info", "warn"])
|
||||
self.assertEqual(entry.log_ids.mapped("state"), ["warn"])
|
||||
|
||||
entry.log_error("error")
|
||||
self.assertEqual(vault.log_ids.mapped("state"), ["info", "warn", "error"])
|
||||
self.assertEqual(entry.log_ids.mapped("state"), ["warn", "error"])
|
||||
155
odoo-bringout-oca-server-auth-vault/vault/tests/test_rights.py
Normal file
155
odoo-bringout-oca-server-auth-vault/vault/tests/test_rights.py
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
# © 2021 Florian Kantelberg - initOS GmbH
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.tests import TransactionCase
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestAccessRights(TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.user = self.env["res.users"].create(
|
||||
{"login": "user", "name": "tester", "email": "user@localhost"}
|
||||
)
|
||||
self.vault = self.env["vault"].create({"name": "Vault"})
|
||||
self.entry = self.env["vault.entry"].create(
|
||||
{"vault_id": self.vault.id, "name": "Entry"}
|
||||
)
|
||||
self.field = self.env["vault.field"].create(
|
||||
{"entry_id": self.entry.id, "name": "Field", "value": "Value"}
|
||||
)
|
||||
self.vault.right_ids.write({"key": "Owner"})
|
||||
|
||||
def test_vault_reencrypt(self):
|
||||
right = self.env["vault.right"].create(
|
||||
{
|
||||
"vault_id": self.vault.id,
|
||||
"user_id": self.user.id,
|
||||
"perm_create": False,
|
||||
}
|
||||
)
|
||||
|
||||
assert not self.vault.reencrypt_required
|
||||
right.unlink()
|
||||
assert self.vault.reencrypt_required
|
||||
|
||||
def test_public_key(self):
|
||||
key = self.env["res.users.key"].create(
|
||||
{
|
||||
"user_id": self.vault.user_id.id,
|
||||
"public": "a public key",
|
||||
"salt": "42",
|
||||
"iv": "2424",
|
||||
"iterations": 4000,
|
||||
"private": "24",
|
||||
}
|
||||
)
|
||||
self.assertTrue(self.vault.right_ids.public_key)
|
||||
self.assertEqual(key.public, self.vault.right_ids.public_key)
|
||||
|
||||
def test_owner_access(self):
|
||||
# The owner can always access despite the permissions
|
||||
for obj in [self.field, self.entry, self.vault]:
|
||||
obj.name = "Owned"
|
||||
|
||||
right = self.vault.right_ids
|
||||
right.perm_write = False
|
||||
obj.name = "Owned"
|
||||
|
||||
right.perm_delete = False
|
||||
obj.unlink()
|
||||
|
||||
def test_no_create(self):
|
||||
self.env["vault.right"].create(
|
||||
{
|
||||
"vault_id": self.vault.id,
|
||||
"user_id": self.user.id,
|
||||
"perm_create": False,
|
||||
}
|
||||
)
|
||||
|
||||
for obj in [self.field, self.entry, self.vault]:
|
||||
with self.assertRaises(AccessError):
|
||||
obj.with_user(self.user).check_access_rule("create")
|
||||
|
||||
def test_no_right(self):
|
||||
# No right defined for test user means access denied
|
||||
for obj in [self.field, self.entry, self.vault]:
|
||||
with self.assertRaises(AccessError):
|
||||
self.assertTrue(obj.with_user(self.user).read())
|
||||
|
||||
with self.assertRaises(AccessError):
|
||||
obj.with_user(self.user).name = "Owned"
|
||||
|
||||
with self.assertRaises(AccessError):
|
||||
obj.with_user(self.user).unlink()
|
||||
|
||||
def test_no_permission(self):
|
||||
# Defined right but no write permission means access denied
|
||||
self.env["vault.right"].create(
|
||||
{
|
||||
"vault_id": self.vault.id,
|
||||
"user_id": self.user.id,
|
||||
"perm_create": False,
|
||||
"perm_write": False,
|
||||
"perm_delete": False,
|
||||
}
|
||||
)
|
||||
for obj in [self.field, self.entry, self.vault]:
|
||||
self.assertTrue(obj.with_user(self.user).read())
|
||||
|
||||
with self.assertRaises(AccessError):
|
||||
obj.with_user(self.user).name = "Owned"
|
||||
|
||||
with self.assertRaises(AccessError):
|
||||
obj.with_user(self.user).unlink()
|
||||
|
||||
def test_granted(self):
|
||||
# Granted write permission allows writing
|
||||
self.env["vault.right"].create(
|
||||
{
|
||||
"vault_id": self.vault.id,
|
||||
"user_id": self.user.id,
|
||||
"perm_write": True,
|
||||
"perm_delete": True,
|
||||
}
|
||||
)
|
||||
for obj in [self.field, self.entry, self.vault]:
|
||||
self.assertTrue(obj.with_user(self.user).read())
|
||||
|
||||
obj.with_user(self.user).name = "Owned"
|
||||
obj.with_user(self.user).unlink()
|
||||
|
||||
def test_owner_share(self):
|
||||
self.env["vault.right"].create(
|
||||
{"vault_id": self.vault.id, "user_id": self.user.id}
|
||||
)
|
||||
|
||||
def test_user_share_no_right(self):
|
||||
# No right defined means AccessError
|
||||
with self.assertRaises(AccessError):
|
||||
self.env["vault.right"].with_user(self.user).create(
|
||||
{"vault_id": self.vault.id, "user_id": 2}
|
||||
)
|
||||
|
||||
def test_user_share_no_permission(self):
|
||||
# Created right but no permission to share
|
||||
right = self.env["vault.right"].create(
|
||||
{"vault_id": self.vault.id, "user_id": self.user.id, "perm_share": False}
|
||||
)
|
||||
|
||||
with self.assertRaises(AccessError):
|
||||
right.with_user(self.user).create({"vault_id": self.vault.id, "user_id": 2})
|
||||
|
||||
def test_user_share_granted(self):
|
||||
# Granted permission to share
|
||||
right = self.env["vault.right"].create(
|
||||
{"vault_id": self.vault.id, "user_id": self.user.id, "perm_share": True}
|
||||
)
|
||||
right.with_user(self.user).create({"vault_id": self.vault.id, "user_id": 2})
|
||||
|
||||
right.unlink()
|
||||
60
odoo-bringout-oca-server-auth-vault/vault/tests/test_user.py
Normal file
60
odoo-bringout-oca-server-auth-vault/vault/tests/test_user.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# © 2021 Florian Kantelberg - initOS GmbH
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
|
||||
from odoo.tests import TransactionCase
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestShare(TransactionCase):
|
||||
def test_user_inbox(self):
|
||||
user = self.env["res.users"].create(
|
||||
{"login": "test", "email": "test@test", "name": "test"}
|
||||
)
|
||||
|
||||
user.action_new_inbox_token()
|
||||
|
||||
model = self.env["res.users"]
|
||||
token = user.inbox_token
|
||||
|
||||
self.assertEqual(user, model.find_user_of_inbox(token))
|
||||
self.assertIn(token, user.inbox_link)
|
||||
|
||||
user.inbox_enabled = False
|
||||
self.assertEqual(model, model.find_user_of_inbox(token))
|
||||
|
||||
user.action_new_inbox_token()
|
||||
self.assertNotEqual(user.inbox_token, token)
|
||||
|
||||
def test_user_key_management(self):
|
||||
action = self.env.ref("vault.action_res_users_keys")
|
||||
|
||||
self.assertEqual(action.id, self.env["res.users"].action_get_vault()["id"])
|
||||
|
||||
def test_invalidation(self):
|
||||
self.env["res.users.key"].store(
|
||||
40000, "invalid", "invalid", "invalid", "invalid", 42
|
||||
)
|
||||
self.assertTrue(self.env.user.keys.filtered("current"))
|
||||
|
||||
vault = self.env["vault"].create({"name": "Test"})
|
||||
self.assertTrue(vault.right_ids)
|
||||
|
||||
inbox = self.env["vault.inbox"].create(
|
||||
{
|
||||
"name": "Inbox Test",
|
||||
"secret": "secret",
|
||||
"iv": "iv",
|
||||
"user_id": self.env.uid,
|
||||
"key": "key",
|
||||
"secret_file": "",
|
||||
"filename": "",
|
||||
}
|
||||
)
|
||||
|
||||
self.env.user.action_invalidate_key()
|
||||
self.assertFalse(self.env.user.keys.filtered("current"))
|
||||
self.assertFalse(inbox.exists())
|
||||
self.assertFalse(vault.right_ids.exists())
|
||||
166
odoo-bringout-oca-server-auth-vault/vault/tests/test_vault.py
Normal file
166
odoo-bringout-oca-server-auth-vault/vault/tests/test_vault.py
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
# © 2021 Florian Kantelberg - initOS GmbH
|
||||
# Copyright 2022 Tecnativa - Víctor Martínez
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests import TransactionCase
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestVault(TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.vault = self.env["vault"].create({"name": "Vault"})
|
||||
self.entry = self.env["vault.entry"].create(
|
||||
{"vault_id": self.vault.id, "name": "Entry"}
|
||||
)
|
||||
self.child = self.env["vault.entry"].create(
|
||||
{"vault_id": self.vault.id, "name": "Child", "parent_id": self.entry.id}
|
||||
)
|
||||
|
||||
def test_entry_path(self):
|
||||
self.assertEqual(self.entry.complete_name, "Entry")
|
||||
self.assertEqual(self.child.complete_name, "Entry / Child")
|
||||
|
||||
def test_wizard_actions(self):
|
||||
values = self.child.action_open_import_wizard()
|
||||
self.assertEqual(values["context"]["default_parent_id"], self.child.id)
|
||||
|
||||
values = self.vault.action_open_import_wizard()
|
||||
self.assertNotIn("default_parent_id", values["context"])
|
||||
|
||||
values = self.child.action_open_export_wizard()
|
||||
self.assertEqual(values["context"]["default_entry_id"], self.child.id)
|
||||
|
||||
values = self.vault.action_open_export_wizard()
|
||||
self.assertNotIn("default_entry_id", values["context"])
|
||||
|
||||
def test_master_key(self):
|
||||
right = self.vault.right_ids
|
||||
self.assertEqual(self.vault.master_key, right.master_key)
|
||||
|
||||
self.vault.master_key = "test"
|
||||
self.assertEqual(right.key, "test")
|
||||
|
||||
def test_share_public_key(self):
|
||||
key = self.env["res.users.key"].create(
|
||||
{
|
||||
"user_id": self.vault.user_id.id,
|
||||
"public": "a public key",
|
||||
"salt": "42",
|
||||
"iv": "2424",
|
||||
"iterations": 4000,
|
||||
"private": "24",
|
||||
}
|
||||
)
|
||||
|
||||
expected = {"user": 1, "public": key.public}
|
||||
self.assertIn(expected, self.vault.share_public_keys())
|
||||
|
||||
def test_keys(self):
|
||||
key = self.env["res.users.key"].create(
|
||||
{
|
||||
"user_id": self.vault.user_id.id,
|
||||
"public": "a public key",
|
||||
"salt": "42",
|
||||
"iv": "2424",
|
||||
"iterations": 4000,
|
||||
"private": "24",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(set("0123456789abcdef:"), set(key.fingerprint))
|
||||
|
||||
key.public = ""
|
||||
self.assertEqual(key.fingerprint, False)
|
||||
|
||||
def test_store_keys(self):
|
||||
model = self.env["res.users.key"]
|
||||
|
||||
# Raise some errors because of wrong parameters
|
||||
with self.assertRaises(ValidationError):
|
||||
model.store(1, "iv", "private", "public", 42, 42)
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
model.store(3000, "iv", "private", "public", "salt", 42)
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
model.store(4000, "iv", "private", "public", "salt", "abc")
|
||||
|
||||
# Actually store a new key
|
||||
uuid = model.store(4000, "iv", "private", "public", "salt", 42)
|
||||
rec = model.search([("uuid", "=", uuid)])
|
||||
self.assertEqual(rec.private, "private")
|
||||
self.assertTrue(rec.current)
|
||||
|
||||
# Don't store the same again
|
||||
uuid = model.store(4000, "iv", "private", "public", "salt", 42)
|
||||
self.assertFalse(uuid)
|
||||
|
||||
# Store a new one and disable the old one
|
||||
uuid = model.store(4000, "iv", "more private", "public", "salt", 42)
|
||||
self.assertFalse(rec.current)
|
||||
|
||||
rec = model.search([("uuid", "=", uuid)])
|
||||
self.assertEqual(rec.private, "more private")
|
||||
self.assertTrue(rec.current)
|
||||
|
||||
# Try to extract the public key again
|
||||
user_id = self.env["res.users"].search([], limit=1, order="id DESC").id
|
||||
public = model.extract_public_key(user_id + 1)
|
||||
self.assertFalse(public)
|
||||
public = model.extract_public_key(self.env.uid)
|
||||
self.assertEqual(public, "public")
|
||||
|
||||
def test_vault_keys(self):
|
||||
keys = self.env.user.get_vault_keys()
|
||||
self.assertEqual(keys, {})
|
||||
|
||||
data = {
|
||||
"user_id": self.env.user.id,
|
||||
"public": "a public key",
|
||||
"salt": "42",
|
||||
"iv": "2424",
|
||||
"iterations": 4000,
|
||||
"private": "24",
|
||||
}
|
||||
self.env["res.users.key"].create(data)
|
||||
|
||||
keys = self.env.user.get_vault_keys()
|
||||
for key in ["private", "public", "iv", "salt", "iterations"]:
|
||||
self.assertEqual(keys[key], data[key])
|
||||
|
||||
def test_vault_entry_recursion(self):
|
||||
child = self.env["vault.entry"].create(
|
||||
{"vault_id": self.vault.id, "name": "Entry", "parent_id": self.entry.id}
|
||||
)
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
self.entry.parent_id = child.id
|
||||
|
||||
def test_search_expired(self):
|
||||
entry = self.env["vault.entry"]
|
||||
self.assertEqual(entry._search_expired("in", []), [])
|
||||
|
||||
domain = entry._search_expired("=", True)
|
||||
self.assertEqual(domain[0][:2], ("expire_date", "<"))
|
||||
self.assertIsInstance(domain[0][2], datetime)
|
||||
|
||||
domain = entry._search_expired("!=", False)
|
||||
self.assertEqual(domain[0][:2], ("expire_date", "<"))
|
||||
self.assertIsInstance(domain[0][2], datetime)
|
||||
|
||||
domain = entry._search_expired("=", False)
|
||||
self.assertTrue(domain[0] == "|")
|
||||
self.assertIn(("expire_date", "=", False), domain)
|
||||
self.assertTrue(any(("expire_date", ">=") == d[:2] for d in domain))
|
||||
|
||||
def test_vault_entry_search_panel_limit(self):
|
||||
res = self.entry.search_panel_select_range("parent_id")
|
||||
total_items = self.env["vault.entry"].search_count([("child_ids", "!=", False)])
|
||||
self.assertEqual(len(res["values"]), total_items)
|
||||
156
odoo-bringout-oca-server-auth-vault/vault/tests/test_widgets.py
Normal file
156
odoo-bringout-oca-server-auth-vault/vault/tests/test_widgets.py
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
# © 2021 Florian Kantelberg - initOS GmbH
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import json
|
||||
import logging
|
||||
from uuid import uuid4
|
||||
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests import TransactionCase
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
TestChild = {
|
||||
"uuid": "42a",
|
||||
"note": "test note child",
|
||||
"name": "test child",
|
||||
"url": "child.example.org",
|
||||
"fields": [],
|
||||
"files": [],
|
||||
"childs": [],
|
||||
}
|
||||
|
||||
TestData = [
|
||||
{
|
||||
"uuid": "42b",
|
||||
"note": "test note child",
|
||||
"name": "don't import",
|
||||
"url": "child.example.org",
|
||||
"fields": [],
|
||||
"files": [],
|
||||
"childs": [],
|
||||
},
|
||||
TestChild,
|
||||
{
|
||||
"uuid": "42",
|
||||
"note": "test note",
|
||||
"name": "test name",
|
||||
"url": "test.example.org",
|
||||
"fields": [
|
||||
{"name": "a", "value": "Hello World", "iv": "abcd"},
|
||||
{"name": "secret", "value": "dlrow olleh", "iv": "abcd"},
|
||||
{"name": "secret", "value": "dlrow olle", "iv": "abcd"},
|
||||
],
|
||||
"files": [
|
||||
{"name": "a", "value": "Hello World", "iv": "abcd"},
|
||||
{"name": "secret", "value": "dlrow olleh", "iv": "abcd"},
|
||||
{},
|
||||
],
|
||||
"childs": [
|
||||
{
|
||||
"uuid": "42aa",
|
||||
"note": "test note subchild",
|
||||
"name": "test subchild",
|
||||
"url": "subchild.example.org",
|
||||
"fields": [],
|
||||
"files": [],
|
||||
"childs": [],
|
||||
},
|
||||
TestChild,
|
||||
],
|
||||
},
|
||||
TestChild,
|
||||
]
|
||||
|
||||
|
||||
class TestWidgets(TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.vault = self.env["vault"].create({"name": "Vault"})
|
||||
self.entry = self.env["vault.entry"].create(
|
||||
{"vault_id": self.vault.id, "name": "Entry"}
|
||||
)
|
||||
|
||||
def test_path_generation(self):
|
||||
wiz = self.env["vault.import.wizard"].create(
|
||||
{"vault_id": self.vault.id, "crypted_content": json.dumps(TestData)}
|
||||
)
|
||||
wiz._onchange_content()
|
||||
|
||||
paths = wiz.path.search([("uuid", "=", wiz.uuid)]).mapped("name")
|
||||
|
||||
self.assertEqual(len(paths), 6)
|
||||
self.assertIn("test name / test child", paths)
|
||||
self.assertIn("test child", paths)
|
||||
self.assertIn("test name", paths)
|
||||
|
||||
def test_import(self):
|
||||
uuid = uuid4()
|
||||
path = self.env["vault.import.wizard.path"].create(
|
||||
{"name": "test", "uuid": uuid}
|
||||
)
|
||||
|
||||
wiz = self.env["vault.import.wizard"].create(
|
||||
{
|
||||
"vault_id": self.vault.id,
|
||||
"crypted_content": json.dumps(TestData),
|
||||
"path": path.id,
|
||||
"uuid": uuid,
|
||||
}
|
||||
)
|
||||
|
||||
wiz.action_import()
|
||||
|
||||
# We have duplicates
|
||||
uuids = {"42", "42a", "42aa", self.entry.uuid}
|
||||
self.assertSetEqual(set(self.vault.entry_ids.mapped("uuid")), uuids)
|
||||
|
||||
# Creation is depth-first which will cause the 42a to move up
|
||||
self.assertEqual(self.vault.entry_ids.mapped("child_ids.uuid"), ["42aa"])
|
||||
|
||||
# This will cause an overwrite of the field
|
||||
domain = [("entry_id.uuid", "=", "42"), ("name", "=", "secret")]
|
||||
rec = self.env["vault.field"].search(domain)
|
||||
self.assertEqual(rec.mapped("value"), ["dlrow olle"])
|
||||
|
||||
# Field with missing keys should fail
|
||||
with self.assertRaises(UserError):
|
||||
TestChild["fields"].append({"name": "12", "value": "eulav"})
|
||||
wiz.crypted_content = json.dumps([TestChild])
|
||||
wiz.action_import()
|
||||
|
||||
def test_export(self):
|
||||
child = self.env["vault.entry"].create(
|
||||
{"vault_id": self.vault.id, "name": "Child", "parent_id": self.entry.id}
|
||||
)
|
||||
|
||||
second = self.env["vault.entry"].create(
|
||||
{"vault_id": self.vault.id, "name": "second"}
|
||||
)
|
||||
|
||||
wiz = self.env["vault.export.wizard"].create({"vault_id": self.vault.id})
|
||||
|
||||
# Export without entry should export entire vault
|
||||
wiz._onchange_content()
|
||||
entries = json.loads(wiz.content)
|
||||
self.assertEqual({e["uuid"] for e in entries}, {second.uuid, self.entry.uuid})
|
||||
self.assertEqual(len(entries), 2)
|
||||
|
||||
wiz.entry_id = self.entry
|
||||
|
||||
# Export the entire tree
|
||||
wiz._onchange_content()
|
||||
entries = json.loads(wiz.content)
|
||||
self.assertEqual(len(entries), 1)
|
||||
self.assertEqual(entries[0]["uuid"], self.entry.uuid)
|
||||
self.assertEqual(entries[0]["childs"][0]["uuid"], child.uuid)
|
||||
|
||||
# Skip exporting childs
|
||||
wiz.include_childs = False
|
||||
wiz._onchange_content()
|
||||
entries = json.loads(wiz.content)
|
||||
self.assertEqual(len(entries), 1)
|
||||
self.assertEqual(entries[0]["uuid"], self.entry.uuid)
|
||||
self.assertEqual(len(entries[0]["childs"]), 0)
|
||||
Loading…
Add table
Add a link
Reference in a new issue