Base security added: Access denied for everyone, admin has access everywhere by design (no need to assign groups to admin user)
bzr revid: jbaubort@wichside-20080714135301-apglvmybfjjqk9fi
This commit is contained in:
parent
866234acb1
commit
13cbbe29ea
|
@ -35,6 +35,7 @@
|
|||
"depends" : [],
|
||||
"init_xml" : [
|
||||
"base_data.xml",
|
||||
"base_security.xml",
|
||||
"base_menu.xml",
|
||||
],
|
||||
"demo_xml" : [
|
||||
|
@ -47,6 +48,7 @@
|
|||
"ir/wizard/wizard_menu_view.xml",
|
||||
"ir/ir.xml",
|
||||
"ir/workflow/workflow_view.xml",
|
||||
"res/ir_property_view.xml",
|
||||
"module/module_data.xml",
|
||||
"module/module_wizard.xml",
|
||||
"module/module_view.xml",
|
||||
|
@ -56,13 +58,17 @@
|
|||
"res/partner/partner_report.xml",
|
||||
"res/partner/partner_view.xml",
|
||||
"res/partner/partner_wizard.xml",
|
||||
"res/partner/partner_data.xml",
|
||||
"res/partner/crm_view.xml",
|
||||
"res/bank_view.xml",
|
||||
"res/country_view.xml",
|
||||
"res/res_currency_view.xml",
|
||||
"res/partner/crm_view.xml",
|
||||
"res/partner/partner_data.xml",
|
||||
"res/ir_property_view.xml",
|
||||
"base_security.xml",
|
||||
"res/res_request_view.xml",
|
||||
"res/res_lang_view.xml",
|
||||
"module/module_data.xml",
|
||||
"module/module_wizard.xml",
|
||||
"module/module_view.xml",
|
||||
"module/module_report.xml",
|
||||
],
|
||||
"active": True,
|
||||
"installable": True,
|
||||
|
|
|
@ -156,9 +156,6 @@ CREATE TABLE res_users (
|
|||
);
|
||||
alter table res_users add constraint res_users_login_uniq unique (login);
|
||||
|
||||
insert into res_users (id,login,password,name,action_id,active) values (1,'root',NULL,'Root',NULL,False);
|
||||
select setval('res_users_id_seq', 2);
|
||||
|
||||
CREATE TABLE res_groups (
|
||||
id serial NOT NULL,
|
||||
name varchar(32) NOT NULL,
|
||||
|
@ -336,3 +333,10 @@ CREATE TABLE ir_model_data (
|
|||
res_id integer, primary key(id)
|
||||
);
|
||||
|
||||
---------------------------------
|
||||
-- Users
|
||||
---------------------------------
|
||||
insert into res_users (id,login,password,name,action_id,active) values (1,'root',NULL,'Root',NULL,False);
|
||||
insert into res_users (id,login,password,name,action_id,active) values (2,'admin','admin','Administrator',NULL,True);
|
||||
insert into ir_model_data (name,module,model,noupdate,res_id) values ('user_admin','base','res.users',True,2);
|
||||
select setval('res_users_id_seq', 3);
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -620,6 +620,7 @@
|
|||
<page string="Object">
|
||||
<field name="name" select="1"/>
|
||||
<field name="model" select="1"/>
|
||||
<field name="parent_id" select="1"/>
|
||||
<separator colspan="4" string="Fields"/>
|
||||
<field colspan="4" context="{'manual':True}" name="field_id" nolabel="1">
|
||||
<tree string="Fields Description">
|
||||
|
@ -672,6 +673,7 @@
|
|||
<tree string="Model Description">
|
||||
<field name="name"/>
|
||||
<field name="model"/>
|
||||
<field name="parent_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -1021,6 +1023,7 @@
|
|||
<field name="operand">user.company_id.id</field>
|
||||
<field name="rule_group" ref="property_rule_group"/>
|
||||
</record>
|
||||
|
||||
<record id="property_rule_bis" model="ir.rule">
|
||||
<field model="ir.model.fields" name="field_id" search="[('model', '=', 'ir.property'), ('name', '=', 'company_id')]"/>
|
||||
<field name="operator">=</field>
|
||||
|
@ -1028,6 +1031,60 @@
|
|||
<field name="rule_group" ref="property_rule_group2"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
===============
|
||||
Object Access
|
||||
===============
|
||||
-->
|
||||
<record id="view_model_form1" model="ir.ui.view">
|
||||
<field name="name">ir.model.form1</field>
|
||||
<field name="model">ir.model</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Model Description">
|
||||
<field name="name" select="1"/>
|
||||
<field name="model" select="1"/>
|
||||
<field name="parent_id" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_model_tree1" model="ir.ui.view">
|
||||
<field name="name">ir.model.tree1</field>
|
||||
<field name="model">ir.model</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Model Description">
|
||||
<field name="name"/>
|
||||
<field name="model"/>
|
||||
<field name="parent_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_model_sec">
|
||||
<field name="name">Objects</field>
|
||||
<field name="res_model">ir.model</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form,tree</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window.view" id="action_model_sec_tree">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="view_model_tree1"/>
|
||||
<field name="act_window_id" ref="action_model_sec" />
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window.view" id="action_model_sec_form">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_model_form1"/>
|
||||
<field name="act_window_id" ref="action_model_sec" />
|
||||
</record>
|
||||
|
||||
<menuitem action="action_model_sec" id="ir_model_model_menu1" parent="base.menu_security"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
||||
|
|
|
@ -49,6 +49,7 @@ class ir_model(osv.osv):
|
|||
'model': fields.char('Object Name', size=64, required=True, search=1),
|
||||
'info': fields.text('Information'),
|
||||
'field_id': fields.one2many('ir.model.fields', 'model_id', 'Fields', required=True),
|
||||
'parent_id': fields.many2one('ir.model', 'Parent id'),
|
||||
'state': fields.selection([('manual','Custom Object'),('base','Base Field')],'Manualy Created',readonly=1),
|
||||
}
|
||||
_defaults = {
|
||||
|
@ -65,9 +66,11 @@ class ir_model(osv.osv):
|
|||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_model_name, 'The model name must start with x_ and not contain any special character !', ['model']),
|
||||
]
|
||||
# FIXME: What it was for ?
|
||||
#_constraints = [
|
||||
# (_check_model_name, 'The model name must start with x_ and not contain any special character !', ['model']),
|
||||
#]
|
||||
|
||||
def unlink(self, cr, user, ids, context=None):
|
||||
for model in self.browse(cr, user, ids, context):
|
||||
if model.state <> 'manual':
|
||||
|
@ -96,6 +99,15 @@ class ir_model(osv.osv):
|
|||
x_custom_model._rec_name = x_custom_model._columns.keys()[0]
|
||||
ir_model()
|
||||
|
||||
class ir_model_tree(osv.osv):
|
||||
_name = 'ir.model.tree'
|
||||
_description = "Objects Tree"
|
||||
_columns = {
|
||||
'model_id': fields.many2one('ir.model', 'Model id', required=True),
|
||||
'parent_id': fields.many2one('ir.model', 'Parent id', required=True),
|
||||
}
|
||||
ir_model_tree()
|
||||
|
||||
class ir_model_fields(osv.osv):
|
||||
_name = 'ir.model.fields'
|
||||
_description = "Fields"
|
||||
|
@ -139,9 +151,6 @@ class ir_model_fields(osv.osv):
|
|||
for field in self.browse(cr, user, ids, context):
|
||||
if field.state <> 'manual':
|
||||
raise except_orm(_('Error'), _("You can not remove the field '%s' !") %(field.name,))
|
||||
#
|
||||
# MAY BE ADD A ALTER TABLE DROP ?
|
||||
#
|
||||
return super(ir_model_fields, self).unlink(cr, user, ids, context)
|
||||
|
||||
def create(self, cr, user, vals, context=None):
|
||||
|
@ -150,6 +159,7 @@ class ir_model_fields(osv.osv):
|
|||
vals['model']=model_data['model']
|
||||
if context and context.get('manual',False):
|
||||
vals['state']='manual'
|
||||
print vals['name']
|
||||
res = super(ir_model_fields,self).create(cr, user, vals, context)
|
||||
if vals.get('state','base')=='manual':
|
||||
if not vals['name'].startswith('x_'):
|
||||
|
@ -186,30 +196,44 @@ class ir_model_access(osv.osv):
|
|||
res = False
|
||||
return res
|
||||
|
||||
def check_tree(self, cr, uid, model_name, mode):
|
||||
cr.execute('SELECT MAX(CASE WHEN perm_'+mode+' THEN 1 else 0 END) '
|
||||
'from ir_model_access a join ir_model m on (m.id=a.model_id) '
|
||||
'join res_groups_users_rel gu on (gu.gid = a.group_id) '
|
||||
'where m.model = %s and gu.uid = %s', (model_name, uid,))
|
||||
res = cr.fetchall()[0][0]
|
||||
if res==None:
|
||||
cr.execute('select model from ir_model where id=(select parent_id from ir_model where model=%s)', (model_name,))
|
||||
parent_name = cr.fetchall()
|
||||
if len(parent_name)>0:
|
||||
res = self.check_tree(cr, uid, parent_name[0][0], mode) # Recursiv until there is no parent
|
||||
print '\tcheck %s = %s' % (parent_name[0][0], str(res))
|
||||
return res
|
||||
|
||||
def check(self, cr, uid, model_name, mode='read',raise_exception=True):
|
||||
assert mode in ['read','write','create','unlink'], 'Invalid access mode for security'
|
||||
if uid == 1:
|
||||
return True # TODO: check security: don't allow xml-rpc request with uid == 1
|
||||
|
||||
# We first check if a specific rule exists
|
||||
cr.execute('SELECT MAX(CASE WHEN perm_'+mode+' THEN 1 else 0 END) '
|
||||
'FROM ir_model_access a '
|
||||
'JOIN ir_model m '
|
||||
'ON (a.model_id=m.id) '
|
||||
'JOIN res_groups_users_rel gu '
|
||||
'ON (gu.gid = a.group_id) '
|
||||
'JOIN ir_model m ON (a.model_id=m.id) '
|
||||
'JOIN res_groups_users_rel gu ON (gu.gid = a.group_id) '
|
||||
'WHERE m.model = %s AND gu.uid = %s', (model_name, uid,))
|
||||
r = cr.fetchall()
|
||||
if r[0][0] == None:
|
||||
cr.execute('SELECT MAX(CASE WHEN perm_'+mode+' THEN 1 else 0 END) '
|
||||
'FROM ir_model_access a '
|
||||
'JOIN ir_model m '
|
||||
'ON (a.model_id = m.id) '
|
||||
'WHERE a.group_id IS NULL AND m.model = %s', (model_name,))
|
||||
r= cr.fetchall()
|
||||
if r[0][0] == None:
|
||||
return False # by default, the user had no access
|
||||
|
||||
if not r[0][0]:
|
||||
print '%s in %s = %s by %i'%(mode, model_name, str(r[0][0]), uid) # FIXME: REMOVE PLEASE
|
||||
|
||||
# Users root and admin have all access (Todo: exclude xml-rpc requests)
|
||||
if uid==1 or uid==2:
|
||||
return True
|
||||
|
||||
# Recursivly check parent if present
|
||||
if r[0][0] == None:
|
||||
res = self.check_tree(cr, uid, model_name, mode)
|
||||
else:
|
||||
res = r[0][0]
|
||||
|
||||
if not res:
|
||||
if raise_exception:
|
||||
msgs = {
|
||||
'read': _('You can not read this document! (%s)'),
|
||||
|
@ -217,14 +241,13 @@ class ir_model_access(osv.osv):
|
|||
'create': _('You can not create this kind of document! (%s)'),
|
||||
'unlink': _('You can not delete this document! (%s)'),
|
||||
}
|
||||
# due to the assert at the begin of the function, we will never have a KeyError
|
||||
raise except_orm(_('AccessError'), msgs[mode] % model_name )
|
||||
return r[0][0]
|
||||
return res
|
||||
|
||||
check = tools.cache()(check)
|
||||
|
||||
#
|
||||
# Methods to clean the cache on the Check Method.
|
||||
# Check rights on actions
|
||||
#
|
||||
def write(self, cr, uid, *args, **argv):
|
||||
res = super(ir_model_access, self).write(cr, uid, *args, **argv)
|
||||
|
|
Loading…
Reference in New Issue