mirror of
https://gitlab.easter-eggs.com/ee/ldapsaisie.git
synced 2024-11-20 00:59:17 +01:00
Add API feature
Some major changes have been made to handle this new feature : - LSsession now have a flag about API mode. The displayTemplate() and displayAjaxReturn() methods have been adjust to correctly handle this mode. - LSauth system have been adjust to handle a custom API mode : - LSauthMethod can support or not this mode : the $api_mode_supported permit to defined if supported (default, false). Currently, only HTTP (default in API mode) and annonymous mode support it. - An api_access parameter permit to configure witch type of user LSobject types could use the API. This flag must be set to True to allow a type of LSobject (default: False). In a same way, a web_access parameter now permit to disable Web access for some types of users (but this parameter is optional and its default value is True). - The HTTP method is the privileged first method for API mode. In this mode, if auth data aren't present in environment, it will request it by triggered a 403 HTTP error. Realm can be configured with new LSAUTHMETHOD_HTTP_API_REALM constant. - The LStemplate system handle API mode to correctly react on errors: it return a JSON answer instead of HTML page. Error pages also now return adjusted HTTP code (404 or 500). - The LSurl system have been adjust to handle API mode : - On declaring handlers, we could now specify if it's an API view with new $api_mode paremeter of add_handler() method - The LSurlRequest object have a new attribute to check if it's an API request - The error_404() method handle the API mode to return JSON answer. Furthermore, if no handlers matched with the requested URL, API mode is automatically enabled if the requested URL starts with 'api/'. - LSform implement it own API mode flag and a new submited flag that be toggle via the new setSubmited() method. Some major changes also occured on LSformElement classes to specifically handle API input/output for each types of attributes: - a new getApiValue() method permit to retrieve the API value of the attribute (on show API view) - the getPostData() method now have to correctly handle API input for the attribute (on create/modify API views). A programmatic way have been adopted for each types of attributes. - The LSimport and LScli create/modify commands also evolved to enable API mode of the LSform. This permit to take advantage of the new capability of LSform/LSformElement to handle input values with a programmatic way. - New routes have been add to handle API views. All this new routes start with 'api/1.0/' and use the same URL schema as the web UI. The API currently permit to search/show/add/modify/remove LSobjects and manages their relations.
This commit is contained in:
parent
e92bc10c8b
commit
0ec390e1fe
36 changed files with 2329 additions and 717 deletions
|
@ -22,6 +22,7 @@ book SYSTEM "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
|||
<!ENTITY install SYSTEM "install/install.docbook">
|
||||
<!ENTITY install-arbo SYSTEM "install/arbo.docbook">
|
||||
<!ENTITY upgrade SYSTEM "upgrade/upgrade.docbook">
|
||||
<!ENTITY api SYSTEM "api/api.docbook">
|
||||
<!ENTITY contrib SYSTEM "contrib/contrib.docbook">
|
||||
]>
|
||||
|
||||
|
@ -53,5 +54,7 @@ book SYSTEM "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
|||
|
||||
&conf;
|
||||
|
||||
&api;
|
||||
|
||||
&contrib;
|
||||
</book>
|
||||
|
|
435
doc/api/api.docbook
Normal file
435
doc/api/api.docbook
Normal file
|
@ -0,0 +1,435 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<chapter>
|
||||
<title>API</title>
|
||||
|
||||
<para>Depuis la version 4.0, LdapSaisie offre une API visant à permettre de faire
|
||||
les mêmes choses que ce qu'il est possible d'accomplir via l'interface web. L'idée
|
||||
n'est bien entendue pas de se substituer systématiquement à la possibilité de se
|
||||
connecter directement à l'annuaire, mais plutôt d'offrir une API web pour l'intégration
|
||||
d'outil préférant ce mode d'interaction, ou encore, pour exposer des méthodes accès aux
|
||||
données de l'annuaire tout en profitant des logiques métiers implémentées/configurées
|
||||
dans LdapSaisie : validation syntaxique et d'unicité, règle de génération et
|
||||
d'interdépendances des attributs, déclencheurs, ...</para>
|
||||
|
||||
<note><simpara>Cette API est actuellement dans une phase de test et n'offre pas encore
|
||||
toutes les fonctionnalités proposées dans l'interface web. Elle est vouée à évoluer pour
|
||||
intégrer petit à petit un maximum de fonctionnalités. Des contributions à ce sujet seront
|
||||
plus qu'appréciée !</simpara></note>
|
||||
|
||||
<sect1>
|
||||
<title>Authentification</title>
|
||||
|
||||
<para>L'authentification à l'API utilise le même composant <literal>LSauth</literal> que
|
||||
lors d'une authentification à l'interface web, cependant, ce composant s'adapte pour
|
||||
prendre en compte de mode de connexion. Par défaut, la méthode d'authentification utilisée
|
||||
sera &LSauthMethod_HTTP; et permettra de se connecter en spécifiant le nom d'utilisateur
|
||||
et le mot de l'utilisateur cherchant à se connecter via une authentification basique HTTP.
|
||||
</para>
|
||||
|
||||
<warning><simpara>Il est à noter que tous les types d'utilisateur ne peuvent pas forcément
|
||||
utiliser l'API : le paramètre <literal>api_access</literal> doit être explicitement
|
||||
positionné à <literal>True</literal> dans <link linkend='config-srv-ldap'>la configuration
|
||||
du serveur LDAP</link>.</simpara></warning>
|
||||
|
||||
<para>Une fois connecté, l'utilisateur endossera les droits associés à ses &LSprofiles;,
|
||||
tout comme un utilisateur connecté à l'interface web.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Méthodes exposées</title>
|
||||
|
||||
<para>Les URLs des méthodes de l'API ont été construites par mimétisme sur celle de l'interface
|
||||
web et sous la racine web <literal>api/</literal>. Par ailleurs, un numéro de version d'API a
|
||||
été insérée dans chacune d'elles afin d'anticiper toutes évolutions futures majeures nécéssitants
|
||||
de conserver une rétrocompatibilité avec les anciennes versions de l'API.</para>
|
||||
|
||||
<para>Toutes les méthodes retournent des informations au format JSON et accepte le paramètre
|
||||
<literal>pretty</literal> permettant d'obtenir un retour plus facilement lisible. Les chaines de
|
||||
caractères échangées doivent par ailleurs être encodées en UTF-8. On trouvera par ailleurs dans
|
||||
le retour JSON :
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>success</term>
|
||||
<listitem><simpara>Booléen précisant si l'action demandée a correctement été exécutée.</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>messages</term>
|
||||
<listitem><simpara>Ce tableau pourra être présent et lister les messages d'informations générées
|
||||
par l'action demandée. Il s'agira des mêmes messages que ceux affichés dans l'interface web
|
||||
lorsque les actions équivalentes y sont faites.</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>errors</term>
|
||||
<listitem><simpara>Ce tableau pourra être présent et lister les messages d'erreurs générées
|
||||
par l'action demandée.</simpara></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
<note><simpara>Les messages d'informations et d'erreurs générées par l'application sont traduites dans
|
||||
la langue courante qui peut être spécifiée via le paramètre <literal>lang</literal> accepté par toutes
|
||||
les méthodes (exemple : <literal>fr_FR</literal> ou <literal>en_US</literal>).</simpara></note>
|
||||
|
||||
<para>Lorsqu'une méthode cible un type d'objets, voir un objet en particulier, ces informations seront
|
||||
transmises dans l'URL appelée. Si le type d'objet ou l'objet demandé est introuvable, une erreur HTTP
|
||||
404 sera générée.</para>
|
||||
|
||||
<!-- Début Liste des méthodes exposées -->
|
||||
<variablelist>
|
||||
<title>Liste des méthodes exposées</title>
|
||||
|
||||
<varlistentry>
|
||||
<term>/api/1.0/object/[object type]</term>
|
||||
<listitem>
|
||||
<para>Cette méthode permet de rechercher/lister les informations d'un type d'objets de
|
||||
l'annuaire en particulier. Le type de l'objet est précisé dans l'URL et doit être encodé en
|
||||
conséquence. Par mimétisme du comportement de l'interface web, la recherche est paginée et
|
||||
accepte des paramètres similaires en plus de paramètre plus appropriés à un fonctionnement
|
||||
programmatique :
|
||||
<variablelist>
|
||||
<title>Paramètres acceptés</title>
|
||||
|
||||
<varlistentry>
|
||||
<term>filter</term>
|
||||
<listitem><simpara>Permet de spécifier un filtre de recherche LDAP personnalisé. Celui-ci
|
||||
sera combiné avec les paramètres propres au type d'objets recherchés et aux autres
|
||||
paramètres spécifiés (<literal>pattern</literal> par exemple).</simpara>
|
||||
<warning><simpara>Pour le moment, seuls les filtres simples du type <literal>attribut=valeur
|
||||
</literal> sont acceptés ici.</simpara></warning>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>predefinedFilter</term>
|
||||
<listitem><simpara>Permet de spécifier un des filtres de recherche LDAP prédéfinis dans la
|
||||
configuration du type d'objet.</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>pattern</term>
|
||||
<listitem><simpara>Permet de spécifier un mot clé de recherche, comme proposé dans
|
||||
l'interface web.</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>approx</term>
|
||||
<listitem><simpara>Booléen permettant d'activer/désactiver la recherche approximative
|
||||
sur le mot clé. Les valeurs acceptées sont <literal>1</literal> ou <literal>0</literal>.
|
||||
</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>basedn</term>
|
||||
<listitem><simpara>Permet de spécifier une base de recherche personnalisé pour la recherche.
|
||||
</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>subDn</term>
|
||||
<listitem><simpara>Dans le cas d'un serveur LDAP configuré avec des <link linkend="config-subDn">
|
||||
sous-niveaux de connexion</link>, permet de spécifier le sous-niveau pour la recherche.</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>scope</term>
|
||||
<listitem><simpara>Permet de spécifier l'étendue de la recherche dans l'annuaire. Valeurs acceptées:
|
||||
<literal>sub</literal>, <literal>one</literal> et <literal>base</literal>.</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>recursive</term>
|
||||
<listitem><simpara>Booléen permettant d'activer/désactiver la recherche recursive, c'est à dire une
|
||||
recherche à la racine de l'annuaire (ou du <link linkend="config-subDn">sous-niveau de connexion</link>)
|
||||
avec une étendue de recherche maximale. Les valeurs acceptées sont <literal>1</literal> ou
|
||||
<literal>0</literal>.</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>displayFormat</term>
|
||||
<listitem><simpara>Permet de spécifier un &LSformat; personnalisé pour le nom des objets dans le résultat
|
||||
de recherche.</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>extraDisplayedColumns</term>
|
||||
<listitem><simpara>Booléen permettant d'activer le retour des colonnes personnalisées dans le résultat
|
||||
de recherche. Les valeurs acceptées sont <literal>1</literal> ou <literal>0</literal>.</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>attributes</term>
|
||||
<listitem><simpara>Liste des attributs supplémentaires que devra retourner la recherche.</simpara>
|
||||
<warning><simpara>Attention, ici ce sont les valeurs brutes des attributs qui seront retournées et
|
||||
par forcément les valeurs telle que retournées habituellement.</simpara></warning>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>sortBy</term>
|
||||
<listitem><simpara>Permet de préciser sur quelle information le résultat de recherche doit être
|
||||
trié. Valeurs acceptées : <literal>displayName</literal>, <literal>subDn</literal> ou un des noms
|
||||
des colonnes personnalisées.</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>sortDirection</term>
|
||||
<listitem><simpara>Permet de préciser l'ordre de tri du résultat de recherche. Valeurs acceptées :
|
||||
<literal>ASC</literal> (A-Z) ou <literal>DESC</literal> (Z-A).</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>page</term>
|
||||
<listitem><simpara>Permet de préciser la page du résultat de recherche.</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>nbObjectsByPage</term>
|
||||
<listitem><simpara>Permet de préciser le nombre maximum d'objets retournés par page du résultat de
|
||||
recherche.</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>all</term>
|
||||
<listitem><simpara>Permet de réclamer le résultat complet de la recherche (désactivation
|
||||
de la pagination). Seul la présence de ce paramètre suffit à activer ce comportement, sa
|
||||
valeur n'a pas d'importance.</simpara></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>withoutCache</term>
|
||||
<listitem><simpara>Booléen permettant de désactiver l'utilisation du cache. Les valeurs acceptées
|
||||
sont <literal>1</literal> ou <literal>0</literal>.</simpara></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
<programlisting linenumbering="unnumbered">
|
||||
<citetitle>Exemple</citetitle>
|
||||
<![CDATA[# curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople?extraDisplayedColumns=1&pretty'
|
||||
{
|
||||
"success": true,
|
||||
"objects": {
|
||||
"uid=hmartin,ou=people,o=ls": {
|
||||
"name": "Henri MARTIN",
|
||||
"Mail": "henri.martin@ls.com"
|
||||
},
|
||||
"uid=s.ldapsaisie,ou=people,o=ls": {
|
||||
"name": "Secretariat LdapSaisie",
|
||||
"Mail": "secretariat@ldapsaisie.biz"
|
||||
},
|
||||
"uid=ls,ou=people,o=ls": {
|
||||
"name": "LdapSaisie",
|
||||
"Mail": "ldap.saisie@ls.com"
|
||||
},
|
||||
"uid=erwpa,ou=people,o=ls": {
|
||||
"name": "Erwan PAGE",
|
||||
"Mail": "erwan.page@ldapsaisie.biz"
|
||||
},
|
||||
"uid=user2,ou=people,ou=company1,ou=companies,o=ls": {
|
||||
"name": "prenom2 nom2",
|
||||
"Mail": "user2@ls.com"
|
||||
}
|
||||
},
|
||||
"total": 14,
|
||||
"page": 1,
|
||||
"nbPages": 3
|
||||
}]]>
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>/api/1.0/object/[object type]/[dn]</term>
|
||||
<listitem>
|
||||
<para>Cette méthode permet de récupérer les informations d'un objet de l'annuaire au format
|
||||
JSON. Le type de l'objet et son DN sont précisés dans l'URL et doivent être encodés en
|
||||
conséquence.
|
||||
<programlisting linenumbering="unnumbered">
|
||||
<citetitle>Exemple</citetitle>
|
||||
<![CDATA[# curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople/uid=hmartin,ou=people,o=ls?pretty'
|
||||
{
|
||||
"dn": "uid=hmartin,ou=people,o=ls",
|
||||
"type": "LSpeople",
|
||||
"name": "Henri MARTIN",
|
||||
"attributes": {
|
||||
"uid": "hmartin",
|
||||
"givenName": "Henri",
|
||||
"sn": "MARTIN",
|
||||
"cn": "Henri MARTIN",
|
||||
"mail": "henri.martin@ls.com",
|
||||
"personalTitle": "M.",
|
||||
"description": [],
|
||||
"jpegPhoto": null,
|
||||
"lsGodfatherDn": {
|
||||
"uid=eeggs,ou=people,o=ls": {
|
||||
"name": "Easter Eggs",
|
||||
"object_type": "LSpeople"
|
||||
}
|
||||
},
|
||||
"uidNumber": "101022",
|
||||
"gidNumber": "102001",
|
||||
"loginShell": "no",
|
||||
"homeDirectory": "\/home\/com",
|
||||
"gecos": null,
|
||||
"shadowExpire": null,
|
||||
"shadowMax": null,
|
||||
"shadowInactive": null,
|
||||
"shadowLastChange": null,
|
||||
"sambaSID": "S-1-5-21-2421470416-3566881284-3047381809-203044",
|
||||
"sambaPrimaryGroupSID": "S-1-5-21-2421470416-3566881284-3047381809-205003",
|
||||
"sambaAcctFlags": [
|
||||
"U"
|
||||
],
|
||||
"sambaHomeDrive": null,
|
||||
"sambaHomePath": null,
|
||||
"sambaProfilePath": null,
|
||||
"sambaLogonScript": null,
|
||||
"sambaLogonTime": null,
|
||||
"sambaLogoffTime": null,
|
||||
"sambaKickoffTime": null,
|
||||
"sambaPwdLastSet": null,
|
||||
"sambaPwdMustChange": null,
|
||||
"sambaPwdCanChange": null
|
||||
},
|
||||
"relations": {
|
||||
"groups": {
|
||||
"cn=direction,ou=groups,o=ls": "direction",
|
||||
"cn=secretariat,ou=groups,o=ls": "secretariat"
|
||||
},
|
||||
"godfather": []
|
||||
}
|
||||
}]]>
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>/api/1.0/object/[object type]/create</term>
|
||||
<listitem>
|
||||
<para>Cette méthode permet de créer un objet dans l'annuaire. Le type de l'objet qui sera créé est
|
||||
précisé dans l'URL et doit être encodé en conséquence. Les informations de l'objet doivent est
|
||||
transmises au format <literal>x-www-form-urlencoded</literal>. Elles peuvent également être au
|
||||
format <literal>multipart/form-data</literal>, en particulier si votre requête contient une image.
|
||||
Par mimétisme avec l'interface web, seuls les attributs prévus dans le formulaire de création du
|
||||
type d'objet peuvent être passées ici. De la même manière, les attributs non-spécifiés ici, pouront
|
||||
être auto-générés en accord avec leur configuration et la requête sera acceptée uniquement si tous les
|
||||
attributs obligatoires y sont spécifiés ou s'ils peuvent être auto-générés.</para>
|
||||
<para>Le format et la syntaxe des valeurs des attributs dépends de leur type HTML. Ainsi, par exemple,
|
||||
un attribut de type HTML <literal>boolean</literal> acceptera comme valeurs possibles <literal>yes
|
||||
</literal> ou <literal>no</literal>. Pour plus de détails sur le type de valeur acceptée par un type
|
||||
d'attribut HTML en particulier, consultez sa documentation. Vous pouvez également analyser le code de
|
||||
la méthode <literal>getPostData()</literal> de la classe PHP correspondante.</para>
|
||||
<para>Si l'application détecte un souci avec les informations transmises pour les attributs, un tableau
|
||||
<literal>fields_errors</literal> sera présent dans la réponse JSON et contiendra pour chacun des attributs
|
||||
problématique, un tableau des messages d'erreurs générées par l'application.</para>
|
||||
<para>Si le type d'objet en prévoit, vous pouvez également utiliser un
|
||||
<link linkend="config-LSobject-LSform-dataEntryForm">masque de saisie</link> via le paramètre <literal>
|
||||
dataEntryForm</literal>.</para>
|
||||
<programlisting linenumbering="unnumbered">
|
||||
<citetitle>Exemple</citetitle>
|
||||
<![CDATA[# curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople/create?pretty' -d "uid=foo.bar&personalTitle=M.&givenName=foo&sn=bar&cn=Foo Bar&mail=foo.bar@example.com&userPassword=Y0urS3cr3t&lsGodfatherDn[]=uid=admin,ou=people,o=ls&gidNumber=70000"
|
||||
{
|
||||
"success": true,
|
||||
"type": "LSpeople",
|
||||
"dn": "uid=foo.bar,ou=people,o=ls",
|
||||
"name": "Foo Bar",
|
||||
"messages": [
|
||||
"Le mail de notification a \u00e9t\u00e9 envoy\u00e9.",
|
||||
"L'objet a \u00e9t\u00e9 ajout\u00e9."
|
||||
]
|
||||
}]]>
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>/api/1.0/object/[object type]/[dn]/modify</term>
|
||||
<listitem>
|
||||
<para>Cette méthode permet de modifier un objet dans l'annuaire. Le type de l'objet et son DN sont
|
||||
précisés dans l'URL et doivent être encodés en conséquence. Les informations de l'objet à modifier
|
||||
doivent être transmises au même format que pour la méthode <literal>create</literal> (voir ci-dessus).
|
||||
Comme pour cette dernière, seuls les attributs prévus dans le formulaire de modification du type
|
||||
d'objet peuvent être passées ici et la réponse JSON pourra contenir un tableau <literal>fields_errors
|
||||
</literal> contenant les erreurs générées par l'application au sujet des valeurs transmises pour les
|
||||
attributs.</para>
|
||||
<programlisting linenumbering="unnumbered">
|
||||
<citetitle>Exemple</citetitle>
|
||||
<![CDATA[# curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople/uid=foo.bar,ou=peopleo=ls/modify?pretty' -d "givenName=foo&sn=bar&cn=Foo Bar"
|
||||
{
|
||||
"dn": "uid=foo.bar,ou=people,o=ls",
|
||||
"type": "LSpeople",
|
||||
"name": "Foo Bar",
|
||||
"success": true,
|
||||
"messages": [
|
||||
"L'objet a bien \u00e9t\u00e9 modifi\u00e9."
|
||||
]
|
||||
}]]>
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>/api/1.0/object/[object type]/[dn]/remove</term>
|
||||
<listitem>
|
||||
<para>Cette méthode permet de supprimer un objet dans l'annuaire. Le type de l'objet et son DN sont
|
||||
précisés dans l'URL et doivent être encodés en conséquence.</para>
|
||||
<programlisting linenumbering="unnumbered">
|
||||
<citetitle>Exemple</citetitle>
|
||||
<![CDATA[# curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople/uid=foo.bar,ou=people,o=ls/remove?pretty'
|
||||
{
|
||||
"dn": "uid=foo.bar,ou=people,o=ls",
|
||||
"type": "LSpeople",
|
||||
"name": "Foo Bar",
|
||||
"success": true,
|
||||
"messages": [
|
||||
"Foo Bar a bien \u00e9t\u00e9 supprim\u00e9."
|
||||
]
|
||||
}]]>
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>/api/1.0/object/[object type]/[dn]/relation/[relation]</term>
|
||||
<listitem>
|
||||
<para>Cette méthode permet de gérer les objets en relation avec un objet en particulier de
|
||||
l'annuaire. Le type de l'objet, son DN et le nom de la relation sont précisés dans l'URL et
|
||||
doivent être encodés en conséquence. Cette méthode accepte les paramètres <literal>add
|
||||
</literal> et <literal>remove</literal> permettant de lister le ou les DN d'objet(s) à
|
||||
respectivement ajouter ou supprimer parmis les objets actuellement en relation avec l'objet
|
||||
spécifié. Si aucun DN n'est spécifié comme devant être ajouté ou supprimé, la méthode
|
||||
retournera simplement les DN des objets en relation. En cas de modification demandée, la
|
||||
méthode retournera la nouvelle liste des DNs des objets en relation, quel que soit le résultat
|
||||
de l'opération de mise à jour.</para>
|
||||
<programlisting linenumbering="unnumbered">
|
||||
<citetitle>Exemple</citetitle>
|
||||
<![CDATA[# curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople/uid=foo.bar,ou=people,o=ls/relation/groups?pretty&add[]=cn=test34,ou=groups,o=ls&add[]=cn=testbr,ou=groups,o=ls'
|
||||
{
|
||||
"dn": "uid=foo.bar,ou=people,o=ls",
|
||||
"type": "LSpeople",
|
||||
"name": "Foo Bar",
|
||||
"relation": "groups",
|
||||
"success": true,
|
||||
"relatedObjects": [
|
||||
"cn=test34,ou=groups,o=ls",
|
||||
"cn=testbr,ou=groups,o=ls"
|
||||
],
|
||||
"messages": [
|
||||
"Objects in relation updated."
|
||||
]
|
||||
}]]>
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
|
@ -3,6 +3,4 @@
|
|||
<!ENTITY conf-LSauthMethod_CAS SYSTEM "LSauthMethod_CAS.docbook">
|
||||
<!ENTITY conf-LSauthMethod_anonymous SYSTEM "LSauthMethod_anonymous.docbook">
|
||||
|
||||
|
||||
|
||||
|
||||
<!ENTITY LSauthMethod_HTTP "<link linkend='config-LSauthMethod_HTTP'>LSauthMethod_HTTP</link>">
|
||||
|
|
|
@ -1,19 +1,32 @@
|
|||
<sect2 id="config-LSauthMethod_HTTP">
|
||||
<title>LSauthMethod_HTTP</title>
|
||||
<para>Cette &LSauthMethod; est utilisée pour gérer l'authentification
|
||||
via les variables d'environnements définies suite à une authentification
|
||||
gérée par le serveur HTTP. En &php;, ces informations sont consultables
|
||||
via les variables <literal>$_SERVER['PHP_AUTH_USER']</literal> et
|
||||
<literal>$_SERVER['PHP_AUTH_PW']</literal>. Si la variable
|
||||
<literal>$_SERVER['PHP_AUTH_USER']</literal> est présente, une recherche
|
||||
dans l'annuaire est effectué pour trouver l'utilisateur correspondant.
|
||||
L'authentification réussie uniquement si un et un seul utilisateur est
|
||||
retourné par la recherche et si une authentification auprès de l'annuaire
|
||||
LDAP réussie à l'aide du DN de l'objet LDAP trouvé et du mot de passe issu
|
||||
de la variable <literal>$_SERVER['PHP_AUTH_PW']</literal>.</para>
|
||||
via les variables d'environnements définies suite à une authentification,
|
||||
potentiellement déléguée au serveur web.</para>
|
||||
<para>Cette méthode récupère dans l'environment d'exécution PHP, le nom
|
||||
d'utilisateur et le mot de passe de l'utilisateur connecté. À partir du
|
||||
nom d'utilisateur, une recherche dans l'annuaire sera effectuée pour
|
||||
trouver l'utilisateur correspondant. L'authentification sera réussie
|
||||
uniquement si un et un seul utilisateur est retourné par la recherche et
|
||||
si une authentification auprès de l'annuaire LDAP réussie à l'aide du DN
|
||||
de l'objet LDAP trouvé et du mot de passe fourni.</para>
|
||||
|
||||
<note><simpara>En cas d'authentification déléguée au serveur web, il est
|
||||
possible de désactiver la vérification du mot de passe via le paramètre
|
||||
<literal>LSAUTHMETHOD_HTTP_TRUST_WITHOUT_PASSWORD_CHALLENGE</literal>
|
||||
(voir ci-dessous).</simpara></note>
|
||||
|
||||
<para>Les variables d'environnements utilisées pour authentifier l'utilisateur
|
||||
connecté dépendent de la méthode configurée via la constante <literal>
|
||||
LSAUTHMETHOD_HTTP_METHOD</literal> (voir ci-dessous). Si ces variables ne sont
|
||||
pas disponibles, une erreur HTTP 403 sera générée pour réclamer une
|
||||
authentification à l'utilisateur.</para>
|
||||
|
||||
<note><simpara>Cette &LSauthMethod; supporte le mode API et il s'agit de la
|
||||
méthode utilisée par défaut dans ce mode.</simpara></note>
|
||||
|
||||
<para>Cette librairie peut être configurée en éditant le fichier de
|
||||
configiration
|
||||
configuration
|
||||
<literal>conf/LSauth/config.LSauthMethod_HTTP.php</literal>.</para>
|
||||
|
||||
<programlisting linenumbering="unnumbered">
|
||||
|
@ -25,6 +38,9 @@
|
|||
|
||||
// Don't check HTTP server's login/password by LDAP authentication challenge
|
||||
//define('LSAUTHMETHOD_HTTP_TRUST_WITHOUT_PASSWORD_CHALLENGE',true);
|
||||
|
||||
// Authentication realm (API mode only)
|
||||
//define('LSAUTHMETHOD_HTTP_API_REALM', ___('LdapSaisie API - Authentication required'));
|
||||
</programlisting>
|
||||
|
||||
<!-- Début Paramètres Configuration -->
|
||||
|
@ -43,7 +59,7 @@
|
|||
<varlistentry>
|
||||
<term>LSAUTHMETHOD_HTTP_METHOD</term>
|
||||
<listitem>
|
||||
<para>Permet de définir la méthode utilisée par le serveur HTTP pour passer
|
||||
<para>Permet de définir la méthode utilisée par le serveur web pour passer
|
||||
à PHP l'identifiant de l'utilisateur connecté et son mot de passe.</para>
|
||||
<para>Cette constance peut pendre les valeurs suivantes :
|
||||
<variablelist>
|
||||
|
@ -51,7 +67,7 @@
|
|||
<varlistentry>
|
||||
<term>PHP_PASS</term>
|
||||
<listitem>
|
||||
<para>Dans cette méthode, le serveur HTTP défini les variables
|
||||
<para>Dans cette méthode, le serveur web défini les variables
|
||||
d'environnement <literal>PHP_AUTH_USER</literal> et <literal>
|
||||
PHP_AUTH_PW</literal>. Cette méthode est la méthode par défaut et
|
||||
convient en cas d'utilisation de <literal>mod_php</literal>.</para>
|
||||
|
@ -61,7 +77,7 @@
|
|||
<varlistentry>
|
||||
<term>REMOTE_USER</term>
|
||||
<listitem>
|
||||
<para>Dans cette méthode, le serveur HTTP défini la variable
|
||||
<para>Dans cette méthode, le serveur web défini la variable
|
||||
d'environnement <literal>REMOTE_USER</literal>. Cette variable ne contient
|
||||
que l'identifiant de l'utilisateur connecté. Cette méthode ne peut donc
|
||||
être utilisée que conjointement avec l'activation du paramètre
|
||||
|
@ -73,12 +89,12 @@
|
|||
<varlistentry>
|
||||
<term>AUTHORIZATION</term>
|
||||
<listitem>
|
||||
<para>Dans cette méthode, le serveur HTTP passe le contenu de l'entête
|
||||
<para>Dans cette méthode, le serveur web passe le contenu de l'entête
|
||||
HTTP <literal>Authorization</literal> dans la variable d'environnement
|
||||
<literal>HTTP_AUTHORIZATION</literal>. Cette méthode convient en cas d'
|
||||
utilisation de PHP en mode CGI ou encore via PHP-FPM.</para>
|
||||
<para>Pour utiliser cette méthode, il faudra adapter la configuration du
|
||||
serveur HTTP. Par exemple, pour Apache HTTPd, vous pouvez utiliser le
|
||||
serveur web. Par exemple, pour Apache HTTPd, vous pouvez utiliser le
|
||||
module <literal>rewrite</literal> et la règle de réécriture suivante :
|
||||
<programlisting linenumbering="unnumbered">
|
||||
<![CDATA[RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]]]>
|
||||
|
@ -104,5 +120,15 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>LSAUTHMETHOD_HTTP_REALM</term>
|
||||
<listitem>
|
||||
<para>Domaine d'authentification (<literal>reaml</literal>) utilisé pour
|
||||
réclamer l'authentification de l'utilisateur (facultatif).</para>
|
||||
<note><simpara>Pour que le message soit traduit, utilisez la fonction
|
||||
<literal>___()</literal> (voir exemple).</simpara></note>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
|
|
@ -19,11 +19,14 @@ serveur LDAP.</para>
|
|||
'useUserCredentials' => [boolean],
|
||||
'LSauth' => array (
|
||||
'method' => [LSauth method],
|
||||
'api_method' => [LSauth method],
|
||||
'LSobjects' => array(
|
||||
'[object type 1]',
|
||||
'[object type 2]' => array(
|
||||
'filter' => '[LDAP filter]',
|
||||
'password_attribute' => '[attribute name]',
|
||||
'web_access' => [booléen],
|
||||
'api_access' => [booléen],
|
||||
)
|
||||
)
|
||||
),
|
||||
|
@ -120,6 +123,18 @@ serveur LDAP.</para>
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>api_method</term>
|
||||
<listitem>
|
||||
<simpara>Nom de la méthode d'authentification &LSauthMethod; à utilisée lors d'une connexion à
|
||||
l'API. Exemple : pour utiliser la classe <literal>LSauthMethod_HTTP</literal>, la valeur de ce
|
||||
paramètre sera <literal>HTTP</literal>. <emphasis>Paramètre facultatif, méthode par défaut :
|
||||
<literal>HTTP</literal>.</emphasis></simpara>
|
||||
<warning><simpara>Toutes les &LSauthMethod; ne supportent pas forcément le mode API.</simpara>
|
||||
</warning>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>LSobjects</term>
|
||||
<listitem>
|
||||
|
@ -151,6 +166,22 @@ serveur LDAP.</para>
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>web_access</term>
|
||||
<listitem>
|
||||
<simpara>Permet de définir si ce type d'objet à le droit d'utiliser l'interface web (facultatif,
|
||||
par défaut : <literal>True</literal>).</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>api_access</term>
|
||||
<listitem>
|
||||
<simpara>Permet de définir si ce type d'objet à le droit d'utiliser l'API (facultatif,
|
||||
par défaut : <literal>False</literal>).</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
|
|
@ -49,3 +49,6 @@
|
|||
|
||||
// Remote logout URL (in SSO context for instance)
|
||||
//define('LSAUTHMETHOD_HTTP_LOGOUT_REMOTE_URL', 'https://idp.domain.tld/logout');
|
||||
|
||||
// Authentication realm
|
||||
//define('LSAUTHMETHOD_HTTP_REALM', ___('LdapSaisie - Authentication required'));
|
||||
|
|
|
@ -50,12 +50,16 @@ $GLOBALS['LSconfig'] = array(
|
|||
),
|
||||
'LSauth' => array (
|
||||
//'method' => 'basic', // Auth method : basic(default), HTTP, CAS or anonymous
|
||||
//'api_method' => 'HTTP', // Auth method that must support API mode : HTTP(default) or anonymous
|
||||
'LSobjects' => array(
|
||||
'LSpeople' => array(
|
||||
'filter' => '(|(uid=%{user})(mail=%{user}))',
|
||||
'password_attribute' => 'userPassword',
|
||||
'api_access' => false,
|
||||
),
|
||||
'LSsysaccount',
|
||||
'LSsysaccount' => array(
|
||||
'api_access' => true,
|
||||
)
|
||||
),
|
||||
//'allow_multi_match' => false, // Allow username multiple match (default: false)
|
||||
),
|
||||
|
|
|
@ -34,6 +34,7 @@ class LSauth extends LSlog_staticLoggerClass {
|
|||
static private $authData=NULL;
|
||||
static private $authObject=NULL;
|
||||
static private $config=array();
|
||||
static private $method=NULL;
|
||||
static private $provider=NULL;
|
||||
|
||||
static private $params = array (
|
||||
|
@ -52,21 +53,28 @@ class LSauth extends LSlog_staticLoggerClass {
|
|||
self :: log_debug('Failed to load LSauthMethod class');
|
||||
return;
|
||||
}
|
||||
if (!isset(self :: $config['method'])) {
|
||||
self :: $config['method']='basic';
|
||||
}
|
||||
$class='LSauthMethod_'.self :: $config['method'];
|
||||
$api_mode = LSsession :: get('api_mode');
|
||||
if ($api_mode)
|
||||
self :: $method = self :: getConfig('api_method', 'HTTP');
|
||||
else
|
||||
self :: $method = self :: getConfig('method', 'basic');
|
||||
$class = "LSauthMethod_".self :: $method;
|
||||
self :: log_debug('provider -> '.$class);
|
||||
if (LSsession :: loadLSclass($class)) {
|
||||
if ($api_mode && !$class :: apiModeSupported()) {
|
||||
LSerror :: addErrorCode('LSauth_08', self :: $method);
|
||||
return;
|
||||
}
|
||||
self :: $provider = new $class();
|
||||
if (!self :: $provider) {
|
||||
LSerror :: addErrorCode('LSauth_05',self :: $config['method']);
|
||||
LSerror :: addErrorCode('LSauth_05', self :: $method);
|
||||
return;
|
||||
}
|
||||
self :: log_debug('Provider Started !');
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
LSerror :: addErrorCode('LSauth_04',self :: $config['method']);
|
||||
LSerror :: addErrorCode('LSauth_04', self :: $method);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -107,19 +115,21 @@ class LSauth extends LSlog_staticLoggerClass {
|
|||
public static function getAuthObjectTypes() {
|
||||
$objTypes = array();
|
||||
foreach(self :: getConfig('LSobjects', array()) as $objType => $objParams) {
|
||||
if (!self :: checkAuthObjectTypeAccess($objType))
|
||||
continue;
|
||||
if (is_int($objType) && is_string($objParams)) {
|
||||
// We just have the object type
|
||||
$objTypes[$objParams] = array('filter' => null, 'password_attribute' => 'userPassword');
|
||||
continue;
|
||||
}
|
||||
|
||||
$objTypes[$objType] = array(
|
||||
'filter' => self :: getConfig("LSobjects.$objType.filter", null, 'string'),
|
||||
'password_attribute' => self :: getConfig("LSobjects.$objType.password_attribute", 'userPassword', 'string'),
|
||||
);
|
||||
}
|
||||
// For retro-compatibility, also retreived old parameters:
|
||||
// For retro-compatibility, also retreived old parameters (excepted in API mode):
|
||||
$oldAuthObjectType = LSconfig :: get('authObjectType', null, 'string', LSsession :: $ldapServer);
|
||||
if ($oldAuthObjectType && !array_key_exists($oldAuthObjectType, $objTypes)) {
|
||||
if ($oldAuthObjectType && !array_key_exists($oldAuthObjectType, $objTypes) && self :: checkAuthObjectTypeAccess($oldAuthObjectType)) {
|
||||
$objTypes[$oldAuthObjectType] = array(
|
||||
'filter' => LSconfig :: get('authObjectFilter', null, 'string', LSsession :: $ldapServer),
|
||||
'password_attribute' => LSconfig :: get('authObjectTypeAttrPwd', 'userPassword', 'string', LSsession :: $ldapServer),
|
||||
|
@ -128,6 +138,22 @@ class LSauth extends LSlog_staticLoggerClass {
|
|||
return $objTypes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the specified auth object type have acces to LdapSaisie (on the current mode)
|
||||
*
|
||||
* @param[in] $objType string The LSobject type
|
||||
*
|
||||
* @return boolean True if specified auth object type have acces to LdapSaisie, False otherwise
|
||||
*/
|
||||
public static function checkAuthObjectTypeAccess($objType) {
|
||||
// Check Web/API access rights
|
||||
if (LSsession :: get('api_mode')) {
|
||||
return self :: getConfig("LSobjects.$objType.api_access", false, 'bool');
|
||||
}
|
||||
return self :: getConfig("LSobjects.$objType.web_access", true, 'bool');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreived LSobjects corresponding to a username
|
||||
*
|
||||
|
@ -299,3 +325,6 @@ ___("LSauth : Not correctly initialized.")
|
|||
LSerror :: defineError('LSauth_07',
|
||||
___("LSauth : Failed to get authentication informations from provider.")
|
||||
);
|
||||
LSerror :: defineError('LSauth_08',
|
||||
___("LSauth : Method %{method} configured doesn't support API mode.")
|
||||
);
|
||||
|
|
|
@ -29,7 +29,10 @@ LSsession :: loadLSclass('LSlog_staticLoggerClass');
|
|||
*/
|
||||
class LSauthMethod extends LSlog_staticLoggerClass {
|
||||
|
||||
var $authData = array();
|
||||
protected $authData = array();
|
||||
|
||||
// Boolean flag to specify if this LSauthMethod support API mode
|
||||
protected static $api_mode_supported = false;
|
||||
|
||||
public function __construct() {
|
||||
// Load config (without warning if not found)
|
||||
|
@ -115,4 +118,13 @@ class LSauthMethod extends LSlog_staticLoggerClass {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check API mode support of this method
|
||||
*
|
||||
* @retval boolean True if API mode is support, false otherwise
|
||||
*/
|
||||
static public function apiModeSupported() {
|
||||
return static :: $api_mode_supported;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ LSsession :: loadLSclass('LSauthMethod_basic');
|
|||
*/
|
||||
class LSauthMethod_HTTP extends LSauthMethod_basic {
|
||||
|
||||
// Boolean flag to specify if this LSauthMethod support API mode
|
||||
protected static $api_mode_supported = true;
|
||||
|
||||
public function __construct() {
|
||||
parent :: __construct();
|
||||
LSauth :: disableLoginForm();
|
||||
|
@ -53,6 +56,7 @@ class LSauthMethod_HTTP extends LSauthMethod_basic {
|
|||
self :: log_debug('HTTP method to retreive auth data is "'.LSAUTHMETHOD_HTTP_METHOD.'"');
|
||||
}
|
||||
|
||||
$missing_info = null;
|
||||
switch(constant('LSAUTHMETHOD_HTTP_METHOD')) {
|
||||
case 'AUTHORIZATION':
|
||||
if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||
|
@ -62,11 +66,12 @@ class LSauthMethod_HTTP extends LSauthMethod_basic {
|
|||
'username' => $authData[0],
|
||||
'password' => $authData[1],
|
||||
);
|
||||
return $this -> authData;
|
||||
}
|
||||
return $this -> authData;
|
||||
else
|
||||
self :: log_warning("Fail to decode and parse $missing_info environment variable.");
|
||||
}
|
||||
else
|
||||
LSerror :: addErrorCode('LSauthMethod_HTTP_01', 'HTTP_AUTHORIZATION');
|
||||
$missing_info = 'HTTP_AUTHORIZATION';
|
||||
break;
|
||||
case 'REMOTE_USER':
|
||||
if (isset($_SERVER['REMOTE_USER']) && !empty($_SERVER['REMOTE_USER'])) {
|
||||
|
@ -76,8 +81,7 @@ class LSauthMethod_HTTP extends LSauthMethod_basic {
|
|||
);
|
||||
return $this -> authData;
|
||||
}
|
||||
else
|
||||
LSerror :: addErrorCode('LSauthMethod_HTTP_01', 'REMOTE_USER');
|
||||
$missing_info = 'REMOTE_USER';
|
||||
break;
|
||||
case 'PHP_AUTH':
|
||||
default:
|
||||
|
@ -88,10 +92,20 @@ class LSauthMethod_HTTP extends LSauthMethod_basic {
|
|||
);
|
||||
return $this -> authData;
|
||||
}
|
||||
else
|
||||
LSerror :: addErrorCode('LSauthMethod_HTTP_01', 'PHP_AUTH_USER');
|
||||
$missing_info = 'PHP_AUTH_USER';
|
||||
}
|
||||
return;
|
||||
self :: log_warning("$missing_info variable not available in environment, trigger 403 error.");
|
||||
|
||||
// Auth data not available, trigger HTTP 403 error
|
||||
if (defined('LSAUTHMETHOD_HTTP_REALM') && constant('LSAUTHMETHOD_HTTP_REALM'))
|
||||
$realm = __(LSAUTHMETHOD_HTTP_REALM);
|
||||
else
|
||||
$realm = _('LdapSaisie - Authentication required');
|
||||
header('WWW-Authenticate: Basic realm="'.$realm.'", charset="UTF-8"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
LSerror :: addErrorCode(null, $realm);
|
||||
LSsession :: displayAjaxReturn();
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
*/
|
||||
class LSauthMethod_anonymous extends LSauthMethod {
|
||||
|
||||
// Boolean flag to specify if this LSauthMethod support API mode
|
||||
protected static $api_mode_supported = true;
|
||||
|
||||
public function __construct() {
|
||||
LSauth :: disableLoginForm();
|
||||
LSauth :: disableSelfAccess();
|
||||
|
|
|
@ -123,13 +123,17 @@ class LSerror {
|
|||
*
|
||||
* @retvat string Le texte des erreurs
|
||||
*/
|
||||
public static function getErrors() {
|
||||
public static function getErrors($raw=false) {
|
||||
if(!empty($_SESSION['LSerror'])) {
|
||||
$txt = '';
|
||||
foreach ($_SESSION['LSerror'] as $error)
|
||||
$txt .= $error."<br />\n";
|
||||
if ($raw)
|
||||
$return = $_SESSION['LSerror'];
|
||||
else {
|
||||
$return = '';
|
||||
foreach ($_SESSION['LSerror'] as $error)
|
||||
$return .= $error."<br />\n";
|
||||
}
|
||||
self :: resetError();
|
||||
return $txt;
|
||||
return $return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,10 @@ class LSform extends LSlog_staticLoggerClass {
|
|||
|
||||
var $warnings = array();
|
||||
|
||||
var $api_mode = false;
|
||||
|
||||
private $submited = false;
|
||||
|
||||
/**
|
||||
* Constructeur
|
||||
*
|
||||
|
@ -64,7 +68,7 @@ class LSform extends LSlog_staticLoggerClass {
|
|||
*
|
||||
* @retval void
|
||||
*/
|
||||
public function __construct(&$ldapObject, $idForm, $submit=NULL){
|
||||
public function __construct(&$ldapObject, $idForm, $submit=NULL, $api_mode=false){
|
||||
$this -> idForm = $idForm;
|
||||
if (!$submit) {
|
||||
$this -> submit = _("Validate");
|
||||
|
@ -72,6 +76,7 @@ class LSform extends LSlog_staticLoggerClass {
|
|||
else {
|
||||
$this -> submit = $submit;
|
||||
}
|
||||
$this -> api_mode = $api_mode;
|
||||
$this -> ldapObject =& $ldapObject;
|
||||
$this -> config = $ldapObject -> getConfig('LSform');
|
||||
LSsession :: loadLSclass('LSformElement');
|
||||
|
@ -428,11 +433,22 @@ class LSform extends LSlog_staticLoggerClass {
|
|||
* @retval boolean true si la saisie du formulaire est présente en POST, false sinon
|
||||
*/
|
||||
public function isSubmit() {
|
||||
if ($this -> submited)
|
||||
return true;
|
||||
if( (isset($_POST['validate']) && ($_POST['validate']=='LSform')) && (isset($_POST['idForm']) && ($_POST['idForm'] == $this -> idForm)) )
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set form as submited
|
||||
*
|
||||
* @retval void
|
||||
*/
|
||||
public function setSubmited() {
|
||||
$this -> submited = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Défini arbitrairement des données en POST
|
||||
*
|
||||
|
|
|
@ -403,4 +403,18 @@ class LSformElement extends LSlog_staticLoggerClass {
|
|||
$opts[] = $opt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive value as return in API response
|
||||
*
|
||||
* @retval mixed API value(s) or null/empty array if no value
|
||||
*/
|
||||
public function getApiValue() {
|
||||
if ($this -> isMultiple()) {
|
||||
return ensureIsArray($this -> values);
|
||||
}
|
||||
if (!$this -> values)
|
||||
return null;
|
||||
return $this -> values[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -223,9 +223,14 @@ class LSformElement_date extends LSformElement {
|
|||
return true;
|
||||
}
|
||||
$values = self :: getData($_POST, $this -> name);
|
||||
$special_values = self :: getData($_POST, $this -> name.'__special_value');
|
||||
self :: log_trace($this." -> getPostData(): values=".varDump($values));
|
||||
self :: log_trace($this." -> getPostData(): special_values=".varDump($special_values));
|
||||
if ($this -> form -> api_mode) {
|
||||
$special_values = false;
|
||||
}
|
||||
else {
|
||||
$special_values = self :: getData($_POST, $this -> name.'__special_value');
|
||||
self :: log_trace($this." -> getPostData(): special_values=".varDump($special_values));
|
||||
}
|
||||
if (!is_array($values) && !is_array($special_values)) {
|
||||
self :: log_trace($this." -> getPostData(): not in POST data");
|
||||
if ($onlyIfPresent) {
|
||||
|
|
|
@ -163,4 +163,21 @@ class LSformElement_image extends LSformElement {
|
|||
}
|
||||
return _("An unknown error occured sending this file.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive value as return in API response
|
||||
*
|
||||
* @retval mixed API value(s) or null/empty array if no value
|
||||
*/
|
||||
public function getApiValue() {
|
||||
if ($this -> isMultiple()) {
|
||||
$values = array();
|
||||
for ($i=0; $i < count($this -> values); $i++)
|
||||
$values[] = base64_encode($this -> values[0]);
|
||||
return $values;
|
||||
}
|
||||
if (!$this -> values)
|
||||
return null;
|
||||
return base64_encode($this -> values[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,29 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
|
|||
*/
|
||||
var $components = array();
|
||||
|
||||
/**
|
||||
* Parse values
|
||||
*
|
||||
* @retval array Parsed values
|
||||
*/
|
||||
private function parseValues() {
|
||||
self :: log_trace('values: '.varDump($this -> values));
|
||||
$parseValues=array();
|
||||
foreach($this -> values as $val) {
|
||||
$decodedValue = json_decode($val, true);
|
||||
self :: log_trace('decoded value: '.varDump($decodedValue));
|
||||
if (is_array($decodedValue)) {
|
||||
$parseValue = array('value' => $val);
|
||||
foreach($decodedValue as $c => $cvalue) {
|
||||
$parseValue[$c] = $this -> translateComponentValue($c,$cvalue);
|
||||
}
|
||||
$parseValues[] = $parseValue;
|
||||
}
|
||||
}
|
||||
self :: log_trace('parsed values: '.varDump($parseValues));
|
||||
return $parseValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne les infos d'affichage de l'élément
|
||||
*
|
||||
|
@ -76,25 +99,9 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
|
|||
public function getDisplay(){
|
||||
$return = $this -> getLabelInfos();
|
||||
|
||||
$parseValues=array();
|
||||
$invalidValues=array();
|
||||
foreach($this -> values as $val) {
|
||||
$decodedValue=json_decode($val, true);
|
||||
if (is_array($decodedValue)) {
|
||||
$parseValue=array('value' => $val);
|
||||
foreach($decodedValue as $c => $cvalue) {
|
||||
$parseValue[$c]=$this -> translateComponentValue($c,$cvalue);
|
||||
}
|
||||
$parseValues[]=$parseValue;
|
||||
}
|
||||
else {
|
||||
$invalidValues[]=$val;
|
||||
}
|
||||
}
|
||||
|
||||
$return['html'] = $this -> fetchTemplate(NULL,
|
||||
array(
|
||||
'parseValues' => $parseValues,
|
||||
'parseValues' => $this -> parseValues(),
|
||||
'fullWidth' => $this -> getParam('html_options.fullWidth', false, 'bool'),
|
||||
)
|
||||
);
|
||||
|
@ -181,7 +188,14 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
|
|||
protected function getSelectListComponentPossibleValues($c) {
|
||||
if (!isset($this -> _cache_getSelectListComponentPossibleValues[$c])) {
|
||||
if (!LSsession :: loadLSclass('LSattr_html_select_list')) return;
|
||||
$this -> _cache_getSelectListComponentPossibleValues[$c]=LSattr_html_select_list :: _getPossibleValues($this -> components[$c]['options'], $this -> name, $this->attr_html->attribute->ldapObject);
|
||||
$this -> _cache_getSelectListComponentPossibleValues[$c] = LSattr_html_select_list :: _getPossibleValues(
|
||||
$this -> components[$c]['options'],
|
||||
$this -> name,
|
||||
$this->attr_html->attribute->ldapObject
|
||||
);
|
||||
self :: log_trace(
|
||||
"Component $c possible values: ".varDump($this -> _cache_getSelectListComponentPossibleValues[$c])
|
||||
);
|
||||
}
|
||||
return $this -> _cache_getSelectListComponentPossibleValues[$c];
|
||||
}
|
||||
|
@ -194,7 +208,7 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
|
|||
*
|
||||
* @retval array
|
||||
**/
|
||||
protected function getSelectListComponentValueLabel($c,$value) {
|
||||
protected function getSelectListComponentValueLabel($c, $value) {
|
||||
if ($this -> getSelectListComponentPossibleValues($c)) {
|
||||
foreach ($this -> _cache_getSelectListComponentPossibleValues[$c] as $v => $label) {
|
||||
if (is_array($label)) {
|
||||
|
@ -205,6 +219,7 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
|
|||
if ($v == $value) return $label;
|
||||
}
|
||||
}
|
||||
self :: log_trace("No label found for value '$value'");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -225,78 +240,241 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
|
|||
return true;
|
||||
}
|
||||
|
||||
$return[$this -> name]=array();
|
||||
if (is_array($_POST[$this -> name.'__values_uuid'])) {
|
||||
foreach ($_POST[$this -> name.'__values_uuid'] as $uuid) {
|
||||
$value=array();
|
||||
$parseValue=array();
|
||||
$errors=array();
|
||||
$unemptyComponents=array();
|
||||
// Extract value form POST data
|
||||
$parseValues = array();
|
||||
// API mode
|
||||
if ($this -> form -> api_mode) {
|
||||
$json_values = $this -> getData($_POST, $this -> name);
|
||||
if (!is_array($json_values) || empty($json_values)) {
|
||||
self :: log_trace($this." -> getPostData(): not in POST data");
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($this -> components as $c => $cconf) {
|
||||
if (isset($_POST[$this -> name.'__'.$c.'__'.$uuid])) {
|
||||
if (!is_array($_POST[$this -> name.'__'.$c.'__'.$uuid]))
|
||||
$_POST[$this -> name.'__'.$c.'__'.$uuid] = array($_POST[$this -> name.'__'.$c.'__'.$uuid]);
|
||||
|
||||
$parseValue[$c]=array();
|
||||
foreach($_POST[$this -> name.'__'.$c.'__'.$uuid] as $val) {
|
||||
if (empty($val))
|
||||
continue;
|
||||
$parseValue[$c][] = $val;
|
||||
if ($cconf['type']=='select_list') {
|
||||
if (!$this -> getSelectListComponentValueLabel($c, $val)) {
|
||||
$errors[]=getFData(_('Invalid value "%{value}" for component %{component}.'),array('value' => $val, 'component' => __($cconf['label'])));
|
||||
}
|
||||
}
|
||||
if (isset($cconf['check_data']) && is_array($cconf['check_data'])) {
|
||||
foreach($cconf['check_data'] as $ruleType => $rconf) {
|
||||
$className='LSformRule_'.$ruleType;
|
||||
if (LSsession::loadLSclass($className)) {
|
||||
$r=new $className();
|
||||
if (!$r -> validate($val,$rconf,$this)) {
|
||||
if (isset($rconf['msg'])) {
|
||||
$errors[]=getFData(__($rconf['msg']),__($cconf['label']));
|
||||
}
|
||||
else {
|
||||
$errors[]=getFData(_('Invalid value "%{value}" for component %{component}.'),array('value' => $val, 'component' => __($cconf['label'])));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$errors[]=getFData(_("Can't validate value of component %{c}."),__($cconf['label']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($parseValue[$c]))
|
||||
continue;
|
||||
|
||||
if (!isset($cconf['multiple']) || !$cconf['multiple']) {
|
||||
$parseValue[$c] = $parseValue[$c][0];
|
||||
}
|
||||
|
||||
$unemptyComponents[]=$c;
|
||||
$value[$c]=$parseValue[$c];
|
||||
}
|
||||
$json_value_count = 0;
|
||||
foreach($json_values as $json_value) {
|
||||
$json_value_count += 1;
|
||||
$input_value = json_decode($json_value, true);
|
||||
if (!is_array($input_value)) {
|
||||
$this -> form -> setElementError(
|
||||
$this -> attr_html,
|
||||
getFData(_('Fail to decode JSON value #%{idx}.'), $json_value_count)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($unemptyComponents)) {
|
||||
// Check required components
|
||||
foreach ($this -> components as $c => $cconf) {
|
||||
if ($cconf['required'] && !isset($value[$c])) {
|
||||
$errors[]=getFData(_('Component %{c} must be defined'),__($cconf['label']));
|
||||
continue;
|
||||
$parseValue = array();
|
||||
$unemptyComponents = array();
|
||||
|
||||
foreach (array_keys($this -> components) as $c) {
|
||||
if (!isset($input_value[$c]))
|
||||
continue;
|
||||
if ($this -> getComponentConfig($c, 'multiple', false, 'bool')) {
|
||||
$parseValue[$c] = array();
|
||||
if (is_array($input_value[$c])) {
|
||||
foreach($input_value[$c] as $val) {
|
||||
if (is_empty($val))
|
||||
continue;
|
||||
$parseValue[$c][] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach($errors as $e) {
|
||||
$this -> form -> setElementError($this -> attr_html,$e);
|
||||
else {
|
||||
$parseValue[$c] = $input_value[$c];
|
||||
}
|
||||
$return[$this -> name][]=json_encode($value);
|
||||
|
||||
if (is_empty($parseValue[$c])) {
|
||||
unset($parseValue[$c]);
|
||||
continue;
|
||||
}
|
||||
$unemptyComponents[] = $c;
|
||||
}
|
||||
|
||||
// Ignore empty value from form
|
||||
if (empty($unemptyComponents))
|
||||
continue;
|
||||
|
||||
$parseValues[] = $parseValue;
|
||||
}
|
||||
}
|
||||
elseif (is_array($_POST[$this -> name.'__values_uuid'])) {
|
||||
// HTML form mode
|
||||
foreach ($_POST[$this -> name.'__values_uuid'] as $uuid) {
|
||||
$parseValue = array();
|
||||
$unemptyComponents = array();
|
||||
|
||||
foreach (array_keys($this -> components) as $c) {
|
||||
if (!isset($_POST[$this -> name.'__'.$c.'__'.$uuid]))
|
||||
continue;
|
||||
$parseValue[$c] = array();
|
||||
foreach($_POST[$this -> name.'__'.$c.'__'.$uuid] as $val) {
|
||||
if (empty($val))
|
||||
continue;
|
||||
$parseValue[$c][] = $val;
|
||||
}
|
||||
|
||||
if (empty($parseValue[$c])) {
|
||||
unset($parseValue[$c]);
|
||||
continue;
|
||||
}
|
||||
if (!$this -> getComponentConfig($c, 'multiple', false, 'bool')) {
|
||||
$parseValue[$c] = $parseValue[$c][0];
|
||||
}
|
||||
$unemptyComponents[] = $c;
|
||||
}
|
||||
|
||||
// Ignore empty value from form
|
||||
if (empty($unemptyComponents))
|
||||
continue;
|
||||
|
||||
$parseValues[] = $parseValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Check extracted values
|
||||
foreach ($parseValues as $parseValue) {
|
||||
// Check component value
|
||||
foreach ($parseValue as $c => $value)
|
||||
$this -> checkComponentValues($c, $value);
|
||||
|
||||
// Check required components
|
||||
foreach (array_keys($this -> components) as $c) {
|
||||
if ($this -> getComponentConfig($c, 'required', false, 'bool') && !isset($parseValue[$c])) {
|
||||
$this -> form -> setElementError(
|
||||
$this -> attr_html,
|
||||
getFData(
|
||||
_('Component %{c} must be defined'),
|
||||
__($this -> getComponentConfig($c, 'label'))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
$return[$this -> name][] = json_encode($parseValue);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check one component's values
|
||||
*
|
||||
* @param[] $c The component name
|
||||
* @param[] $value The values of the component
|
||||
*
|
||||
* @retval void
|
||||
**/
|
||||
private function checkComponentValues($c, $value) {
|
||||
if ($this -> getComponentConfig($c, 'multiple', false, 'bool')) {
|
||||
foreach ($value as $val) {
|
||||
$this -> checkComponentValue($c, $val);
|
||||
}
|
||||
}
|
||||
else
|
||||
$this -> checkComponentValue($c, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check one component's value
|
||||
*
|
||||
* @param[] $c The component name
|
||||
* @param[] $value The value to check
|
||||
*
|
||||
* @retval void
|
||||
**/
|
||||
private function checkComponentValue($c, $value) {
|
||||
$label = __($this -> getComponentConfig($c, 'label'));
|
||||
|
||||
// select_list components : check values
|
||||
if ($this -> getComponentConfig($c, 'type') == 'select_list') {
|
||||
if (!$this -> getSelectListComponentValueLabel($c, $value)) {
|
||||
$this -> form -> setElementError(
|
||||
$this -> attr_html,
|
||||
getFData(
|
||||
_('Invalid value "%{value}" for component %{component}.'),
|
||||
array('value' => $value, 'component' => $label)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply check data rules
|
||||
foreach($this -> getComponentConfig($c, 'check_data', array(), 'array') as $ruleType => $rconf) {
|
||||
$className = 'LSformRule_'.$ruleType;
|
||||
if (LSsession::loadLSclass($className)) {
|
||||
$r = new $className();
|
||||
if (!$r -> validate($value, $rconf, $this)) {
|
||||
if (isset($rconf['msg'])) {
|
||||
$this -> form -> setElementError(
|
||||
$this -> attr_html,
|
||||
getFData(__($rconf['msg']), $label)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$this -> form -> setElementError(
|
||||
$this -> attr_html,
|
||||
getFData(
|
||||
_('Invalid value "%{value}" for component %{component}.'),
|
||||
array('value' => $value, 'component' => $label)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this -> form -> setElementError(
|
||||
$this -> attr_html,
|
||||
getFData(_("Can't validate value of component %{c}."), $label)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a configuration parameter for a specific component (or default value)
|
||||
*
|
||||
* @param[] $component The component name
|
||||
* @param[] $param The configuration parameter
|
||||
* @param[] $default The default value (default : null)
|
||||
* @param[] $cast Cast resulting value in specific type (default : disabled)
|
||||
*
|
||||
* @retval mixed The configuration parameter value or default value if not set
|
||||
**/
|
||||
public function getComponentConfig($component, $param, $default=null, $cast=null) {
|
||||
return LSconfig :: get(
|
||||
$param, $default, $cast,
|
||||
(array_key_exists($component, $this -> components)?$this -> components[$component]:array())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive value as return in API response
|
||||
*
|
||||
* @retval mixed API value(s) or null/empty array if no value
|
||||
*/
|
||||
public function getApiValue() {
|
||||
$values = array();
|
||||
foreach(ensureIsArray($this -> values) as $value) {
|
||||
$decodedValue = json_decode($value, true);
|
||||
if (is_array($decodedValue)) {
|
||||
$parsedValue = array();
|
||||
foreach(array_keys($this -> components) as $c) {
|
||||
if (!isset($decodedValue[$c]))
|
||||
continue;
|
||||
if ($this -> getComponentConfig($c, 'multiple', false, 'bool')) {
|
||||
$parsedValue[$c] = ensureIsArray($decodedValue[$c]);
|
||||
}
|
||||
else {
|
||||
$parsedValue[$c] = $decodedValue[$c];
|
||||
}
|
||||
}
|
||||
$values[] = $parsedValue;
|
||||
}
|
||||
}
|
||||
if ($this -> isMultiple()) {
|
||||
return $values;
|
||||
}
|
||||
if (!$values)
|
||||
return null;
|
||||
return $values[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -117,26 +117,48 @@ class LSformElement_labeledValue extends LSformElement {
|
|||
if($this -> isFreeze()) {
|
||||
return true;
|
||||
}
|
||||
if (isset($_POST[$this -> name."_labels"]) && isset($_POST[$this -> name."_values"])) {
|
||||
$return[$this -> name] = array();
|
||||
// Extract value form POST data
|
||||
$values = array();
|
||||
// API mode
|
||||
if ($this -> form -> api_mode) {
|
||||
if (isset($_POST[$this -> name])) {
|
||||
foreach(ensureIsArray($_POST[$this -> name]) as $val) {
|
||||
if (is_empty($val))
|
||||
continue;
|
||||
$parseValue = self :: parseValue($val);
|
||||
if (isset($parseValue['label']) && isset($parseValue['value'])) {
|
||||
$values[] = '['.$parseValue['label'].']'.$parseValue['value'];
|
||||
}
|
||||
else {
|
||||
$this -> form -> setElementError(
|
||||
$this -> attr_html,
|
||||
getFData(_('Invalid value : "%{value}".'), $val)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (isset($_POST[$this -> name."_labels"]) && isset($_POST[$this -> name."_values"])) {
|
||||
$_POST[$this -> name."_labels"] = ensureIsArray($_POST[$this -> name."_labels"]);
|
||||
$_POST[$this -> name."_values"] = ensureIsArray($_POST[$this -> name."_values"]);
|
||||
foreach($_POST[$this -> name."_labels"] as $key => $label) {
|
||||
$val = $_POST[$this -> name."_values"][$key];
|
||||
if (!empty($label) && !is_empty($val)) {
|
||||
$return[$this -> name][$key] = "[$label]$val";
|
||||
$values[$key] = "[$label]$val";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($values) {
|
||||
$return[$this -> name] = $values;
|
||||
}
|
||||
elseif ($onlyIfPresent) {
|
||||
self :: log_debug($this -> name.": not in POST data => ignore it");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
$return[$this -> name] = array();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,6 +41,41 @@ class LSformElement_mailQuota extends LSformElement {
|
|||
1000000000 => 'Go'
|
||||
);
|
||||
|
||||
/**
|
||||
* Parse one value
|
||||
*
|
||||
* @param[in] $value string The value to parse
|
||||
*
|
||||
* @retval array Parsed value
|
||||
*/
|
||||
public function parseValue($value) {
|
||||
if (preg_match('/^([0-9]+)'.$this -> getSuffix().'$/',$value,$regs)) {
|
||||
$infos = array(
|
||||
'size' => $regs[1],
|
||||
);
|
||||
if ($infos['size'] == 0) {
|
||||
return array(
|
||||
'size' => 0,
|
||||
'valueSize' => 0,
|
||||
'valueSizeFact' => 1,
|
||||
'valueTxt' => "0",
|
||||
);
|
||||
}
|
||||
krsort($this -> sizeFacts, SORT_NUMERIC);
|
||||
foreach($this -> sizeFacts as $fact => $unit) {
|
||||
if ($infos['size'] >= $fact) {
|
||||
$infos['valueSize'] = round($infos['size'] / $fact, 2);
|
||||
$infos['valueSizeFact'] = $fact;
|
||||
$infos['valueTxt'] = $infos['valueSize'].$unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ksort($this -> sizeFacts, SORT_NUMERIC);
|
||||
return $infos;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne les infos d'affichage de l'élément
|
||||
*
|
||||
|
@ -54,26 +89,9 @@ class LSformElement_mailQuota extends LSformElement {
|
|||
$quotas=array();
|
||||
|
||||
foreach ($this -> values as $value) {
|
||||
if (preg_match('/([0-9]*)/'.$this -> getSuffix(),$value,$regs)) {
|
||||
$infos = array(
|
||||
'size' => $regs[1]
|
||||
);
|
||||
if ($infos['size'] >= 1000000000) {
|
||||
$infos['valueSizeFact']=1000000000;
|
||||
}
|
||||
else if ($infos['size'] >= 1000000) {
|
||||
$infos['valueSizeFact']=1000000;
|
||||
}
|
||||
else if ($infos['size'] >= 1000) {
|
||||
$infos['valueSizeFact']=1000;
|
||||
}
|
||||
else {
|
||||
$infos['valueSizeFact']=1;
|
||||
}
|
||||
$infos['valueSize'] = $infos['size'] / $infos['valueSizeFact'];
|
||||
$infos['valueTxt'] = $infos['valueSize'].$this ->sizeFacts[$infos['valueSizeFact']];
|
||||
|
||||
$quotas[$value] = $infos;
|
||||
$parsed_value = $this -> parseValue($value);
|
||||
if ($parsed_value) {
|
||||
$quotas[$value] = $parsed_value;
|
||||
}
|
||||
else {
|
||||
$quotas[$value] = array(
|
||||
|
@ -137,36 +155,69 @@ class LSformElement_mailQuota extends LSformElement {
|
|||
if($this -> isFreeze()) {
|
||||
return true;
|
||||
}
|
||||
if (isset($_POST[$this -> name.'_size'])) {
|
||||
$return[$this -> name]=array();
|
||||
$values = array();
|
||||
if ($this -> form -> api_mode) {
|
||||
if (isset($_POST[$this -> name])) {
|
||||
foreach(ensureIsArray($_POST[$this -> name]) as $value) {
|
||||
if ($this -> parseValue($value) !== false) {
|
||||
$values[] = $value;
|
||||
}
|
||||
else {
|
||||
$this -> form -> setElementError(
|
||||
$this -> attr_html,
|
||||
getFData(_('Invalid value : "%{value}".'), $value)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (isset($_POST[$this -> name.'_size'])) {
|
||||
$_POST[$this -> name.'_size'] = ensureIsArray($_POST[$this -> name.'_size']);
|
||||
if(isset($_POST[$this -> name.'_sizeFact']) && !is_array($_POST[$this -> name.'_sizeFact'])) {
|
||||
$_POST[$this -> name.'_sizeFact'] = array($_POST[$this -> name.'_sizeFact']);
|
||||
}
|
||||
foreach($_POST[$this -> name.'_size'] as $key => $val) {
|
||||
if (!empty($val)) {
|
||||
$f = 1;
|
||||
if (isset($_POST[$this -> name.'_sizeFact'][$key]) && ($_POST[$this -> name.'_sizeFact'][$key]!=1)) {
|
||||
$f = $_POST[$this -> name.'_sizeFact'][$key];
|
||||
}
|
||||
$return[$this -> name][$key] = ($val*$f).$this->getSuffix();
|
||||
if (empty($val))
|
||||
continue;
|
||||
$f = 1;
|
||||
if (isset($_POST[$this -> name.'_sizeFact'][$key]) && ($_POST[$this -> name.'_sizeFact'][$key]!=1)) {
|
||||
$f = $_POST[$this -> name.'_sizeFact'][$key];
|
||||
}
|
||||
$values[$key] = ($val*$f).$this->getSuffix();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Accept raw value to make import easier
|
||||
elseif (isset($_POST[$this -> name])) {
|
||||
$return[$this -> name]=$_POST[$this -> name];
|
||||
return true;
|
||||
|
||||
if ($values) {
|
||||
$return[$this -> name] = $values;
|
||||
}
|
||||
elseif ($onlyIfPresent) {
|
||||
self :: log_debug($this -> name.": not in POST data => ignore it");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
$return[$this -> name] = array();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive value as return in API response
|
||||
*
|
||||
* @retval mixed API value(s) or null/empty array if no value
|
||||
*/
|
||||
public function getApiValue() {
|
||||
$values = array();
|
||||
foreach(ensureIsArray($this -> values) as $value) {
|
||||
$parsed_value = $this -> parseValue($value);
|
||||
if (is_array($parsed_value)) {
|
||||
$values[] = $parsed_value['size'];
|
||||
}
|
||||
}
|
||||
if ($this -> isMultiple()) {
|
||||
return $values;
|
||||
}
|
||||
if (!$values)
|
||||
return null;
|
||||
return $values[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ class LSformElement_maildir extends LSformElement_text {
|
|||
$retval = parent :: getPostData($return);
|
||||
|
||||
// Si une valeur est recupérée
|
||||
if ($retval&&$_POST['LSformElement_maildir_'.$this -> name.'_do']) {
|
||||
if ($retval && !$this -> form -> api_mode && $_POST['LSformElement_maildir_'.$this -> name.'_do']) {
|
||||
$cur = $this -> form -> ldapObject -> attrs[$this -> name] -> getValue();
|
||||
$cur=$cur[0];
|
||||
$new = $return[$this -> name][0];
|
||||
|
|
|
@ -62,7 +62,7 @@ class LSformElement_password extends LSformElement {
|
|||
return true;
|
||||
}
|
||||
|
||||
if ($this -> getParam('html_options.confirmInput', False, 'bool')) {
|
||||
if (!$this -> form -> api_mode && $this -> getParam('html_options.confirmInput', False, 'bool')) {
|
||||
$confirm_data = self :: getData($_POST, $this -> name . '_confirm');
|
||||
$confirmed = false;
|
||||
if (!is_array($confirm_data)) {
|
||||
|
|
|
@ -38,9 +38,46 @@ class LSformElement_quota extends LSformElement {
|
|||
1 => 'o',
|
||||
1024 => 'Ko',
|
||||
1048576 => 'Mo',
|
||||
1073741824 => 'Go'
|
||||
1073741824 => 'Go',
|
||||
1099511627776 => 'To',
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Parse one value
|
||||
*
|
||||
* @param[in] $value string The value to parse
|
||||
*
|
||||
* @retval array Parsed value
|
||||
*/
|
||||
public function parseValue($value) {
|
||||
if (preg_match('/^([0-9]+)$/', $value, $regs)) {
|
||||
$infos = array(
|
||||
'size' => ceil($regs[1]/$this -> getFactor()),
|
||||
);
|
||||
if ($infos['size'] == 0) {
|
||||
return array(
|
||||
'size' => 0,
|
||||
'valueSize' => 0,
|
||||
'valueSizeFact' => 1,
|
||||
'valueTxt' => "0",
|
||||
);
|
||||
}
|
||||
krsort($this -> sizeFacts, SORT_NUMERIC);
|
||||
foreach($this -> sizeFacts as $fact => $unit) {
|
||||
if ($infos['size'] >= $fact) {
|
||||
$infos['valueSize'] = round($infos['size'] / $fact, 2);
|
||||
$infos['valueSizeFact'] = $fact;
|
||||
$infos['valueTxt'] = $infos['valueSize'].$unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ksort($this -> sizeFacts, SORT_NUMERIC);
|
||||
return $infos;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne les infos d'affichage de l'élément
|
||||
*
|
||||
|
@ -54,26 +91,9 @@ class LSformElement_quota extends LSformElement {
|
|||
$quotas=array();
|
||||
|
||||
foreach ($this -> values as $value) {
|
||||
if (preg_match('/^([0-9]*)$/',$value,$regs)) {
|
||||
$infos = array(
|
||||
'size' => ceil($regs[1]/$this -> getFactor())
|
||||
);
|
||||
if ($infos['size'] >= 1073741824) {
|
||||
$infos['valueSizeFact']=1073741824;
|
||||
}
|
||||
else if ($infos['size'] >= 1048576) {
|
||||
$infos['valueSizeFact']=1048576;
|
||||
}
|
||||
else if ($infos['size'] >= 1024) {
|
||||
$infos['valueSizeFact']=1024;
|
||||
}
|
||||
else {
|
||||
$infos['valueSizeFact']=1;
|
||||
}
|
||||
$infos['valueSize'] = $infos['size'] / $infos['valueSizeFact'];
|
||||
$infos['valueTxt'] = $infos['valueSize'].$this ->sizeFacts[$infos['valueSizeFact']];
|
||||
|
||||
$quotas[$value] = $infos;
|
||||
$parsed_value = $this -> parseValue($value);
|
||||
if ($parsed_value) {
|
||||
$quotas[$value] = $parsed_value;
|
||||
}
|
||||
else {
|
||||
$quotas[$value] = array(
|
||||
|
@ -128,36 +148,71 @@ class LSformElement_quota extends LSformElement {
|
|||
if($this -> isFreeze()) {
|
||||
return true;
|
||||
}
|
||||
if (isset($_POST[$this -> name.'_size'])) {
|
||||
$return[$this -> name]=array();
|
||||
$values = array();
|
||||
if ($this -> form -> api_mode) {
|
||||
if (isset($_POST[$this -> name])) {
|
||||
foreach(ensureIsArray($_POST[$this -> name]) as $value) {
|
||||
$values[] = ceil($value*$this -> getFactor());
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (isset($_POST[$this -> name.'_size'])) {
|
||||
$_POST[$this -> name.'_size'] = ensureIsArray($_POST[$this -> name.'_size']);
|
||||
if(isset($_POST[$this -> name.'_sizeFact']) && !is_array($_POST[$this -> name.'_sizeFact'])) {
|
||||
$_POST[$this -> name.'_sizeFact'] = array($_POST[$this -> name.'_sizeFact']);
|
||||
}
|
||||
foreach($_POST[$this -> name.'_size'] as $key => $val) {
|
||||
if (!empty($val)) {
|
||||
$f = 1;
|
||||
if (isset($_POST[$this -> name.'_sizeFact'][$key]) && ($_POST[$this -> name.'_sizeFact'][$key]!=1)) {
|
||||
$f = $_POST[$this -> name.'_sizeFact'][$key];
|
||||
}
|
||||
$val=preg_replace('/,/','.',$val);
|
||||
$return[$this -> name][$key] = ceil(ceil(($val*$f)*$this -> getFactor()));
|
||||
if (empty($val))
|
||||
continue;
|
||||
$f = 1;
|
||||
if (isset($_POST[$this -> name.'_sizeFact'][$key]) && ($_POST[$this -> name.'_sizeFact'][$key]!=1)) {
|
||||
$f = $_POST[$this -> name.'_sizeFact'][$key];
|
||||
}
|
||||
$val = preg_replace('/,/', '.', $val);
|
||||
$values[$key] = ceil(ceil(($val*$f)*$this -> getFactor()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($values) {
|
||||
$return[$this -> name] = $values;
|
||||
}
|
||||
elseif ($onlyIfPresent) {
|
||||
self :: log_debug($this -> name.": not in POST data => ignore it");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
$return[$this -> name] = array();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive factor value
|
||||
*
|
||||
* @retval integer Factor value
|
||||
*/
|
||||
private function getFactor() {
|
||||
return $this -> getParam('html_options.factor', 1);
|
||||
return $this -> getParam('html_options.factor', 1, 'int');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive value as return in API response
|
||||
*
|
||||
* @retval mixed API value(s) or null/empty array if no value
|
||||
*/
|
||||
public function getApiValue() {
|
||||
$values = array();
|
||||
foreach(ensureIsArray($this -> values) as $value) {
|
||||
$parsed_value = $this -> parseValue($value);
|
||||
if (is_array($parsed_value)) {
|
||||
$values[] = $parsed_value['size'];
|
||||
}
|
||||
}
|
||||
if ($this -> isMultiple()) {
|
||||
return $values;
|
||||
}
|
||||
if (!$values)
|
||||
return null;
|
||||
return $values[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -184,8 +184,8 @@ class LSformElement_supannCompositeAttribute extends LSformElement {
|
|||
* @retval boolean true si la valeur est présente en POST, false sinon
|
||||
*/
|
||||
public function getPostData(&$return, $onlyIfPresent=false) {
|
||||
if ($onlyIfPresent) {
|
||||
self :: log_warning("getPostData : does not support \$onlyIfPresent mode => Post data ignored");
|
||||
if ($onlyIfPresent || $this -> form -> api_mode) {
|
||||
self :: log_warning("getPostData : does not support \$onlyIfPresent / API mode => Post data ignored");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -157,43 +157,70 @@ class LSformElement_valueWithUnit extends LSformElement {
|
|||
if($this -> isFreeze()) {
|
||||
return true;
|
||||
}
|
||||
$return[$this -> name]=array();
|
||||
if (isset($_POST[$this -> name.'_valueWithUnit'])) {
|
||||
$_POST[$this -> name.'_valueWithUnit'] = ensureIsArray($_POST[$this -> name.'_valueWithUnit']);
|
||||
if(isset($_POST[$this -> name.'_unitFact']) && !is_array($_POST[$this -> name.'_unitFact'])) {
|
||||
$_POST[$this -> name.'_unitFact'] = array($_POST[$this -> name.'_unitFact']);
|
||||
}
|
||||
foreach($_POST[$this -> name.'_valueWithUnit'] as $key => $val) {
|
||||
if (!empty($val)) {
|
||||
$f = 1;
|
||||
if (isset($_POST[$this -> name.'_unitFact'][$key]) && ($_POST[$this -> name.'_unitFact'][$key]!=1)) {
|
||||
$f = $_POST[$this -> name.'_unitFact'][$key];
|
||||
}
|
||||
if ($this -> getParam('html_options.store_integer')) {
|
||||
if ($this -> getParam('html_options.round_down')) {
|
||||
$return[$this -> name][$key] = floor($val*$f);
|
||||
}
|
||||
else {
|
||||
$return[$this -> name][$key] = ceil($val*$f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$return[$this -> name][$key] = ($val*$f);
|
||||
}
|
||||
|
||||
if ($this -> form -> api_mode) {
|
||||
if (isset($_POST[$this -> name]) && $_POST[$this -> name]) {
|
||||
$return[$this -> name] = array();
|
||||
foreach(ensureIsArray($_POST[$this -> name]) as $value) {
|
||||
if ($this -> getParam('html_options.store_integer')) {
|
||||
$value = ($this -> getParam('html_options.round_down')?floor($value):ceil($value));
|
||||
}
|
||||
$return[$this -> name][] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($_POST[$this -> name])) {
|
||||
$_POST[$this -> name] = ensureIsArray($_POST[$this -> name]);
|
||||
$return[$this -> name] = array_merge($return[$this -> name], $_POST[$this -> name]);
|
||||
}
|
||||
if (isset($_POST[$this -> name.'_value'])) {
|
||||
$_POST[$this -> name.'_value'] = ensureIsArray($_POST[$this -> name.'_value']);
|
||||
$return[$this -> name] = array_merge($return[$this -> name], $_POST[$this -> name.'_value']);
|
||||
else {
|
||||
$return[$this -> name] = array();
|
||||
if (isset($_POST[$this -> name.'_valueWithUnit'])) {
|
||||
$_POST[$this -> name.'_valueWithUnit'] = ensureIsArray($_POST[$this -> name.'_valueWithUnit']);
|
||||
if(isset($_POST[$this -> name.'_unitFact']) && !is_array($_POST[$this -> name.'_unitFact'])) {
|
||||
$_POST[$this -> name.'_unitFact'] = array($_POST[$this -> name.'_unitFact']);
|
||||
}
|
||||
foreach($_POST[$this -> name.'_valueWithUnit'] as $key => $val) {
|
||||
if (empty($val))
|
||||
continue;
|
||||
$f = 1;
|
||||
if (isset($_POST[$this -> name.'_unitFact'][$key]) && ($_POST[$this -> name.'_unitFact'][$key]!=1)) {
|
||||
$f = $_POST[$this -> name.'_unitFact'][$key];
|
||||
}
|
||||
if ($this -> getParam('html_options.store_integer')) {
|
||||
$return[$this -> name][$key] = (
|
||||
$this -> getParam('html_options.round_down')?
|
||||
floor($val*$f):
|
||||
ceil($val*$f)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$return[$this -> name][$key] = ($val*$f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST[$this -> name.'_value'])) {
|
||||
$_POST[$this -> name.'_value'] = ensureIsArray($_POST[$this -> name.'_value']);
|
||||
$return[$this -> name] = array_merge($return[$this -> name], $_POST[$this -> name.'_value']);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive value as return in API response
|
||||
*
|
||||
* @retval mixed API value(s) or null/empty array if no value
|
||||
*/
|
||||
public function getApiValue() {
|
||||
$values = array();
|
||||
foreach (ensureIsArray($this -> values) as $value)
|
||||
if (preg_match('/^([0-9]*)$/', $value, $regs))
|
||||
$values[] = intval($regs[1]);
|
||||
if ($this -> isMultiple()) {
|
||||
return $values;
|
||||
}
|
||||
if (!$values)
|
||||
return null;
|
||||
return $values[0];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
86
src/includes/class/class.LSformRule_rlcMemberDetails.php
Normal file
86
src/includes/class/class.LSformRule_rlcMemberDetails.php
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2007 Easter-eggs
|
||||
* http://ldapsaisie.labs.libre-entreprise.org
|
||||
*
|
||||
* Author: See AUTHORS file in top-level directory.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* LSformRule to check rlcMemberDetails attribute value
|
||||
*
|
||||
* @author Benjamin Renard <brenard@easter-eggs.com>
|
||||
*/
|
||||
class LSformRule_rlcMemberDetails extends LSformRule {
|
||||
|
||||
// Validate values one by one or all together
|
||||
public const validate_one_by_one = False;
|
||||
|
||||
/**
|
||||
* Validate rlcMemberDetails attribute value
|
||||
*
|
||||
* @param string $values The value to validate
|
||||
* @param array $options Validation options
|
||||
* @param object $formElement The related formElement object
|
||||
*
|
||||
* @return boolean true if the value is valide, false if not
|
||||
*/
|
||||
public static function validate($value, $options=array(), &$formElement) {
|
||||
$members = array();
|
||||
foreach($value as $json_value) {
|
||||
if (is_empty($json_value)) {
|
||||
self :: log_error("validate($json_value): Empty value are not authorized");
|
||||
return false;
|
||||
}
|
||||
$v = json_decode($json_value);
|
||||
if (is_null($v)) {
|
||||
self :: log_error("validate($json_value): fail to decode JSON value");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($v->role) || is_empty($v->role) || !isset($v->uid) || is_empty($v->uid)) {
|
||||
self :: log_error("validate($json_value): invalid value (no uid or role)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!in_array($v->role, array('facilitator', 'governing_board_referent', 'contributor', 'observer'))) {
|
||||
self :: log_error("validate($json_value): invalid role $v->role");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!array_key_exists($v->role, $members))
|
||||
$members[$v->role] = array();
|
||||
if (in_array($v->uid, $members[$v->role])) {
|
||||
self :: log_error("validate($json_value): member $v->uid duplicated as $v->role");
|
||||
return false;
|
||||
}
|
||||
$members[$v->role][] = $v->uid;
|
||||
}
|
||||
self :: log_debug("validate(): members: ".print_r($members, true));
|
||||
foreach (array('facilitator', 'governing_board_referent', 'contributor') as $role) {
|
||||
if (!array_key_exists($role, $members)) {
|
||||
self :: log_error("validate(): no $role");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (count($members['governing_board_referent']) > 1) {
|
||||
self :: log_error("validate(): more than one governing_board_referent found");
|
||||
return false;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
}
|
|
@ -170,8 +170,8 @@ class LSimport {
|
|||
$globalErrors=array();
|
||||
// Instanciate an LSobject
|
||||
$object = new $LSobject();
|
||||
// Instanciate a creation LSform
|
||||
$form = $object -> getForm('create');
|
||||
// Instanciate a creation LSform (in API mode)
|
||||
$form = $object -> getForm('create', null, true);
|
||||
// Set form data from inputed data
|
||||
if ($form -> setPostData($objData,true)) {
|
||||
// Validate form
|
||||
|
@ -204,8 +204,8 @@ class LSimport {
|
|||
// Instanciate a new LSobject and load data from it's DN
|
||||
$object = new $LSobject();
|
||||
if ($object -> loadData($dn)) {
|
||||
// Instanciate a modify form
|
||||
$form = $object -> getForm('modify');
|
||||
// Instanciate a modify form (in API mode)
|
||||
$form = $object -> getForm('modify', null, true);
|
||||
// Set form data from inputed data
|
||||
if ($form -> setPostData($objData,true)) {
|
||||
// Validate form
|
||||
|
|
|
@ -199,22 +199,22 @@ class LSldapObject extends LSlog_staticLoggerClass {
|
|||
}
|
||||
|
||||
/**
|
||||
* Construit un formulaire de l'objet
|
||||
* Constuct a form for this object
|
||||
*
|
||||
* Cette méthode construit un formulaire LSform à partir de la configuration de l'objet
|
||||
* et de chaque attribut.
|
||||
* This method create a LSform from the object and its attributes configurations.
|
||||
*
|
||||
* @param[in] $idForm [<b>required</b>] Identifiant du formulaire a créer
|
||||
* @param[in] $load DN d'un objet similaire dont la valeur des attribut doit être chargé dans le formulaire.
|
||||
* @param[in] $idForm string Form identifier (required)
|
||||
* @param[in] $load string DN of a similar object. If defined, attributes values of this object will be loaded in the form.
|
||||
* @param[in] $api_mode boolean Enable API mode (defaut: false)
|
||||
*
|
||||
* @author Benjamin Renard <brenard@easter-eggs.com>
|
||||
*
|
||||
* @retval LSform Le formulaire crée
|
||||
* @retval LSform The created LSform object
|
||||
*/
|
||||
public function getForm($idForm,$load=NULL) {
|
||||
public function getForm($idForm, $load=NULL, $api_mode=false) {
|
||||
LSsession :: loadLSclass('LSform');
|
||||
$LSform = new LSform($this,$idForm);
|
||||
$this -> forms[$idForm] = array($LSform,$load);
|
||||
$LSform = new LSform($this, $idForm, null, $api_mode);
|
||||
$this -> forms[$idForm] = array($LSform, $load);
|
||||
|
||||
if ($load) {
|
||||
$type = $this -> getType();
|
||||
|
@ -1890,6 +1890,9 @@ class LSldapObject extends LSlog_staticLoggerClass {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
elseif ($key=='type') {
|
||||
return $this -> getType();
|
||||
}
|
||||
// Unknown key, log warning
|
||||
self :: log_warning("__get($key): invalid property requested\n".LSlog :: get_debug_backtrace_context());
|
||||
}
|
||||
|
@ -2460,8 +2463,8 @@ class LSldapObject extends LSlog_staticLoggerClass {
|
|||
if (is_null($objType) || empty($attrs_values))
|
||||
LScli :: usage('You must provide LSobject type, DN and at least one change.');
|
||||
|
||||
// Instanciate a create LSform
|
||||
$form = $obj -> getForm('create');
|
||||
// Instanciate a create LSform (in API mode)
|
||||
$form = $obj -> getForm('create', null, true);
|
||||
|
||||
// Check all changed attributes are in modify form and are'nn freezed
|
||||
foreach ($attrs_values as $attr => $value) {
|
||||
|
@ -2559,7 +2562,7 @@ class LSldapObject extends LSlog_staticLoggerClass {
|
|||
elseif ($objType && class_exists($objType)) {
|
||||
LScli :: need_ldap_con();
|
||||
$obj = new $objType();
|
||||
$form = $obj -> getForm('create');
|
||||
$form = $obj -> getForm('create', null, true); // Instanciate create form in API mode
|
||||
$form -> autocomplete_attrs_values($opts, $comp_word);
|
||||
}
|
||||
|
||||
|
@ -2639,8 +2642,8 @@ class LSldapObject extends LSlog_staticLoggerClass {
|
|||
return True;
|
||||
}
|
||||
|
||||
// Instanciate a modify LSform
|
||||
$form = $obj -> getForm('modify');
|
||||
// Instanciate a modify LSform (in API mode)
|
||||
$form = $obj -> getForm('modify', null, true);
|
||||
|
||||
// Check all changed attributes are in modify form and are'nn freezed
|
||||
foreach ($changes as $attr => $value) {
|
||||
|
@ -2742,7 +2745,7 @@ class LSldapObject extends LSlog_staticLoggerClass {
|
|||
self :: log_error("Fail to load object $dn data from LDAP");
|
||||
}
|
||||
else {
|
||||
$form = $obj -> getForm('modify');
|
||||
$form = $obj -> getForm('modify', null, True); // Instanciate modify form in API mode
|
||||
$form -> autocomplete_attrs_values($opts, $comp_word);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1181,7 +1181,8 @@ class LSsearch extends LSlog_staticLoggerClass {
|
|||
$params = array (
|
||||
'basedn',
|
||||
'sortBy',
|
||||
'sortDirection'
|
||||
'sortDirection',
|
||||
'attributes',
|
||||
);
|
||||
if ($key=='LSobject') {
|
||||
return $this -> LSobject;
|
||||
|
@ -1266,7 +1267,7 @@ class LSsearch extends LSlog_staticLoggerClass {
|
|||
return $this -> getHash();
|
||||
}
|
||||
else {
|
||||
throw new Exception('Incorrect property !');
|
||||
throw new Exception("Incorrect property '$key'!");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,6 +99,9 @@ class LSsession {
|
|||
// List of currently loaded LSaddons
|
||||
private static $loadedAddons = array();
|
||||
|
||||
// API mode
|
||||
private static $api_mode = false;
|
||||
|
||||
/**
|
||||
* Get session info by key
|
||||
*
|
||||
|
@ -128,6 +131,8 @@ class LSsession {
|
|||
return self :: globalSearch();
|
||||
case 'email_sender':
|
||||
return self :: getEmailSender();
|
||||
case 'api_mode':
|
||||
return boolval(self :: $api_mode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -1608,6 +1613,8 @@ class LSsession {
|
|||
* @retval void
|
||||
*/
|
||||
public static function displayTemplate() {
|
||||
if (self :: $api_mode)
|
||||
return self :: displayAjaxReturn();
|
||||
$KAconf = LSconfig :: get('keepLSsessionActive');
|
||||
if (
|
||||
(
|
||||
|
@ -1671,54 +1678,79 @@ class LSsession {
|
|||
}
|
||||
|
||||
/**
|
||||
* Défini que l'affichage se fera ou non via un retour Ajax
|
||||
* Set Ajax display mode
|
||||
*
|
||||
* @param[in] $val boolean True to enable Ajax display mode (optional, default: true)
|
||||
*
|
||||
* @param[in] $val boolean True pour que l'affichage se fasse par un retour
|
||||
* Ajax, false sinon
|
||||
* @retval void
|
||||
*/
|
||||
public static function setAjaxDisplay($val=true) {
|
||||
self :: $ajaxDisplay = (boolean)$val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Ajax display mode is enabled
|
||||
*
|
||||
* @retval boolean True if Ajax display mode is enabled, False otherwise
|
||||
*/
|
||||
public static function getAjaxDisplay() {
|
||||
return (boolean)self :: $ajaxDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Affiche un retour Ajax
|
||||
*
|
||||
* @retval void
|
||||
*/
|
||||
public static function displayAjaxReturn($data=array()) {
|
||||
public static function displayAjaxReturn($data=array(), $pretty=false) {
|
||||
if (isset($data['LSredirect']) && (!LSdebugDefined()) ) {
|
||||
echo json_encode($data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (class_exists('LStemplate'))
|
||||
if (!self :: $api_mode && class_exists('LStemplate'))
|
||||
$data['LSjsConfig'] = LStemplate :: getJSconfigParam();
|
||||
|
||||
// Infos
|
||||
if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
|
||||
$txt_infos="<ul>\n";
|
||||
foreach($_SESSION['LSsession_infos'] as $info) {
|
||||
$txt_infos.="<li>$info</li>\n";
|
||||
if (self :: $api_mode) {
|
||||
$data['messages'] = $_SESSION['LSsession_infos'];
|
||||
}
|
||||
else {
|
||||
$txt_infos="<ul>\n";
|
||||
foreach($_SESSION['LSsession_infos'] as $info) {
|
||||
$txt_infos.="<li>$info</li>\n";
|
||||
}
|
||||
$txt_infos.="</ul>\n";
|
||||
$data['LSinfos'] = $txt_infos;
|
||||
}
|
||||
$txt_infos.="</ul>\n";
|
||||
$data['LSinfos'] = $txt_infos;
|
||||
$_SESSION['LSsession_infos']=array();
|
||||
}
|
||||
|
||||
if (LSerror :: errorsDefined()) {
|
||||
$data['LSerror'] = LSerror :: getErrors();
|
||||
$data[(self :: $api_mode?'errors':'LSerror')] = LSerror :: getErrors(self :: $api_mode);
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['imgload'])) {
|
||||
if (!self :: $api_mode && isset($_REQUEST['imgload'])) {
|
||||
$data['imgload'] = $_REQUEST['imgload'];
|
||||
}
|
||||
|
||||
if (LSdebugDefined()) {
|
||||
if (!self :: $api_mode && LSdebugDefined()) {
|
||||
$data['LSdebug'] = LSdebug_print(true,false);
|
||||
}
|
||||
|
||||
echo json_encode($data);
|
||||
echo json_encode($data, (($pretty||isset($_REQUEST['pretty']))?JSON_PRETTY_PRINT:0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set API mode
|
||||
*
|
||||
* @param[in] $val boolean True to enable API mode (optional, default: true)
|
||||
*
|
||||
* @retval void
|
||||
*/
|
||||
public static function setApiMode($val=true) {
|
||||
self :: $api_mode = (boolean)$val;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2306,6 +2338,22 @@ class LSsession {
|
|||
return self :: canAccess($LSobject,NULL,'w','rdn');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check user right to compute the result of a LSformat
|
||||
*
|
||||
* @param[in] $LSformat string The LSformat string to check
|
||||
* @param[in] $LSobject string The LSobject type
|
||||
* @param[in] $dn string The LSobject DN (optional, default: the container_dn of the LSobject type)
|
||||
*
|
||||
* @retval boolean True is user can compute the result of the LSformat, False otherwise
|
||||
*/
|
||||
public static function canComputeLSformat($LSformat, $LSobject, $dn=NULL) {
|
||||
foreach (getFieldInFormat($LSformat) as $attr)
|
||||
if (!self :: canAccess($LSobject, $dn, 'r', $attr))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne le droit de l'utilisateur à gérer la relation d'objet
|
||||
*
|
||||
|
|
|
@ -455,10 +455,22 @@ class LStemplate extends LSlog_staticLoggerClass {
|
|||
* @retval void
|
||||
**/
|
||||
public static function fatal_error($error=null) {
|
||||
self :: assign('pagetitle', _("A fatal error occured."));
|
||||
self :: assign('error', _("A fatal error occured. If problem persist, please contact support."));
|
||||
self :: assign('details', $error);
|
||||
self :: display("error.tpl");
|
||||
http_response_code(500);
|
||||
if (LSsession :: get('api_mode')) {
|
||||
$errors = array(_("A fatal error occured. If problem persist, please contact support."));
|
||||
if ($error)
|
||||
$errors[] = $error;
|
||||
echo json_encode(
|
||||
array('errors' => $errors, 'success' => false),
|
||||
(isset($_REQUEST['pretty'])?JSON_PRETTY_PRINT:0)
|
||||
);
|
||||
}
|
||||
else {
|
||||
self :: assign('pagetitle', _("A fatal error occured."));
|
||||
self :: assign('error', _("A fatal error occured. If problem persist, please contact support."));
|
||||
self :: assign('details', $error);
|
||||
self :: display("error.tpl");
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
|
|
|
@ -61,21 +61,23 @@ class LSurl extends LSlog_staticLoggerClass {
|
|||
* @param[in] $handler callable The URL pattern handler (must be callable, required)
|
||||
* @param[in] $authenticated boolean Permit to define if this URL is accessible only for authenticated users (optional, default: true)
|
||||
* @param[in] $override boolean Allow override if a command already exists with the same name (optional, default: false)
|
||||
* @param[in] $api_mode boolean Enable API mode (optional, default: false)
|
||||
**/
|
||||
public static function add_handler($pattern, $handler=null, $authenticated=true, $override=true) {
|
||||
public static function add_handler($pattern, $handler=null, $authenticated=true, $override=true, $api_mode=false) {
|
||||
if (is_array($pattern)) {
|
||||
if (is_null($handler))
|
||||
foreach($pattern as $p => $h)
|
||||
self :: add_handlers($p, $h, $override);
|
||||
self :: add_handler($p, $h, $override, $api_mode);
|
||||
else
|
||||
foreach($pattern as $p)
|
||||
self :: add_handlers($p, $handler, $override);
|
||||
self :: add_handler($p, $handler, $override, $api_mode);
|
||||
}
|
||||
else {
|
||||
if (!isset(self :: $patterns[$pattern])) {
|
||||
self :: $patterns[$pattern] = array(
|
||||
'handler' => $handler,
|
||||
'authenticated' => $authenticated,
|
||||
'api_mode' => $api_mode,
|
||||
);
|
||||
}
|
||||
elseif ($override) {
|
||||
|
@ -83,6 +85,7 @@ class LSurl extends LSlog_staticLoggerClass {
|
|||
self :: $patterns[$pattern] = array(
|
||||
'handler' => $handler,
|
||||
'authenticated' => $authenticated,
|
||||
'api_mode' => $api_mode,
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -128,12 +131,15 @@ class LSurl extends LSlog_staticLoggerClass {
|
|||
self :: redirect($default_url);
|
||||
exit();
|
||||
}
|
||||
self :: log_debug("Current URL match with no pattern. Use error 404 handler.");
|
||||
// Error 404
|
||||
$api_mode = (strpos($current_url, 'api/') === 0);
|
||||
self :: log_debug("Current URL match with no pattern. Use error 404 handler (API mode=$api_mode).");
|
||||
return new LSurlRequest(
|
||||
$current_url,
|
||||
array(
|
||||
'handler' => array('LSurl', 'error_404'),
|
||||
'authenticated' => false,
|
||||
'api_mode' => $api_mode,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -228,9 +234,17 @@ class LSurl extends LSlog_staticLoggerClass {
|
|||
* @retval void
|
||||
**/
|
||||
public static function error_404($request=null) {
|
||||
LStemplate :: assign('error', _("The requested page was not found."));
|
||||
LSsession :: setTemplate('error.tpl');
|
||||
LSsession :: displayTemplate();
|
||||
http_response_code(404);
|
||||
$error = _("The requested page was not found.");
|
||||
if (LSsession :: getAjaxDisplay() || ($request && $request->api_mode)) {
|
||||
LSerror :: addErrorCode(null, $error);
|
||||
LSsession :: displayAjaxReturn();
|
||||
}
|
||||
else {
|
||||
LStemplate :: assign('error', $error);
|
||||
LSsession :: setTemplate('error.tpl');
|
||||
LSsession :: displayTemplate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -249,7 +263,9 @@ class LSurl extends LSlog_staticLoggerClass {
|
|||
self :: log_fatal(_("This request could not be handled."));
|
||||
}
|
||||
|
||||
if (class_exists('LStemplate'))
|
||||
if ($request -> api_mode)
|
||||
LSsession :: setApiMode();
|
||||
elseif (class_exists('LStemplate'))
|
||||
LStemplate :: assign('request', $request);
|
||||
|
||||
// Check authentication (if need)
|
||||
|
|
|
@ -37,6 +37,9 @@ class LSurlRequest extends LSlog_staticLoggerClass {
|
|||
// Request need authentication ?
|
||||
private $authenticated = true;
|
||||
|
||||
// API mode enabled ?
|
||||
private $api_mode = false;
|
||||
|
||||
// Parameters detected on requested URL
|
||||
private $url_params = array();
|
||||
|
||||
|
@ -44,6 +47,7 @@ class LSurlRequest extends LSlog_staticLoggerClass {
|
|||
$this -> current_url = $current_url;
|
||||
$this -> handler = $handler_infos['handler'];
|
||||
$this -> authenticated = (isset($handler_infos['authenticated'])?boolval($handler_infos['authenticated']):true);
|
||||
$this -> api_mode = (isset($handler_infos['api_mode'])?boolval($handler_infos['api_mode']):false);
|
||||
$this -> url_params = $url_params;
|
||||
}
|
||||
|
||||
|
@ -61,6 +65,8 @@ class LSurlRequest extends LSlog_staticLoggerClass {
|
|||
return $this -> handler;
|
||||
if ($key == 'authenticated')
|
||||
return $this -> authenticated;
|
||||
if ($key == 'api_mode')
|
||||
return $this -> api_mode;
|
||||
if ($key == 'referer')
|
||||
return $this -> get_referer();
|
||||
if (array_key_exists($key, $this->url_params)) {
|
||||
|
|
|
@ -354,11 +354,12 @@ LSurl :: add_handler('#^tmp/(?P<filename>[^/]+)$#', 'handle_tmp_file');
|
|||
* @param[in] $request LSurlRequest The request
|
||||
* @param[in] $instanciate boolean Instanciate and return an object (optional, default: true)
|
||||
* @param[in] $check_access callable|null Permit to specify check access method (optional, default: LSsession :: canAccess())
|
||||
* @param[in] $api_mode boolean Enable API mode (optional, default: false)
|
||||
*
|
||||
* @retval LSobject|boolean The instanciated LSobject (or True if $instanciate=false), or False
|
||||
* on error/access refused
|
||||
*/
|
||||
function get_LSobject_from_request($request, $instanciate=true, $check_access=null) {
|
||||
function get_LSobject_from_request($request, $instanciate=true, $check_access=null, $api_mode=false) {
|
||||
$LSobject = $request -> LSobject;
|
||||
$dn = (isset($request -> dn)?$request -> dn:null);
|
||||
|
||||
|
@ -367,7 +368,7 @@ function get_LSobject_from_request($request, $instanciate=true, $check_access=nu
|
|||
$check_access = array('LSsession', 'canAccess');
|
||||
|
||||
// Handle SELF redirect
|
||||
if ( $LSobject == 'SELF' ) {
|
||||
if ( !$api_mode && $LSobject == 'SELF' ) {
|
||||
$LSobject = LSsession :: getLSuserObject() -> getType();
|
||||
$dn = LSsession :: getLSuserObjectDn();
|
||||
LSurl :: redirect("object/$LSobject/".urlencode($dn));
|
||||
|
@ -377,13 +378,19 @@ function get_LSobject_from_request($request, $instanciate=true, $check_access=nu
|
|||
if ($dn) {
|
||||
if (!call_user_func($check_access, $LSobject, $dn)) {
|
||||
LSerror :: addErrorCode('LSsession_11');
|
||||
LSsession :: displayTemplate();
|
||||
if ($api_mode)
|
||||
LSsession :: displayAjaxReturn();
|
||||
else
|
||||
LSsession :: displayTemplate();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!LSsession :: in_menu($LSobject) && !call_user_func($check_access, $LSobject)) {
|
||||
LSerror :: addErrorCode('LSsession_11');
|
||||
LSsession :: displayTemplate();
|
||||
if ($api_mode)
|
||||
LSsession :: displayAjaxReturn();
|
||||
else
|
||||
LSsession :: displayTemplate();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1469,3 +1476,429 @@ function handle_old_addon_view($request) {
|
|||
LSurl :: redirect();
|
||||
}
|
||||
LSurl :: add_handler('#^addon_view\.php#', 'handle_old_addon_view', false);
|
||||
|
||||
/*
|
||||
* API
|
||||
*/
|
||||
|
||||
/*
|
||||
* LSobject API view helper to retreive LSobject from request
|
||||
*
|
||||
* Just a wrapper on get_LSobject_from_request() helper function to
|
||||
* correctly set parameters for API context.
|
||||
*
|
||||
* See get_LSobject_from_request() for details.
|
||||
*
|
||||
* @param[in] $request LSurlRequest The request
|
||||
* @param[in] $instanciate boolean Instanciate and return an object (optional, default: true)
|
||||
* @param[in] $check_access callable|null Permit to specify check access method (optional, default: see get_LSobject_from_request())
|
||||
*
|
||||
* @retval LSobject|boolean The instanciated LSobject (or True if $instanciate=false), or False
|
||||
* on error/access refused
|
||||
*/
|
||||
function get_LSobject_from_API_request($request, $instanciate=true, $check_access=null) {
|
||||
return get_LSobject_from_request($request, $instanciate, $check_access, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle API LSobject search
|
||||
*
|
||||
* @param[in] $request LSurlRequest The request
|
||||
*
|
||||
* @retval void
|
||||
**/
|
||||
function handle_api_LSobject_search($request) {
|
||||
LSsession :: setAjaxDisplay();
|
||||
$object = get_LSobject_from_API_request($request);
|
||||
if (!$object)
|
||||
return;
|
||||
|
||||
$LSobject = $object -> getType();
|
||||
|
||||
if (!LSsession :: loadLSclass('LSsearch')) {
|
||||
LSsession :: addErrorCode('LSsession_05', 'LSsearch');
|
||||
LSsession :: displayAjaxReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Instanciate a LSsearch
|
||||
$search = new LSsearch($LSobject, 'api', null, isset($_REQUEST['reset']));
|
||||
$search -> setParam('onlyAccessible', True);
|
||||
if (!$search -> setParamsFromRequest()) {
|
||||
LSsession :: displayAjaxReturn();
|
||||
return;
|
||||
}
|
||||
|
||||
// Run search
|
||||
if (!$search -> run())
|
||||
LSlog :: fatal('Fail to run search.');
|
||||
|
||||
$all = isset($_REQUEST['all']);
|
||||
|
||||
if ($all) {
|
||||
$entries = $search -> listEntries();
|
||||
if (!is_array($entries))
|
||||
LSlog :: fatal("Fail to retreive search result");
|
||||
}
|
||||
else {
|
||||
// Retrieve page
|
||||
$page_nb = (isset($_REQUEST['page'])?(int)$_REQUEST['page']:0);
|
||||
$page = $search -> getPage($page_nb);
|
||||
|
||||
/*
|
||||
* $page = array(
|
||||
* 'nb' => $page,
|
||||
* 'nbPages' => 1,
|
||||
* 'list' => array(),
|
||||
* 'total' => $this -> total
|
||||
* );
|
||||
*/
|
||||
|
||||
// Check page
|
||||
if (!is_array($page) || $page_nb > $page['nbPages'])
|
||||
LSlog :: fatal("Fail to retreive page #$page_nb.");
|
||||
}
|
||||
|
||||
// Handle JSON output
|
||||
$data = array(
|
||||
'success' => true,
|
||||
'objects' => array(),
|
||||
'total' => $search -> total,
|
||||
);
|
||||
if (!$all) {
|
||||
$data['page'] = $page['nb'] + 1;
|
||||
$data['nbPages'] = $page['nbPages'];
|
||||
}
|
||||
foreach(($all?$entries:$page['list']) as $obj) {
|
||||
$data['objects'][$obj -> dn] = array(
|
||||
'name' => $obj -> displayName,
|
||||
);
|
||||
if ($search -> displaySubDn)
|
||||
$data['objects'][$obj -> dn][$search -> label_level] = $obj -> subDn;
|
||||
if ($search -> extraDisplayedColumns) {
|
||||
foreach ($search -> visibleExtraDisplayedColumns as $cid => $conf) {
|
||||
$data['objects'][$obj -> dn][$conf['label']] = $obj -> $cid;
|
||||
}
|
||||
}
|
||||
foreach ($search -> attributes as $attr) {
|
||||
if (LSsession :: canAccess($LSobject, $obj -> dn, 'r', $attr))
|
||||
$data['objects'][$obj -> dn][$attr] = $obj -> $attr;
|
||||
}
|
||||
}
|
||||
LSsession :: displayAjaxReturn($data);
|
||||
}
|
||||
LSurl :: add_handler('#^api/1.0/object/(?P<LSobject>[^/]+)/?$#', 'handle_api_LSobject_search', true, false, true);
|
||||
|
||||
/*
|
||||
* Handle API LSobject create request
|
||||
*
|
||||
* @param[in] $request LSurlRequest The request
|
||||
*
|
||||
* @retval void
|
||||
**/
|
||||
function handle_api_LSobject_create($request) {
|
||||
LSsession :: setAjaxDisplay();
|
||||
$object = get_LSobject_from_API_request(
|
||||
$request,
|
||||
true, // instanciate object
|
||||
array('LSsession', 'canCreate') // Check access method
|
||||
);
|
||||
|
||||
if (!$object)
|
||||
return;
|
||||
|
||||
$data = array('success' => false);
|
||||
$LSobject = $object -> getType();
|
||||
$form = $object -> getForm('create', null, true); // Create form in API mode
|
||||
|
||||
if (isset($_REQUEST['dataEntryForm'])) {
|
||||
$form -> applyDataEntryForm((string)$_REQUEST['dataEntryForm']);
|
||||
}
|
||||
$form -> setSubmited();
|
||||
|
||||
if ($form->validate(true)) {
|
||||
// Data update for LDAP object
|
||||
if ($object -> updateData('create')) {
|
||||
$data['success'] = true;
|
||||
$data['type'] = $object -> getType();
|
||||
$data['dn'] = $object -> getDn();
|
||||
$data['name'] = $object -> getDisplayName();
|
||||
LSsession :: addInfo(_("Object has been added."));
|
||||
}
|
||||
else {
|
||||
$data['fields_errors'] = $form -> getErrors();
|
||||
}
|
||||
}
|
||||
else if ($form -> definedError()) {
|
||||
$data['fields_errors'] = $form -> getErrors();
|
||||
}
|
||||
LSsession :: displayAjaxReturn($data);
|
||||
}
|
||||
LSurl :: add_handler('#^api/1.0/object/(?P<LSobject>[^/]+)/create/?$#', 'handle_api_LSobject_create', true, false, true);
|
||||
|
||||
/*
|
||||
* Handle API LSobject show request
|
||||
*
|
||||
* @param[in] $request LSurlRequest The request
|
||||
*
|
||||
* @retval void
|
||||
**/
|
||||
function handle_api_LSobject_show($request) {
|
||||
LSsession :: setAjaxDisplay();
|
||||
$object = get_LSobject_from_API_request($request);
|
||||
if (!$object)
|
||||
return;
|
||||
|
||||
$data = array(
|
||||
'success' => true,
|
||||
'dn' => $object -> getDn(),
|
||||
'type' => $object -> getType(),
|
||||
'name' => $object -> getDisplayName(),
|
||||
'attributes' => array(),
|
||||
'relations' => array(),
|
||||
);
|
||||
|
||||
$view = $object -> getView();
|
||||
foreach($view -> elements as $element) {
|
||||
$data['attributes'][$element -> name] = $element -> getApiValue();
|
||||
}
|
||||
|
||||
if (LSsession :: loadLSclass('LSrelation')) {
|
||||
foreach ($object -> getConfig('LSrelation', array(), 'array') as $rel_name => $rel_conf) {
|
||||
$data['relations'][$rel_name] = array();
|
||||
$relation = new LSrelation($object, $rel_name);
|
||||
$list = $relation -> listRelatedObjects();
|
||||
if (is_array($list)) {
|
||||
foreach($list as $o) {
|
||||
$data['relations'][$rel_name][$o -> getDn()] = $o -> getDisplayName(NULL,true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LSlog :: error("Fail to load related objects.");
|
||||
}
|
||||
}
|
||||
}
|
||||
LSsession :: displayAjaxReturn($data);
|
||||
}
|
||||
LSurl :: add_handler('#^api/1.0/object/(?P<LSobject>[^/]+)/?(?P<dn>[^/]+)/?$#', 'handle_api_LSobject_show', true, false, true);
|
||||
|
||||
/*
|
||||
* Handle API LSobject modify request
|
||||
*
|
||||
* @param[in] $request LSurlRequest The request
|
||||
*
|
||||
* @retval void
|
||||
**/
|
||||
function handle_api_LSobject_modify($request) {
|
||||
LSsession :: setAjaxDisplay();
|
||||
$object = get_LSobject_from_API_request(
|
||||
$request,
|
||||
true, // instanciate object
|
||||
array('LSsession', 'canEdit') // Check access method
|
||||
);
|
||||
if (!$object)
|
||||
return;
|
||||
|
||||
$data = array(
|
||||
'dn' => $object -> getDn(),
|
||||
'type' => $object -> getType(),
|
||||
'name' => $object -> getDisplayName(),
|
||||
'success' => false,
|
||||
);
|
||||
$form = $object -> getForm('modify', null, true); // Create form in API mode
|
||||
$form -> setSubmited();
|
||||
|
||||
if ($form->validate(true)) {
|
||||
// Update LDAP object data
|
||||
if ($object -> updateData('modify')) {
|
||||
// Update successful
|
||||
if (LSerror::errorsDefined()) {
|
||||
LSsession :: addInfo(_("The object has been partially modified."));
|
||||
}
|
||||
else {
|
||||
LSsession :: addInfo(_("The object has been modified successfully."));
|
||||
$data['success'] = true;
|
||||
}
|
||||
}
|
||||
elseif ($form -> definedError()) {
|
||||
$data['fields_errors'] = $form -> getErrors();
|
||||
}
|
||||
}
|
||||
else if ($form -> definedError()) {
|
||||
$data['fields_errors'] = $form -> getErrors();
|
||||
}
|
||||
LSsession :: displayAjaxReturn($data);
|
||||
}
|
||||
LSurl :: add_handler('#^api/1.0/object/(?P<LSobject>[^/]+)/(?P<dn>[^/]+)/modify/?$#', 'handle_api_LSobject_modify', true, false, true);
|
||||
|
||||
/*
|
||||
* Handle API LSobject remove request
|
||||
*
|
||||
* @param[in] $request LSurlRequest The request
|
||||
*
|
||||
* @retval void
|
||||
**/
|
||||
function handle_api_LSobject_remove($request) {
|
||||
LSsession :: setAjaxDisplay();
|
||||
$object = get_LSobject_from_API_request(
|
||||
$request,
|
||||
true, // instanciate object
|
||||
array('LSsession', 'canRemove') // Check access method
|
||||
);
|
||||
if (!$object)
|
||||
return;
|
||||
|
||||
$data = array(
|
||||
'dn' => $object -> getDn(),
|
||||
'type' => $object -> getType(),
|
||||
'name' => $object -> getDisplayName(),
|
||||
'success' => false,
|
||||
);
|
||||
|
||||
// Remove object (if validated)
|
||||
if ($object -> remove()) {
|
||||
LSsession :: addInfo(getFData(_('%{objectname} has been successfully deleted.'), $data['name']));
|
||||
$data['success'] = true;
|
||||
}
|
||||
else {
|
||||
LSerror :: addErrorCode('LSldapObject_15', $objectname);
|
||||
}
|
||||
LSsession :: displayAjaxReturn($data);
|
||||
}
|
||||
LSurl :: add_handler('#^api/1.0/object/(?P<LSobject>[^/]+)/(?P<dn>[^/]+)/remove/?$#', 'handle_api_LSobject_remove', true, false, true);
|
||||
|
||||
/*
|
||||
* Handle API LSobject relation request
|
||||
*
|
||||
* @param[in] $request LSurlRequest The request
|
||||
*
|
||||
* @retval void
|
||||
**/
|
||||
function handle_api_LSobject_relation($request) {
|
||||
LSsession :: setAjaxDisplay();
|
||||
$object = get_LSobject_from_API_request(
|
||||
$request,
|
||||
true, // instanciate object
|
||||
);
|
||||
if (!$object)
|
||||
return;
|
||||
|
||||
$LSobject = $object -> getType();
|
||||
|
||||
// Handle relation URL parameter
|
||||
$relationName = $request -> relation;
|
||||
if (!is_array($object -> getConfig("LSrelation.$relationName"))) {
|
||||
LSlog :: log_error("LSobject $LSobject have no relation '$relationName'.");
|
||||
LSsession :: displayAjaxReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check user access to this relation
|
||||
if (
|
||||
(isset($_REQUEST['add']) || isset($_REQUEST['remove'])) &&
|
||||
!LSsession :: relationCanEdit($object -> dn, $LSobject, $relationName)
|
||||
) {
|
||||
LSerror :: addErrorCode('LSsession_11');
|
||||
LSsession :: displayAjaxReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load LSrelation PHP class (with warning)
|
||||
if (!LSsession :: loadLSclass('LSrelation', null, true)) {
|
||||
LSsession :: displayAjaxReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
$relation = new LSrelation($object, $relationName);
|
||||
|
||||
$data = array(
|
||||
'dn' => $object -> getDn(),
|
||||
'type' => $object -> getType(),
|
||||
'name' => $object -> getDisplayName(),
|
||||
'relation' => $relationName,
|
||||
'success' => false,
|
||||
);
|
||||
$warnings = array();
|
||||
|
||||
// List current related objects
|
||||
$list = $relation -> listRelatedObjects();
|
||||
$listDns = array();
|
||||
if (is_array($list)) {
|
||||
foreach($list as $o) {
|
||||
$listDns[] = $o -> getDn();
|
||||
}
|
||||
}
|
||||
LSlog :: debug("Current related object(s): ".varDump($listDns));
|
||||
|
||||
// Keep a copy of initial related objects list
|
||||
$initialListDns = $listDns;
|
||||
|
||||
// Handle add
|
||||
$relatedLSobject = $object -> getConfig("LSrelation.$relationName.LSobject");
|
||||
$search = new LSsearch(
|
||||
$relatedLSobject,
|
||||
"LSrelation.api.$LSobject.$relationName",
|
||||
array(
|
||||
'scope' => 'base',
|
||||
)
|
||||
);
|
||||
if (isset($_REQUEST['add'])) {
|
||||
foreach (ensureIsArray($_REQUEST['add']) as $dn) {
|
||||
$dn = urldecode($dn);
|
||||
// Check if DN is already in relation
|
||||
if (in_array($dn, $listDns)) {
|
||||
LSlog :: debug("LSobject $relatedLSobject $dn is already in relation with ".$object -> getDn().".");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check DN refer to a related object
|
||||
$search -> setParam('basedn', $dn);
|
||||
$search -> run(false);
|
||||
$result = $search -> listObjectsDn();
|
||||
if (!is_array($result) || count($result) != 1) {
|
||||
$warnings[] = "No $relatedLSobject found for DN $dn";
|
||||
}
|
||||
$listDns[] = $dn;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['remove'])) {
|
||||
// Handle remove
|
||||
foreach (ensureIsArray($_REQUEST['remove']) as $dn) {
|
||||
$dn = urldecode($dn);
|
||||
$found = false;
|
||||
while(true) {
|
||||
$key = array_search($dn, $listDns);
|
||||
if ($key === false) break;
|
||||
$found = true;
|
||||
unset($listDns[$key]);
|
||||
}
|
||||
if (!$found)
|
||||
LSlog :: debug("LSobject $relatedLSobject $dn is not in relation with ".$object -> getDn().".");
|
||||
}
|
||||
}
|
||||
|
||||
// Add new related objects list in result
|
||||
$data['relatedObjects'] = array_values($listDns);
|
||||
|
||||
if ($warnings) {
|
||||
LSerror :: addErrorCode(false, "Some problems detected on requested changes.");
|
||||
$data['warnings'] = $warnings;
|
||||
}
|
||||
else if ($initialListDns == $listDns) {
|
||||
LSsession :: addInfo('No changes done.');
|
||||
$data['success'] = true;
|
||||
}
|
||||
else {
|
||||
LSlog :: debug("New related object(s) list: ".varDump($listDns));
|
||||
if ($relation -> updateRelations($listDns)) {
|
||||
LSsession :: addInfo('Objects in relation updated.');
|
||||
$data['success'] = true;
|
||||
}
|
||||
else {
|
||||
LSerror :: addErrorCode(false, "Fail to update objects in relation");
|
||||
}
|
||||
}
|
||||
LSsession :: displayAjaxReturn($data);
|
||||
}
|
||||
LSurl :: add_handler('#^api/1.0/object/(?P<LSobject>[^/]+)/(?P<dn>[^/]+)/relation/(?P<relation>[^/]+)/?$#', 'handle_api_LSobject_relation', true, false, true);
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue