The security model is role-based with roles hierarchy and permissions for every object (operation, page, file) in the system. The possible actions (and hence the possible permissions) that a user can perform with the objects is not fixed - it can be expanded in future to include more. Each object has its own set of actions/permissions that are meaningful for its type. For example an operation has read, execute, chmod and chown while a page has read, write, rename, delete, chmod, chown (more on these later). A permission is the combination of role-action-object. In fact in Guzaba the subjects (the users) are represented by their own role internally. This way each subject has its own primary and unique role which can contain other roles (in a three like or more precisely in an oriented acyclic graph structure). A role that contains other roles automatically receives all their permissions as delegated to it (thus containing the roles). The primary role of a subject can not be contained in another role (which is meaningless - a subject to contain another subject) - instead it can contain many ordinary roles. Each object has owner - a role. This can be an ordinary role a primary role for a specific subject - in this case it is said that the subject owns the object or in the former - that the role owns the object. The owner of has always the full set of permissions for the object (i.e. can perform any action that is supported and meaningful for this object) and these permissions are irrevokable. They are granted automatically when an object is created and by default no other subject/role besides the owner has any permissions. Then the subject (user) can grant some permissions (chmod) to one or more of the roles of which he is member, or even change the ownership (chown) and grant it to another role or subject. Here comes an important limitaion introduced in order to provide isolation and separation of the duties and the possible document flow. A permission or ownership can be granted by the owner only to a role that he is member of or another subject that is member of one of the roles of the owner (the latter is not implemented yet!). This way is possible to completely separate two departments by placing the subjects in two completely separate roles hierarchies with only one intersection - one role which members can pass documents between the two departments.
Some objects in Guzaba CMS are versioned. Each change in their content results in creating a new revision of this object. The revision is infact an independent object of itself with its own owner and permissions. Thus the different revisions can have different permissions and owners. In this sense the versioned objects are more like a union of several objects with common handle and are changed all at the time when specific actions are performed on the object. For example when renaming or moving the object all the revisions are moved or renamed (the "rename" permission is not implemented yet - at the moment renaming requires "write" permission instead of "rename"!). Whena new revision is created it behaves like an ordinary object - it is owned by the subject that created it (even if it is based on an earlier revision from a different owner) and has the default permissions for the owner as described above. When a subjects accesses a versioned object without specifying which revision is requested the last accesible ("read"-able) by this subject revision will be provided. This way having different permissions for the different revisions permits to have drafts of the documents (not published/accessible yet for all roles). When a new revision is created (or a secuence of revisions) they are not accessible by all, and when according the organization's internal policies a specific revision is approved it is marked as "read"-able for the required role. This way in a more complex environment is possible to have multilevel drafts - a different draft revision to be accessible for different roles.
A general policy in Guzaba CMS (unlike UNIX) is that is a subject/role has no read access to an object the object will not be shown at all. Then deleting, moving or renaming a group that contains subelements (like an ordinary tree structure of files & folders) the permissions of the subelements are also checked. In case for one of the subelements is not even readable by the subject an error message will be shown which does not reveal the name of the object, but only its ID. This is required in order to follow the stated policy that if a subject has no permission to read an object there should be no way to even obtain its name (no covert way for obtaining information!). In this case when an action can not be performed because of a lack of permissions the subject should contact another subject who has more permissions in order to resolve the situation.
There are two "layers" of permission checks when a specific operation is executed over a specific object. Lets say a subject wants to read a specific page. First the system will check does the subject has permission to execute the operation "reading a page" and then will check does he have permission to execute the "read" action over the specific requested page. This allows both finegraned permission tunning (on a per object basis) and a easy denial of a specific action by revoking the "execute" permission over the operation that implements the specific action (in the example "read" action).
The roles are represented by the "framework\roles\classes\roles" class. Internally only a role can be an owner of an object or a permission holder. Each subject has its own role. The subjects IDs start from 10001 and their respective roles also start with role_id 10001. When in the documentation is said that a subject owns an object means that its main role is the actual owner. The subjects primary roles (role_id>=10001) can not be part of any other role. If a role contains (inherits) another role then it automatically gets all its permissions and possesions (if the other role is onwer of some objects). In Guzaba framework it is possible for an ordinary role (1<role_id<10001) not just subject primary roles to be owners of objects. In this case all subjects that are part of this role would be owners of these objects. Ownership of an object means that the role has permission to execute all supported actions on the object and these permissions are irrevocable (if they need to be revoked then the owner must be changed). The ordinary roles (1<=role_id<=10001) are organized in an oriented (directed) acyclic graph. It is a graph not a tree structure because there can be intersections in the structure (role1 inherits/contains role2 and role3 while both role2 and role3 inherit role4), it is oriented, beucase one role contains another (there is a direction), and is acyclic because if it wasn't then the roles within a cycle would have the same permissions and would be basically the same (role1 contains role2, role2 contains role3 and role3 contains role1). There are internal checks in the role class for preventing (when granting roles) and detecting cycles (during runtime).
A subject is a user or a system service (called for example by cron) that performs some actions in the system. Generally "subject" and "user" are interchangeable terms. The main subject class is "framework\subjects\classes\subject". It provides some methods for retreiving the roles of the subject. Internally the class contains an instance of the primary role of the subject and all method related to its roles call some public methods of the "framework\roles\classes\role" object. In order an object to be recognized by the system (mostly for authorization purposes) as a "subject" it must implement the interface "framework\authoruization\interfaces\subject". framework\subjects\classes\subject implements this interface. In future other classes may implement it also.
Objects (and operations)
In Guzaba framework everything that can be modified by a "subject" and is not a role is an "object" (even the subjects are in this term objects because they do maintain permissions and ownership record and are manipulated as ordinary objects). In order a specific class to be recognized as "object" it must implement "framework\authorization\interfaces\object". At the moment all "objects" in Guzaba framework inherit the activeRecord class which in fact provides the infrastructure for an object to become an "object" in Guzaba terms. It is possible for a class to inherit activeRecord and not implement the object interface as well the reverse - to implement the object interface but not inherit the activeRecord class (the system amy behave erratically in this case as it is not tested but will be supported in future).
A "permission" is a combination of a role, object and a possible action that can be executed on the object. Every class that is declared to be "object" (is to say implements the interface "framework\authorization\interfaces\object") must declare in a class constant SUPPORTED_ACTIONS (a comma delimeted string) the names of the actions that it supports. Then it can be said for example that the "subject" "John" has the "permission" to execute the action "read" over the "object" of type "page" with ID "55".
The monitor (framework\monitor\classes\monitor) is (and should remain) the only library that is used for permission checks. No modification of any type of the permissions or ownership can occur using its methods.
All the modifications of permissions or ownership are done through this class. No other class does or should do such changes.