Security in Odoo

OpenERP has two kinds of security restrictions that can be assigned to a user group:

    Access Rights are CRUD yes/no flags and allow per-model access control. They state whether members of this group may perform a Create, Read, Update, and Delete operation on any document of a certain document model (e.g. a project task). The default policy is DENY, so by default any operation will be refused if the user does not explicitly have the right to perform it via one of her groups' access rights.

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 

access_hr_employee_category_user,hr.employee.category.user,model_hr_employee_category,base.group_hr_user,1,1,1,1

Record Rules are filters applied on CRUD operations, and allow per-document (record ) access-control, once access right are already granted. Users will only be able to perform an operation on a given document if the document matches at least one of the record rules. The default policy is ALLOW, so if no rule exists for a given model, all documents of that model may be accessed by users who have the necessary access rights.

Both Access Rights and Record Rules may also be defined globally without assigning them to a specific group, in which case they apply to everyone. There is one pitfall for Record Rules: global rules may NOT be relaxed by other rules (on purpose!), so use with care.

    object/model: project.task
    name: See own tasks only
    domain: ['|',('user_id','=',False),('user_id','=',user.id)]
        (means: your own tasks and unassigned ones)
    apply for read: [x]
    apply for write: [x]
    apply for create: [x]
    apply for delete: [x]
    groups: Project / User

The domain of a record rule is a standard OpenERP domain that is evaluated on the records on which you are trying to perform the operation, and can refer to a user variable that contains the current user's data .

If you want to allow special users (e.g. Project Managers) to view all tasks in the system, you can relax this rule for them by adding another rule to the Project Manager group which allows access to all tasks.

There is a special "domain filter" that means "ALLOW ALL" and is useful to relax another stricter rule: [(1,'=',1)].

Global Rule :Apply for all the groups in the sysytem by using the key global.

   <record id="hr_employee_multi_comp_rule" model="ir.rule">
            <field name="name">Employee multi company rule</field>
            <field name="model_id" ref="model_hr_employee"/>
            <field eval="True" name="global"/>
            <field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
        </record>

Group Rule :

   <record id="hr_employee_interview_project_manager" model="ir.rule">
        <field name="name">Interview Project Manager</field>
        <field name="model_id" ref="model_hr_evaluation_evaluation"/>
        <field name="domain_force">[('employee_id', 'child_of',     [user.employee_ids[0].id])]</field>
        <field eval="False" name="global"/>
        <field name="groups"     eval="[(4,ref('base.group_hr_project_manager'))]"/>
    </record>

Syntax :

<record model="ir.rule" id="ir_values_my_costume_rule">
        <field name="name">My Rule Name</field>
        <field name="model_id" ref="model_your_model_name"/>
        <field name="domain_force">[('field','operator','value'),('user_id','=',user.id)]</field>
        <field name="perm_read" eval="True"/>
        <field name="perm_write" eval="True"/>
        <field name="perm_unlink" eval="True"/>
        <field name="perm_create" eval="True"/>
    </record>

By default True
so need not to mention explicitly

Record Rules For Objects

Record rules determine who can access the objects, depending on the rules set for the particular object. A record rule has some tests to be performed on objects.

You can manage four access modes on objects independently, depending on the test:

        Read access : can read the data in the object,

        Create access : can create a new record in the object,

        Write access : can modify the contents of records in the object,

        Delete access : can delete records from the object.

To configure a rule on an object, use the menu Administration ? Security ? Record Rules. The fields in the ir.rule object describe:

        Object : Object on which to have the rule

        Name : Name of the rule

        Global : If global is checked, then that rule would be applied for all the groups; and if it is unchecked, then that rule would be applied only for the groups selected for it

        Domain : A list of all the tests for the object. It is specified through a Python expression as a list of tuples.

                If there are multiple tests on same object, then all of them are joined using AND operator, and depending on the result the rule would be satisfied

                If there are multiple rules on same object, then all of them are joined using OR operator

        Access Modes : Read, Write, Create, Delete as described earlier

                    If only one access mode is checked, then only that mode would be applied

                    If all of them are checked, then all the access modes would be applied

            But at least one access mode has to be checked, all of them cannot be unchecked. If all of them are unchecked, it would raise an exception.

       
Step 1:Define Group Cateogies (.xml file)

Step 2 :Define User Groups for Caetgories(User,Manager,Vendor)


3.Define the record rules for the group
ir.rule :
Control the visibility of data to the particular user of the group .

Creating Category

First you have to create category for your group like this:

<record model="ir.module.category" id="module_my_gourp_category">
        <field name="name">My Group Category</field>
        <field name="description">Group Description.</field>
        <field name="sequence">10</field>
    </record>

Then give category reference in your group like this:

<record id="my_group" model="res.groups">
    <field name="name">My Group</field>
    <field name="category_id" ref="module_my_gourp_category"/>
</record>

Creating Groups
  <record id="base.group_hr_manager" model="res.groups">
        <field name="name">Manager</field>
        <field name="comment">the user will have an access to the human resources configuration as well as statistic reports.</field>
        <field name="category_id" ref="base.module_category_human_resources"/>
        <field name="implied_ids" eval="[(4, ref('base.group_hr_user'))]"/>
    # Inheritng the group  base.group_hr_user
        <field name="users" eval="[(4, ref('base.user_root'))]"/>
    #  base.user_root inherit the  base.group_hr_manager &     base.group_hr_user i.e Admin is Manager as well as User
    </record>

base.group_system (admin user)


This will create selection for group instead of check box .
If there is hierarchy followed in all the groups for the model then category will appear as Checkboz otherwise if there is no clean hierarchy the category will appear as checkbox .

1. Can Record Rules override Acces Rules?
NO  , Access rules are per Model access rules and record rules are per Record rules so they can't override the first rule.

2. Are Record Rules only used to filter some visible data? Yes

3. Can Record Rules be used to reduce or increase the permissions? or even both?
    Indirectly it could as you could allow people to see datas that is not natively supposed to be displayed. It's a kind of reduc/increase permission

Domain

Each tuple in the search domain needs to have 3 elements, in the form: ('field_name', 'operator', value), where:

    field_name must be a valid name of field of the object model, possibly following many-to-one relationships using dot-notation, e.g 'street' or 'partner_id.country' are valid values.

    operator must be a string with a valid comparison operator from this list: =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, parent_left, parent_right The semantics of most of these operators are obvious. The child_of operator will look for records who are children or grand-children of a given record, according to the semantics of this model (i.e following the relationship field named by self._parent_name, by default parent_id.

 value must be a valid value to compare with the values of field_name, depending on its type

Domain criteria can be combined using 3 logical operators than can be added between tuples: '&' (logical AND, default), '|' (logical OR), '!' (logical NOT). These are prefix operators and the arity of the '&' and '|' operator is 2, while the arity of the '!' is just 1. Be very careful about this when you combine them the first time.

Here is an example of searching for Partners named ABC from Belgium and Germany whose language is not english ::

[('name','=','ABC'),'!',('language.code','=','en_US'),'|',('country_id.code','=','be'),('country_id.code','=','de')]

The '&' is omitted as it is the default, and of course we could have used '!=' for the language, but what this domain really represents is::

(name is 'ABC' AND (language is NOT english) AND (country is Belgium OR Germany))

List of Domain operators: ! (Not), | (Or), & (And)  
Priority :NAO

List of Term operators:
'=', '!=', '<=', '<', '>', '>=', '=?', '=like', '=ilike', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of'
<> not equal to



Comparison operators

A domain is a list of criteria, each criterion being a triple (either a list or a tuple) of (field_name, operator, value) where:
[(field_name, operator, value)]

    field_name (str) a field name of the current model, or a relationship traversal through a Many2one using dot-notation e.g. 'street' or 'partner_id.country'
    operator (str) an operator used to compare the field_name with the value. Valid operators are:
    value: variable type, must be comparable (through operator) to the named field
   

Comparison operators (Term operators )

Description     PY     XML     Notes

equals to     =     =    

not equals to     !=     &lt;&gt;    

greater than     >     &gt;    

greater than or equal to     >=     &gt;=    

less than     <     &lt;    

less than or equal to     <=     &lt;=    

unset or equals to     =?     =?     unset or equals to (returns true if value is either None or False, otherwise behaves like  =)

matches value     =like     =like    

matches field_name against the value pattern. An underscore _ in the pattern stands for (matches) any single character; a percent sign % matches any string of zero or more characters.

matches %value%     like     like    

matches field_name against the %value% pattern. Similar to =like but wraps value with ‘%’ before matching

doesn’t match %value%     not like     not like    
doesn’t match against the %value% pattern

case insensitive like     ilike     ilike    

case insensitive not like     not ilike     not ilike    
case insensitive =like     =ilike     =ilike    

equal to any of     in     in     is equal to any of the items from value, value should be a list of items

unequal to all of     not in     not in    

child of     child_of     child_of     Takes the semantics of the model into account (i.e following the relationship field named by _parent_name).


Combining logical expresions ( Domain operators )
Domain criteria can be combined using logical operators in prefix form:



Description     PY     Aridad     Notes

Logical AND     &     2     default operation to combine criteria following one another. Arity 2 (uses the next 2 criteria or combinations).

logical OR     |     2    

logical NOT     !     1    



Example
To search for partners named ABC, from belgium or germany, whose language is not english:
[('name','=','ABC'),
 ('language.code','!=','en_US'),
 '|',('country_id.code','=','be'),
     ('country_id.code','=','de')]

This domain is interpreted as:
    (name is 'ABC')
AND (language is NOT english)
AND (country is Belgium OR Germany)


In OpenERP domain filter, it will be written as:

syntax : Each tuple in the domain has three fields ->  ('field_name', 'operator', value)

field_name : a valid name of field of the object model or in the database table

operator : valid operators are =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, parent_left, parent_right (openerp/osv/expression.py)

value : a valid value to compare with the values of field_name, depending on its type.
                                                                                                                                                                                                                                                                       
ie, domain = [('field1','=',10)] # where field1 should be a field in the model and 10 will be the value

or domain = [('field1','=',field2)] # where field1 and field2 should be the fields in the model

Condition AND

Simple condition in programming:   

if field1 = 5 and field2 = 10

In OpenERP domain filter, it will be written as:

ie, domain = [('field1','=',5),('field2','=',10)]

or domain = [('field1','=',field3),('field1','=',field3)]

Note : Note that if you don't specify any condition at the beginning and condition will be applied.

Condition OR

Simple condition in programming:   

if field1 = 5 or field2 = 10

In OpenERP domain filter, it will be written as:

ie, domain = ['|', ('field1','=',5),('field2','=',10)]

or domain = ['|', ('field1','=',field3),('field1','=',field3)]



Multiple Condition

Simple condition in programming: 

if field1 = 5 or (field2 ! = 10 and field3 = 12)

In OpenERP domain filter, it will be written as:

domain = ['|',('field1','=',5),('&',('field2','!=',10),('field3','=','12'))]




Available domain operator in openerp/odoo?
This gives a overview:

List of Domain operators: ! (Not), | (Or), & (And)
NAO

List of Term operators:
'=', '!=', '<=', '<', '>', '>=', '=?', '=like', '=ilike', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of'

Usage:

Input records:

Record 1: Openerp

Record 2: openerp

Record 3: Opensource

Record 4: opensource

Record 5: Open

Record 6: open

Record 7: Odoo

Record 8: odoo

Record 9: Odooopenerp

Record 10: OdooOpenerp

'like': [('input', 'like', 'open')] - Returns case sensitive (wildcards - '%open%') search.

O/p: open, opensource, openerp, Odooopenerp

'not like': [('input', 'not like', 'open')] - Returns results not matched with case sensitive (wildcards - '%open%') search.

O/p: Openerp, Opensource, Open, Odoo, odoo, OdooOpenerp

'=like': [('name', '=like', 'open')] - Returns exact (= 'open') case sensitive search.

O/p: open

'ilike': [('name', 'ilike', 'open')] - Returns exact case insensitive (wildcards - '%open%') search.

O/p: Openerp, openerp, Opensource, opensource, Open, open, Odooopenerp, OdooOpenerp

'not ilike': [('name', 'not ilike', 'open')] - Returns results not matched with exact case insensitive (wildcards - '%open%') search.

O/p: Odoo, odoo

'=ilike': [('name', '=ilike', 'open')] - Returns exact (= 'open' or 'Open') case insensitive search.

O/p: Open, open

'=?' is a short-circuit that makes the term TRUE if right is None or False, '=?' behaves like '=' in other cases

name = 'odoo' parent_id = False [('name', 'like', name), ('parent_id', '=?', parent_id)] - Returns name domain result & True

name = 'odoo' parent_id = 'openerp' [('name', 'like', name), ('parent_id', '=?', parent_id)] - Returns name domain result & parent_id domain result


'in': [('value1', 'in', ['value1', 'value2'])] - in operator will check the value1 is present or not in list of right term

'not in': [('value1', 'not in', ['value2'])] - not in operator will check the value1 is not present in list of right term While these 'in' and 'not in' works with list/tuple of values, the latter '=' and '!=' works with string

'=': value = 10 [('value','=',value)] - term left side has 10 in db and term right our value 10 will match

'!=': value = 15 [('value','!=',value)] - term left side has 10 in db and term right our value 10 will not match

'child_of': parent_id = '1' #Agrolait 'child_of': [('partner_id', 'child_of', parent_id)] - return left and right list of partner_id for given parent_id
checks child-parent relationaship

'<=', '<', '>', '>=': These operators are largely used in openerp for comparing dates - [('date', '>=', date_begin), ('date', '<=', date_end)]. You can use these operators to compare int or float also.



0 comments:

Copyright © 2013 SoftKul