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.

242 lines
8.3 KiB

8 years ago
8 years ago
  1. # -*- coding: utf-8 -*-
  2. # © 2016 Akretion Raphaël REVERDY
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from odoo.tests.common import TransactionCase
  5. from odoo.tools.config import config
  6. from odoo.exceptions import ValidationError, UserError
  7. import logging
  8. _logger = logging.getLogger(__name__)
  9. try:
  10. from cryptography.fernet import Fernet
  11. except ImportError as err:
  12. _logger.debug(err)
  13. class TestKeychain(TransactionCase):
  14. def setUp(self):
  15. super(TestKeychain, self).setUp()
  16. self.keychain = self.env['keychain.account']
  17. config['keychain_key'] = Fernet.generate_key()
  18. self.old_running_env = config.get('running_env', '')
  19. config['running_env'] = None
  20. def _init_data(self):
  21. return {
  22. "c": True,
  23. "a": "b",
  24. "d": "",
  25. }
  26. def _validate_data(self, data):
  27. return 'c' in data
  28. keychain_clss = self.keychain.__class__
  29. keychain_clss._keychain_test_init_data = _init_data
  30. keychain_clss._keychain_test_validate_data = _validate_data
  31. self.keychain._fields['namespace'].selection.append(
  32. ('keychain_test', 'test')
  33. )
  34. def tearDown(self):
  35. config['running_env'] = self.old_running_env
  36. return super(TestKeychain, self).tearDown()
  37. def _create_account(self):
  38. vals = {
  39. "name": "test",
  40. "namespace": "keychain_test",
  41. "login": "test",
  42. "technical_name": "keychain.test"
  43. }
  44. return self.keychain.create(vals)
  45. def test_password(self):
  46. """It should encrypt passwords."""
  47. account = self._create_account()
  48. passwords = ('', '12345', 'djkqfljfqm', u""""'(§è!ç""")
  49. for password in passwords:
  50. account.clear_password = password
  51. account._inverse_set_password()
  52. self.assertTrue(account.clear_password != account.password)
  53. self.assertEqual(account._get_password(), password)
  54. def test_wrong_key(self):
  55. """It should raise an exception when encoded key != decoded."""
  56. account = self._create_account()
  57. password = 'urieapocq'
  58. account.clear_password = password
  59. account._inverse_set_password()
  60. config['keychain_key'] = Fernet.generate_key()
  61. try:
  62. account._get_password()
  63. self.fail('It should not work with another key')
  64. except UserError as err:
  65. self.assertTrue(True, 'It should raise a UserError')
  66. self.assertTrue(
  67. 'has been encrypted with a diff' in str(err),
  68. 'It should display the right msg')
  69. else:
  70. self.fail('It should raise a UserError')
  71. def test_no_key(self):
  72. """It should raise an exception when no key is set."""
  73. account = self._create_account()
  74. del config.options['keychain_key']
  75. with self.assertRaises(UserError) as err:
  76. account.clear_password = 'aiuepr'
  77. account._inverse_set_password()
  78. self.fail('It should not work without key')
  79. self.assertTrue(
  80. 'Use a key similar to' in str(err.exception),
  81. 'It should display the right msg')
  82. def test_badly_formatted_key(self):
  83. """It should raise an exception when key is not acceptable format."""
  84. account = self._create_account()
  85. config['keychain_key'] = ""
  86. with self.assertRaises(UserError):
  87. account.clear_password = 'aiuepr'
  88. account._inverse_set_password()
  89. self.fail('It should not work missing formated key')
  90. self.assertTrue(True, 'It shoud raise a ValueError')
  91. def test_retrieve_env(self):
  92. """Retrieve env should always return False at the end"""
  93. config['running_env'] = False
  94. self.assertListEqual(self.keychain._retrieve_env(), [False])
  95. config['running_env'] = 'dev'
  96. self.assertListEqual(self.keychain._retrieve_env(), ['dev', False])
  97. config['running_env'] = 'prod'
  98. self.assertListEqual(self.keychain._retrieve_env(), ['prod', False])
  99. def test_multienv(self):
  100. """Encrypt with dev, decrypt with dev."""
  101. account = self._create_account()
  102. config['keychain_key_dev'] = Fernet.generate_key()
  103. config['keychain_key_prod'] = Fernet.generate_key()
  104. config['running_env'] = 'dev'
  105. account.clear_password = 'abc'
  106. account._inverse_set_password()
  107. self.assertEqual(
  108. account._get_password(),
  109. 'abc', 'Should work with dev')
  110. config['running_env'] = 'prod'
  111. with self.assertRaises(UserError):
  112. self.assertEqual(
  113. account._get_password(),
  114. 'abc', 'Should not work with prod key')
  115. def test_multienv_blank(self):
  116. """Encrypt with blank, decrypt for all."""
  117. account = self._create_account()
  118. config['keychain_key'] = Fernet.generate_key()
  119. config['keychain_key_dev'] = Fernet.generate_key()
  120. config['keychain_key_prod'] = Fernet.generate_key()
  121. config['running_env'] = ''
  122. account.clear_password = 'abc'
  123. account._inverse_set_password()
  124. self.assertEqual(
  125. account._get_password(),
  126. 'abc', 'Should work with dev')
  127. config['running_env'] = 'prod'
  128. self.assertEqual(
  129. account._get_password(),
  130. 'abc', 'Should work with prod')
  131. def test_multienv_force(self):
  132. """Set the env on the record"""
  133. account = self._create_account()
  134. account.environment = 'prod'
  135. config['keychain_key'] = Fernet.generate_key()
  136. config['keychain_key_dev'] = Fernet.generate_key()
  137. config['keychain_key_prod'] = Fernet.generate_key()
  138. config['running_env'] = ''
  139. account.clear_password = 'abc'
  140. account._inverse_set_password()
  141. with self.assertRaises(UserError):
  142. self.assertEqual(
  143. account._get_password(),
  144. 'abc', 'Should not work with dev')
  145. config['running_env'] = 'prod'
  146. self.assertEqual(
  147. account._get_password(),
  148. 'abc', 'Should work with prod')
  149. def test_wrong_json(self):
  150. """It should raise an exception when data is not valid json."""
  151. account = self._create_account()
  152. wrong_jsons = ("{'hi':'o'}", "{'oq", '[>}')
  153. for json in wrong_jsons:
  154. with self.assertRaises(ValidationError) as err:
  155. account.write({"data": json})
  156. self.fail('Should not validate baddly formatted json')
  157. self.assertTrue(
  158. 'Data should be a valid JSON' in str(err.exception),
  159. 'It should raise a ValidationError')
  160. def test_invalid_json(self):
  161. """It should raise an exception when data don't pass _validate_data."""
  162. account = self._create_account()
  163. invalid_jsons = ('{}', '{"hi": 1}')
  164. for json in invalid_jsons:
  165. with self.assertRaises(ValidationError) as err:
  166. account.write({"data": json})
  167. self.assertTrue(
  168. 'Data not valid' in str(err.exception),
  169. 'It should raise a ValidationError')
  170. def test_valid_json(self):
  171. """It should work with valid data."""
  172. account = self._create_account()
  173. valid_jsons = ('{"c": true}', '{"c": 1}', '{"a": "o", "c": "b"}')
  174. for json in valid_jsons:
  175. try:
  176. account.write({"data": json})
  177. self.assertTrue(True, 'Should validate json')
  178. except:
  179. self.fail('It should validate a good json')
  180. def test_default_init_and_valid(self):
  181. """."""
  182. self.keychain._fields['namespace'].selection.append(
  183. ('keychain_test_default', 'test')
  184. )
  185. account = self.keychain.create({
  186. "name": "test",
  187. "namespace": "keychain_test_default",
  188. "login": "test",
  189. "technical_name": "keychain.test"
  190. })
  191. try:
  192. account.write({"login": "test default"})
  193. except ValidationError:
  194. self.fail('It should validate any json in default')
  195. self.assertEqual(
  196. account.data, account._serialize_data(
  197. account._default_init_data()),
  198. 'Data should be default value')