Browse Source
Merge pull request #1168 from acsone/9.0-keychain-caching
Merge pull request #1168 from acsone/9.0-keychain-caching
[9.0] Keychain account cachingpull/1563/head
Pedro M. Baeza
6 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 201 additions and 15 deletions
-
5keychain/README.rst
-
1keychain/models/__init__.py
-
2keychain/models/keychain.py
-
100keychain/models/keychain_backend.py
-
1keychain/tests/__init__.py
-
18keychain/tests/test_keychain.py
-
81keychain/tests/test_keychain_backend.py
-
4keychain/views/keychain_view.xml
@ -1 +1,2 @@ |
|||||
from . import keychain |
from . import keychain |
||||
|
from . import keychain_backend |
@ -0,0 +1,100 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Akretion Sebastien Beau |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from openerp import api, fields, models |
||||
|
from openerp.tools.config import config |
||||
|
|
||||
|
|
||||
|
class KeychainBackend(models.AbstractModel): |
||||
|
_name = 'keychain.backend' |
||||
|
_backend_name = None |
||||
|
|
||||
|
name = fields.Char(required=True) |
||||
|
password = fields.Char( |
||||
|
compute="_compute_password", |
||||
|
inverse="_inverse_password", |
||||
|
required=True) |
||||
|
data = fields.Serialized( |
||||
|
compute="_compute_keychain", |
||||
|
inverse="_inverse_keychain", |
||||
|
help="Additionnal data as json") |
||||
|
keychain_account_id = fields.Many2one( |
||||
|
'keychain.account', compute='_compute_keychain_account') |
||||
|
|
||||
|
@api.multi |
||||
|
def _compute_keychain_account(self): |
||||
|
for backend in self: |
||||
|
backend.keychain_account_id = backend._get_existing_keychain() |
||||
|
|
||||
|
@api.multi |
||||
|
def _get_technical_name(self): |
||||
|
self.ensure_one() |
||||
|
return '%s,%s' % (self._name, self.id) |
||||
|
|
||||
|
@api.multi |
||||
|
def _get_existing_keychain(self): |
||||
|
self.ensure_one() |
||||
|
return self.env['keychain.account'].retrieve([ |
||||
|
('namespace', '=', self._backend_name), |
||||
|
('technical_name', '=', self._get_technical_name()) |
||||
|
]) |
||||
|
|
||||
|
@api.multi |
||||
|
def _prepare_keychain(self): |
||||
|
self.ensure_one() |
||||
|
env = config.get('running_env') |
||||
|
return { |
||||
|
'name': "%s %s" % (self.name, env), |
||||
|
'technical_name': self._get_technical_name(), |
||||
|
'namespace': self._backend_name, |
||||
|
'environment': env, |
||||
|
} |
||||
|
|
||||
|
@api.multi |
||||
|
def _get_keychain_account(self): |
||||
|
self.ensure_one() |
||||
|
if not self.keychain_account_id: |
||||
|
vals = self._prepare_keychain() |
||||
|
self.keychain_account_id = self.env['keychain.account'].create( |
||||
|
vals) |
||||
|
return self.keychain_account_id |
||||
|
|
||||
|
@api.multi |
||||
|
def _inverse_password(self): |
||||
|
for record in self: |
||||
|
account = self._get_keychain_account() |
||||
|
if record.password and record.password != '******': |
||||
|
account.clear_password = record.password |
||||
|
|
||||
|
@api.multi |
||||
|
def _compute_password(self): |
||||
|
for record in self: |
||||
|
account = record._get_existing_keychain() |
||||
|
if account and account.password: |
||||
|
record.password = "******" |
||||
|
else: |
||||
|
record.password = "" |
||||
|
|
||||
|
@api.multi |
||||
|
def _inverse_keychain(self): |
||||
|
for record in self: |
||||
|
account = record._get_keychain_account() |
||||
|
account.data = account._serialize_data(record.data) |
||||
|
|
||||
|
@api.multi |
||||
|
def _compute_keychain(self): |
||||
|
for record in self: |
||||
|
account = record._get_existing_keychain() |
||||
|
if account: |
||||
|
record.data = account.get_data() |
||||
|
else: |
||||
|
record.data = {} |
||||
|
|
||||
|
@api.multi |
||||
|
def _get_password(self): |
||||
|
self.ensure_one() |
||||
|
if self.keychain_account_id: |
||||
|
return self.keychain_account_id._get_password() |
||||
|
else: |
||||
|
return False |
@ -1 +1,2 @@ |
|||||
from . import test_keychain |
from . import test_keychain |
||||
|
from . import test_keychain_backend |
@ -0,0 +1,81 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Akretion Mourad EL HADJ MIMOUNE |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from openerp.tests.common import TransactionCase |
||||
|
from openerp.tools.config import config |
||||
|
|
||||
|
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'] |
||||
|
self.keychain_backend = self.env['keychain.backend'] |
||||
|
|
||||
|
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._test_backend_init_data = _init_data |
||||
|
keychain_clss._test_backend_validate_data = _validate_data |
||||
|
|
||||
|
keychain_backend_clss = self.keychain_backend.__class__ |
||||
|
keychain_backend_clss._backend_name = 'test_backend' |
||||
|
|
||||
|
self.keychain._fields['namespace'].selection.append( |
||||
|
('test_backend', 'test backend') |
||||
|
) |
||||
|
|
||||
|
def test_keychain_bakend(self): |
||||
|
"""It should work with valid data.""" |
||||
|
config['keychain_key_dev'] = Fernet.generate_key() |
||||
|
config['running_env'] = 'dev' |
||||
|
vals = { |
||||
|
'name': 'backend_test', |
||||
|
'password': 'test', |
||||
|
'data': '{"a": "o", "c": "b"}' |
||||
|
} |
||||
|
# we use new because keychain.backend is an abstract model |
||||
|
backend = self.keychain_backend.new(vals) |
||||
|
backend._inverse_keychain() |
||||
|
account = backend._get_existing_keychain() |
||||
|
self.assertEqual( |
||||
|
backend.data, '{"a": "o", "c": "b"}', |
||||
|
'Account data is not correct') |
||||
|
backend._inverse_password() |
||||
|
self.assertTrue(account, 'Account was not created') |
||||
|
self.assertEqual( |
||||
|
account.clear_password, u'test', |
||||
|
'Account clear password is not correct') |
||||
|
self.assertEqual(backend.password, u'test') |
||||
|
backend._compute_password() |
||||
|
self.assertEqual( |
||||
|
backend.password, u'******', 'Backend password was not computed') |
||||
|
self.assertEqual( |
||||
|
account.name, u'backend_test dev', 'Account name is not correct') |
||||
|
self.assertEqual( |
||||
|
account.namespace, u'test_backend', |
||||
|
'Account namespace is not correct') |
||||
|
self.assertEqual( |
||||
|
account.environment, u'dev', 'Account environment is not correct') |
||||
|
self.assertEqual( |
||||
|
account.technical_name, '%s,%s' % (backend._name, backend.id), |
||||
|
'Account technical_name is not correct') |
Write
Preview
Loading…
Cancel
Save
Reference in new issue