Object Access¶
The feature called Object access
solves the problem of restricting
access to a specific object. This is different from type level
permissions which are handled through policies and ACLs.
Nomenclature¶
-
Object
Any instance of a LimeType. Ex a company or a person -
User
A user of the system. Not to be confused with a coworker object -
Owner
A user that is considered to own a object -
Group
A Security group in lime, capable of referencing a number of members (users) and subgroups -
Operations
What is allowed to be done with a object. The supported operations areREAD
,UPDATE
andDELETE
. -
Permission
A definition of what operations are permitted in the defined context -
Record access
The older implementation of this type of access restriction
Concept¶
Every object in lime, independent of type, is assigned a owner, a group and a set of permissions.
The permissions are separated into three different context:
- What operations are allowed when the logged in user is the owner
- What operations are allowed when the logged in user is a member of the assigned group
- What operations are allowed when non of the above apply
The permissions are additive, so that if the user, i.ex. are allowed to read as a result of being the owner in context #1 but does not qualify for context #2, then permission is still granted.
Example:
Consider the following settings for a object:
Owner: Kalle
Group: Sales
Permission:
owner: READ, UPDATE, DELETE
group: READ, UPDATE
other: READ
This would then translate to:
Kalle
may READ, UPDATE and DELETE- Any one in the group
Sales
may READ and UPDATE - Everyone may READ
NOTE:
These permissions apply everywhere (except some legacy use cases) and are always enforced. Take care that any integration user or similar have adequate permissions.
Changing permissions¶
By default the following values are set when a object is created:
-
Owner
The current user -
Group
The current users default group -
Permissions
The default permissions for the limetype of the object
These properties are exposed on the LimeObject
and can be manipulated
and saved together with the object.
Example:
limeobject.security_model.owner_id = user.id
limeobject.security_model.group_id = group.id
limeobject.security_model.permissions.group.update = True
limeobject.security_model.permissions.other.read = False
uow = application.unit_of_work()
uow.add(limeobject)
uow.commit()
This could i.ex. be called using custom limeobjects
Checking permissions¶
The security model for a limeobject can be applied to a specific user
using the apply
method in order to resolve what operations should be
permitted to the supplied user. This will be enforced by the system for
the logged in user but might also be needed in customizations if a user
is impersonated.
Example:
if limeobject.security_model.apply(User).read == True:
do_the_thing()
Configuration¶
- The users default group and the default permissions for a limetype can be configured through the admin pages in the webclient.
- Groups are managed through LISA or by python script
Example: For a customer who wants their projects to be restricted to the offices of the users but allow managers to see everything.
The users:
Bill:
info: is a mangager
default_group: Stockholm
Kalle:
info: works in Stockholm
default_group: Stockholm
Anna:
info: works in Oslo but helps out in Stockholm
default_group: Oslo
Define groups for the users and their offices:
Managers:
members:
- Bill
Stockholm:
members:
- managers
- Kalle
- Anna
Oslo:
members:
- managers
- Anna
Default permissions for limetypes:
Project.default_permissions:
owner: None
group: READ
other: None
Resolution:
- Objects created by
Kalle
will be accessible to the groupstockholm
. This meansKalle
,Anna
andBill
. - Objects created by
Anna
will be accessible to the groupOslo
but also the groupmanagers
asmanagers
is a member ofOslo
. This meansAnna
andBill
. - Objects created by
Bill
will be accessible toStockholm
similar toKalle
. - The default permissions for project grants no permissions for the owner or other
Technical details¶
The database schema for user tables has been extended with the following columns:
-
_sys_owner
id of the owner (user) -
_sys_group
id of the group -
_sys_permissions
A integer value representing all the permissions
_sys_permissions
is the integer representation of a the 9 bits that
make up the permissions.
Bit no | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Bit value | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Access type | READ | UPDATE | DELETE | READ | UPDATE | DELETE | READ | UPDATE | DELETE |
Applies to | owner | owner | owner | group | group | group | other | other | other |
Example:
- Allowing everyone to READ but nothing els:
100100100
- Allowing Only owner to access or modify the record:
111000000
- Allowing everyone to do everything:
111111111
- Allowing no-one to do nothing:
000000000
This binary value is then stored in the database as an integer in base
10. That means that the sequence 111111111
would be stored as the
value 511
.
Separation from Record access¶
Please note that Object access
is fundamentally different from Record
access
although it solves the same problem. The features can, and
should, co-exist if the desktop client is used. Great care should be
taken to configure the two in a way that the same rules apply as they
are enforced in different parts of the application. Record access
being enforced only on read operations in the desktop client and Object
access
being enforced in most non-legacy use cases.
It is a long term goal to replace record access with object access in all parts of Lime CRM.
Compatibility with Record access¶
Lime supplies tools to apply object access rules to record access in an attempt to provide consistency while both record access and object access are in play. This is achived by generating record access functions that reflects the object access logic.
The regeneration can be triggered by running:
$limefu object-access configure-legacy-support -a my_app
or, for a specific limetype:
$limefu object-access configure-legacy-support -a my_app -t my_limetype
Please note that this function does nothing if there is an existing function for the type or if a non-function based record access query is configured in LISA.
One can override existing configuration and force regeneration of the sql functions by using the --override flag.