Authorization

From StatusNet
Jump to: navigation, search
Roles are identified by 32-char strings. Rights to do things are granted 
to roles, /not/ to individuals (for now). You can give rights to an 
individual by adding them to a role. We have a table in the database, 
user_role, that maps users (by id) to roles.

Note that "roles" are similar to "groups" in POSIX systems; but we 
already have groups in StatusNet, which are orthogonal, so I've used the 
term "role" instead (which I think is clearer, anyways).

Non-local users cannot exercise any additional rights, for the simple 
reason that we don't authenticate them.

Rights are constants in a new class, 'Right' (lib/right.php). The value 
of the rights are strings right now; they could be integers if we need 
them to be. The constant names are verbs or verb phrases, like 
"deleteOthersNotice" or "banUsers".

We have two pre-defined roles in the system:

    * 'moderator' is someone who manages the social life of an instance.
      They have (or will have) rights to do things like delete other
      users' notices, ban users, block users from posting to the public
      timeline, deleting another users' account, promoting a member of
      any group to group admin, marking a notice as spam, sending a
      direct message to anyone, granting or revoking roles from other users.
    * 'admin' is someone who handles the technical parts of an instance.
      Their primary right is to change configuration settings (like the
      theme, name of the instance, etc.) (Yes, there's a slight overlap
      with the "group admin" name. I guess we could say "site admin" and
      "group admin" to  distinguish.)

There's no reason that one person couldn't have both of these roles 
simultaneously; on small systems it makes a lot of sense.

Which roles can execute which rights are defined in User::hasRight(). 
It's just a switch() statement right now. It's strictly forbidden (by 
me) for any code to try to do roles-to-rights mapping itself; instead it 
must use this helper function. This way, as the authorization framework 
matures, most code will be insulated from the changes.

There is not an interface for granting roles to users; there will be by 
the time we release 0.9.x.

Plugins can define their own roles, and should probably use prefixed 
strings to prevent namespace collisions (e.g. "MyPlugin::registeredUser" 
rather than just "registeredUser" or "reg" or "registered"). Plugins can 
also define their own rights, which should also be prefixed strings and 
should probably also be defined constants (so: class MyPlugin { const 
canUse = "MyPlugin::canUse"; ... }.

Plugins can hook the UserRightsCheck event to describe the rules for 
their own roles and rights/./ So a plugin with its own authorization 
stuff might look something like this:

    class MyPlugin
    {
        const canUse = "MyPlugin::canUse";

        function onEndNoticeSave($notice)
        {
             $user = common_current_user();

             if ($user->hasRight(MyPlugin::canUse)) {
                // do something here
             }
        }
        
        function onUserRightsCheck($user, $right, &$result) {
               if ($right == MyPlugin::canUse) {
                   $result = $user->hasRole("MyPlugin::registeredUser");
	           return false; // done processing!
               }
               return true; // unchanged!
        }
    }


Note that the plugin uses User::hasRight(), even though it defines the 
rights mapping itself later.

Event handlers can also hook UserRightsCheck /to override the default 
rights system./ So, if on your system, /anyone /can delete another 
person's notice (say), you could do this:

     function FreeForAll($user, $right, &$result)
     {
         if ($right == Right::deleteOthersNotice) {
              $result = true;
              return false; // no further or default processing
         }
         return true;
     }

     Event::addHandler('UserRightsCheck', 'FreeForAll');

Note that the return value from rights-modifying code may be 
counter-intuitive.

Future versions of the software (post-0.9.x) may have the following 
features, depending on demand:

    * Grant of rights to users as well as roles.
    * A finer-grained system of built-in roles. I vastly prefer a very
      simple system; I doubt 99% of sites will need more than
      "moderator" and "admin".
    * Use of the rights system for some of the existing "rights" --
      things that only registered users can do that anonymous users
      can't, for example.
    * Storing the mapping of role-to-right in the database.
    * Allowing some super-user to re-jigger the rights mappings in some
      kind of Web interface.
Personal tools
Namespaces
Variants
Actions
Navigation
Status.net
Toolbox