diff --git a/auth_dynamic_groups/README.md b/auth_dynamic_groups/README.md new file mode 100644 index 000000000..82e765cba --- /dev/null +++ b/auth_dynamic_groups/README.md @@ -0,0 +1,15 @@ +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. 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..4becc6cd5 --- /dev/null +++ b/auth_dynamic_groups/model/res_groups.py @@ -0,0 +1,77 @@ +# -*- 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 . +# +############################################################################## +import logging +from openerp.osv.orm import Model +from openerp.osv import fields +from openerp.tools.safe_eval import safe_eval +from openerp import SUPERUSER_ID + + +class res_groups(Model): + _inherit = 'res.groups' + + _columns = { + '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') + } + + def eval_dynamic_group_condition(self, cr, uid, ids, context=None): + result = True + user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, + context=context) + for this in self.browse(cr, uid, ids, context=context): + result &= bool( + safe_eval( + this.dynamic_group_condition, + { + 'user': user, + 'any': any, + 'all': all, + 'filter': filter, + })) + return result + + def _check_dynamic_group_condition(self, cr, uid, ids, context=None): + try: + for this in self.browse(cr, uid, ids, context=context): + if this.is_dynamic: + this.eval_dynamic_group_condition() + except (NameError, SyntaxError, TypeError) as e: + logging.info(e) + return False + return True + + _constraints = [ + (_check_dynamic_group_condition, + 'The condition doesn\'t evaluate correctly!', + ['dynamic_group_condition']), + ] + + def action_evaluate(self, cr, uid, ids, context=None): + user_obj = self.pool.get('res.users') + for user in user_obj.browse( + cr, uid, + user_obj.search(cr, uid, [], context=context), + context=context): + user_obj.update_dynamic_groups(user.id, 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..fa6381167 --- /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, uid, + groups_obj.search(cr, uid, + [('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..fdc2be61d --- /dev/null +++ b/auth_dynamic_groups/view/res_groups.xml @@ -0,0 +1,30 @@ + + + + + form + res.groups + + + + + + + {'readonly': [('is_dynamic', '=', True)]} + + + +