mirror of
https://gitlab.easter-eggs.com/ee/ldapsaisie.git
synced 2024-11-24 02:49:07 +01:00
Compare commits
5 commits
fee03668f5
...
0eb73ee5bf
Author | SHA1 | Date | |
---|---|---|---|
|
0eb73ee5bf | ||
|
5e17a8ec81 | ||
|
2e0338e678 | ||
|
965efeeda5 | ||
|
b7a68f6a9e |
6 changed files with 392 additions and 85 deletions
|
@ -171,7 +171,11 @@ build:doc:html:
|
||||||
- apk add make git
|
- apk add make git
|
||||||
- git config user.name $GITLAB_USER_NAME
|
- git config user.name $GITLAB_USER_NAME
|
||||||
- git config user.email $GITLAB_USER_EMAIL
|
- git config user.email $GITLAB_USER_EMAIL
|
||||||
- VERSION=`git describe --tags`
|
- |
|
||||||
|
VERSION=$(
|
||||||
|
git describe --tags 2> /dev/null || \
|
||||||
|
echo "0.0-$( git log --oneline|wc -l )-$( git describe --tags --always )"
|
||||||
|
)
|
||||||
- cd doc
|
- cd doc
|
||||||
- git fetch origin $DOC_BRANCH
|
- git fetch origin $DOC_BRANCH
|
||||||
- git rev-parse --verify $DOC_BRANCH && git branch -D $DOC_BRANCH || echo "No existing local git $DOC_BRANCH branch"
|
- git rev-parse --verify $DOC_BRANCH && git branch -D $DOC_BRANCH || echo "No existing local git $DOC_BRANCH branch"
|
||||||
|
@ -236,7 +240,11 @@ build:doc:append_additional_versions:
|
||||||
- apk add git
|
- apk add git
|
||||||
- git config user.name $GITLAB_USER_NAME
|
- git config user.name $GITLAB_USER_NAME
|
||||||
- git config user.email $GITLAB_USER_EMAIL
|
- git config user.email $GITLAB_USER_EMAIL
|
||||||
- VERSION=`git describe --tags`
|
- |
|
||||||
|
VERSION=$(
|
||||||
|
git describe --tags 2> /dev/null || \
|
||||||
|
echo "0.0-$( git log --oneline|wc -l )-$( git describe --tags --always )"
|
||||||
|
)
|
||||||
- cd doc
|
- cd doc
|
||||||
- git fetch origin $DOC_BRANCH
|
- git fetch origin $DOC_BRANCH
|
||||||
- git rev-parse --verify $DOC_BRANCH && git branch -D $DOC_BRANCH || echo "No existing local git $DOC_BRANCH branch"
|
- git rev-parse --verify $DOC_BRANCH && git branch -D $DOC_BRANCH || echo "No existing local git $DOC_BRANCH branch"
|
||||||
|
|
|
@ -13,8 +13,15 @@ guider dans le choix d'un mot de passe sûre.
|
||||||
|
|
||||||
- `minScore`
|
- `minScore`
|
||||||
|
|
||||||
Le score minimal pour que le mot de passe soit accepté. Il doit s'agir d'un entier cimpris entre 0
|
Le score minimal pour que le mot de passe soit accepté. Il doit s'agir d'un entier compris entre
|
||||||
(le plus faible) et 4 (le plus sécurisé). Paramètre facultatif valant 4 par défaut.
|
0 (le plus faible) et 4 (le plus sécurisé). Paramètre facultatif valant 4 par défaut.
|
||||||
|
|
||||||
|
- `minGuessesLog10`
|
||||||
|
|
||||||
|
Permet de définir le logarithme en base 10 du nombre minimum estimé de tentative pour deviner le
|
||||||
|
mot de passe. Par exemple, si `minGuessesLog10` est égal à 6, cela signifie que le mot de passe
|
||||||
|
ne sera accepté que si `Zxcvbn` estime qu'il faut au moins 1 million (10^6) de tentatives pour le
|
||||||
|
deviner. Paramètre facultatif valant 10 par défaut.
|
||||||
|
|
||||||
- `userDataAttrs`
|
- `userDataAttrs`
|
||||||
|
|
||||||
|
@ -24,6 +31,11 @@ guider dans le choix d'un mot de passe sûre.
|
||||||
le protège que peut des attaques ciblées. Paramètre facultatif, mais il est fortement conseillé de
|
le protège que peut des attaques ciblées. Paramètre facultatif, mais il est fortement conseillé de
|
||||||
renseigner un maximum d'attributs contenant des informations personnelles relatives à l'utilisteur.
|
renseigner un maximum d'attributs contenant des informations personnelles relatives à l'utilisteur.
|
||||||
|
|
||||||
|
- `banPersonalInfo`
|
||||||
|
|
||||||
|
Booléen permettant d'interdire toutes utilisations d'informations personnelles dans le choix du mot
|
||||||
|
de passe. Paramètre facultatif et vrai par défaut.
|
||||||
|
|
||||||
- `showWarning`
|
- `showWarning`
|
||||||
|
|
||||||
Booléen définissant si les messages d'alertes retournés par la librairie `Zxcvbn` doivent être
|
Booléen définissant si les messages d'alertes retournés par la librairie `Zxcvbn` doivent être
|
||||||
|
@ -52,6 +64,29 @@ guider dans le choix d'un mot de passe sûre.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- `banDictionaries`
|
||||||
|
|
||||||
|
Ce paramètre permet d'interdire tous mots issues de certains dictionnaires. Il s'agit d'un
|
||||||
|
tableau devant contenir les noms des dictionaires interdits. La librairie `Zxcvbn` fournis
|
||||||
|
les dictionnaires suivant :
|
||||||
|
|
||||||
|
- `us_tv_and_film` : les mots les plus courrament utilisés dans les séries et films américains
|
||||||
|
- `passwords` : les mot de passse les plus courrament utilisés
|
||||||
|
- `male_names` : les prénoms masculins les plus courrant
|
||||||
|
- `female_names` : les prénoms féminins les plus courrant
|
||||||
|
- `surnames` : les nom de familles les plus courrant aux États Unis
|
||||||
|
- `english_wikipedia` : les mots les plus courrament utilisés dans les articles en anglais de
|
||||||
|
Wikipédia
|
||||||
|
- `french_wikipedia` : les mots les plus courrament utilisés dans les articles en français de
|
||||||
|
Wikipédia
|
||||||
|
- `user_inputs` : les informations personnelles fournis lors de la validation du mot de passe
|
||||||
|
|
||||||
|
__Note :__ lister ce dictionnaire dans se paramètre à le même effet que le paramètre
|
||||||
|
`banPersonalInfo` documenté ci-dessus.
|
||||||
|
|
||||||
|
Vous pouvez également lister ici tout dictionnaires personnalisés que vous auriez ajouté grâce
|
||||||
|
au paramètre `customDictionaries`.
|
||||||
|
|
||||||
- `zxcvbn_autoload_path`
|
- `zxcvbn_autoload_path`
|
||||||
|
|
||||||
Le chemin vers le fichier de chargement automatique des classes de la librairie *ZxcvbnPhp*. Ce
|
Le chemin vers le fichier de chargement automatique des classes de la librairie *ZxcvbnPhp*. Ce
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
# Les commandes *CLI* personnalisées
|
# Les commandes *CLI* personnalisées
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
Les [LSaddons](../../conf/index.md#configuration-des-lsaddons) peuvent fournir des commandes *CLI*
|
Les [LSaddons](../../conf/index.md#configuration-des-lsaddons) peuvent fournir des commandes *CLI*
|
||||||
personnalisées qui seront accessibles via la commande `ldapsaisie` fournie avec l'application. Cela
|
personnalisées qui seront accessibles via la commande `ldapsaisie` fournie avec l'application. Cela
|
||||||
peut, par exemple, vous permettre de rendre accessible en ligne de commandes une procédure
|
peut, par exemple, vous permettre de rendre accessible en ligne de commandes une procédure
|
||||||
|
@ -8,79 +10,152 @@ exécutant cette procédure régulièrement.
|
||||||
|
|
||||||
Pour mettre en place une telle commande *CLI* personnalisée, il est nécessaire de :
|
Pour mettre en place une telle commande *CLI* personnalisée, il est nécessaire de :
|
||||||
|
|
||||||
- Déclarer cette vue dans la fonction `LSaddon_[addon]_support` de l'addon à l'aide de la méthode
|
- Déclarer cette commande *CLI* personnalisée dans la fonction `LSaddon_[addon]_support` de l'addon
|
||||||
`LScli :: add_command()` ;
|
à l'aide de la méthode `LScli::add_command()` ;
|
||||||
|
|
||||||
- Déclarer la fonction implémentant cette commande *CLI* personnalisée. Cette fonction acceptera,
|
- Déclarer la fonction implémentant cette commande *CLI* personnalisée. Cette fonction acceptera,
|
||||||
en tant qu'unique paramètre, un tableau des arguments reçus lors de l'exécution de la commande et
|
en tant qu'unique paramètre, un tableau des arguments reçus lors de l'exécution de la commande et
|
||||||
retournera `True` ou `False` en cas de succès/d'erreur d'exécution de la commande. Cette valeur de
|
retournera `True` ou `False` en cas de succès/d'erreur d'exécution de la commande. Cette valeur
|
||||||
retour influencera le code retourné par la commande : `0` en cas de succès, `1` en cas d'erreur.
|
de retour influencera le code retourné par la commande : `0` en cas de succès, `1` en cas
|
||||||
|
d'erreur.
|
||||||
|
|
||||||
- Bien que cela ne soit pas obligatoire, il sera également possible de déclarer une fonction
|
- Bien que cela ne soit pas obligatoire, il sera également possible de déclarer une fonction
|
||||||
permettant l'autocomplétion des arguments acceptés par la commande.
|
permettant l'autocomplétion des arguments acceptés par la commande. Pour plus d'informations à ce
|
||||||
|
propos, reportez-vous à la [section dédiée](#auto-completion).
|
||||||
|
|
||||||
Cette méthode recevra en paramètre :
|
## Outils à votre disposition
|
||||||
|
|
||||||
- `$command_args`
|
Pour vous aider dans l'écriture de vos méthodes *CLI*, la classe `LScli` offre des méthodes
|
||||||
|
pour les tâches les plus courantes :
|
||||||
|
|
||||||
Un tableau des arguments déjà reçus par la commande.
|
- `LScli::usage($error, ...$extra_args)`
|
||||||
|
|
||||||
- `$comp_word_num`
|
Affichage du message d'aide de votre commande avant arrêt. Un message d'erreur peut également
|
||||||
|
être spécifié avec d'éventuels arguments supplémentaires pour le composer (via `sprintf()`). Si un
|
||||||
|
message d'erreur est fourni, le code de retour de la commande sera `1` et à défaut, `0`.
|
||||||
|
|
||||||
Un entier indiquant le rang de l'argument que l'autocomplétion tente de compléter. Il peut
|
- `LScli::need_ldap_con()`
|
||||||
s'agir du rang d'un paramètre déjà fourni et présent dans le tableau `$command_args` ou bien
|
|
||||||
d'un rang supérieur aux nombres d'arguments déjà fournis à la commande et dans ce cas il s'agira
|
|
||||||
d'autocompléter tous potentiels autre argument que pourrait accepter cette commande.
|
|
||||||
|
|
||||||
- `$comp_word`
|
Permet d'établir la connexion à l'annuaire LDAP (si ce n'est pas déjà fait).
|
||||||
|
|
||||||
Une chaîne de caractères correspondant à ce qu'a déjà saisi l'utilisateur de l'argument que l'on
|
- `LScli::run_external_command($command, $data_stdin=null, $escape_command_args=true, $cwd=null)` :
|
||||||
tente d'autocompléter. Cette chaîne de caractères peut être vide ou non, en fonction de s'il
|
|
||||||
s'agit d'un nouvel argument à autocompléter ou non.
|
|
||||||
|
|
||||||
- `$opts`
|
Permet d'exécuter une commande externe et de récupérer un tableau contenant le code de
|
||||||
|
retour de la commande exécutée, le contenu affiché sur la sortie standard et le contenu
|
||||||
|
affiché sur la sortie d'erreur.
|
||||||
|
|
||||||
Un tableau des potentiels arguments globaux acceptés par *LScli* dans le contexte actuel (par
|
La commande à exécuter peut être passée sous la forme d'une chaîne de caractères ou d'un
|
||||||
exemple, `-d` ou `--debug` pour l'activation du mode debug). La réponse de cette fonction devra
|
tableau de chaînes de caractères correspondant à la commande et ses arguments. Par défaut,
|
||||||
inclure ces potentiels arguments si le contexte d'autocomplétion si prête (nouvel argument par
|
les caractères spéciaux contenus dans les paramètres passés à la commande seront
|
||||||
exemple).
|
"échappés", mais il est possible de désactiver cela via le paramètre `$escape_command_args`.
|
||||||
|
|
||||||
Pour finir, cette fonction devra retourner un tableau des potentielles valeurs que pourrait
|
Il est possible de fournir des données à passer à la commande via son entrée standard via
|
||||||
prendre l'argument autocomplété. Si une unique proposition est faite à l'utilisateur, celle-ci
|
le paramètre `$data_stdin`.
|
||||||
sera automatiquement proposée à l'utilisateur et à défaut, la liste des valeurs possibles lui
|
|
||||||
seront affichées.
|
|
||||||
|
|
||||||
!!! note
|
Enfin, il est possible de spécifier l'emplacement du dossier courant d'exécution de la
|
||||||
|
commande via le paramètre `$cwd`.
|
||||||
|
|
||||||
Pour vous aider dans l'écrire d'une telle méthode d'autocomplétion, des méthodes statiques
|
- `LScli::confirm($question=null)`
|
||||||
sont fournies par la classe `LScli` pour les autocomplétions les plus courantes :
|
|
||||||
|
|
||||||
- `LScli :: autocomplete_class_name()`
|
Permet de demander à l'utilisateur de confirmer quelque chose. La question à poser peut être
|
||||||
|
passée en paramètre et cette méthode retournera `true` ou `false` en fonction du choix de
|
||||||
|
l'utilisateur.
|
||||||
|
|
||||||
Autocomplétion du nom d'une classe PHP.
|
- `LScli::parse_arg_value($value, $custom_values=null)`
|
||||||
|
|
||||||
- `LScli :: autocomplete_addon_name()`
|
Permet d'interpréter la valeur d'un argument fourni par l'utilisateur. Celui-ci pourra spécifier
|
||||||
|
le type de l'argument en préfixant l'argument de son type entre crochets (exemple : `[bool]1`,
|
||||||
|
types supportés : `string`, `str`, `bool`, `boolean`, `int`, `integer`, `float`, `array`) et à
|
||||||
|
défaut, la valeur sera analysée comme une valeur JSON permettant de passer des paramètres
|
||||||
|
complexes à vos méthodes (un tableau associatif arborescent par exemple).
|
||||||
|
|
||||||
Autocomplétion du nom d'un [LSaddon](../../conf/index.md#configuration-des-lsaddons).
|
Des valeurs particulières seront également analysées de manières prédéfinies si elles ne
|
||||||
|
sont pas préfixées d'un type particulier. C'est le cas par défaut des chaînes de
|
||||||
|
caractères `true` et `false` qui seront comprises comme des booléens et `null` qui sera
|
||||||
|
compris comme la valeur `NULL` au sens PHP.
|
||||||
|
|
||||||
- `LScli :: autocomplete_int()`
|
Vous pouvez également spécifier vos propres valeurs particulières via l'argument
|
||||||
|
`$custom_values` sous la forme d'un tableau associatif dont les clés sont les valeurs
|
||||||
|
particulières fournies par l'utilisateur et la valeur correspondante, la valeur au sens
|
||||||
|
_PHP_.
|
||||||
|
|
||||||
Autocomplétion d'un nombre entier.
|
__Important :__ l'analyse des valeurs particulières sera faite en mettant
|
||||||
|
__en minuscule__ la valeur fournie par l'utilisateur. Il est donc important que vos
|
||||||
|
valeurs particulières spécifiées via l'argument `$custom_values` soient toutes en
|
||||||
|
minuscule.
|
||||||
|
|
||||||
- `LScli :: autocomplete_LSobject_types()`
|
## Auto-complétion
|
||||||
|
|
||||||
Autocomplétion du nom d'un type d'[LSobject](../../conf/index.md#configuration-lsobject).
|
Lors de la déclaration de votre commande CLI personnalisée à l'aide de la méthode
|
||||||
|
`LScli::add_command()`, vous avez la possibilité de spécifier une fonction permettant
|
||||||
|
l'autocomplétion des arguments acceptés par celle-ci.
|
||||||
|
|
||||||
- `LScli :: autocomplete_LSobject_dn()`
|
Cette fonction recevra en paramètre :
|
||||||
|
|
||||||
Autocomplétion du DN d'un type précis d'[LSobject](../../conf/index.md#configuration-lsobject) de
|
- `$command_args`
|
||||||
l'annuaire.
|
|
||||||
|
|
||||||
Par ailleurs, la méthode `LScli :: autocomplete_opts()` vous facilitera la construction de la
|
Un tableau des arguments déjà reçus par la commande.
|
||||||
liste des valeurs d'autocomplétion de l'argument courant en fonction de ce qui a déjà été
|
|
||||||
saisi par l'utilisateur (paramètre `$comp_word`). Cette méthode s'occupera en l'occurrence de
|
- `$comp_word_num`
|
||||||
filtrer parmi toutes les valeurs contextuelles possibles, celles qui correspondent au préfixe
|
|
||||||
fourni par l'utilisateur.
|
Un entier indiquant le rang de l'argument que l'autocomplétion tente de compléter. Il peut
|
||||||
|
s'agir du rang d'un paramètre déjà fourni et présent dans le tableau `$command_args` ou bien
|
||||||
|
d'un rang supérieur aux nombres d'arguments déjà fournis à la commande et dans ce cas il s'agira
|
||||||
|
d'autocompléter tous potentiels autres arguments que pourrait accepter cette commande.
|
||||||
|
|
||||||
|
- `$comp_word`
|
||||||
|
|
||||||
|
Une chaîne de caractères correspondant à ce qu'a déjà saisi l'utilisateur de l'argument que l'on
|
||||||
|
tente d'autocompléter. Cette chaîne de caractères peut être vide ou non, en fonction de s'il
|
||||||
|
s'agit d'un nouvel argument à autocompléter ou non.
|
||||||
|
|
||||||
|
- `$opts`
|
||||||
|
|
||||||
|
Un tableau des potentiels arguments globaux acceptés par *LScli* dans le contexte actuel (par
|
||||||
|
exemple, `-d` ou `--debug` pour l'activation du mode debug). La réponse de cette fonction devra
|
||||||
|
inclure ces potentiels arguments si le contexte d'autocomplétion s'y prête (nouvel argument par
|
||||||
|
exemple).
|
||||||
|
|
||||||
|
Pour finir, cette fonction devra retourner un tableau des potentielles valeurs que pourrait
|
||||||
|
prendre l'argument autocomplété. Si une unique proposition est faite à l'utilisateur, celle-ci
|
||||||
|
sera automatiquement proposée à l'utilisateur et à défaut, la liste des valeurs possibles lui
|
||||||
|
seront affichées.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
Pour vous aider dans l'écriture d'une telle méthode d'autocomplétion, des méthodes statiques
|
||||||
|
sont fournies par la classe `LScli` pour les autocomplétions les plus courantes :
|
||||||
|
|
||||||
|
- `LScli::autocomplete_class_name()` : Autocomplétion du nom d'une classe PHP.
|
||||||
|
|
||||||
|
- `LScli::autocomplete_addon_name()` : Autocomplétion du nom d'un
|
||||||
|
[LSaddon](../../conf/index.md#configuration-des-lsaddons).
|
||||||
|
|
||||||
|
- `LScli::autocomplete_int()` : Autocomplétion d'un nombre entier.
|
||||||
|
|
||||||
|
- `LScli::autocomplete_LSobject_types()` : Autocomplétion du nom d'un type
|
||||||
|
d'[LSobject](../../conf/index.md#configuration-lsobject).
|
||||||
|
|
||||||
|
- `LScli::autocomplete_LSobject_dn()` : Autocomplétion du DN d'un type précis
|
||||||
|
d'[LSobject](../../conf/index.md#configuration-lsobject) de l'annuaire.
|
||||||
|
|
||||||
|
- `LScli::autocomplete_LSobject_attr_name()` : Autocomplétion du nom d'un attribut précis
|
||||||
|
pour un type d'[LSobject](../../conf/index.md#configuration-lsobject) de l'annuaire.
|
||||||
|
|
||||||
|
- `LScli::autocomplete_LSobject_ioFormat()` : Autocomplétion du nom d'un
|
||||||
|
[ioFormat](../../conf/LSobject/ioFormat.md#ioformat) pour un type
|
||||||
|
d'[LSobject](../../conf/index.md#configuration-lsobject) de l'annuaire.
|
||||||
|
|
||||||
|
- `LScli::autocomplete_LSform_name()` : Autocomplétion du nom d'un formulaire de
|
||||||
|
l'application.
|
||||||
|
|
||||||
|
Par ailleurs, la méthode `LScli::autocomplete_opts()` vous facilitera la construction de la
|
||||||
|
liste des valeurs d'autocomplétion de l'argument courant en fonction de ce qui a déjà été
|
||||||
|
saisi par l'utilisateur (paramètre `$comp_word`). Cette méthode s'occupera en l'occurrence de
|
||||||
|
filtrer parmi toutes les valeurs contextuelles possibles, celles qui correspondent au préfixe
|
||||||
|
fourni par l'utilisateur.
|
||||||
|
|
||||||
|
## Exemple d'implémentation
|
||||||
|
|
||||||
Pour implémenter une telle commande *CLI* personnalisée, vous pouvez vous inspirer de l'exemple
|
Pour implémenter une telle commande *CLI* personnalisée, vous pouvez vous inspirer de l'exemple
|
||||||
fourni ci-dessous ou encore des commandes *CLI* fournies par les autres
|
fourni ci-dessous ou encore des commandes *CLI* fournies par les autres
|
||||||
|
@ -88,30 +163,38 @@ fourni ci-dessous ou encore des commandes *CLI* fournies par les autres
|
||||||
|
|
||||||
**Structure du fichier includes/addons/LSaddons.[addon name].php :**
|
**Structure du fichier includes/addons/LSaddons.[addon name].php :**
|
||||||
|
|
||||||
```
|
```php
|
||||||
<?php
|
<?php
|
||||||
function LSaddon_myaddon_support() {
|
function LSaddon_myaddon_support() {
|
||||||
|
|
||||||
$retval=true;
|
$retval=true;
|
||||||
|
|
||||||
// Some check
|
# Some other checks need to verify your addon support
|
||||||
|
|
||||||
if ($retval) {
|
if ($retval) {
|
||||||
if (php_sapi_name() == 'cli') {
|
if (php_sapi_name() == 'cli') {
|
||||||
LScli :: add_command(
|
LScli::add_command(
|
||||||
'my_custom_cli_cmd', // The CLI command name (required)
|
# The CLI command name (required)
|
||||||
'cli_my_custom_cli_cmd', // The CLI command handler (must be callable, required)
|
'my_custom_cli_cmd',
|
||||||
'My custom CLI command', // A short description of what this command does (required)
|
# The CLI command handler (must be callable, required)
|
||||||
'[arg1] [arg2] [...]', // A short list of commands available arguments show in usage message
|
'cli_my_custom_cli_cmd',
|
||||||
// (optional, default: false)
|
# A short description of what this command does (required)
|
||||||
'This command permit to ...', // A long description of what this command does (optional, default:
|
'My custom CLI command',
|
||||||
// false)
|
# A short list of commands available arguments show in usage message
|
||||||
true, // Permit to define if this command need connection to LDAP server
|
# (optional, default: false)
|
||||||
// (optional, default: true)
|
'[arg1] [arg2] [...]',
|
||||||
'cli_my_custom_cli_cmd_autocompleter', // Callable of the CLI command arguments autocompleter (optional,
|
# A long description of what this command does
|
||||||
// default: null)
|
# (optional, default: false)
|
||||||
true // Allow override if a command already exists with the same name
|
'This command permit to ...',
|
||||||
// (optional, default: null)
|
# Permit to define if this command need connection to LDAP server
|
||||||
|
# (optional, default: true)
|
||||||
|
true,
|
||||||
|
# Callable of the CLI command arguments autocompleter
|
||||||
|
# (optional, default: null)
|
||||||
|
'cli_my_custom_cli_cmd_autocompleter',
|
||||||
|
# Allow override if a command already exists with the same name
|
||||||
|
# (optional, default: null)
|
||||||
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,18 +238,18 @@ function cli_my_custom_cli_cmd($command_args) {
|
||||||
$dn = $arg;
|
$dn = $arg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LScli :: usage("Invalid $arg parameter.");
|
LScli::usage("Invalid $arg parameter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_null($objType) || is_null($dn))
|
if (is_null($objType) || is_null($dn))
|
||||||
LScli :: usage('You must provide LSobject type and DN.');
|
LScli::usage('You must provide LSobject type and DN.');
|
||||||
|
|
||||||
if (!LSsession :: loadLSobject($objType))
|
if (!LSsession::loadLSobject($objType))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
$obj = new $objType();
|
$obj = new $objType();
|
||||||
if (!$obj->loadData($dn)) {
|
if (!$obj->loadData($dn)) {
|
||||||
self :: log_fatal("Fail to load object $dn data from LDAP");
|
self::log_fatal("Fail to load object $dn data from LDAP");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +269,9 @@ function cli_my_custom_cli_cmd($command_args) {
|
||||||
*
|
*
|
||||||
* @return array<string> List of available options for the word to autocomplete
|
* @return array<string> List of available options for the word to autocomplete
|
||||||
**/
|
**/
|
||||||
public static function cli_my_custom_cli_cmd_autocompleter($command_args, $comp_word_num, $comp_word, $opts) {
|
public static function cli_my_custom_cli_cmd_autocompleter(
|
||||||
|
$command_args, $comp_word_num, $comp_word, $opts
|
||||||
|
) {
|
||||||
$opts = array_merge($opts, array ('-f', '--force'));
|
$opts = array_merge($opts, array ('-f', '--force'));
|
||||||
|
|
||||||
// Handle positional args
|
// Handle positional args
|
||||||
|
@ -200,33 +285,40 @@ public static function cli_my_custom_cli_cmd_autocompleter($command_args, $comp_
|
||||||
if (is_null($objType)) {
|
if (is_null($objType)) {
|
||||||
// Defined it
|
// Defined it
|
||||||
$objType = $command_args[$i];
|
$objType = $command_args[$i];
|
||||||
LScli :: unquote_word($objType);
|
LScli::unquote_word($objType);
|
||||||
$objType_arg_num = $i;
|
$objType_arg_num = $i;
|
||||||
|
|
||||||
// Check object type exists
|
// Check object type exists
|
||||||
$objTypes = LScli :: autocomplete_LSobject_types($objType);
|
$objTypes = LScli::autocomplete_LSobject_types($objType);
|
||||||
|
|
||||||
// Load it if exist and not trying to complete it
|
// Load it if exist and not trying to complete it
|
||||||
if (in_array($objType, $objTypes) && $i != $comp_word_num) {
|
if (in_array($objType, $objTypes) && $i != $comp_word_num) {
|
||||||
LSsession :: loadLSobject($objType, false);
|
LSsession::loadLSobject($objType, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif (is_null($dn)) {
|
elseif (is_null($dn)) {
|
||||||
$dn = $command_args[$i];
|
$dn = $command_args[$i];
|
||||||
LScli :: unquote_word($dn);
|
LScli::unquote_word($dn);
|
||||||
$dn_arg_num = $i;
|
$dn_arg_num = $i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If objType not already choiced (or currently autocomplete), add LSobject types to available options
|
// If objType not already chosen (or currently autocomplete),
|
||||||
|
// add LSobject types to available options
|
||||||
if (!$objType || $objType_arg_num == $comp_word_num)
|
if (!$objType || $objType_arg_num == $comp_word_num)
|
||||||
$opts = array_merge($opts, LScli :: autocomplete_LSobject_types($comp_word));
|
$opts = array_merge(
|
||||||
|
$opts,
|
||||||
|
LScli::autocomplete_LSobject_types($comp_word)
|
||||||
|
);
|
||||||
|
|
||||||
// If dn not alreay choiced (or currently autocomplete), try autocomplete it
|
// If dn not already chosen (or currently autocomplete), try autocomplete it
|
||||||
elseif (!$dn || $dn_arg_num == $comp_word_num)
|
elseif (!$dn || $dn_arg_num == $comp_word_num)
|
||||||
$opts = array_merge($opts, LScli :: autocomplete_LSobject_dn($objType, $comp_word));
|
$opts = array_merge(
|
||||||
|
$opts,
|
||||||
|
LScli::autocomplete_LSobject_dn($objType, $comp_word)
|
||||||
|
);
|
||||||
|
|
||||||
return LScli :: autocomplete_opts($opts, $comp_word);
|
return LScli::autocomplete_opts($opts, $comp_word);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -780,6 +780,28 @@ class LScli extends LSlog_staticLoggerClass {
|
||||||
return array(LScli :: quote_word("$rdn_attr=", $quote_char));
|
return array(LScli :: quote_word("$rdn_attr=", $quote_char));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autocomplete LSobject attribute name
|
||||||
|
*
|
||||||
|
* @param string $objType LSobject type
|
||||||
|
* @param string $prefix Option prefix (optional, default=empty string)
|
||||||
|
* @param boolean $case_sensitive Set to false if options are case insensitive (optional, default=true)
|
||||||
|
* @param string $quote_char Quote character (optional, if not set, $prefix will be unquoted and its
|
||||||
|
* quote char (if detected) will be used to quote options)
|
||||||
|
*
|
||||||
|
* @return array List of available options
|
||||||
|
**/
|
||||||
|
public static function autocomplete_LSobject_attr_name($objType, $prefix='', $case_sensitive=true, $quote_char='') {
|
||||||
|
if (!LSsession ::loadLSobject($objType, false))
|
||||||
|
return array();
|
||||||
|
return self :: autocomplete_opts(
|
||||||
|
LSconfig :: keys("LSobjects.$objType.attrs"),
|
||||||
|
$prefix,
|
||||||
|
$case_sensitive,
|
||||||
|
$quote_char
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Autocomplete LSobject ioFormat option
|
* Autocomplete LSobject ioFormat option
|
||||||
*
|
*
|
||||||
|
@ -805,6 +827,17 @@ class LScli extends LSlog_staticLoggerClass {
|
||||||
return self :: autocomplete_opts($ioFormats, $prefix, $case_sensitive, $quote_char);
|
return self :: autocomplete_opts($ioFormats, $prefix, $case_sensitive, $quote_char);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autocomplete LSform name
|
||||||
|
*
|
||||||
|
* @param string $prefix LSform name prefix (optional, default=empty string)
|
||||||
|
*
|
||||||
|
* @return array List of matched LSform names
|
||||||
|
**/
|
||||||
|
public static function autocomplete_LSform_name($prefix='', $quote_char=null) {
|
||||||
|
return self :: autocomplete_opts(["create", "modify", "lostPassword"], $prefix, true, $quote_char);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Autocomplete LSformRule name
|
* Autocomplete LSformRule name
|
||||||
*
|
*
|
||||||
|
|
|
@ -114,11 +114,20 @@ class LSformRule extends LSlog_staticLoggerClass {
|
||||||
* - values to test
|
* - values to test
|
||||||
* - Optional arguments :
|
* - Optional arguments :
|
||||||
* - -p|--param: LSformRule parameters (format: param=value)
|
* - -p|--param: LSformRule parameters (format: param=value)
|
||||||
|
* - Other optional arguments to specify on which LDAP object's attribute to run the test:
|
||||||
|
* - -t|--object-type: LSobject type
|
||||||
|
* - -D|--dn: LDAP object DN
|
||||||
|
* - -f|--form: LdapSaisie form name (create, modify, ...)
|
||||||
|
* - -a|--attr: the attribute name (must be included in the specified form)
|
||||||
*
|
*
|
||||||
* @return boolean True on success, false otherwise
|
* @return boolean True on success, false otherwise
|
||||||
**/
|
**/
|
||||||
public static function cli_test_form_rule($command_args) {
|
public static function cli_test_form_rule($command_args) {
|
||||||
$rule_name = null;
|
$rule_name = null;
|
||||||
|
$objType = null;
|
||||||
|
$dn = null;
|
||||||
|
$form = null;
|
||||||
|
$attr = null;
|
||||||
$values = array();
|
$values = array();
|
||||||
$params = array();
|
$params = array();
|
||||||
for ($i=0; $i < count($command_args); $i++) {
|
for ($i=0; $i < count($command_args); $i++) {
|
||||||
|
@ -133,6 +142,26 @@ class LSformRule extends LSlog_staticLoggerClass {
|
||||||
LScli :: usage('Parameter "'.$param_parts[0].'" already specified.');
|
LScli :: usage('Parameter "'.$param_parts[0].'" already specified.');
|
||||||
$params[$param_parts[0]] = LScli :: parse_arg_value($param_parts[1]);
|
$params[$param_parts[0]] = LScli :: parse_arg_value($param_parts[1]);
|
||||||
}
|
}
|
||||||
|
else if (in_array($command_args[$i], ['-t', '--object-type'])) {
|
||||||
|
$i++;
|
||||||
|
LScli :: unquote_word($command_args[$i]);
|
||||||
|
$objType = $command_args[$i];
|
||||||
|
}
|
||||||
|
else if (in_array($command_args[$i], ['-D', '--dn'])) {
|
||||||
|
$i++;
|
||||||
|
LScli :: unquote_word($command_args[$i]);
|
||||||
|
$dn = $command_args[$i];
|
||||||
|
}
|
||||||
|
else if (in_array($command_args[$i], ['-f', '--form'])) {
|
||||||
|
$i++;
|
||||||
|
LScli :: unquote_word($command_args[$i]);
|
||||||
|
$form = $command_args[$i];
|
||||||
|
}
|
||||||
|
else if (in_array($command_args[$i], ['-a', '--attr'])) {
|
||||||
|
$i++;
|
||||||
|
LScli :: unquote_word($command_args[$i]);
|
||||||
|
$attr = $command_args[$i];
|
||||||
|
}
|
||||||
else if (is_null($rule_name)) {
|
else if (is_null($rule_name)) {
|
||||||
$rule_name = $command_args[$i];
|
$rule_name = $command_args[$i];
|
||||||
}
|
}
|
||||||
|
@ -144,8 +173,41 @@ class LSformRule extends LSlog_staticLoggerClass {
|
||||||
if (is_null($rule_name) || empty($values))
|
if (is_null($rule_name) || empty($values))
|
||||||
LScli :: usage('You must provide LSformRule type and at least one value to test.');
|
LScli :: usage('You must provide LSformRule type and at least one value to test.');
|
||||||
|
|
||||||
self :: log_trace("test_form_rule($rule_name): params=".varDump($params));
|
|
||||||
$formElement = null;
|
if ($objType || $dn || $form || $attr) {
|
||||||
|
if ( ! ( $objType && $dn && $form && $attr ) )
|
||||||
|
LScli :: usage(
|
||||||
|
'To specify which form element you want to simulate the execution of a rule on, '.
|
||||||
|
'you must provide the following set of information: the object type (-t/--type), '.
|
||||||
|
'the object DN (-D/--dn), the form (-f/--form), and the attribute (-a/--attr).'
|
||||||
|
);
|
||||||
|
if (!LSsession :: loadLSobject($objType))
|
||||||
|
return false;
|
||||||
|
$obj = new $objType();
|
||||||
|
if (!$obj->loadData($dn)) {
|
||||||
|
self :: log_fatal("Fail to load object $dn data from LDAP");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$formObj = $obj->getForm($form);
|
||||||
|
if (!$formObj->hasElement($attr))
|
||||||
|
LScli :: usage("The attribute $attr is not included in the form $form of $objType.");
|
||||||
|
$formElement = $formObj -> getElement($attr);
|
||||||
|
self :: log_debug("Run $rule_name rule as if we are on the attribute $attr of the $objType object $dn");
|
||||||
|
|
||||||
|
$attr_params = LSconfig :: get("LSobjects.$objType.attrs.$attr.check_data.$rule_name.params", [], "array");
|
||||||
|
if ($attr_params) {
|
||||||
|
self :: log_debug(
|
||||||
|
"Merge provided parameters with configured one from $objType configuration: ".
|
||||||
|
varDump($attr_params)
|
||||||
|
);
|
||||||
|
$params = array_merge_recursive($attr_params, $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$formElement = null;
|
||||||
|
|
||||||
|
self :: log_debug("Run $rule_name rule with following parameters: ".varDump($params));
|
||||||
|
|
||||||
$errors = self :: validate_values($rule_name, $values, array('params' => $params), $formElement);
|
$errors = self :: validate_values($rule_name, $values, array('params' => $params), $formElement);
|
||||||
if (is_array($errors)) {
|
if (is_array($errors)) {
|
||||||
print "Test triggered errors :\n - ".implode("\n - ", $errors)."\n";
|
print "Test triggered errors :\n - ".implode("\n - ", $errors)."\n";
|
||||||
|
@ -168,7 +230,10 @@ class LSformRule extends LSlog_staticLoggerClass {
|
||||||
* @return array<string> List of available options for the word to autocomplete
|
* @return array<string> List of available options for the word to autocomplete
|
||||||
**/
|
**/
|
||||||
public static function cli_test_form_rule_args_autocompleter($command_args, $comp_word_num, $comp_word, $opts) {
|
public static function cli_test_form_rule_args_autocompleter($command_args, $comp_word_num, $comp_word, $opts) {
|
||||||
$opts = array_merge($opts, array('-p', '--param'));
|
$opts = array_merge(
|
||||||
|
$opts,
|
||||||
|
['-p', '--param', '-t', '--object-type', '-D', '--dn', '-f', '--form', '-a', '--attr']
|
||||||
|
);
|
||||||
|
|
||||||
// Handle positional args
|
// Handle positional args
|
||||||
$rule_name = null;
|
$rule_name = null;
|
||||||
|
@ -176,10 +241,12 @@ class LSformRule extends LSlog_staticLoggerClass {
|
||||||
$rule_name_arg_num = null;
|
$rule_name_arg_num = null;
|
||||||
$rule_name_quote_char = null;
|
$rule_name_quote_char = null;
|
||||||
$params = array();
|
$params = array();
|
||||||
|
$objType = null;
|
||||||
for ($i=0; $i < count($command_args); $i++) {
|
for ($i=0; $i < count($command_args); $i++) {
|
||||||
switch ($command_args[$i]) {
|
switch ($command_args[$i]) {
|
||||||
case '-p':
|
case '-p':
|
||||||
case '--params':
|
case '--params':
|
||||||
|
if ($comp_word_num == $i) return LScli :: autocomplete_opts([$comp_word], $comp_word);
|
||||||
$i++;
|
$i++;
|
||||||
$quote_char = LScli :: unquote_word($command_args[$i]);
|
$quote_char = LScli :: unquote_word($command_args[$i]);
|
||||||
$param_parts = explode('=', $command_args[$i]);
|
$param_parts = explode('=', $command_args[$i]);
|
||||||
|
@ -192,6 +259,42 @@ class LSformRule extends LSlog_staticLoggerClass {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '-t':
|
||||||
|
case '--object-type':
|
||||||
|
if ($comp_word_num == $i) return LScli :: autocomplete_opts([$comp_word], $comp_word);
|
||||||
|
$i++;
|
||||||
|
if ($comp_word_num == $i) return LScli :: autocomplete_LSobject_types($comp_word);
|
||||||
|
if (isset($command_args[$i])) {
|
||||||
|
$objType = $command_args[$i];
|
||||||
|
LScli :: unquote_word($objType);
|
||||||
|
}
|
||||||
|
$opts = array_diff($opts, ['-t', '--object-type']);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-D':
|
||||||
|
case '--dn':
|
||||||
|
if ($comp_word_num == $i) return LScli :: autocomplete_opts([$comp_word], $comp_word);
|
||||||
|
$i++;
|
||||||
|
if ($objType && $comp_word_num == $i) return LScli :: autocomplete_LSobject_dn($objType, $comp_word);
|
||||||
|
$opts = array_diff($opts, ['-d', '--dn']);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-f':
|
||||||
|
case '--form':
|
||||||
|
if ($comp_word_num == $i) return LScli :: autocomplete_opts([$comp_word], $comp_word);
|
||||||
|
$i++;
|
||||||
|
if ($comp_word_num == $i) return LScli :: autocomplete_LSform_name($comp_word);
|
||||||
|
$opts = array_diff($opts, ['-f', '--form']);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-a':
|
||||||
|
case '--attr':
|
||||||
|
if ($comp_word_num == $i) return LScli :: autocomplete_opts([$comp_word], $comp_word);
|
||||||
|
$i++;
|
||||||
|
if ($objType && $comp_word_num == $i) return LScli :: autocomplete_LSobject_attr_name($objType, $comp_word);
|
||||||
|
$opts = array_diff($opts, ['-a', '--attr']);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// If rule name not defined
|
// If rule name not defined
|
||||||
if (is_null($rule_name)) {
|
if (is_null($rule_name)) {
|
||||||
|
@ -319,6 +422,19 @@ LScli :: add_command(
|
||||||
' param_name=param_value',
|
' param_name=param_value',
|
||||||
' Multiple parameters could be specified by using this',
|
' Multiple parameters could be specified by using this',
|
||||||
' optional argument multiple time',
|
' optional argument multiple time',
|
||||||
|
'',
|
||||||
|
' - Other optional arguments to specify on which LDAP object\'s attribute',
|
||||||
|
' to run the test:',
|
||||||
|
' - -t|--object-type: LSobject type',
|
||||||
|
' - -D|--dn: LDAP object DN',
|
||||||
|
' - -f|--form: LdapSaisie form name (create, modify, ...)',
|
||||||
|
' - -a|--attr: the attribute name (must be included in the specified',
|
||||||
|
' form)',
|
||||||
|
' In this case, the LSformRule validate() method will receive a real',
|
||||||
|
' LSformElement object reference as third parameter and will have access',
|
||||||
|
' to the associated context. Furthermore, if the rule is configured on',
|
||||||
|
' the specified object\'s attribute, the configured rule\'s parameters',
|
||||||
|
' will be automatically merged with the specified ones.',
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
array('LSformRule', 'cli_test_form_rule_args_autocompleter')
|
array('LSformRule', 'cli_test_form_rule_args_autocompleter')
|
||||||
|
|
|
@ -30,7 +30,10 @@ class LSformRule_zxcvbn extends LSformRule {
|
||||||
// CLI parameters autocompleters
|
// CLI parameters autocompleters
|
||||||
protected static $cli_params_autocompleters = array(
|
protected static $cli_params_autocompleters = array(
|
||||||
'minScore' => array('LScli', 'autocomplete_int'),
|
'minScore' => array('LScli', 'autocomplete_int'),
|
||||||
|
'minGuessesLog10' => array('LScli', 'autocomplete_int'),
|
||||||
'userDataAttrs' => null,
|
'userDataAttrs' => null,
|
||||||
|
'banPersonalInfo' => array('LScli', 'autocomplete_bool'),
|
||||||
|
'banDictionaries' => null,
|
||||||
'showWarning' => array('LScli', 'autocomplete_bool'),
|
'showWarning' => array('LScli', 'autocomplete_bool'),
|
||||||
'showSuggestions' => array('LScli', 'autocomplete_bool'),
|
'showSuggestions' => array('LScli', 'autocomplete_bool'),
|
||||||
'customDictionaries' => null,
|
'customDictionaries' => null,
|
||||||
|
@ -82,14 +85,32 @@ class LSformRule_zxcvbn extends LSformRule {
|
||||||
}
|
}
|
||||||
self :: log_trace("User data: ".varDump($userData));
|
self :: log_trace("User data: ".varDump($userData));
|
||||||
$result = $zxcvbn->passwordStrength($value, $userData);
|
$result = $zxcvbn->passwordStrength($value, $userData);
|
||||||
self :: log_trace("Zxcvbn result: ".varDump($result));
|
self :: log_debug("Zxcvbn result: ".varDump($result));
|
||||||
self :: log_debug("Zxcvbn score: ".$result['score']);
|
self :: log_debug("Zxcvbn score: ".$result['score']);
|
||||||
|
self :: log_debug("Zxcvbn guesses log10: ".$result['guesses_log10']);
|
||||||
|
|
||||||
$minScore = LSconfig :: get('params.minScore', 4, 'int', $options);
|
$minScore = LSconfig :: get('params.minScore', 4, 'int', $options);
|
||||||
if($result['score'] >= $minScore) {
|
$minGuessesLog10 = LSconfig :: get('params.minGuessesLog10', 10, 'int', $options);
|
||||||
return True;
|
$banDictionaries = LSconfig :: get('params.banDictionaries', [], 'array', $options);
|
||||||
|
if (LSconfig :: get('params.banPersonalInfo', true, 'bool', $options))
|
||||||
|
$banDictionaries[] = "user_inputs";
|
||||||
|
|
||||||
|
$banned_tokens = [];
|
||||||
|
if ($banDictionaries) {
|
||||||
|
foreach($result["sequence"] as $match) {
|
||||||
|
if ($match->pattern == "dictionary" && in_array($match->dictionaryName, $banDictionaries))
|
||||||
|
$banned_tokens[] = $match->token;
|
||||||
|
}
|
||||||
|
self :: log_debug("Zxcvbn banned token(s) found: '".implode("', '", $banned_tokens)."'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(
|
||||||
|
$result['score'] >= $minScore
|
||||||
|
&& $result['guesses_log10'] >= $minGuessesLog10
|
||||||
|
&& !$banned_tokens
|
||||||
|
)
|
||||||
|
return True;
|
||||||
|
|
||||||
$errors = array();
|
$errors = array();
|
||||||
if (
|
if (
|
||||||
$result['feedback']['warning'] &&
|
$result['feedback']['warning'] &&
|
||||||
|
@ -97,6 +118,8 @@ class LSformRule_zxcvbn extends LSformRule {
|
||||||
) {
|
) {
|
||||||
$errors[] = $result['feedback']['warning'];
|
$errors[] = $result['feedback']['warning'];
|
||||||
}
|
}
|
||||||
|
if ($banned_tokens)
|
||||||
|
$errors[] = _("Banned token found in this password.");
|
||||||
if (!$errors)
|
if (!$errors)
|
||||||
$errors[] = _('The security of this password is too weak.');
|
$errors[] = _('The security of this password is too weak.');
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue