Files
odoo-addons/addons/cetmix_tower_server/tests/test_key.py

920 lines
34 KiB
Python

from odoo.exceptions import AccessError, ValidationError
from .common import TestTowerCommon
class TestTowerKey(TestTowerCommon):
"""Test class for tower key."""
@classmethod
def setUpClass(cls):
super().setUpClass()
# Create another manager for testing
cls.manager_2 = cls.Users.create(
{
"name": "Second Manager",
"login": "manager2",
"email": "manager2@test.com",
"groups_id": [(4, cls.env.ref("cetmix_tower_server.group_manager").id)],
}
)
# Create test servers
cls.server_1 = cls.Server.create(
{
"name": "Test Server 1",
"ip_v4_address": "192.168.1.1",
"ssh_port": 22,
"ssh_username": "admin",
"ssh_password": "password",
"ssh_auth_mode": "p",
}
)
cls.server_2 = cls.Server.create(
{
"name": "Test Server 2",
"ip_v4_address": "192.168.1.2",
"ssh_port": 22,
"ssh_username": "admin",
"ssh_password": "password",
"ssh_auth_mode": "p",
}
)
cls.test_key = cls.Key.create(
{"name": "Test Key", "key_type": "s", "secret_value": "test value"}
)
def test_key_creation(self):
"""
Test key creation.
We override create method so need to check if reference is generated properly
"""
# -- 1--
# Check new key values
key_one = self.Key.create(
{"name": " test key meme ", "secret_value": "test value", "key_type": "s"}
)
self.assertEqual(
key_one.reference, "test_key_meme", "Reference must be 'test_key_meme'"
)
self.assertEqual(
key_one.name,
"test key meme",
"Trailing and leading whitespaces must be removed from name",
)
def test_extract_key_strings(self):
"""Check if key strings are extracted properly"""
code = (
"Hey #!cxtower.secret.MEME_KEY!# & Doge #!cxtower.secret.DOGE_KEY !# so "
"like #!cxtower.secret.MEME_KEY!#!\n"
"They make #!memes together."
"And this is another string for the same #!cxtower.secret.MEME_KEY !#"
)
key_strings = self.Key._extract_key_strings(code)
self.assertEqual(len(key_strings), 3, "Must be 3 key stings")
self.assertIn(
"#!cxtower.secret.MEME_KEY!#",
key_strings,
"Key string must be in key strings",
)
self.assertIn(
"#!cxtower.secret.DOGE_KEY !#",
key_strings,
"Key string must be in key strings",
)
self.assertIn(
"#!cxtower.secret.MEME_KEY !#",
key_strings,
"Key string must be in key strings",
)
def test_parse_key_string(self):
"""Check if key string is parsed correctly"""
# Test global key
doge_key = self.Key.create(
{
"name": "doge key",
"reference": "DOGE_KEY",
"secret_value": "Doge dog",
"key_type": "s",
}
)
key_string = "#!cxtower.secret.DOGE_KEY!#"
key_value = self.Key._parse_key_string(key_string)
self.assertEqual(key_value, "Doge dog", "Key value doesn't match")
# Test the same key string but with some spaces before the key terminator
key_string = "#!cxtower.secret.DOGE_KEY !#"
key_value = self.Key._parse_key_string(key_string)
self.assertEqual(key_value, "Doge dog", "Key value doesn't match")
# Test partner specific key
self.KeyValue.create(
{
"key_id": doge_key.id,
"secret_value": "Doge partner",
"partner_id": self.user_bob.partner_id.id,
}
)
# compose kwargs
kwargs = {
"partner_id": self.user_bob.partner_id.id,
"server_id": self.server_test_1.id,
}
key_value = self.Key._parse_key_string(key_string, **kwargs)
self.assertEqual(key_value, "Doge partner", "Key value doesn't match")
# Test server specific key
self.KeyValue.create(
{
"key_id": doge_key.id,
"secret_value": "Doge server",
"server_id": self.server_test_1.id,
}
)
key_value = self.Key._parse_key_string(key_string, **kwargs)
# Test server and partner specific key
self.KeyValue.create(
{
"key_id": doge_key.id,
"secret_value": "Doge server and partner",
"server_id": self.server_test_1.id,
"partner_id": self.user_bob.partner_id.id,
}
)
key_value = self.Key._parse_key_string(key_string, **kwargs)
self.assertEqual(
key_value, "Doge server and partner", "Key value doesn't match"
)
# Test missing key
key_string = "#!cxtower.secret.ANOTHER_KEY!#"
key_value = self.Key._parse_key_string(key_string)
self.assertIsNone(key_value, "Key value must be 'None'")
# Test missformatted key
key_string = "#!cxtower.ANOTHER_KEY!#"
key_value = self.Key._parse_key_string(key_string)
self.assertIsNone(key_value, "Key value must be 'None'")
# Test another missformatted key
key_string = "#!cxtower.notasecret.DOGE_KEY!#"
key_value = self.Key._parse_key_string(key_string)
self.assertIsNone(key_value, "Key value must be 'None'")
def test_resolve_key(self):
"""Check generic key resolver"""
self.Key.create(
{
"name": "doge key",
"reference": "DOGE_KEY",
"secret_value": "Doge dog",
"key_type": "s",
}
)
# Existing key
key_value = self.Key._resolve_key("secret", "DOGE_KEY")
self.assertEqual(key_value, "Doge dog", "Key value doesn't match")
# Non existing key
key_value = self.Key._resolve_key("server", "PEPE_KEY")
self.assertIsNone(key_value, "Key value must be 'None'")
def test_resolve_key_type_secret(self):
"""Check 'secret' type key resolver"""
doge_key = self.Key.create(
{
"name": "doge key",
"reference": "DOGE_KEY",
"key_type": "s",
}
)
# 1. Test server and partner specific key
server_partner_value = self.KeyValue.create(
{
"key_id": doge_key.id,
"secret_value": "Doge server and partner",
"server_id": self.server_test_1.id,
"partner_id": self.user_bob.partner_id.id,
}
)
kwargs = {
"partner_id": self.user_bob.partner_id.id,
"server_id": self.server_test_1.id,
}
key_value = self.Key._resolve_key_type_secret("DOGE_KEY", **kwargs)
self.assertEqual(
key_value, "Doge server and partner", "Key value doesn't match"
)
# 2. Global key
doge_key.write({"secret_value": "Doge dog"})
key_value = self.Key._resolve_key_type_secret("DOGE_KEY")
self.assertEqual(key_value, "Doge dog", "Key value doesn't match")
# 3. Non existing key
key_value = self.Key._resolve_key_type_secret("PEPE_KEY")
self.assertIsNone(key_value, "Key value must be 'None'")
# 4. Partner specific key
self.KeyValue.create(
{
"key_id": doge_key.id,
"secret_value": "Doge partner",
"partner_id": self.user_bob.partner_id.id,
}
)
kwargs = {
"partner_id": self.user_bob.partner_id.id,
}
key_value = self.Key._resolve_key_type_secret("DOGE_KEY", **kwargs)
self.assertEqual(key_value, "Doge partner", "Key value doesn't match")
# 5. Test server specific key
self.KeyValue.create(
{
"key_id": doge_key.id,
"secret_value": "Doge server",
"server_id": self.server_test_1.id,
}
)
kwargs = {
"server_id": self.server_test_1.id,
}
key_value = self.Key._resolve_key_type_secret("DOGE_KEY", **kwargs)
self.assertEqual(key_value, "Doge server", "Key value doesn't match")
# 6. Test with non matching partner. Should return server specific value
kwargs = {
"partner_id": self.user.partner_id.id,
"server_id": self.server_test_1.id,
}
key_value = self.Key._resolve_key_type_secret("DOGE_KEY", **kwargs)
self.assertEqual(key_value, "Doge server", "Key value doesn't match")
# 7. Change partner in the server-partner specific value.
# Should return server specific value
server_partner_value.write({"partner_id": self.manager.partner_id.id})
kwargs = {
"server_id": self.server_test_1.id,
}
key_value = self.Key._resolve_key_type_secret("DOGE_KEY", **kwargs)
self.assertEqual(key_value, "Doge server", "Key value doesn't match")
# 8. Test with the global key again
key_value = self.Key._resolve_key_type_secret("DOGE_KEY")
self.assertEqual(key_value, "Doge dog", "Key value doesn't match")
def test_parse_code(self):
"""Test code parsing"""
def check_parsed_code(
code, code_parsed_expected, expected_key_values=None, **kwargs
):
"""Helper function for code parse testing
Args:
code (Text): code to parse
code_parsed_expected (Text): expected parsed code
expected_key_values (list, optional): key values that are expected
to be returned. Defaults to None.
"""
code_parsed = self.Key._parse_code(code, **kwargs)
self.assertEqual(
code_parsed,
code_parsed_expected,
msg="Parsed code doesn't match expected one",
)
if expected_key_values:
result = self.Key._parse_code_and_return_key_values(code, **kwargs)
code_parsed = result["code"]
key_values = result["key_values"]
self.assertEqual(
code_parsed,
code_parsed_expected,
msg="Parsed code doesn't match expected one",
)
self.assertEqual(
len(key_values),
len(expected_key_values),
"Number of key values doesn't match number of expected ones",
)
for expected_value in expected_key_values:
self.assertIn(
expected_value,
key_values,
f"Value {expected_value} must be in the returned key values",
)
# Create new key
self.Key.create(
{
"name": "Meme key",
"reference": "MEME_KEY",
"secret_value": "Pepe Frog",
"key_type": "s",
}
)
# Check key parser
# 1 - single line
code = "The key to understand this meme is #!cxtower.secret.MEME_KEY!#"
code_parsed_expected = "The key to understand this meme is Pepe Frog"
expected_key_values = ["Pepe Frog"]
check_parsed_code(code, code_parsed_expected, expected_key_values)
# 2 - multi line
code = "Welcome #!cxtower.secret.MEME_KEY!#\nNew hero of this city!"
code_parsed_expected = "Welcome Pepe Frog\nNew hero of this city!"
expected_key_values = ["Pepe Frog"]
check_parsed_code(code, code_parsed_expected, expected_key_values)
# 3 - Key not found
code = "Don't mess with #!cxtower.secret.DOGE_LIKE!# He will make you cry"
code_parsed_expected = "Don't mess with None He will make you cry"
expected_key_values = []
check_parsed_code(code, code_parsed_expected, expected_key_values)
check_parsed_code(code, code_parsed_expected)
# 4 - Multi keys
# Create new key
doge_key = self.Key.create(
{
"name": "doge key",
"reference": "DOGE_KEY",
"secret_value": "Doge dog",
"key_type": "s",
}
)
code = (
"Hey #!cxtower.secret.MEME_KEY!# & Doge #!cxtower.secret.DOGE_KEY !# so "
"like #!cxtower.secret.MEME_KEY!#!\n"
"They make #!memes together. Check #!cxtower.secret.MEME_KEY&#!"
"cxtower.secret.DOGE_KEY"
)
code_parsed_expected = (
"Hey Pepe Frog & Doge Doge dog so "
"like Pepe Frog!\n"
"They make #!memes together. Check #!cxtower.secret.MEME_KEY&#!"
"cxtower.secret.DOGE_KEY"
)
expected_key_values = ["Pepe Frog", "Doge dog"]
check_parsed_code(code, code_parsed_expected, expected_key_values)
# 5 - Partner specific key
# Create new key for partner Bob
self.KeyValue.create(
{
"key_id": doge_key.id,
"secret_value": "Doge wow",
"partner_id": self.user_bob.partner_id.id,
}
)
# compose kwargs
kwargs = {"partner_id": self.user_bob.partner_id.id}
code_parsed_expected = (
"Hey Pepe Frog & Doge Doge wow so "
"like Pepe Frog!\n"
"They make #!memes together. Check #!cxtower.secret.MEME_KEY&#!"
"cxtower.secret.DOGE_KEY"
)
expected_key_values = ["Pepe Frog", "Doge wow"]
check_parsed_code(code, code_parsed_expected, expected_key_values, **kwargs)
# 6 - Server specific key
# Create new key for server Test 1
self.KeyValue.create(
{
"key_id": doge_key.id,
"secret_value": "Doge much",
"server_id": self.server_test_1.id,
}
)
# compose kwargs
kwargs = {
"partner_id": self.user_bob.partner_id.id, # not needed but may keep it
"server_id": self.server_test_1.id,
}
code_parsed_expected = (
"Hey Pepe Frog & Doge Doge much so "
"like Pepe Frog!\n"
"They make #!memes together. Check #!cxtower.secret.MEME_KEY&#!"
"cxtower.secret.DOGE_KEY"
)
expected_key_values = ["Pepe Frog", "Doge much"]
check_parsed_code(code, code_parsed_expected, expected_key_values, **kwargs)
def test_replace_with_spoiler(self):
"""Check if secrets are replaced with spoiler correctly"""
code = (
"Hey Pepe Frog & Doge Doge much so "
"like Pepe Frog!\n"
"They make #!memes together. Check #!cxtower.secret.MEME_KEY&#!"
"cxtower.secret.DOGE_KEY"
)
placeholder = self.Key.SECRET_VALUE_PLACEHOLDER
expected_code = (
f"Hey {placeholder} & Doge {placeholder} so "
f"like {placeholder}!\n"
"They make #!memes together. Check #!cxtower.secret.MEME_KEY&#!"
"cxtower.secret.DOGE_KEY"
)
key_values = ["Pepe Frog", "Doge much"]
result = self.Key._replace_with_spoiler(code, key_values)
self.assertEqual(result, expected_code, "Result doesn't match expected code")
# --------------------------------------
# Check with some random key values now
# Original code should rename unchanged
# --------------------------------------
key_values = ["Wow much", "No like"]
result = self.Key._replace_with_spoiler(code, key_values)
self.assertEqual(result, code, "Result doesn't match expected code")
def test_user_access(self):
"""Test that regular users have no access to keys"""
user_key = self.Key.with_user(self.user)
# Create test key
key = self.Key.create(
{"name": "Test Key", "secret_value": "test value", "key_type": "s"}
)
# Test CRUD operations
with self.assertRaises(AccessError):
user_key.create(
{"name": "New Key", "secret_value": "secret", "key_type": "s"}
)
with self.assertRaises(AccessError):
user_key.browse(key.id).read(["name"])
with self.assertRaises(AccessError):
user_key.browse(key.id).write({"name": "Updated Name"})
with self.assertRaises(AccessError):
user_key.browse(key.id).unlink()
def test_manager_read_access(self):
"""Test manager read access rules"""
manager_key = self.Key.with_user(self.manager)
# Create test keys
key_secret = self.Key.create(
{"name": "Secret Key", "secret_value": "secret value", "key_type": "s"}
)
key_ssh = self.Key.create(
{"name": "SSH Key", "secret_value": "ssh key", "key_type": "k"}
)
# Test read access for secret key - should read (all managers can read secrets)
self.assertTrue(manager_key.search([("id", "=", key_secret.id)]))
# Test read access for SSH key without server access - should not find
self.assertFalse(manager_key.search([("id", "=", key_ssh.id)]))
# Add manager to server users and set SSH key - should find SSH key
self.write_and_invalidate(
self.server_1,
**{"user_ids": [(4, self.manager.id)], "ssh_key_id": key_ssh.id},
)
self.assertTrue(manager_key.search([("id", "=", key_ssh.id)]))
# Remove key from server - should not find again
self.server_1.write({"ssh_key_id": False})
self.assertFalse(manager_key.search([("id", "=", key_ssh.id)]))
# Add as key user - should find both
key_secret.write({"user_ids": [(4, self.manager.id)]})
key_ssh.write({"user_ids": [(4, self.manager.id)]})
self.assertTrue(manager_key.search([("id", "=", key_secret.id)]))
self.assertTrue(manager_key.search([("id", "=", key_ssh.id)]))
def test_manager_write_access(self):
"""Test manager write/create access rules"""
manager_key = self.Key.with_user(self.manager)
# Create test keys as root and ensure manager is not in manager_ids
key_secret = self.Key.create(
{
"name": "Secret Key",
"secret_value": "secret value",
"key_type": "s",
"manager_ids": [(5, 0)], # Clear manager_ids
}
)
key_ssh = self.Key.create(
{
"name": "SSH Key",
"secret_value": "ssh key",
"key_type": "k",
"manager_ids": [(5, 0)], # Clear manager_ids
}
)
# Try write without being manager - should fail
with self.assertRaises(AccessError):
manager_key.browse(key_secret.id).write({"name": "Updated Secret"})
with self.assertRaises(AccessError):
manager_key.browse(key_ssh.id).write({"name": "Updated SSH"})
# Add as key manager - should write to secret
key_secret.write({"manager_ids": [(4, self.manager.id)]})
manager_key.browse(key_secret.id).write({"name": "Updated Secret"})
self.assertEqual(key_secret.name, "Updated Secret")
# Add as server manager and set SSH key - should write to SSH key
self.server_1.write(
{"manager_ids": [(4, self.manager.id)], "ssh_key_id": key_ssh.id}
)
manager_key.browse(key_ssh.id).write({"name": "Updated SSH"})
self.assertEqual(key_ssh.name, "Updated SSH")
def test_manager_create_access(self):
"""Test manager create access rules"""
manager_key = self.Key.with_user(self.manager)
manager_2_key = self.Key.with_user(self.manager_2)
# Try create secret key when not a manager - should fail
with self.assertRaises(AccessError):
manager_2_key.create(
{
"name": "New Secret",
"secret_value": "secret",
"key_type": "s",
"manager_ids": [(5, 0)], # Prevent automatic manager addition
}
)
# Try create SSH key when not a server manager - should fail
with self.assertRaises(AccessError):
manager_2_key.create(
{
"name": "New SSH",
"secret_value": "ssh key",
"key_type": "k",
"manager_ids": [(5, 0)], # Prevent automatic manager addition
}
)
# Add as server manager - should create SSH key
self.server_1.write({"manager_ids": [(4, self.manager.id)]})
new_ssh_key = manager_key.create(
{"name": "New SSH", "secret_value": "ssh key", "key_type": "k"}
)
# Link key to server
self.server_1.write({"ssh_key_id": new_ssh_key.id})
self.assertTrue(new_ssh_key.exists())
def test_manager_unlink_access(self):
"""Test manager unlink access rules"""
manager_key = self.Key.with_user(self.manager)
# Create keys as root
key_secret = self.Key.create(
{"name": "Secret Key", "secret_value": "secret value", "key_type": "s"}
)
key_ssh = self.Key.create(
{"name": "SSH Key", "secret_value": "ssh key", "key_type": "k"}
)
# Link SSH key to server
self.server_1.write({"ssh_key_id": key_ssh.id})
# Try delete without being manager and creator - should fail
with self.assertRaises(AccessError):
manager_key.browse(key_secret.id).unlink()
with self.assertRaises(AccessError):
manager_key.browse(key_ssh.id).unlink()
# Add as manager but not creator - should still fail
key_secret.write({"manager_ids": [(4, self.manager.id)]})
self.server_1.write({"manager_ids": [(4, self.manager.id)]})
with self.assertRaises(AccessError):
manager_key.browse(key_secret.id).unlink()
with self.assertRaises(AccessError):
manager_key.browse(key_ssh.id).unlink()
# Create own keys - should delete
own_secret = manager_key.create(
{
"name": "Own Secret",
"secret_value": "secret",
"key_type": "s",
"manager_ids": [(4, self.manager.id)],
}
)
own_ssh = manager_key.create(
{"name": "Own SSH", "secret_value": "ssh key", "key_type": "k"}
)
# Link own SSH key to server
self.server_1.write({"ssh_key_id": own_ssh.id})
own_secret.unlink()
own_ssh.unlink()
self.assertFalse(own_secret.exists())
self.assertFalse(own_ssh.exists())
def test_root_access(self):
"""Test root access rules"""
root_key = self.Key.with_user(self.root)
# Create
key = root_key.create(
{"name": "Root Key", "secret_value": "root secret", "key_type": "s"}
)
self.assertTrue(key.exists())
# Read
self.assertEqual(root_key.browse(key.id).name, "Root Key")
# Write
root_key.browse(key.id).write({"name": "Updated Root Key"})
self.assertEqual(key.name, "Updated Root Key")
# Delete
key.unlink()
self.assertFalse(key.exists())
def test_key_value_user_access(self):
"""Test that regular users have no access to key values"""
user_key_value = self.KeyValue.with_user(self.user)
# Create test key and key value
key = self.Key.create({"name": "Test Key", "key_type": "s"})
key_value = self.KeyValue.create(
{"key_id": key.id, "secret_value": "test value"}
)
# Test CRUD operations
with self.assertRaises(AccessError):
user_key_value.create({"key_id": key.id, "secret_value": "new value"})
with self.assertRaises(AccessError):
user_key_value.browse(key_value.id).read(["secret_value"])
with self.assertRaises(AccessError):
user_key_value.browse(key_value.id).write({"secret_value": "updated value"})
with self.assertRaises(AccessError):
user_key_value.browse(key_value.id).unlink()
def test_key_value_manager_read_access(self):
"""Test manager read access rules for key values"""
manager_key_value = self.KeyValue.with_user(self.manager)
# Create test key and key values
key = self.Key.create({"name": "Test Key", "key_type": "s"})
global_value = self.KeyValue.create(
{"key_id": key.id, "secret_value": "global value"}
)
server_value = self.KeyValue.create(
{
"key_id": key.id,
"secret_value": "server value",
"server_id": self.server_1.id,
}
)
# Test read access - should not find without proper access
self.assertTrue(manager_key_value.search([("id", "=", global_value.id)]))
self.assertFalse(manager_key_value.search([("id", "=", server_value.id)]))
# Add as key user - should find global value and server value for that key
key.write({"user_ids": [(4, self.manager.id)]})
self.assertTrue(manager_key_value.search([("id", "=", global_value.id)]))
self.assertTrue(manager_key_value.search([("id", "=", server_value.id)]))
# Remove from key users
key.write({"user_ids": [(3, self.manager.id)]})
self.assertTrue(manager_key_value.search([("id", "=", global_value.id)]))
self.assertFalse(manager_key_value.search([("id", "=", server_value.id)]))
# Add as server user - should find server value
self.server_1.write({"user_ids": [(4, self.manager.id)]})
self.assertTrue(manager_key_value.search([("id", "=", global_value.id)]))
self.assertTrue(manager_key_value.search([("id", "=", server_value.id)]))
def test_key_value_manager_write_access(self):
"""Test manager write/create access rules for key values"""
manager_key_value = self.KeyValue.with_user(self.manager)
# Create test key and key values
key = self.Key.create({"name": "Test Key", "key_type": "s"})
global_value = self.KeyValue.create(
{"key_id": key.id, "secret_value": "global value"}
)
server_value = self.KeyValue.create(
{
"key_id": key.id,
"secret_value": "server value",
"server_id": self.server_1.id,
}
)
# Try write without proper access - should fail
with self.assertRaises(AccessError):
manager_key_value.browse(global_value.id).write(
{"secret_value": "new value"}
)
with self.assertRaises(AccessError):
manager_key_value.browse(server_value.id).write(
{"secret_value": "new value"}
)
# Add as key manager - should write to global value
key.write({"manager_ids": [(4, self.manager.id)]})
manager_key_value.browse(global_value.id).write(
{"secret_value": "updated global"}
)
self.assertEqual(
global_value._get_secret_value("secret_value"), "updated global"
)
# Add as server manager - should write to server value
self.server_1.write({"manager_ids": [(4, self.manager.id)]})
manager_key_value.browse(server_value.id).write(
{"secret_value": "updated server"}
)
self.assertEqual(
server_value._get_secret_value("secret_value"), "updated server"
)
# Test create access
for_bob = manager_key_value.create(
{
"key_id": key.id,
"secret_value": "for bob",
"partner_id": self.user_bob.partner_id.id,
}
)
self.assertTrue(for_bob.exists())
def test_key_value_manager_unlink_access(self):
"""Test manager unlink access rules for key values"""
manager_key_value = self.KeyValue.with_user(self.manager)
# Create test key and key values
key = self.Key.create({"name": "Test Key", "key_type": "s"})
# Create values as root
global_value = self.KeyValue.create(
{"key_id": key.id, "secret_value": "global value"}
)
server_value = self.KeyValue.create(
{
"key_id": key.id,
"secret_value": "server value",
"server_id": self.server_1.id,
}
)
# Try delete without proper access - should fail
with self.assertRaises(AccessError):
manager_key_value.browse(global_value.id).unlink()
with self.assertRaises(AccessError):
manager_key_value.browse(server_value.id).unlink()
# Add as manager but not creator - should still fail
key.write({"manager_ids": [(4, self.manager.id)]})
self.server_1.write({"manager_ids": [(4, self.manager.id)]})
with self.assertRaises(AccessError):
manager_key_value.browse(global_value.id).unlink()
with self.assertRaises(AccessError):
manager_key_value.browse(server_value.id).unlink()
# Create own values - should delete
own_partner_value = manager_key_value.create(
{
"key_id": key.id,
"secret_value": "own partner",
"partner_id": self.user_bob.partner_id.id,
}
)
# Unlink server value first to avoid constraint error
server_value.unlink()
# Create server value
own_server_value = manager_key_value.create(
{
"key_id": key.id,
"secret_value": "own server",
"server_id": self.server_1.id,
}
)
own_partner_value.unlink()
own_server_value.unlink()
self.assertFalse(own_partner_value.exists())
self.assertFalse(own_server_value.exists())
def test_key_value_root_access(self):
"""Test root access rules for key values"""
root_key_value = self.KeyValue.with_user(self.root)
# Create test key
key = self.Key.create({"name": "Test Key", "key_type": "s"})
# Create
value = root_key_value.create({"key_id": key.id, "secret_value": "root value"})
self.assertTrue(value.exists())
# Read
self.assertEqual(
root_key_value.browse(value.id)._get_secret_value("secret_value"),
"root value",
)
# Write
root_key_value.browse(value.id).write({"secret_value": "updated value"})
self.assertEqual(value._get_secret_value("secret_value"), "updated value")
# Delete
value.unlink()
self.assertFalse(value.exists())
def test_key_value_global_unique(self):
"""Test global value uniqueness"""
# Try to create a value for the same key
with self.assertRaises(ValidationError):
another_global_value = self.KeyValue.create(
{"key_id": self.test_key.id, "secret_value": "another test value"}
)
#
another_global_value.unlink()
def test_key_value_server_unique(self):
"""Test server value uniqueness"""
# Create server tight value
self.KeyValue.create(
{
"key_id": self.test_key.id,
"secret_value": "server related",
"server_id": self.server_1.id,
}
)
# Try create another value for the same server
with self.assertRaises(ValidationError):
self.KeyValue.create(
{
"key_id": self.test_key.id,
"secret_value": "another server related",
"server_id": self.server_1.id,
}
)
def test_key_value_partner_unique(self):
"""Test partner value uniqueness"""
# Create partner tight value
self.KeyValue.create(
{
"key_id": self.test_key.id,
"secret_value": "partner related",
"partner_id": self.user_bob.partner_id.id,
}
)
# Try create another value for the same partner
with self.assertRaises(ValidationError):
self.KeyValue.create(
{
"key_id": self.test_key.id,
"secret_value": "another partner related",
"partner_id": self.user_bob.partner_id.id,
}
)
def test_key_value_server_partner_unique(self):
"""Test server and partner value uniqueness"""
# Create server and partner tight value
self.KeyValue.create(
{
"key_id": self.test_key.id,
"secret_value": "server related",
"server_id": self.server_1.id,
"partner_id": self.user_bob.partner_id.id,
}
)
# Try create another value for the same server and partner
with self.assertRaises(ValidationError):
self.KeyValue.create(
{
"key_id": self.test_key.id,
"secret_value": "another server related",
"server_id": self.server_1.id,
"partner_id": self.user_bob.partner_id.id,
}
)