API «autoriser»

The programming interface (API) "autoriser" introduced in SPIP 2.0 allows to acutely manage the authorizations given to an author to perform an action on an object.

Check an authorization

The verification of an authorization is done by a call of the form:

include_spip('inc/autoriser');
if (autoriser('modifier', 'article', $id_article)) {
...
}

The function autoriser($faire, $type, $id, $qui, $opt) takes 5 arguments of which only the first one is mandatory:

  • $faire is a chain that designates the action subject to authorization. It is generally a simple verb (modifier, creer, supprimer, voir, configurer...), sometimes associated with a context (the words are then glued: changerlangue, publierdans...).
    There are a few exceptions where the code>$faire is not a verb and is used without any other argument (autoriser('webmestre') for example, or autoriser('ecrire') — which here refers to the administration space and not the action—).
  • $type is a string that designates the object on which the action is to be performed. It is generally the type of an editorial object (article, section, keyword, keywords group, ...).
  • $id is the id (primary key) of the object to which the action relates. $id is usually an integer, but can be a string if it matches the primary key of the relevant SQL table.
  • $qui designates the author (in the sense of SPIP) who is going to do the action. If it is not provided (or null in the call of the authorize function, the connected author is implicitly taken into account. Otherwise $qui can be the author id of an author whose rights we want to check, or an associative array that describes the author (an array that then contains the fields of the spip_auteurs table for the author concerned)
  • $opt is an associative array of contextual additional data about the action that is sometimes used by the authorization. For example, when you want to edit/publish an article, you will call autoriser('instituer', 'article', $id_article, null, array('statut' => 'publie'))

The function autoriser returns «true» or «false» according to the rights of the author to perform the requested action.

In a template, the verification of an authorization is done by the tag #AUTORISER.

Give an exceptional authorization

Sometimes it is necessary to do an action that will be subject to authorization for an author who normally does not have the right to do so. This can happen, for example, in the case of a scheduled action which will then be executed anonymously.

In this case, there is a mechanism via the function autoriser_exception that gives an exceptional authorization, for the time to perform the concerned action.

include_spip('inc/autoriser');
// give a temporary exceptional authorization
autoriser_exception('modifier', 'article', $id_article);
// create the desired action
include_spip('action/editer_objet');
objet_modifier('article', $id_article, array('titre' => 'Nouveau titre'));
// withdraw the exceptional authorization
autoriser_exception('modifier', 'article', $id_article, false);

The function autoriser_exception($faire, $type, $id, $autoriser) takes 4 arguments:

  • $faire with the same meaning as for autoriser()
  • $type with the same meaning as for autoriser()
  • $id awith the same meaning as for autoriser()
  • $autoriser which is a Boolean and indicates whether the exceptional authorization is granted or not:
    • When $autoriser is «true»or is not provided, an exceptional permission is granted: all subsequent calls to autoriser() with the same arguments $faire, $type and $id will returntrue
    • When $autoriser is «false» this means that the authorization returns under the normal regime and will be verified according to the current rule (it can therefore still be authorized or actually prohibited). The false does not indicate here that the action is forbidden, but simply that there is no longer an exception.

Declaring a new authorisation

When the generic function autoriser() is called, it looks for a named function to delegate the checking to.

If no $type is provided in the call to autoriser(), the function is searched in the following order:

  • autoriser_$faire
  • autoriser_$faire_dist
  • autoriser_defaut
  • autoriser_defaut_dist

If a $type is provided in the call to autoriser(), the search is done in the following order:

  • autoriser_$type_$faire
  • autoriser_$type_$faire_dist
  • autoriser_$type
  • autoriser_$type_dist
  • autoriser_$faire
  • autoriser_$faire_dist
  • autoriser_defaut
  • autoriser_defaut_dist

In both cases, the search goes from the most restricted to the most general. This allows you to define permission families with a general rule (for an action for example), which is then specified for certain objects that follow a different rule.

To define a permission, it is enough to create a function with one of the names in the list above. The function will receive as arguments those sent to the functionautoriser() and must return «true» or «false».

One can define a generic authorization. When it is an authorization that is not yet defined, it is usually suffixed with a _dist that always allows a webmaster to override it in its mes_options.php (by declaring the function of the same name, but without its suffix _dist).

Warning: we see that in the name of the function, the order of $faire and $type is reversed with respect to that of the call toautoriser().

Note also that from SPIP 3.0 the $type argument is assumed to correspond to an object, and is normalized during the call: checking that it corresponds to an object type and otherwise removing the final "s". This ensures that the right authorization function will be called even if we use a synonym of $type (syndic instead of site for example, or groupe_mot instead of groupe_mots which is a naming exception).
It is however possible to escape this normalization by prefixing the $type by a ’_’ (underscore) in the call to autoriser().

In any case, all other ’_’ characters are removed from the $type

Thus a call to autoriser('modifier', 'groupes_mots', $id_groupe) will delegate to the autoriser_groupemots_modifier() function (or one of the variants according to the above rule if this specific function does not exist).
In versions prior to [- >spip30] one should always be very careful to use the name of the object without error, because otherwise the default authorization will be called which can lead to a more or less serious authorization error depending on the case.

Example of authorization function:

/**
 * Allow to create an article:
 * It is necessary that a section exists and that one has the necessary status to create
 * 
 * @return bool
 */
function autoriser_article_creer_dist($faire, $type, $id, $qui, $opt) {
	return (sql_countsel('spip_rubriques')>0 AND in_array($qui['statut'], array('0minirezo', '1comite')));
}

Development support

When developing a plugin, it can be useful to understand how authorizations are called and in what order.

To do this, simply add the following line to the file mes_options.php:

define('_DEBUG_AUTORISER', true);

Each call to autoriser() will then be traced in the spip.log file with the name of the called function and the result it returned.

Author jack Published :

Translations : English, français