Users, groups and permissions in OpenPlatform
OpenPlatform separates who (users), where (applications) and what (permissions) with groups in the middle:
- A user has a name, an email, a language, a password and flags (
safor administrator,isconfirmed,isdisabled,isinactive,notifications,sounds...) and belongs to any number of groups (schema@User,plugins/setup/schemas/users.js). - A group has a name, a colour, an icon, an optional
referenceand a list of permissions (schema@Group,plugins/setup/schemas/groups.js). - An application declares its own permissions: each has a name and a
value, a plain string that the application understands (plugins/setup/schemas/apps.js).
How the access is computed
The function FUNC.permissions(userid, callback) in definitions/func.js builds, for a user:
- the groups of the user that are not disabled;
- the rows of
tbl_group_permissionof those groups: a row with a permission gives that permission of an application, and a row without a permission just gives the application (the user sees it and receives an empty list of permissions); - the
valueof each granted permission, only for applications that are not removed and not disabled.
The result has three parts: the applications of the user (apps), the permission values by application (permissions) and the groups (groups). It is stored as JSON in the column cache of the user, with a cachefilter that lists the groups (G<id>) and the applications (A<id>) it depends on. When a group or an application changes, FUNC.clearcache(id) clears the cache of every user whose filter contains that identifier, and the next request rebuilds it.
Where the application sees it
- The portal lists only the applications in
appsand refuses to open any other one ("App not found"). - The application receives its own list in
permissionswhen it verifies a launch (an array of thevaluestrings), together with the ids of the groups, so it can decide what to show (how an app connects). - The setup screen decides who may use it by the flag
saof the user.
A good habit, from the way the code works: name the value of a permission after the action in your application (orders.read, orders.write) and map groups to those values in OpenPlatform, so that your application only checks strings.