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

# -*- 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')