fixup! [ADD] server_environment_iap

This commit is contained in:
Maksym Yankin 2021-12-28 19:00:51 +02:00
parent 4aae255531
commit 383f877097
10 changed files with 96 additions and 174 deletions

View File

@ -2,15 +2,12 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Server Environment IAP Account",
"summary": """
Override IAP Accounts from server environment file""",
"name": "IAP Account configuration with server_environment",
"summary": "Configure IAP Account with server_environment_files",
"version": "14.0.1.0.0",
"license": "AGPL-3",
"author": "Camptocamp, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-env",
"depends": ["iap", "server_environment"],
"data": [
"views/iap_views.xml",
],
"data": ["views/iap_views.xml"],
}

View File

@ -1,70 +1,31 @@
# Copyright 2021 Camptocamp SA <https://www.camptocamp.com/>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.addons.server_environment.server_env import serv_config
SECTION = "iap.account"
from odoo import api, models
class IapAccount(models.Model):
_name = "iap.account"
_inherit = [
"iap.account",
"server.env.techname.mixin",
"server.env.mixin",
]
_inherit = "iap.account"
is_environment = fields.Boolean(
string="Defined by environment",
compute="_compute_is_environment",
help="If check, the value in the database will be ignored"
" and alternatively, the system will use the service name defined"
" in your odoo.cfg environment file.",
)
def _compute_is_environment(self):
for account in self:
account.is_environment = serv_config.has_option(
SECTION, account.service_name
)
@property
def _server_env_fields(self):
base_fields = super()._server_env_fields
iap_fields = {
"service_name": {},
"account_token": {},
}
iap_fields.update(base_fields)
return iap_fields
@api.model
def get(self, service_name, force_create=True):
account = super().get(service_name, force_create=True)
if serv_config.has_option(SECTION, service_name):
cvalue = serv_config.get(SECTION, service_name)
if not cvalue:
# if service name is empty it's probably not a production instance,
# so we need to remove it from database
account.unlink()
raise UserError(
_("Service name %s is empty in " "server_environment_file")
% (service_name,)
)
if cvalue != account.account_token:
# we write in db on first access;
# should we have preloaded values in database at,
# server startup, modules loading their parameters
# from data files would break on unique key error.
account.account_token = cvalue
return account
def _server_env_global_section_name(self):
"""Name of the global section in the configuration files
@api.model
def create(self, vals):
service_name = vals.get("service_name")
if serv_config.has_option(SECTION, service_name):
# enforce account_token from config file
vals = dict(vals, account_token=serv_config.get(SECTION, service_name))
return super().create(vals)
def write(self, vals):
for rec in self:
service_name = vals.get("service_name") or rec.service_name
if serv_config.has_option(SECTION, service_name):
# enforce account_token from config file
newvals = dict(
vals, account_token=serv_config.get(SECTION, service_name)
)
else:
newvals = vals
super().write(newvals)
return True
Can be customized in your model
"""
return "iap_account"

View File

@ -1,16 +1,4 @@
To configure this module, you need to add a section ``[iap.account]`` to
you server_environment_files configurations, where the keys are service names
as would normally be set in the Technical / IAP Accounts Odoo menu.
When first using a value, the system will read it from the server environment file
and override any value that would be present in the database, so the server environment file has precedence.
When creating or modifying values that are in the server environment file, the
module replace changes, enforcing the configuration value.
For example you can use this module like that:
.. code::
[iap.account]
partner_autocomplete=secret_token
With this module installed, the IAP Accounts can be configured
in the `server_environment_files` module, or in the environment variable ``SERVER_ENV_CONFIG``
and/or ``SERVER_ENV_CONFIG_SECRET``. See the documentation of `server_environment` for
more information.

View File

@ -1,2 +0,0 @@
This module is maintained by:
* Odoo Community Association

View File

@ -1 +1,3 @@
Override IAP Accounts from the server environment file.
This module allows to configure the IAP Accounts
using the `server_environment` mechanism: you can then have different
IAP Accounts for the production and the test environment.

View File

@ -1,2 +1,2 @@
It would be nice to set IAP Accounts in the server environment file, possibly make their key and value
readonly in the user interface and remove them from database except production.
* Due to the special nature of this addon, you cannot test it on the OCA
runbot.

View File

@ -1,2 +0,0 @@
Before using this module, you must be familiar with the
server_environment module.

View File

@ -1,5 +1,6 @@
<odoo>
<record model="iap.account" id="some_record_id">
<field name="tech_name">account_xml</field>
<field name="service_name">iap_from_config</field>
<field name="account_token">value_from_xml</field>
</record>

View File

@ -1,28 +1,30 @@
# Copyright 2016-2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import psycopg2
from odoo.exceptions import UserError
from odoo.modules.module import get_resource_path
from odoo.tests import tagged
from odoo.tests.common import Form
from odoo.tools import convert_file
from odoo.tools.misc import mute_logger
from odoo.addons.server_environment.tests.common import ServerEnvironmentCase
from ..models import iap_account
@tagged("post_install", "-at_install")
class TestEnv(ServerEnvironmentCase):
def setUp(self):
super().setUp()
self.IAP = self.env["iap.account"]
self.env_config = (
"[iap.account]\n" "iap_from_config=config_value\n" "iap_empty=\n"
"[iap_account.account_1]\n"
"service_name=partner_autocomplete_1\n"
"account_token=my_secret_token_1\n"
"[iap_account.account_2]\n"
"service_name=partner_autocomplete_2\n"
"account_token=my_secret_token_2\n"
"[iap_account.account_xml]\n"
"service_name=partner_autocomplete_xml\n"
"account_token=my_secret_token_xml\n"
)
self.service_name = "iap_from_config"
self.account_token = "config_value"
self.some_service = "some.service"
self.some_token = "some.token"
def _load_xml(self, module, filepath):
convert_file(
@ -35,67 +37,51 @@ class TestEnv(ServerEnvironmentCase):
kind="test",
)
def _search_account(self, service, token):
return self.IAP.search(
[("service_name", "=", service), ("account_token", "=", token)]
)
def test_empty(self):
"""Empty config values cause error"""
with self.load_config(public=self.env_config, serv_config_class=iap_account):
with self.assertRaises(UserError):
self.IAP.get("iap_empty")
iap_nonexistant = self.IAP.get("iap_nonexistant")
self.assertTrue(iap_nonexistant.account_token)
def test_get_account(self):
def test_create_account_from_config(self):
"""Get account data from config"""
with self.load_config(public=self.env_config, serv_config_class=iap_account):
# it's not in db
res = self._search_account(self.service_name, self.account_token)
self.assertFalse(res)
# read so it's created in db
account = self.IAP.get("iap_from_config")
self.assertEqual(account.account_token, "config_value")
self.assertEqual(len(account), 1)
with self.load_config(public=self.env_config):
account = self.IAP.create({"tech_name": "account_1"})
self.assertEqual(account.service_name, "partner_autocomplete_1")
self.assertEqual(account.account_token, "my_secret_token_1")
# `tech_name` must be unique
with self.assertRaises(psycopg2.IntegrityError):
with mute_logger("odoo.sql_db"), self.cr.savepoint():
self.IAP.create({"tech_name": "account_1"})
def test_override_xmldata(self):
with self.load_config(public=self.env_config, serv_config_class=iap_account):
self._load_xml("server_environment_iap", "tests/config_iap_test.xml")
self.assertEqual(
self.IAP.get("iap_from_config").account_token, "config_value"
def test_create_account_not_in_config(self):
"""We can set account data that is not in config file"""
with self.load_config(public=self.env_config):
account = self.IAP.create(
{
"tech_name": "account_4",
"service_name": "new_partner_autocomplete",
"account_token": "my_new_secret_token",
}
)
self.assertEqual(account.service_name, "new_partner_autocomplete")
self.assertEqual(account.account_token, "my_new_secret_token")
def test_set_param_1(self):
# TODO: should it be overriden on xml import?
# def test_override_xmldata(self):
# with self.load_config(public=self.env_config):
# self._load_xml("server_environment_iap", "tests/config_iap_test.xml")
# account = self.IAP.search([("tech_name", "=", "account_xml")])
# self.assertEqual(account.service_name, "partner_autocomplete_xml")
# self.assertEqual(account.account_token, "my_secret_token_xml")
def test_update_account_data(self):
"""We can't set account data that is in config file"""
with self.load_config(public=self.env_config, serv_config_class=iap_account):
with self.load_config(public=self.env_config):
# when creating, the value is overridden by config file
self.IAP.create(
{"service_name": "iap_from_config", "account_token": "new_value"}
account = self.IAP.create(
{
"tech_name": "account_2",
}
)
acc = self.IAP.get("iap_from_config")
self.assertEqual(acc.account_token, "config_value")
# when writing, the value is overridden by config file
res = self._search_account(self.service_name, self.account_token)
self.assertEqual(len(res), 1)
res.write({"account_token": "new_value"})
acc = self.IAP.get("iap_from_config")
self.assertEqual(acc.account_token, "config_value")
# unlink works normally...
res = self._search_account(self.service_name, self.account_token)
self.assertEqual(len(res), 1)
res.unlink()
res = self._search_account(self.service_name, self.account_token)
self.assertEqual(len(res), 0)
# but the value is recreated when getting param again
acc = self.IAP.get("iap_from_config")
self.assertEqual(acc.account_token, "config_value")
self.assertEqual(len(acc), 1)
def test_set_param_2(self):
"""We can set parameters that are not in config file"""
with self.load_config(public=self.env_config, serv_config_class=iap_account):
self.IAP.create(
{"service_name": "some.service", "account_token": "some.token"}
)
self.assertEqual(self.IAP.get("some.service").account_token, "some.token")
account_form = Form(account)
self.assertEqual(account.service_name, "partner_autocomplete_2")
self.assertEqual(account.account_token, "my_secret_token_2")
with self.assertRaises(AssertionError):
account_form.service_name = "new_partner_autocomplete"
with self.assertRaises(AssertionError):
account_form.account_token = "my_new_secret_token"

View File

@ -1,34 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="iap_account_view_form" model="ir.ui.view">
<field name="name">iap.account.form.inherit</field>
<field name="model">iap.account</field>
<field name="inherit_id" ref="iap.iap_account_view_form" />
<field name="groups_id" eval="[(4, ref('base.group_system'))]" />
<field name="arch" type="xml">
<field name="account_token" position="after">
<field name="is_environment" />
</field>
<field name="service_name" position="attributes">
<attribute
name="attrs"
>{'readonly': [('is_environment', '=', True)]}</attribute>
</field>
<field name="account_token" position="attributes">
<attribute
name="attrs"
>{'readonly': [('is_environment', '=', True)]}</attribute>
<field name="service_name" position="before">
<field name="tech_name" groups="base.group_no_one" />
</field>
</field>
</record>
<record id="iap_account_view_tree" model="ir.ui.view">
<field name="name">iap.account.tree.inherit</field>
<field name="model">iap.account</field>
<field name="inherit_id" ref="iap.iap_account_view_tree" />
<field name="groups_id" eval="[(4, ref('base.group_system'))]" />
<field name="arch" type="xml">
<field name="account_token" position="after">
<field name="is_environment" />
<field name="service_name" position="before">
<field name="tech_name" groups="base.group_no_one" />
</field>
</field>
</record>
</odoo>