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 are
READ,UPDATEandDELETE.- 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 whould then translate to:
Kallemay READ, UPDATE and DELETEAny one in the group
Salesmay READ and UPDATEEveryone 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
Kallewill be accessible to the groupstockholm. This meansKalle,AnnaandBill.Objects created by
Annawill be accessible to the groupOslobut also the groupmanagersasmanagersis a member ofOslo. This meansAnnaandBill.Objects created by
Billwill be accessible toStockholmsimilar 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:
100100100Allowing Only owner to access or modify the record:
111000000Allowing everyone to do everything:
111111111Allowing 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.