From 88117959b5e8c5e02e9e3c8c5a21691e0e78cf53 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 13 Oct 2010 23:53:40 +0200 Subject: [PATCH] [REM] base, workflow: removed res.roles object, replaced by dedicated res.groups bzr revid: odo@openerp.com-20101013215340-jaiihef9chsym48z --- bin/addons/base/base.sql | 16 +---- bin/addons/base/base_update.xml | 5 +- bin/addons/base/ir/ir.xml | 64 +------------------ bin/addons/base/ir/ir_model.py | 2 +- bin/addons/base/ir/workflow/workflow.py | 4 +- bin/addons/base/ir/workflow/workflow_view.xml | 2 +- bin/addons/base/res/res_user.py | 27 -------- bin/addons/base/security/ir.model.access.csv | 2 - bin/osv/orm.py | 54 ++++++---------- bin/workflow/wkf_expr.py | 16 ++--- 10 files changed, 35 insertions(+), 157 deletions(-) diff --git a/bin/addons/base/base.sql b/bin/addons/base/base.sql index eb9eb5b9d75..ad9deada1f3 100644 --- a/bin/addons/base/base.sql +++ b/bin/addons/base/base.sql @@ -159,20 +159,6 @@ CREATE TABLE res_groups ( primary key(id) ); -create table res_roles ( - id serial NOT NULL, - parent_id int references res_roles on delete set null, - name varchar(64) NOT NULL, - primary key(id) -); - -CREATE TABLE res_roles_users_rel ( - uid integer NOT NULL references res_users on delete cascade, - rid integer NOT NULL references res_roles on delete cascade -); -create index res_roles_users_rel_uid_idx on res_roles_users_rel (uid); -create index res_roles_users_rel_rid_idx on res_roles_users_rel (rid); - CREATE TABLE res_groups_users_rel ( uid integer NOT NULL references res_users on delete cascade, gid integer NOT NULL references res_groups on delete cascade @@ -222,7 +208,7 @@ create table wkf_transition trigger_expr_id varchar(128) default NULL, signal varchar(64) default null, - role_id int references res_roles on delete set null, + group_id int references res_groups on delete set null, primary key(id) ); diff --git a/bin/addons/base/base_update.xml b/bin/addons/base/base_update.xml index a397b39cba2..0cf6eae845e 100644 --- a/bin/addons/base/base_update.xml +++ b/bin/addons/base/base_update.xml @@ -144,13 +144,10 @@ - + - - - diff --git a/bin/addons/base/ir/ir.xml b/bin/addons/base/ir/ir.xml index 5821e3cafdb..1f815ed1604 100644 --- a/bin/addons/base/ir/ir.xml +++ b/bin/addons/base/ir/ir.xml @@ -708,7 +708,7 @@ - + Users ir.actions.act_window @@ -761,68 +761,6 @@ - - res.roles.form - res.roles - form - -
- - - - - - - - - - - - - - - - -
- - res.roles.tree - res.roles - tree - child_id - - - - - - - - - - res.roles.search - res.roles - search - - - - - - - - - - - - - - - Roles - ir.actions.act_window - res.roles - form - - - - ir.ui.view diff --git a/bin/addons/base/ir/ir_model.py b/bin/addons/base/ir/ir_model.py index b87e8bc9801..e6b4a2da98f 100644 --- a/bin/addons/base/ir/ir_model.py +++ b/bin/addons/base/ir/ir_model.py @@ -554,7 +554,7 @@ class ir_model_data(osv.osv): if model=='workflow.activity': cr.execute('select res_type,res_id from wkf_instance where id IN (select inst_id from wkf_workitem where act_id=%s)', (res_id,)) wkf_todo.extend(cr.fetchall()) - cr.execute("update wkf_transition set condition='True', role_id=NULL, signal=NULL,act_to=act_from,act_from=%s where act_to=%s", (res_id,res_id)) + cr.execute("update wkf_transition set condition='True', group_id=NULL, signal=NULL,act_to=act_from,act_from=%s where act_to=%s", (res_id,res_id)) cr.execute("delete from wkf_transition where act_to=%s", (res_id,)) for model,id in wkf_todo: diff --git a/bin/addons/base/ir/workflow/workflow.py b/bin/addons/base/ir/workflow/workflow.py index 30fd666c03e..4815c482ae4 100644 --- a/bin/addons/base/ir/workflow/workflow.py +++ b/bin/addons/base/ir/workflow/workflow.py @@ -149,8 +149,8 @@ class wkf_transition(osv.osv): 'signal': fields.char('Signal (button Name)', size=64, help="When the operation of transition comes from a button pressed in the client form, "\ "signal tests the name of the pressed button. If signal is NULL, no button is necessary to validate this transition."), - 'role_id': fields.many2one('res.roles', 'Role Required', - help="The role that a user must have to validate this transition."), + 'group_id': fields.many2one('res.groups', 'Group Required', + help="The group that a user must have to be authorized to validate this transition."), 'condition': fields.char('Condition', required=True, size=128, help="Expression to be satisfied if we want the transition done."), 'act_from': fields.many2one('workflow.activity', 'Source Activity', required=True, select=True, ondelete='cascade', diff --git a/bin/addons/base/ir/workflow/workflow_view.xml b/bin/addons/base/ir/workflow/workflow_view.xml index b4e9b0daf46..a207eea52ab 100644 --- a/bin/addons/base/ir/workflow/workflow_view.xml +++ b/bin/addons/base/ir/workflow/workflow_view.xml @@ -217,7 +217,7 @@ - + diff --git a/bin/addons/base/res/res_user.py b/bin/addons/base/res/res_user.py index 10d4b0f9ce9..0ea344561f9 100644 --- a/bin/addons/base/res/res_user.py +++ b/bin/addons/base/res/res_user.py @@ -82,32 +82,6 @@ class groups(osv.osv): groups() -class roles(osv.osv): - _name = "res.roles" - _columns = { - 'name': fields.char('Role Name', size=64, required=True), - 'parent_id': fields.many2one('res.roles', 'Parent', select=True, - help="The parent role can be used to construct a hierarchy of roles. Parent roles inherit from the roles of their descendants."), - 'child_id': fields.one2many('res.roles', 'parent_id', 'Children'), - 'users': fields.many2many('res.users', 'res_roles_users_rel', 'rid', 'uid', 'Users'), - 'description': fields.text('Description', help="Description of this role and where it is relevant in workflows and processes"), - 'workflow_transition_ids': fields.one2many('workflow.transition', 'role_id', 'Workflow Transitions', - help="The workflow transitions associated with this role"), - } - def check(self, cr, uid, ids, role_id): - """Verifies that the role with id ``role_id`` is granted directly or indirectly to a - user that possesses the roles with ids ``ids``. Indirectly means that one of the - roles with id in ``ids`` is an ancestor role of the role with id ``role_id``. - """ - if role_id in ids: - return True - cr.execute('select parent_id from res_roles where id=%s', (role_id,)) - roles = cr.fetchone()[0] - if roles: - return self.check(cr, uid, ids, roles) - return False -roles() - def _lang_get(self, cr, uid, context={}): obj = self.pool.get('res.lang') ids = obj.search(cr, uid, [('translatable','=',True)]) @@ -236,7 +210,6 @@ class users(osv.osv): 'action_id': fields.many2one('ir.actions.actions', 'Home Action', help="If specified, this action will be opened at logon for this user, in addition to the standard menu."), 'menu_id': fields.many2one('ir.actions.actions', 'Menu Action', help="If specified, the action will replace the standard menu for this user."), 'groups_id': fields.many2many('res.groups', 'res_groups_users_rel', 'uid', 'gid', 'Groups'), - 'roles_id': fields.many2many('res.roles', 'res_roles_users_rel', 'uid', 'rid', 'Roles'), # Special behavior for this field: res.company.search() will only return the companies # available to the current user (should be the user's companies?), when the user_preference diff --git a/bin/addons/base/security/ir.model.access.csv b/bin/addons/base/security/ir.model.access.csv index 96576dd945d..92b21dd96d1 100644 --- a/bin/addons/base/security/ir.model.access.csv +++ b/bin/addons/base/security/ir.model.access.csv @@ -108,8 +108,6 @@ "access_ir_actions_server_group_system","ir_actions_server_group_system","model_ir_actions_server","group_system",1,1,1,1 "access_res_bank_group_system","res_bank_group_system","model_res_bank","group_system",1,1,1,1 "access_res_payterm_group_system","res_payterm_group_system","model_res_payterm","group_system",1,1,1,1 -"access_res_roles_group_erpmanager","res_roles_group_erp_manager","model_res_roles","group_erp_manager",1,1,1,1 -"access_res_roles_all","res_roles_all","model_res_roles",,1,0,0,0 "access_res_bank_group_partner_manager","res_bank_group_partner_manager","model_res_bank","group_partner_manager",1,1,1,1 "access_res_bank_user","res_bank user","model_res_bank","group_user",1,0,0,0 "access_maintenance_group_user","maintenance_contract group_user","model_maintenance_contract","group_system",1,1,1,1 diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 7e3529f9b6f..9f33379184c 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1365,47 +1365,33 @@ class orm_template(object): return fields - def __view_look_dom_arch(self, cr, user, node, view_id, context=None): - fields_def = self.__view_look_dom(cr, user, node, view_id, context=context) + def _disable_workflow_buttons(self, cr, user, node): + if user == 1: + # admin user can always activate workflow buttons + return node - rolesobj = self.pool.get('res.roles') + # TODO handle the case of more than one workflow for a model or multiple + # transitions with different groups and same signal usersobj = self.pool.get('res.users') - buttons = (n for n in node.getiterator('button') if n.get('type') != 'object') for button in buttons: - can_click = True - if user != 1: # admin user has all roles - user_roles = usersobj.read(cr, user, [user], ['roles_id'])[0]['roles_id'] - # TODO handle the case of more than one workflow for a model - cr.execute("""SELECT DISTINCT t.role_id - FROM wkf - INNER JOIN wkf_activity a ON a.wkf_id = wkf.id - INNER JOIN wkf_transition t ON (t.act_to = a.id) - WHERE wkf.osv = %s - AND t.signal = %s - """, (self._name, button.get('name'),)) - roles = cr.fetchall() - - # draft -> valid = signal_next (role X) - # draft -> cancel = signal_cancel (no role) - # - # valid -> running = signal_next (role Y) - # valid -> cancel = signal_cancel (role Z) - # - # running -> done = signal_next (role Z) - # running -> cancel = signal_cancel (role Z) - - # As we don't know the object state, in this scenario, - # the button "signal_cancel" will be always shown as there is no restriction to cancel in draft - # the button "signal_next" will be show if the user has any of the roles (X Y or Z) - # The verification will be made later in workflow process... - if roles: - can_click = any((not role) or rolesobj.check(cr, user, user_roles, role) for (role,) in roles) - + user_groups = usersobj.read(cr, user, [user], ['groups_id'])[0]['groups_id'] + cr.execute("""SELECT DISTINCT t.group_id + FROM wkf + INNER JOIN wkf_activity a ON a.wkf_id = wkf.id + INNER JOIN wkf_transition t ON (t.act_to = a.id) + WHERE wkf.osv = %s + AND t.signal = %s + """, (self._name, button.get('name'))) + group_ids = [x[0] for x in cr.fetchall()] + can_click = not group_ids or bool(set(user_groups).intersection(group_ids)) button.set('readonly', str(int(not can_click))) + return node + def __view_look_dom_arch(self, cr, user, node, view_id, context=None): + fields_def = self.__view_look_dom(cr, user, node, view_id, context=context) + node = self._disable_workflow_buttons(cr, user, node) arch = etree.tostring(node, encoding="utf-8").replace('\t', '') - fields = {} if node.tag == 'diagram': if node.getchildren()[0].tag == 'node': diff --git a/bin/workflow/wkf_expr.py b/bin/workflow/wkf_expr.py index 0150105c3ab..71a15a181f9 100644 --- a/bin/workflow/wkf_expr.py +++ b/bin/workflow/wkf_expr.py @@ -68,17 +68,17 @@ def execute(cr, ident, workitem, activity): return _eval_expr(cr, ident, workitem, activity['action']) def check(cr, workitem, ident, transition, signal): - ok = True - if transition['signal']: - ok = (signal==transition['signal']) + if transition['signal'] and signal != transition['signal']: + return False uid = ident[0] - if transition['role_id'] and uid != 1: + if transition['group_id'] and uid != 1: pool = pooler.get_pool(cr.dbname) - user_roles = pool.get('res.users').read(cr, uid, [uid], ['roles_id'])[0]['roles_id'] - ok = ok and pool.get('res.roles').check(cr, uid, user_roles, transition['role_id']) - ok = ok and _eval_expr(cr, ident, workitem, transition['condition']) - return ok + user_groups = pool.get('res.users').read(cr, uid, [uid], ['groups_id'])[0]['groups_id'] + if not transition['group_id'] in user_groups: + return False + + return _eval_expr(cr, ident, workitem, transition['condition']) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: