chamilo 2 0 rights

Upload: khildin

Post on 10-Apr-2018

222 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/8/2019 Chamilo 2 0 Rights

    1/28

    Chamilo 2.0 Rights Management | 1

    To Have and Have NotChamilo 2.0 Rights Management

  • 8/8/2019 Chamilo 2 0 Rights

    2/28

    2 | To Have and Have Not

  • 8/8/2019 Chamilo 2 0 Rights

    3/28

  • 8/8/2019 Chamilo 2 0 Rights

    4/28

    4 | To Have and Have Not

    Credits

    Author

    Hans De Bisschop ([email protected])

    Developers

    Hans De Bisschop ([email protected]) Sven Vanpoucke ([email protected])

    Special thanks

    Eduard Vossen ([email protected]) Jean-Marie Maes ([email protected]) ... and the entire Chamilo community

    This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. To

    view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to

    Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

  • 8/8/2019 Chamilo 2 0 Rights

    5/28

    Chamilo 2.0 Rights Management | 5

    All our dreams can come

    true, if we have the

    courage to pursue them.

    - Walt Disney (1901-1966)

  • 8/8/2019 Chamilo 2 0 Rights

    6/28

    6 | To Have and Have Not

    Contents

    Credits ..................................................................................................................................................... 4

    Introduction ............................................................................................................................................. 8

    The Concepts: A Bridge over Troubled Water ......................................................................................... 9

    Rights ................................................................................................................................................... 9

    Locations ............................................................................................................................................. 9

    Inheritance ...................................................................................................................................... 9

    Locking ........................................................................................................................................... 10

    Relations ............................................................................................................................................ 10

    Templates .......................................................................................................................................... 10

    Summary ........................................................................................................................................... 11

    Persistent storage: A Thriller ................................................................................................................. 11

    How do we map these locations to actual components and object instances? ............................... 12

    Wont having one single location tree result in gigantic tree structures? ........................................ 12

    We only store parent ids, that cant be ideal, can it? ...................................................................... 13

    Summary ........................................................................................................................................... 13

    London is Calling for a Rights Interface ................................................................................................. 14

    Helper methods ................................................................................................................................. 14

    Example ......................................................................................................................................... 14

    Available rights .................................................................................................................................. 15

    The Rights Utilities will rock you ........................................................................................................... 15

    create_location.................................................................................................................................. 15

    create_application_root_location | create_subtree_root_location ................................................ 16

    parse_locations_file | parse_tree ..................................................................................................... 16

    is_allowed .......................................................................................................................................... 16

    get_right ............................................................................................................................................ 16

    is_allowed_for_... .............................................................................................................................. 17

    move_multiple .................................................................................................................................. 17

    get_root | get_root_id ...................................................................................................................... 17

    get_location_by_identifier | get_location_id_by_identifier ............................................................ 17

    get_rights_legend .............................................................................................................................. 17

    invert_..._right_location .................................................................................................................... 17

    set_..._right_location_value .............................................................................................................. 17

    switch_location_inherit | switch_location_lock ............................................................................... 17

  • 8/8/2019 Chamilo 2 0 Rights

    7/28

    Chamilo 2.0 Rights Management | 7

    get_..._right_location ........................................................................................................................ 18

    get_rights_icon .................................................................................................................................. 18

    get_availabble_rights ........................................................................................................................ 18

    get_allowed_users ............................................................................................................................ 18

    Still standing: The Rights Editor Manager ............................................................................................. 18

    Excluding users and groups ............................................................................................................... 19

    Filtering users and groups ................................................................................................................. 19

    RightsEditorManager modus ............................................................................................................. 19

    The Iron Lion: A Nested Tree ................................................................................................................. 19

    Why nested trees / nested set models?............................................................................................ 20

    How does it work? ............................................................................................................................. 20

    Sultan of Swing: The Rights Algorithm .................................................................................................. 21

    The Invisible Touch: Where are rights visible? ...................................................................................... 23

    End of the Line: Using Rights ................................................................................................................. 24

    Defining a rights interface ................................................................................................................. 24

    Installing static locations ................................................................................................................... 25

    Adding dynamic locations ................................................................................................................. 25

    Performing checks ............................................................................................................................. 26

    Get involved .......................................................................................................................................... 26

    Index ...................................................................................................................................................... 27

  • 8/8/2019 Chamilo 2 0 Rights

    8/28

    8 | To Have and Have Not

    Introduction

    User account control, (digital) rights management, access control, credentials verification ... It hardly

    matters what you call it, its one of those annoying realities of life. In the ideal world there would be

    no need to check any kind of access rights, but since that utopia is still more or less a dream, we need

    a system. What does the system have to know?

    Who are you? Where are you? What do you want to do?

    The reply is simple enough; it can be reduced to the most basic components a computer can

    understand: a simple 0 or 1, true or false. For the humans among you that would be a go ahead or

    no can do, buster.

    Sounds easy enough, right? Wrong. The theory of it all

    might be deceivingly easy, but in reality rights

    management is a combination of complex (hierarchical)

    structures, inheritance, locks, algorithms and last but not

    least: frustrated users. Because of the sheer complexity

    and scale of such systems its often a nightmare to

    maintain and an even bigger nightmare to set up or

    implement.

    The fact that you hardly ever see the system doesnt make

    things any easier either. Apart from the odd error

    message when you try to do something youre not

    allowed to, youll never really see the system in action.

    That being said a lot of the options we have in e.g. Chamilo are there because something in the

    background has determined that we can see those options.

    Even though its not strictly related to the actual rights management application, one of the most

    basic examples of such a check is the login procedure. Even before a user can see anything the

    system will have verified who you are, where you are going and what you want to do. If its your firstlogin, youll obviously get to see the login screen. Access to all other components will automatically

    be denied. But if its not your first visit youll get the go ahead and youll be presented with a

    plethora of different features and options.

    So sit back and enjoy the ride. Welcome to the first circle of hell.

    Fig. 1 - Dante shown holding a copy of the Divine

    Comedy, next to the entrance to Hell, the seven

    terraces of Mount Purgatory and the city of

    Florence, with the spheres of Heaven above.

  • 8/8/2019 Chamilo 2 0 Rights

    9/28

    Chamilo 2.0 Rights Management | 9

    The Concepts: A Bridge over Troubled Water

    Before we can delve into the actual management and the structures related to it, its essential that

    we explain a few basic Chamilo rights management concepts. These concepts will be used

    throughout this document, so be sure you understand the completely before reading on.

    Rights

    Elementary, dear Watson is how the great detective would describe rights.

    Rights are the most basic of components in the entire rights framework, hence

    its name. What are rights? To name a few simple examples: add, edit, delete,

    view, share, use... Theyre the basic actions someone may want to perform in

    the context of a certain Chamilo component or application. Elementary rights

    can be defined on a per-application basis.

    Locations

    So that was the easy part, now the going gets tough. We already have the what (right); now we need

    a where, we need a location that allows you to perform the specified action. What is a location?

    A course is a location A content object is a location The course browser is a location The homepage is a location A personal calendar publication is a location An application configuration form is a location

    It shouldnt take you long to notice that there are 2 types of locations in that list. Some locations are

    user-defined and theres no way to know how many of them there will be (ifany at all). The second

    kind is somewhat less complex. They usually correspond to components available in Chamilo and its

    applications. Things like the course browser, the homepage or a configuration form are set in stone.

    Theres no way an end-user can add or delete instances of these components.

    A very basic usage example of this second type of locations: Can Jane Doe publish

    a calendar event in the personal calendar? In this case the location would be

    the publisher component of the application. It is not an instance of a user-

    definable object, but a component as defined by the developer.

    Locations are almost obviously related to each other in some way. Practically

    speaking locations will form a hierarchical tree with the actual platform-location

    as the root node of the entire system. If you consider locations to be a tree in which separate

    locations are linked, you can introduce some additional concepts to reduce the amount of overhead

    and configuration required.

    Inheritance

    If a right is not specifically enabled for a specific location, the user will be denied access to that

    location. That means defining rights for all locations throughout the entire system.

  • 8/8/2019 Chamilo 2 0 Rights

    10/28

    10 | To Have and Have Not

    Consider the following: I strongly believe in the concept of creative commons and want all my objects

    to be shared with every other user. To make this happen I would have to define several rights for

    every single object in my repository. Thats all nice and dandy if you have 10 objects, but if you have

    a 1000 objects it would be frustrating to say the least. Wouldnt it be easier to just define that right

    for my user repository (the top location in that locations tree)? It obviously would be ... and thats

    what inheritance does. Unless explicitly disabled, the system will automatically check for permissions

    with the locations direct parents.

    Locking

    So inheritance goes upwards, what about downwards? Imagine you want all content objects to be

    shareable with everyone and at the same time you want to prevent anyone from not sharing their

    own objects. To override the general setting all they would have to do is disable

    inheritance for their own repository and set their own rights.

    Locking is a way to prevent this. As soon as someone flags a location as locked, no

    one will be able to define rights for any of the children on that specific location.They will automatically inherit the set of rights as defined by the locked parent.

    Relations

    After the what (right) and the where (location) comes the who . Who are you? is the basic question

    the system will be concerned about and depending on the answer, the results will be very different

    indeed. For every right on every location a relation can be defined with one or more users and/or

    one or more user groups. Its this combination of a right, a location and a user or group, which can be

    set to true or false, thus defining the actual right as a whole.

    Please keep in mind that while you can define rights for individual users, this is not considered a bestpractice. In most cases it will be possible to group users which will require similar or identical access

    rights, e.g. university faculties, organisation branches, interest groups. It is far more effective to

    define general rights for entire groups of users and grant additional rights when and if necessary.

    Templates

    Defining groups can be practical and save you a lot of time, but even then there

    are limitations. Groups are hierarchical by nature. E.g. a university contains many

    faculties; each faculty contains teachers and students. So basically you ll end up

    having several teachers and students groups which, for the sake of this example,

    share the exact same rights.

    Again, if you have 10 groups this is manageable, but if you have e.g. over 450.000

    students on 64 campuses like the State University of New York with who knows how many hundreds

    or thousands of subgroups, this would be hell. Even in less extreme scenarios with about 50 groups

    and a few thousand users it would be an administrative nightmare to constantly (and consistently!)

    manage all those rights.

    Wouldnt it be easier to just define e.g. a student template and apply it / link it to all student groups?

    That way you would only have change the template and it would automatically apply to all linked

    users and groups. Of course it would be, so thats exactly what we did in Chamilo 2.0.

  • 8/8/2019 Chamilo 2 0 Rights

    11/28

    Chamilo 2.0 Rights Management | 11

    Summary

    You can define:

    Rights Locations Templates

    You can apply templates to:

    Users Groups

    You can apply rights to:

    Users Groups Templates

    Persistent storage: A Thriller

    Most of the concepts described before can be mapped to storage units relatively easy. Locations and

    rights are the exception though, but before we get to that, let s have a look at the more

    straightforward storage units.

    The tables that follow reflect typical implementations of these storage units in most of the commonly

    used DBMS-systems.

    Field Type Extraid int(10) The numeric identifier of the template

    name char(250) The name

    description text The description

    Table 1 Storage unit structure for a (rights) template

    Field Type Extra

    id int(10) The numeric identifier of the user right location

    user_id int(10) The numeric identifier of the user

    right_id int(10) The numeric identifier of the right

    location_id int(10) The numeric identifier of the location

    value tinyint(3) The actual value, true (1) or false (0)

    Table 2 Storage unit structure for the relation between a user, a right and a location

    Field Type Extra

    id int(10) The numeric identifier of the group right location

    group_id int(10) The numeric identifier of the group

    right_id int(10) The numeric identifier of the right

    location_id int(10) The numeric identifier of the location

    value tinyint(3) The actual value, true (1) or false (0)

    Table 3 Storage unit structure for the relation between a group, a right and a location

  • 8/8/2019 Chamilo 2 0 Rights

    12/28

    12 | To Have and Have Not

    Field Type Extra

    id int(10) The numeric identifier of the template right location

    rights_template_id int(10) The numeric identifier of the template

    right_id int(10) The numeric identifier of the right

    location_idint(10) The numeric identifier of the location

    value tinyint(3) The actual value, true (1) or false (0)

    Table 4 Storage unit structure for the relation between a (rights) template, a right and a location

    Field Type Extra

    user_id int(10) The numeric identifier of the user

    rights_template_id int(10) The numeric identifier of the template

    Table 5 Storage unit structure for the relation between a user and a (rights) template

    Field Type Extra

    group_id int(10) The numeric identifier of the group

    rights_template_id int(10) The numeric identifier of the template

    Table 6 Storage unit structure for the relation between a group and a (rights) template

    So what about the rights? Where are they stored? Short answer: not in the persistent storage. Long

    answer: check the next chapter. That brings us to the more complicated part: the locations. Taking

    into account what we learned from the description of a location in the previous chapter, locations

    would have the following properties.

    Field Type Extra

    id int(10) The numeric identifier of the location

    location_id char(50) A textual descriptor of the locationparent_id int(10) The numeric identifier of the parent location

    inherit tinyint(3) Does the location inherit rights?

    locked tinyint(3) Is the location locked?

    Table 7 A possible storage unit structure for locations?

    There are more than a few problems with this kind of approach though, so lets have a look at the

    ones which make the aforementioned table of properties largely insufficient.

    How do we map these locations to actual components and object instances?

    You cant, which is why a few extra properties are necessary. First and foremost theres the

    identifier, which in most cases is nothing more than the id of the object instance or a unique id which

    was given to a specific component.

    The rocket scientists among you may be realizing right now that there is no way that all object

    instances throughout the entire system have unique ids and they would be quite right too. They

    dont and thats why we store an additional property type which is more than likely the object

    instance class. E.g. content_object, group.

    Wont having one single location tree result in gigantic tree structures?

    It most definitely will and performance wise that is a very bad thing. On top of that there will hardly

    ever be a reason to interlink location trees of different applications. So lets store the application the

    location is stored in, that should help a bit. It does, but it s not enough. Some location trees would

  • 8/8/2019 Chamilo 2 0 Rights

    13/28

    Chamilo 2.0 Rights Management | 13

    still get extremely big and the best example of that is the

    repository. Imagine a repository location tree for a

    platform with 10.000 users whom each have about a 100

    content objects. Thats 1 million locations and more

    importantly thats quite disturbing. Recursion through

    that isnt hell, thats the end of days, plain and simple.

    But wait a minute. Theres little or no interaction

    between location trees of different applications, couldnt

    we extend this principle a bit further? It turns out we

    can, which is once more nicely illustrated by the

    repository. Repositories are the personal property of

    individual users. Rights management-wise there is

    nothing that really spans multiple repositories. So once more we decided it would be acceptable to

    split things up a bit more to allow sub trees per application. To make this possible two additionalproperties were introduced: tree_identifier and tree_type. The same principle applies to them

    as does to the regular identifier and type.

    The combination of these 4 properties allows us to isolate a very specific place in the entire system

    without too much recursion and without having to retrieve lots of data which is irrelevant for what

    we want to achieve.

    We only store parent ids, that cant be ideal, can it?

    Unless you have a mainframe at your disposal, there is no way that just using parent ids is ever going

    to be the best and fastest solution. Were obviously not the first ones to come to this conclusion. Tosolve these kinds of problems several alternative storage structures were conceived, one of which

    are nested trees. For more information on nested trees, check the corresponding chapter. For now,

    suffice it to say well need 2 more properties: a left_value and a right_value.

    Summary

    Field Type Extra

    id int(10) The numeric identifier of the location

    location_id char(50) A textual descriptor of the location

    left_value int(10) The left value of the location node

    right_value int(10) The right value of the location node

    parent_id int(10) The numeric identifier of the parent location

    inherit tinyint(3) Does the location inherit rights?

    locked tinyint(3) Is the location locked?

    identifier int(10) The numerical identifier of the object instance or component the

    location represents

    type char(20) The type of the object instance or component the location

    represents

    tree_identifier int(10) The numerical identifier of this specific subtree of an application

    tree_type char(20) The type of this specific subtree of an application

    application char(30) The name of the application

    Table 8 Storage unit structure for a location

    Fig. 2 Simple trees like this one can quickly

    become very big and very complicated

  • 8/8/2019 Chamilo 2 0 Rights

    14/28

    14 | To Have and Have Not

    London is Calling for a Rights Interface

    As explained in the previous chapter, locations are strictly related to applications. Within the context

    of a specific application the application-property of a location will therefore mostly be identical all

    the time. We thought it would be somewhat counterintuitive to force a developer to continuously

    pass on the application name when performing a rights check.

    Helper methods

    To make the passing of the additional parameter superfluous the application rights classes were

    implemented as an interface to the actual workhorse which is located in the rights folder. (The

    RightsUtilities class, which is the subject of the next chapter) All methods in these classes are

    implemented statically for easy access throughout the application and/or platform.

    Apart from these straightforward helper methods, the application rights classes could also contain

    functionality to extend the basic rights checking algorithm or any of the other default rights methods.

    Fig. 3 An example of a typical course group in Chamilo 2.0s courses application

    Example

    Courses contain a structure called course groups. These course groups group any number of users

    already subscribed to the course. Supposing we want to define rights for this specific course group

    within the confines of the course, it becomes necessary to store an additional relation between the

    course group, the location and the right.

    Even more important is the fact that we would have to check this relation whenever we access a

    specific tool inside a course for additional rights. Implementing such an extension could be achieved

  • 8/8/2019 Chamilo 2 0 Rights

    15/28

    Chamilo 2.0 Rights Management | 15

    by extending the default is_allowed helper method to not only check the default algorithm, but to

    also take this additional relation into account.

    ... And of course theres always the possibility to put functionality specific to the application in

    question in its own rights interface.

    Available rights

    As mentioned in the chapter on storage units, there is no storage unit for rights. Available rights are a

    static fact, within the confines of an application they are universal constants which the user cannot

    manipulate in any way. He can only use them. That is why they are not stored in the database as you

    may have expected but are defined in the applications rights interface as constants.

    Considering that they are defined locally, available rights can vary greatly from application to

    application. Keep in mind though that every single additional right will complicate things

    considerably for the end-user (and the developers!), so please consider the available rights and their

    relations well. Simplicity really is essential for an already complex system.

    The Rights Utilities will rock you

    The advantage of a central rights management system is that all default

    functionality can be centralized as well, thus not bothering application developers

    with the several complex layers of functionality and the boring / mind numbing

    algorithms involved in making rights management work.

    The most visible part, which is pretty relative, of the system is the

    RightsUtilities class which, just like the rights interfaces, contains a number of static methods to

    make life easier for the developer and per extension the end-user. What follows is an overview of the

    methods in this class, their function and what they require to work correctly.

    create_location

    A helper method which allows us to quickly create a new location object instance. As can be

    expected it expects all essential properties as parameters: name, application, type, identifier,

    inherit, parent_id, locked, tree_identifier and tree_type. Additionally you can request that

    the location object be returned by setting the last parameter, return_location, to true.

  • 8/8/2019 Chamilo 2 0 Rights

    16/28

    16 | To Have and Have Not

    create_application_root_location | create_subtree_root_location

    Helper methods used to create the root nodes of application (sub) trees during the installation of the

    application or the initialization of certain components.

    parse_locations_file | parse_tree

    Predefined rights locations are defined as XML-files and processed by these helper methods during

    installation and the initialization of certain components.

    is_allowed

    The start of the big one. This is the method youll be using (indirectly) whenever youre checking

    permissions for the currently logged in user. It shouldnt come as a surprise that it requires a range of

    parameters to work correctly.

    Parameter Description

    right The right to be checked

    location The numeric identifier of the locations object instance id or

    component identifier

    type The type of the location

    application The application name

    user_id The numeric identifier of the user were checking rights for

    tree_identifier The numeric identifier of the locations subtree

    tree_type The type of the location subtree

    Table 9 Parameters of the is_allowed method in the RightsUtilities class

    So why is this just the beginning? Dont we have everything we need to perform

    the actual permissions check? We do, but there is that nasty bugger calledperformance. Thats why is_allowed caches all requests made during the course

    of a single PHP request and quickly returns a cached value once it detects we re

    verifying the same permission once more. The performance gain of such a

    relatively simple bit of functionality is not to be underestimated in a system that

    will no doubt be processing an ever growing number of requests all the time. Rights are everywhere;

    checks are everywhere, so speed is essential.

    As far as the parameters go, most of them are in essence optional, although not passing them to the

    method doesnt make much sense. The only one which will be ignored in most regular usages of the

    method is the user_id. If and when the user_id is not set the system will default to the currentlylogged in user, which is what well want it to do most of the time anyway.

    get_right

    is_allowed was the start of the big one, this is THE big one. get_right takes the same parameters

    as is_allowed but will actually verify the permissions for the given set of parameters. The result

    couldnt be simpler: true or false. The consequences couldnt be bigger as it determines what

    someone can do in Chamilo.

    Interesting to know is that users which have been flagged as platform administrator bypass all these

    checks and immediately get true returned for every single rights request on the system. So if you

  • 8/8/2019 Chamilo 2 0 Rights

    17/28

    Chamilo 2.0 Rights Management | 17

    want to know what other users see, it could be a good idea to use the functionality that allows an

    administrator to hijack another users account temporarily.

    The actual algorithm has its own chapter.

    is_allowed_for_...The two previous methods take every single relation, group membership and template into account

    which might in some way be related to the user we re checking permissions for. This is the desired

    behaviour most of the times, but in some case well want to be more specific. Methods exist to check

    permissions for a specific rights template, user and group. Theyll prove particularly useful when

    granting or denying rights to users, groups and rights templates.

    The methods use their respective get_..._rights_location method to verify

    the actual permission and take inheritance into account when determining the

    resulting permission.

    move_multiple

    Method which allows us to move multiple locations to a new parent at the same time.

    get_root | get_root_id

    Sometimes we will want to retrieve the root node of a location (sub) tree or its id. get_root_id is a

    simple extension on get_root that simply returns the id of the location returned by the

    aforementioned method.

    get_location_by_identifier | get_location_id_by_identifier

    Helper methods to retrieve a location object based on the application, identifier, type,

    tree_identifier and tree_type. As was already the case with the get_root_id method,

    get_location_id_by_identifier returns the numerical id of the location object returned by

    get_location_by_identifier.

    get_rights_legend

    Returns some HTML that explains the meaning of the icons used in the rights configuration pages.

    invert_..._right_location

    Convert true to false and vice versa for a combination of a right, location and, depending on the

    variant, a user /group / rights template. Considering that the rights management system returns false

    unless told otherwise, an invert on a relation which has not yet been defined will result in the

    creation of that relation and its being set to true.

    set_..._right_location_value

    Similar to the invert internally, but the method takes an additional parameter being the value to use

    for the relation between the right, location and e.g. user. Like the invert-methods, this method will

    create the relation if it doesnt exist yet.

    switch_location_inherit | switch_location_lock

    Invert the inheritance and lock switches for a given location object

  • 8/8/2019 Chamilo 2 0 Rights

    18/28

    18 | To Have and Have Not

    get_..._right_location

    Gets the value of a specific rights relation based on the right_id, location_id and e.g. user_id. If

    the requested relation doesnt exist, false will returned.

    get_rights_icon

    Helper method that returns a visual status of permission instead of a simple true or false. Particularly

    useful to help the end-users / administrators to use rights.

    get_availabble_rights

    Returns the rights available in a specific application as defined in their respective rights interface.

    get_allowed_users

    Returns an array ofuser_ids containing all users which have permissions for a certain right on a

    certain location. E.g. moderators for English in the Chamilo translation tool are determined this way.

    Still standing: The Rights Editor Manager

    Having a fantastic back-end is a start, but its nothing if not completely useless for end-users or

    platform administrators. To provide developers with an easy and consistent way of offering rights

    management to their intended audience a general rights editor manager was implemented. This

    manager allows you to configure rights for one or more locations linked to any number of

    (predefined) users and/or groups.

    Instantiating a new RightsEditorManager is easy to say the least and once instantiated all you have

    to do is run it. The manager takes two parameters, the first being the current object which offers themanager a context to run in. The second parameter is an array of locations for which we ll be

    allowing the manager instance to manipulate rights for.

    $manager = new RightsEditorManager($this, $locations);$manager->run();

    Fig. 4 - The default layout of the RightsEditorManager in the repository

  • 8/8/2019 Chamilo 2 0 Rights

    19/28

    Chamilo 2.0 Rights Management | 19

    Some additional functionality was added to make the RightsEditorManager useable in as many

    situations as possible.

    Excluding users and groups

    In some cases we may want to exclude a certain set of users or groups from the rights editor

    manager. E.g. the currently logged in user when youre configuring permissions for your own objects.

    To exclude users or groups, simply call one of the following methods and pass on an array of

    user_ids or group_ids.

    //Exclude the currently logged in user$manager->exclude_users(array($this->get_user_id()));//Exclude the currently logged in users groups$manager->exclude_groups($this->get_user()->get_groups(true));

    Filtering users and groups

    To allow flexible usage of the RightsEditorManager interface to the rights application, its necessary

    to be able to filter the list of users and/or groups for whom it is possible to manage rights by means

    of said instance.

    This functional requirement resulted in 2 new methods called limit_users and limit_groups,

    both of which accept an array of respectively user ids and group ids.

    //Limit users to the currently logged in user$manager->limit_users(array($this->get_user_id()));//Limit groups to the currently logged in users groups$manager->limit_groups($this->get_user()->get_groups(true));

    This does not interfere with the exclude_users or exclude_groups functionality. Users and/or

    groups excluded by means of those methods will still be excluded.

    RightsEditorManager modus

    Some applications use groups, some applications only take users into account, others use both. To

    reflect this difference in context, a special modus property was added to the RightsEditorManager.

    Per default the modus will be set to both, enabling the configuration of both users and groups.

    //Allow configuration of groups and users, the default$manager->set_modus(RightsEditorManager :: MODUS_BOTH);//Only allow configuration of groups$manager->set_modus(RightsEditorManager :: MODUS_GROUPS);//Only allow configuration of users$manager->set_modus(RightsEditorManager :: MODUS_USERS);

    The Iron Lion: A Nested Tree

    Locations in Chamilo 2.0 are visually represented as a hierarchical tree. This implicates that each

    node had one parent and can have one or more siblings and/or children. As explained in a previous

    chapter, several problems arose when we only stored a parent for each location node in the tree.

    The absolute reference concerning the storage of trees in SQL would have to be Joe Celkos Trees and

    hierarchies in SQL for smarties. Its a must-read if you want to know more about this method of

    storing and retrieving data, as well as the other alternatives or solutions that exist for this problemdepending on the context.

  • 8/8/2019 Chamilo 2 0 Rights

    20/28

    20 | To Have and Have Not

    The simple usage of the parent-child relation to manipulate the data is what he describes as the

    adjacency list model and is far from quick or easy to use if you need to retrieve entire sets of

    hierarchical data frequently.

    Why nested trees / nested set models?

    How does it work?

    Fig. 5 A typical hierarchical tree structure with the assigned left and right values.

    From Wikipedia:

    The technique is an answer to the problem that the standard SQL operations are unable to

    express all desirable operations on hierarchies directly. A hierarchy can be expressed in terms of a

    parent-child relation but if it can have arbitrary depth, this does not allow the expression of

    operations such as determining whether an element is somewhere in the subhierarchy of another

    element. When the hierarchy is of fixed depth, the operations are possible, but expensive, due to

    the necessity of performing one relational join per level.

    Several resolutions exist and are available in some relational database management systems:

    support for a dedicated hierarchy data type, such as in SQL's hierarchical query facility; extending the relational language with hierarchy manipulations, such as in the nested

    relational algebra.

    extending the relational language with transitive closure; this allows a parent-childrelation to be used, but execution remains expensive;

    the queries can be expressed in a language that supports iteration and is wrapped aroundthe relational operations, such as PL/SQL or T-SQL

    When these solutions are not available or not feasible, another approach must be taken.

  • 8/8/2019 Chamilo 2 0 Rights

    21/28

    Chamilo 2.0 Rights Management | 21

    The expensive nature of the updates is part of the reason we introduced trees per application at first

    and also sub trees later on. Limiting the number of related nodes directly limits the number of left

    and right values that have to be recalculated and per extension the expense of updates.

    There are plenty of examples on the internet of practical ways to use this structure, what follows are

    just a few basic examples which proved essential for rights management:

    Finding all leaf nodesSELECT * FROM table WHERE right = left + 1;

    Finding all parents of a nodeSELECT * FROM table WHERE left < node.left AND right > node.right

    Finding all children of a nodeSELECT * FROM table WHERE left > node.left AND right < node.right

    Number of children(node.right node.left 1) / 2

    Is the node a child of ... ?node.left > parent.left && parent.right > node.right

    Is the node a parent of ... ?node.left < child.left && child.right < node.right

    Sultan of Swing: The Rights Algorithm

    Now that you fully understand the way the rights management system works it s time to go over the

    entire permissions checking algorithm as used in Chamilo 2.0. Imagine a developer has called the

    is_allowed method and passed on all commonly used parameters.

    Parameter Description

    right The right to be checked

    location The numeric identifier of the locations object instance id or

    component identifier

    type The type of the location

    application The application name

    tree_identifier The numeric identifier of the locations subtree

    tree_type The type of the location subtree

    Table 10 The parameters being passed to the is_allowed method of RightsUtilities

    From Wikipedia:

    The solution of the nested set model is to number the nodes according to a tree traversal, which

    visits each node twice, assigning numbers in the order of visiting, and at both visits. This leaves

    two numbers for each node, which are stored as two attributes. Querying becomes inexpensive:

    hierarchy membership can be tested by comparing these numbers. Updating requiresrenumbering and is therefore expensive.

  • 8/8/2019 Chamilo 2 0 Rights

    22/28

    22 | To Have and Have Not

    This would result in the following logic flow:

    1. Is the user_id set?1.1. Yes, retrieve the user object for the given id1.2. No, retrieve the current user_id from the session and retrieve the user object

    2. Generate a unique cache_id from all parameters and verify whether the check was performedbefore.

    2.1. Yes, return the result2.2. No, continue

    3. Is the user a platform administrator?3.1. Yes, immediately return true3.2. No, continue

    4.

    Retrieve the location based on the parameters (identifier, type, tree_identifier,tree_type, application)

    4.1. Return false if the location does not exist4.2. If it does, continue

    5. Does the location have a locked parent?5.1. Yes, the locked parent becomes the new base location5.2. No, continue

    6. Retrieve the hierarchical sequence containing the location and its parents7. Get the groups the user is a member of and for each group

    7.1. Retrieve rights templates applied to the group and for each template and each location thesequence

    7.1.1.Check whether a template relation is defined and if it the right is granted, return true7.1.2.If the location does not inherit from its parent, break the loop

    7.2. For each location in the sequence7.2.1.Check whether a group relation is defined and if it the right is granted, return true7.2.2.If the location does not inherit from its parent, break the loop

    8. Get the rights templates applied to the individual user and for each template and each location inthe sequence

    8.1. Check whether a template relation is defined and if it the right is granted, return true8.2. If the location does not inherit from its parent, break the loop

    9. For each location in the sequence9.1. Check whether a user relation is defined and if it the right is granted, return true9.2. If the location does not inherit from its parent, break the loop

    10. If we encountered no granted permissions by now, return false.11.Cache the result for later reference

  • 8/8/2019 Chamilo 2 0 Rights

    23/28

    Chamilo 2.0 Rights Management | 23

    The Invisible Touch: Where are rights visible?

    If implemented well throughout the platform then the rights management should be fairly invisible.

    With the exception of things like configuring sharing-rights in the repository, the system almost

    always operates in the background. Additional options will be made visible or will be hidden

    according to the rights which a user is granted, either directly or by means of a rights template or

    group membership.

    Should you happen to be trying to access a page which you have no permissions for, youre likely to

    encounter error messages like the one below. They are, quite obviously, a direct result of a

    permissions check via the rights management application.

    Fig. 6 A possible error message indicating a user does not have the necessary permissions

    A somewhat less obvious example is the selection of moderators in the Chamilo translation

    application. Visually it looks like just another element finder, but in the background the selection is

    converted to basic rights. The get_allowed_users method is used to retrieve the moderators for a

    specific language and as you may have guessed individual languages are defined as locations.

    Fig. 7 An example of rights management operating in the background of the translations tool

  • 8/8/2019 Chamilo 2 0 Rights

    24/28

    24 | To Have and Have Not

    Basically a lot of things could be described as rights. The current system of subscribing users to a

    course is also a way of defining certain globalised right and could just as easily be expressed as a set

    of rights. At the same time we should carefully consider where and when to use complete rights

    management and where to use other solutions.

    Its by no means the solution to everything and forcing it to be something it s not would only lead toserious performance issues and unnecessary complicating of the existing structures.

    End of the Line: Using Rights

    Up until now you havent actually had to do anything, have you? The entire framework is there, but

    how do you go about performing actual permissions checks in your applications?

    Defining a rights interface

    Before you can get started youll have to implement a rights interface for your application whichmakes using the RightsUtilities class just a little easier. As discussed before this interface also

    contains the definition of your elementary rights, so you may want to take some time to determine

    what those rights should be.

    The result could be as simple as this:

  • 8/8/2019 Chamilo 2 0 Rights

    25/28

    Chamilo 2.0 Rights Management | 25

    Installing static locations

    As you may have noticed, the above example defines a few locations within the application as

    constants. Why define them that way? The answer is simple: performance. Storing and querying

    relatively short integers is a lot faster than storing and especially querying long strings.

    These components are not defined by the user when he or she runs the application, they are added

    whenever the application is installed and never change. Such static locations are defined in an xml

    file located in the applications rights folder and could look like this:

    Adding dynamic locations

    If your application will contain dynamic locations, defined by users, youll have to add some code to

    the respective objects to make sure corresponding locations are created whenever a new instance of

    such a user-defined object is created. An example of this is the creation of content objects:

    function create(){

    $dm = RepositoryDataManager :: get_instance();$this->set_object_number($dm->get_next_content_object_number());

    if (! $dm->create_content_object($this, 'new')){

    return false;}

    $parent = $this->get_parent_id();if (! $parent){

    $parent_id = RepositoryRights :: get_user_root_id($this->get_owner_id());}else{

    $parent_id = RepositoryRights ::get_location_id_by_identifier_from_user_subtree('repository_ca

    tegory', $this->get_parent_id(), $this->get_owner_id());}

    if (! RepositoryRights :: create_location_in_user_tree($this->get_title(),'content_object', $this->get_id(), $parent_id, $this->get_owner_id()))

    {return false;

    }

    return true;}

    Please note that if your object is part of a hierarchic structure, you will have to determine the rights

    locations of those parents. It might be interesting to create some helper methods in your rightsinterface that can handle these things for you. In a lot of cases these methods will simply be

  • 8/8/2019 Chamilo 2 0 Rights

    26/28

    26 | To Have and Have Not

    references to a general RightsUtilities method with a few more predefined parameters. Just have

    a look at the helper methods from the code snippet for the creation of content objects.

    Performing checks

    The culmination of all these objects, interfaces and algorithms is without a doubt the actual check for

    a certain right on a certain location, so here goes:

    if (! LaikaRights :: is_allowed(LaikaRights :: VIEW_RIGHT, LaikaRights ::LOCATION_GRAPHER, 'laika_component'))

    {$this->display_header($trail);$this->display_error_message(Translation :: get('NotAllowed'));$this->display_footer();exit();

    }

    Talk about an anti-climax ... but lets face it: would you be inclined to use a system that forces you to

    perform six calls to different methods and who knows how many other operations to perform such a

    basic check? We sure wouldnt.

    Get involved

    Do you like the possibilities that rights management creates for Chamilo 2.0? Would you like to get

    involved or are you interested in cooperating?

    Dont hesitate to contact us via e-mail or let us know about your project(s) via the community

    website located at http://www.chamilo.org. Were looking forward to hearing from you.

  • 8/8/2019 Chamilo 2 0 Rights

    27/28

    Chamilo 2.0 Rights Management | 27

    Index

    A

    Adjacent List .................................................................. 20

    Algorithm..................................................... 14, 15, 17, 21

    C

    Child ........................................................................ 20, 21

    Code snippet ................................................................. 26

    Component........................... ........ 9, 12, 13, 16, 21, 25, 26

    D

    DBMS ............................................................................. 11

    Dynamic........................................................................ 25

    G

    Group ........................ ..... 10, 11, 12, 14, 17, 18, 19, 22, 23

    H

    Helper ................... ..................... ...... 14, 15, 16, 17, 18, 25

    I

    identifier ................... 11, 12, 13, 15, 16, 17, 21, 22, 25, 26

    Inheritance ............................... 8, 9, 10, 12, 13, 15, 17, 22

    Interface ................... ..................... .. 14, 15, 18, 19, 24, 25

    is_allowed ........................ ................ 15, 16, 17, 21, 24, 26

    L

    Left .................................................................... 13, 20, 21

    Locking ...................... ..................... .. 10, 12, 13, 15, 17, 22

    N

    Nested Set.................................................................... 20

    Nested Tree .................... ..................... ............... 13, 19, 20

    P

    Parent..................10, 12, 13, 15, 17, 19, 20, 21, 22, 25, 26

    R

    Relation ................... ............. 10, 11, 12, 14, 17, 18, 20, 22

    Right .... 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22,

    24, 26

    RightsEditorManager .............................................. 18, 19

    RightsUtilities ................................ ... 14, 15, 16, 21, 24, 26

    Root ..................... ..................... ................ 9, 16, 17, 25, 26

    S

    Static .................................................................. 15, 25, 26

    Storage unit .................... ..................... ......... 11, 12, 13, 15

    T

    Template ..................... ..................... 10, 11, 12, 17, 22, 23

    tree_identifier .................... .............. 13, 15, 16, 17, 21, 22

    tree_type ......................................... 13, 15, 16, 17, 21, 22

    type .......................9, 12, 13, 15, 16, 17, 21, 22, 24, 25, 26

    U

    User .... 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 23,

    24, 25, 26

  • 8/8/2019 Chamilo 2 0 Rights

    28/28

    This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. To

    view a copy of this license visit http://creativecommons org/licenses/by sa/3 0/ or send a letter to