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.
Any instance of a LimeType. Ex a company or a person
A user of the system. Not to be confused with a coworker object
A user that is considered to own a object
A Security group in lime, capable of referencing a number of members (users) and subgroups
What is allowed to be done with a object. The supported operations are
A definition of what operations are permitted in the defined context
The older implementation of this type of access restriction
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.
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:
Kallemay READ, UPDATE and DELETE
- Any one in the group
Salesmay READ and UPDATE
- Everyone may READ
These permissions apply everywhere (except some legacy use cases) and are always enforced. Take care that any integration user or similar have adequate permissions.
By default the following values are set when a object is created:
The current user
The current users default group
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.
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
The security model for a limeobject can be applied to a specific user
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
if limeobject.security_model.apply(User).read == True: do_the_thing()
- 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.
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
- Objects created by
Kallewill be accessible to the group
stockholm. This means
- Objects created by
Annawill be accessible to the group
Oslobut also the group
managersis a member of
Oslo. This means
- Objects created by
Billwill be accessible to
- The default permissions for project grants no permissions for the owner or other
The database schema for user tables has been extended with the following columns:
_sys_ownerid of the owner (user)
_sys_groupid of the group
A integer value representing all the permissions
_sys_permissions is the integer representation of a the 9 bits that
make up the permissions.
- Allowing everyone to READ but nothing els:
- Allowing Only owner to access or modify the record:
- Allowing everyone to do everything:
- Allowing no-one to do nothing:
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
Separation from Record access¶
Please note that
Object access is fundamentally different from
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.
being enforced only on read operations in the desktop client and
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.