Submitted : API « authorize »

**SPIP**

# Article submitted

The article "**API «authorize»**
(https://www.spip.net/ecrire/?exec=article&id_article=6599)" is submitted
for publication. on Wednesday 30 September 2020.

* * *

## API «authorize»

Wednesday 30 September 2020 , by [jack](.././?page=auteur&id_auteur=593&)

The programming interface (https://en.wikipedia.org/wiki/API) (API)
"authorize" introduced in SPIP 2.0
(https://www.spip.net/ecrire/?exec=article&id_article=3837) allows to
finely manage the authorizations given to an author to perform an action on
an object.

## Table of contents

* Check an authorization
* Give an exceptional authorization
* Declare a new authorisation
* Development support

## Check an authorization[|Back to the table of
contents](#s-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)` accepts 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</code>** 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 chain that designates what the action is about. It is
generally the type of an editorial object (article, section, word, word
group, ...).
* **`$id`** designs l’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 do the requested action.

In a template, the verification of an authorization is done by the tag
`#AUTORISER` (https://www.spip.net/ecrire/?exec=article&id_article=5103).

## Give an exceptional authorization[|Back to the table of
contents](#s-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
(https://www.spip.net/ecrire/?exec=article&id_article=6581) which will then
be executed anonymously.

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

    include_spip
    
    &#40;

    'inc/autoriser'

    &#41;

    ;

    // give a temporary exceptional authorization

    autoriser_exception
    
    &#40;

    'modifier'

    ,

    'article'

    ,

    $id_article

    &#41;

    ;

    // create the desired action

    include_spip
    
    &#40;

    'action/editer_objet'

    &#41;

    ;

    objet_modifier
    
    &#40;

    'article'

    ,

    $id_article

    ,

    array
    
     (http://www.php.net/array)
    
    &#40;

    'titre'

    =>

    'Nouveau titre'

    &#41;

    &#41;

    ;

    // withdraw the exceptional authorization

    autoriser_exception
    
    &#40;

    'modifier'

    ,

    'article'

    ,

    $id_article

    ,

    false

    &#41;

    ;

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 return`true`
    * 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.

## Declare a new authorisation[|Back to the table of
contents](#s-Declare-a-new-authorisation)

When the generic function `autoriser()` is called, it looks for a named
function to delegate the check 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 precise 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 function`autoriser()` 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 to`autoriser()`.

Note also that from SPIP 3.0
(https://www.spip.net/ecrire/?exec=article&id_article=5533) le `$type` 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 rubric exists and that one has the necessary
status to create
     *
     * @return bool
     */

    function
    
     autoriser_article_creer_dist
    
    &#40;

    $faire

    ,

    $type

    ,

    $id

    ,

    $qui

    ,

    $opt

    &#41;

    &#123;

    return

    &#40;
    
    sql_countsel
    
    &#40;

    'spip_rubriques'

    &#41;

    >

    0
    
     AND
    
    in_array
    
     (http://www.php.net/in_array)
    
    &#40;

    $qui

    &#91;

    'statut'

    &#93;

    ,

    array
    
     (http://www.php.net/array)
    
    &#40;

    '0minirezo'

    ,

    '1comite'

    &#41;

    &#41;

    &#41;

    ;

    &#125;

## Development support[|Back to the table of
contents](#s-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`
(https://www.spip.net/ecrire/?exec=article&id_article=4909):

    define
    
     (http://www.php.net/define)
    
    &#40;

    '_DEBUG_AUTORISER'

    ,

    true

    &#41;

    ;

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.

— Sent by SPIP (https://www.spip.net/)

rubon57-4eda4.jpg