You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
7.7 KiB
223 lines
7.7 KiB
# -*- coding: utf-8 -*-
|
|
# © 2016 Akretion Raphaël REVERDY
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
|
|
from odoo.tests.common import TransactionCase
|
|
from odoo.tools.config import config
|
|
from odoo.exceptions import ValidationError, UserError
|
|
|
|
|
|
import logging
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
try:
|
|
from cryptography.fernet import Fernet
|
|
except ImportError as err:
|
|
_logger.debug(err)
|
|
|
|
|
|
class TestKeychain(TransactionCase):
|
|
|
|
def setUp(self):
|
|
super(TestKeychain, self).setUp()
|
|
|
|
self.keychain = self.env['keychain.account']
|
|
config['keychain_key'] = Fernet.generate_key()
|
|
|
|
self.old_running_env = config.get('running_env', '')
|
|
config['running_env'] = None
|
|
|
|
def _init_data(self):
|
|
return {
|
|
"c": True,
|
|
"a": "b",
|
|
"d": "",
|
|
}
|
|
|
|
def _validate_data(self, data):
|
|
return 'c' in data
|
|
|
|
keychain_clss = self.keychain.__class__
|
|
keychain_clss._keychain_test_init_data = _init_data
|
|
keychain_clss._keychain_test_validate_data = _validate_data
|
|
|
|
self.keychain._fields['namespace'].selection.append(
|
|
('keychain_test', 'test')
|
|
)
|
|
|
|
def tearDown(self):
|
|
config['running_env'] = self.old_running_env
|
|
return super(TestKeychain, self).tearDown()
|
|
|
|
def _create_account(self):
|
|
vals = {
|
|
"name": "test",
|
|
"namespace": "keychain_test",
|
|
"login": "test",
|
|
"technical_name": "keychain.test"
|
|
}
|
|
return self.keychain.create(vals)
|
|
|
|
def test_password(self):
|
|
"""It should encrypt passwords."""
|
|
account = self._create_account()
|
|
passwords = ('', '12345', 'djkqfljfqm', u"""&é"'(§è!ç""")
|
|
|
|
for password in passwords:
|
|
account.clear_password = password
|
|
account._inverse_set_password()
|
|
self.assertTrue(account.clear_password != account.password)
|
|
self.assertEqual(account._get_password(), password)
|
|
|
|
def test_wrong_key(self):
|
|
"""It should raise an exception when encoded key != decoded."""
|
|
account = self._create_account()
|
|
password = 'urieapocq'
|
|
account.clear_password = password
|
|
account._inverse_set_password()
|
|
config['keychain_key'] = Fernet.generate_key()
|
|
try:
|
|
account._get_password()
|
|
self.assertTrue(False, 'It should not work with another key')
|
|
except UserError as err:
|
|
self.assertTrue(True, 'It should raise a UserError')
|
|
self.assertTrue(
|
|
'has been encrypted with a diff' in str(err),
|
|
'It should display the right msg')
|
|
else:
|
|
self.assertTrue(False, 'It should raise a UserError')
|
|
|
|
def test_no_key(self):
|
|
"""It should raise an exception when no key is set."""
|
|
account = self._create_account()
|
|
del config.options['keychain_key']
|
|
|
|
with self.assertRaises(UserError) as err:
|
|
account.clear_password = 'aiuepr'
|
|
account._inverse_set_password()
|
|
self.assertTrue(False, 'It should not work without key')
|
|
self.assertTrue(
|
|
'Use a key similar to' in str(err.exception),
|
|
'It should display the right msg')
|
|
|
|
def test_badly_formatted_key(self):
|
|
"""It should raise an exception when key is not acceptable format."""
|
|
account = self._create_account()
|
|
|
|
config['keychain_key'] = ""
|
|
with self.assertRaises(UserError):
|
|
account.clear_password = 'aiuepr'
|
|
account._inverse_set_password()
|
|
self.assertTrue(False, 'It should not work missing formated key')
|
|
|
|
self.assertTrue(True, 'It shoud raise a ValueError')
|
|
|
|
def test_retrieve_env(self):
|
|
"""Retrieve env should always return False at the end"""
|
|
config['running_env'] = False
|
|
self.assertListEqual(self.keychain._retrieve_env(), [False])
|
|
|
|
config['running_env'] = 'dev'
|
|
self.assertListEqual(self.keychain._retrieve_env(), ['dev', False])
|
|
|
|
config['running_env'] = 'prod'
|
|
self.assertListEqual(self.keychain._retrieve_env(), ['prod', False])
|
|
|
|
def test_multienv(self):
|
|
"""Encrypt with dev, decrypt with dev."""
|
|
account = self._create_account()
|
|
config['keychain_key_dev'] = Fernet.generate_key()
|
|
config['keychain_key_prod'] = Fernet.generate_key()
|
|
config['running_env'] = 'dev'
|
|
|
|
account.clear_password = 'abc'
|
|
account._inverse_set_password()
|
|
self.assertEqual(
|
|
account._get_password(),
|
|
'abc', 'Should work with dev')
|
|
|
|
config['running_env'] = 'prod'
|
|
with self.assertRaises(UserError):
|
|
self.assertEqual(
|
|
account._get_password(),
|
|
'abc', 'Should not work with prod key')
|
|
|
|
def test_multienv_blank(self):
|
|
"""Encrypt with blank, decrypt for all."""
|
|
account = self._create_account()
|
|
config['keychain_key'] = Fernet.generate_key()
|
|
config['keychain_key_dev'] = Fernet.generate_key()
|
|
config['keychain_key_prod'] = Fernet.generate_key()
|
|
config['running_env'] = ''
|
|
|
|
account.clear_password = 'abc'
|
|
account._inverse_set_password()
|
|
self.assertEqual(
|
|
account._get_password(),
|
|
'abc', 'Should work with dev')
|
|
|
|
config['running_env'] = 'prod'
|
|
self.assertEqual(
|
|
account._get_password(),
|
|
'abc', 'Should work with prod')
|
|
|
|
def test_multienv_force(self):
|
|
"""Set the env on the record"""
|
|
|
|
account = self._create_account()
|
|
account.environment = 'prod'
|
|
|
|
config['keychain_key'] = Fernet.generate_key()
|
|
config['keychain_key_dev'] = Fernet.generate_key()
|
|
config['keychain_key_prod'] = Fernet.generate_key()
|
|
config['running_env'] = ''
|
|
|
|
account.clear_password = 'abc'
|
|
account._inverse_set_password()
|
|
|
|
with self.assertRaises(UserError):
|
|
self.assertEqual(
|
|
account._get_password(),
|
|
'abc', 'Should not work with dev')
|
|
|
|
config['running_env'] = 'prod'
|
|
self.assertEqual(
|
|
account._get_password(),
|
|
'abc', 'Should work with prod')
|
|
|
|
def test_wrong_json(self):
|
|
"""It should raise an exception when data is not valid json."""
|
|
account = self._create_account()
|
|
wrong_jsons = ("{'hi':'o'}", "{'oq", '[>}')
|
|
for json in wrong_jsons:
|
|
with self.assertRaises(ValidationError) as err:
|
|
account.write({"data": json})
|
|
self.assertTrue(
|
|
False,
|
|
'Should not validate baddly formatted json')
|
|
self.assertTrue(
|
|
'Data should be a valid JSON' in str(err.exception),
|
|
'It should raise a ValidationError')
|
|
|
|
def test_invalid_json(self):
|
|
"""It should raise an exception when data don't pass _validate_data."""
|
|
account = self._create_account()
|
|
invalid_jsons = ('{}', '{"hi": 1}')
|
|
for json in invalid_jsons:
|
|
with self.assertRaises(ValidationError) as err:
|
|
account.write({"data": json})
|
|
self.assertTrue(
|
|
'Data not valid' in str(err.exception),
|
|
'It should raise a ValidationError')
|
|
|
|
def test_valid_json(self):
|
|
"""It should work with valid data."""
|
|
account = self._create_account()
|
|
valid_jsons = ('{"c": true}', '{"c": 1}', '{"a": "o", "c": "b"}')
|
|
for json in valid_jsons:
|
|
try:
|
|
account.write({"data": json})
|
|
self.assertTrue(True, 'Should validate json')
|
|
except:
|
|
self.assertTrue(False, 'It should validate a good json')
|