diff --git a/auth_dynamic_groups/README.rst b/auth_dynamic_groups/README.rst new file mode 100644 index 000000000..051e80c0e --- /dev/null +++ b/auth_dynamic_groups/README.rst @@ -0,0 +1,30 @@ +Description +----------- +This module allows defining groups whose membership is a condition expressed as +python code. For every user, it is evaluated during login if she belongs to +the group or not. + +Usage +----- +Check `Dynamic` on a group you want to be dynamic. Now fill in the condition, +using `user` which is a browse record of the user in question that evaluates +truthy if the user is supposed to be a member of the group and falsy if not. + +There is a constraint on the field to check for validity if this expression. +When you're satisfied, click the button `Evaluate` to prefill the group's +members. The condition will be checked now for every user who logs in. + +Example +------- +We have a group called `Amsterdam` and want it to contain all users from +city of Amsterdam. So we use the membership condition + +``` +user.partner_id.city == 'Amsterdam' +``` + +Now we can be sure every user living in this city is in the right group, and we +can start assigning local menus to it, adjust permissions, etc. Keep in mind +that view overrides can also be restricted by a group id, this gives a lot of +possibilities to dynamically adapt views based on arbitrary properties +reachable via the user record. diff --git a/auth_dynamic_groups/__init__.py b/auth_dynamic_groups/__init__.py new file mode 100644 index 000000000..9da2ac3b6 --- /dev/null +++ b/auth_dynamic_groups/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from . import model diff --git a/auth_dynamic_groups/__openerp__.py b/auth_dynamic_groups/__openerp__.py new file mode 100644 index 000000000..f4c5bd555 --- /dev/null +++ b/auth_dynamic_groups/__openerp__.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013-2015 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{ + "name": "Dynamic groups", + "version": "1.0", + "author": "Therp BV", + "complexity": "normal", + 'summary': 'Have membership conditions for certain groups', + "category": "Tools", + "depends": [ + 'base', + ], + "data": [ + 'view/res_groups.xml', + ], + "auto_install": False, + "installable": True, + "external_dependencies": { + 'python': [], + }, +} diff --git a/auth_dynamic_groups/model/__init__.py b/auth_dynamic_groups/model/__init__.py new file mode 100644 index 000000000..ad311212d --- /dev/null +++ b/auth_dynamic_groups/model/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from . import res_users +from . import res_groups diff --git a/auth_dynamic_groups/model/res_groups.py b/auth_dynamic_groups/model/res_groups.py new file mode 100644 index 000000000..7acb8fb4e --- /dev/null +++ b/auth_dynamic_groups/model/res_groups.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from openerp import models, fields, api, exceptions +from openerp.tools.safe_eval import safe_eval +from openerp import _ + + +class res_groups(models.Model): + _inherit = 'res.groups' + + is_dynamic = fields.Boolean('Dynamic') + dynamic_group_condition = fields.Text( + 'Condition', help='The condition to be met for a user to be a ' + 'member of this group. It is evaluated as python code at login ' + 'time, you get `user` passed as a browse record') + + @api.multi + def eval_dynamic_group_condition(self): + result = all( + self.mapped( + lambda this: safe_eval( + this.dynamic_group_condition, + { + 'user': self.env.user, + 'any': any, + 'all': all, + 'filter': filter, + }))) + return result + + @api.multi + @api.constrains('dynamic_group_condition') + def _check_dynamic_group_condition(self): + try: + self.filtered('is_dynamic').eval_dynamic_group_condition() + except (NameError, SyntaxError, TypeError): + raise exceptions.ValidationError( + _('The condition doesn\'t evaluate correctly!')) + + @api.multi + def action_evaluate(self): + res_users = self.env['res.users'] + for user in res_users.search([]): + res_users.update_dynamic_groups(user.id, self.env.cr.dbname) diff --git a/auth_dynamic_groups/model/res_users.py b/auth_dynamic_groups/model/res_users.py new file mode 100644 index 000000000..bb875e152 --- /dev/null +++ b/auth_dynamic_groups/model/res_users.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from openerp.models import Model +from openerp.modules.registry import RegistryManager +from openerp import SUPERUSER_ID + + +class res_users(Model): + _inherit = 'res.users' + + def _login(self, db, login, password): + uid = super(res_users, self)._login(db, login, password) + + if uid: + self.update_dynamic_groups(uid, db) + + return uid + + def update_dynamic_groups(self, uid, db): + pool = RegistryManager.get(db) + cr = pool._db.cursor() + user = pool.get('res.users').browse(cr, SUPERUSER_ID, uid) + groups_obj = pool.get('res.groups') + user.write( + { + 'groups_id': [ + (4, dynamic_group.id) + if dynamic_group.eval_dynamic_group_condition() + else (3, dynamic_group.id) + for dynamic_group in groups_obj.browse( + cr, SUPERUSER_ID, + groups_obj.search(cr, SUPERUSER_ID, + [('is_dynamic', '=', True)])) + ], + }) + cr.commit() + cr.close() diff --git a/auth_dynamic_groups/view/res_groups.xml b/auth_dynamic_groups/view/res_groups.xml new file mode 100644 index 000000000..2a8f54de4 --- /dev/null +++ b/auth_dynamic_groups/view/res_groups.xml @@ -0,0 +1,32 @@ + + + + + form + res.groups + + + + + + + {'readonly': [('is_dynamic', '=', True)]} + + + + +