changeset 23bf5dcbb12e in trytond:default details: https://hg.tryton.org/trytond?cmd=changeset;node=23bf5dcbb12e description: Add permission groups on export
By default an export is only available for his creator and administrators. We add a list of groups that are allowed to read and a second subset of groups that are allowed to modify it. issue8695 review252331002 diffstat: CHANGELOG | 1 + trytond/ir/__init__.py | 6 +- trytond/ir/export.py | 24 ++++++- trytond/ir/view/export_list.xml | 1 + trytond/res/__init__.py | 29 ++++---- trytond/res/ir.py | 44 +++++++++++-- trytond/res/ir.xml | 126 +++++++++++++++++++++++++++++++++++++++ trytond/res/view/export_form.xml | 9 ++ trytond/res/view/export_list.xml | 9 ++ 9 files changed, 221 insertions(+), 28 deletions(-) diffs (346 lines): diff -r e9e944b2f249 -r 23bf5dcbb12e CHANGELOG --- a/CHANGELOG Tue Oct 08 19:06:18 2019 +0200 +++ b/CHANGELOG Mon Oct 14 00:09:32 2019 +0200 @@ -1,3 +1,4 @@ +* Add permission groups on export * Retry cron job on DatabaseOperationalError * Add visual context on tree view * Add start value to PYSON Date and DateTime diff -r e9e944b2f249 -r 23bf5dcbb12e trytond/ir/__init__.py --- a/trytond/ir/__init__.py Tue Oct 08 19:06:18 2019 +0200 +++ b/trytond/ir/__init__.py Mon Oct 14 00:09:32 2019 +0200 @@ -13,7 +13,7 @@ from .note import * from .cron import * from .lang import * -from .export import * +from . import export from .rule import * from .module import * from .cache import * @@ -73,8 +73,8 @@ NoteRead, Cron, Lang, - Export, - ExportLine, + export.Export, + export.ExportLine, RuleGroup, Rule, Module, diff -r e9e944b2f249 -r 23bf5dcbb12e trytond/ir/export.py --- a/trytond/ir/export.py Tue Oct 08 19:06:18 2019 +0200 +++ b/trytond/ir/export.py Mon Oct 14 00:09:32 2019 +0200 @@ -2,10 +2,8 @@ # this repository contains the full copyright notices and license terms. "Exports" from ..model import ModelView, ModelSQL, fields - -__all__ = [ - 'Export', 'ExportLine', - ] +from trytond.pool import Pool +from trytond.rpc import RPC class _ClearCache(ModelSQL): @@ -33,6 +31,24 @@ export_fields = fields.One2Many('ir.export.line', 'export', 'Fields') + @classmethod + def __setup__(cls): + super().__setup__() + cls.__rpc__.update( + update=RPC(instantiate=0, readonly=False)) + + @classmethod + def update(cls, exports, fields): + pool = Pool() + Line = pool.get('ir.export.line') + to_delete = [] + to_save = [] + for export in exports: + to_delete.extend(export.export_fields) + to_save.extend(Line(export=export, name=f) for f in fields) + Line.delete(to_delete) + Line.save(to_save) + class ExportLine(_ClearCache, ModelSQL, ModelView): "Export line" diff -r e9e944b2f249 -r 23bf5dcbb12e trytond/ir/view/export_list.xml --- a/trytond/ir/view/export_list.xml Tue Oct 08 19:06:18 2019 +0200 +++ b/trytond/ir/view/export_list.xml Mon Oct 14 00:09:32 2019 +0200 @@ -4,4 +4,5 @@ <tree> <field name="name" expand="1"/> <field name="resource" expand="1"/> + <field name="create_uid"/> </tree> diff -r e9e944b2f249 -r 23bf5dcbb12e trytond/res/__init__.py --- a/trytond/res/__init__.py Tue Oct 08 19:06:18 2019 +0200 +++ b/trytond/res/__init__.py Mon Oct 14 00:09:32 2019 +0200 @@ -4,7 +4,7 @@ from .group import * from .user import * -from .ir import * +from . import ir from . import routes __all__ = ['register', 'routes'] @@ -20,18 +20,21 @@ Warning_, UserApplication, UserConfigStart, - UIMenuGroup, - ActionGroup, - ModelButtonGroup, - ModelButtonRule, - ModelButtonClick, - RuleGroupGroup, - Lang, - SequenceType, - SequenceTypeGroup, - Sequence, - SequenceStrict, - ModuleConfigWizardItem, + ir.UIMenuGroup, + ir.ActionGroup, + ir.ModelButtonGroup, + ir.ModelButtonRule, + ir.ModelButtonClick, + ir.RuleGroupGroup, + ir.Lang, + ir.SequenceType, + ir.SequenceTypeGroup, + ir.Sequence, + ir.SequenceStrict, + ir.ModuleConfigWizardItem, + ir.Export, + ir.Export_Group, + ir.Export_Write_Group, module='res', type_='model') Pool.register( UserConfig, diff -r e9e944b2f249 -r 23bf5dcbb12e trytond/res/ir.py --- a/trytond/res/ir.py Tue Oct 08 19:06:18 2019 +0200 +++ b/trytond/res/ir.py Mon Oct 14 00:09:32 2019 +0200 @@ -2,14 +2,7 @@ # this repository contains the full copyright notices and license terms. from ..model import ModelSQL, DeactivableMixin, fields from ..pool import Pool, PoolMeta - -__all__ = [ - 'UIMenuGroup', 'ActionGroup', 'ModelButtonGroup', - 'ModelButtonRule', 'ModelButtonClick', - 'RuleGroupGroup', 'Lang', 'SequenceType', - 'SequenceTypeGroup', 'Sequence', 'SequenceStrict', - 'ModuleConfigWizardItem', - ] +from trytond.pyson import Eval class UIMenuGroup(ModelSQL): @@ -244,3 +237,38 @@ super(ModuleConfigWizardItem, cls).delete(items) # Restart the cache for get_preferences User._get_preferences_cache.clear() + + +class Export(metaclass=PoolMeta): + __name__ = 'ir.export' + + groups = fields.Many2Many( + 'ir.export-res.group', 'export', 'group', "Groups", + help="The user groups that can use the export.") + write_groups = fields.Many2Many( + 'ir.export-write-res.group', 'export', 'group', + "Modification Groups", + domain=[ + ('id', 'in', Eval('groups', [])), + ], + states={ + 'invisible': ~Eval('groups'), + }, + depends=['groups'], + help="The user groups that can modify the export.") + + +class Export_Group(ModelSQL): + "Export Group" + __name__ = 'ir.export-res.group' + + export = fields.Many2One( + 'ir.export', "Export", required=True, select=True, ondelete='CASCADE') + group = fields.Many2One( + 'res.group', "Group", required=True, ondelete='CASCADE') + + +class Export_Write_Group(Export_Group): + "Export Modification Group" + __name__ = 'ir.export-write-res.group' + _table = None # Needed to reset Export_Group._table diff -r e9e944b2f249 -r 23bf5dcbb12e trytond/res/ir.xml --- a/trytond/res/ir.xml Tue Oct 08 19:06:18 2019 +0200 +++ b/trytond/res/ir.xml Mon Oct 14 00:09:32 2019 +0200 @@ -904,5 +904,131 @@ <field name="perm_delete" eval="True"/> </record> + <record model="ir.ui.view" id="export_view_form"> + <field name="model">ir.export</field> + <field name="inherit" ref="ir.export_view_form"/> + <field name="name">export_form</field> + </record> + + <record model="ir.ui.view" id="export_view_list"> + <field name="model">ir.export</field> + <field name="inherit" ref="ir.export_view_tree"/> + <field name="name">export_list</field> + </record> + + <record model="ir.rule.group" id="rule_group_export_read"> + <field name="name">User in groups</field> + <field name="model" search="[('model', '=', 'ir.export')]"/> + <field name="global_p" eval="False"/> + <field name="default_p" eval="True"/> + <field name="perm_read" eval="True"/> + <field name="perm_write" eval="False"/> + <field name="perm_create" eval="False"/> + <field name="perm_delete" eval="False"/> + </record> + <record model="ir.rule" id="rule_group_export_read1"> + <field name="domain" eval="[('groups', 'in', Eval('user.groups', []))]" pyson="1"/> + <field name="rule_group" ref="rule_group_export_read"/> + </record> + <record model="ir.rule" id="rule_group_export_read2"> + <field name="domain" eval="[('create_uid', '=', Eval('user.id', -1))]" pyson="1"/> + <field name="rule_group" ref="rule_group_export_read"/> + </record> + + <record model="ir.rule.group" id="rule_group_export_write"> + <field name="name">User in modification groups</field> + <field name="model" search="[('model', '=', 'ir.export')]"/> + <field name="global_p" eval="False"/> + <field name="default_p" eval="True"/> + <field name="perm_read" eval="True"/> + <field name="perm_write" eval="True"/> + <field name="perm_create" eval="True"/> + <field name="perm_delete" eval="True"/> + </record> + <record model="ir.rule" id="rule_group_export_write1"> + <field name="domain" eval="[('write_groups', 'in', Eval('user.groups', []))]" pyson="1"/> + <field name="rule_group" ref="rule_group_export_write"/> + </record> + <record model="ir.rule" id="rule_group_export_write2"> + <field name="domain" eval="[('create_uid', '=', Eval('user.id', -1))]" pyson="1"/> + <field name="rule_group" ref="rule_group_export_write"/> + </record> + + <record model="ir.rule.group" id="rule_group_export_any"> + <field name="name">Any export</field> + <field name="model" search="[('model', '=', 'ir.export')]"/> + <field name="global_p" eval="False"/> + <field name="default_p" eval="False"/> + <field name="perm_read" eval="True"/> + <field name="perm_write" eval="True"/> + <field name="perm_create" eval="True"/> + <field name="perm_delete" eval="True"/> + </record> + <record model="ir.rule" id="rule_group_export_any1"> + <field name="domain" eval="[]" pyson="1"/> + <field name="rule_group" ref="rule_group_export_any"/> + </record> + <record model="ir.rule.group-res.group" id="rule_group_export_any_admin"> + <field name="rule_group" ref="rule_group_export_any"/> + <field name="group" ref="group_admin"/> + </record> + + <record model="ir.rule.group" id="rule_group_export_line_read"> + <field name="name">User in groups</field> + <field name="model" search="[('model', '=', 'ir.export.line')]"/> + <field name="global_p" eval="False"/> + <field name="default_p" eval="True"/> + <field name="perm_read" eval="True"/> + <field name="perm_write" eval="False"/> + <field name="perm_create" eval="False"/> + <field name="perm_delete" eval="False"/> + </record> + <record model="ir.rule" id="rule_group_export_line_read1"> + <field name="domain" eval="[('export.groups', 'in', Eval('user.groups', []))]" pyson="1"/> + <field name="rule_group" ref="rule_group_export_line_read"/> + </record> + <record model="ir.rule" id="rule_group_export_line_read2"> + <field name="domain" eval="[('export.create_uid', '=', Eval('user.id', -1))]" pyson="1"/> + <field name="rule_group" ref="rule_group_export_line_read"/> + </record> + + <record model="ir.rule.group" id="rule_group_export_line_write"> + <field name="name">User in modification groups</field> + <field name="model" search="[('model', '=', 'ir.export.line')]"/> + <field name="global_p" eval="False"/> + <field name="default_p" eval="True"/> + <field name="perm_read" eval="True"/> + <field name="perm_write" eval="True"/> + <field name="perm_create" eval="True"/> + <field name="perm_delete" eval="True"/> + </record> + <record model="ir.rule" id="rule_group_export_line_write1"> + <field name="domain" eval="[('export.write_groups', 'in', Eval('user.groups', []))]" pyson="1"/> + <field name="rule_group" ref="rule_group_export_line_write"/> + </record> + <record model="ir.rule" id="rule_group_export_line_write2"> + <field name="domain" eval="[('export.create_uid', '=', Eval('user.id', -1))]" pyson="1"/> + <field name="rule_group" ref="rule_group_export_line_write"/> + </record> + + <record model="ir.rule.group" id="rule_group_export_line_any"> + <field name="name">Any export</field> + <field name="model" search="[('model', '=', 'ir.export.line')]"/> + <field name="global_p" eval="False"/> + <field name="default_p" eval="False"/> + <field name="perm_read" eval="True"/> + <field name="perm_write" eval="True"/> + <field name="perm_create" eval="True"/> + <field name="perm_delete" eval="True"/> + </record> + <record model="ir.rule" id="rule_group_export_line_any1"> + <field name="domain" eval="[]" pyson="1"/> + <field name="rule_group" ref="rule_group_export_line_any"/> + </record> + <record model="ir.rule.group-res.group" id="rule_group_export_line_any_admin"> + <field name="rule_group" ref="rule_group_export_line_any"/> + <field name="group" ref="group_admin"/> + </record> + </data> </tryton> diff -r e9e944b2f249 -r 23bf5dcbb12e trytond/res/view/export_form.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/res/view/export_form.xml Mon Oct 14 00:09:32 2019 +0200 @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<!-- This file is part of Tryton. The COPYRIGHT file at the top level of +this repository contains the full copyright notices and license terms. --> +<data> + <xpath expr="//field[@name='export_fields']" position="after"> + <field name="groups" colspan="4"/> + <field name="write_groups" colspan="4"/> + </xpath> +</data> diff -r e9e944b2f249 -r 23bf5dcbb12e trytond/res/view/export_list.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/res/view/export_list.xml Mon Oct 14 00:09:32 2019 +0200 @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<!-- This file is part of Tryton. The COPYRIGHT file at the top level of +this repository contains the full copyright notices and license terms. --> +<data> + <xpath expr="//field[@name='create_uid']" position="after"> + <field name="groups"/> + <field name="write_groups"/> + </xpath> +</data>