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
|
||||
- git config user.name $GITLAB_USER_NAME
|
||||
- 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
|
||||
- git fetch origin $DOC_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
|
||||
- git config user.name $GITLAB_USER_NAME
|
||||
- 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
|
||||
- git fetch origin $DOC_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`
|
||||
|
||||
Le score minimal pour que le mot de passe soit accepté. Il doit s'agir d'un entier cimpris entre 0
|
||||
(le plus faible) et 4 (le plus sécurisé). Paramètre facultatif valant 4 par défaut.
|
||||
Le score minimal pour que le mot de passe soit accepté. Il doit s'agir d'un entier compris entre
|
||||
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`
|
||||
|
||||
|
@ -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
|
||||
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`
|
||||
|
||||
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`
|
||||
|
||||
Le chemin vers le fichier de chargement automatique des classes de la librairie *ZxcvbnPhp*. Ce
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# Les commandes *CLI* personnalisées
|
||||
|
||||
## Introduction
|
||||
|
||||
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
|
||||
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 :
|
||||
|
||||
- Déclarer cette vue dans la fonction `LSaddon_[addon]_support` de l'addon à l'aide de la méthode
|
||||
`LScli :: add_command()` ;
|
||||
- Déclarer cette commande *CLI* personnalisée dans la fonction `LSaddon_[addon]_support` de l'addon
|
||||
à l'aide de la méthode `LScli::add_command()` ;
|
||||
|
||||
- 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
|
||||
retournera `True` ou `False` en cas de succès/d'erreur d'exécution de la commande. Cette valeur de
|
||||
retour influencera le code retourné par la commande : `0` en cas de succès, `1` en cas d'erreur.
|
||||
retournera `True` ou `False` en cas de succès/d'erreur d'exécution de la commande. Cette valeur
|
||||
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
|
||||
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
|
||||
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.
|
||||
- `LScli::need_ldap_con()`
|
||||
|
||||
- `$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
|
||||
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.
|
||||
- `LScli::run_external_command($command, $data_stdin=null, $escape_command_args=true, $cwd=null)` :
|
||||
|
||||
- `$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
|
||||
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 si prête (nouvel argument par
|
||||
exemple).
|
||||
La commande à exécuter peut être passée sous la forme d'une chaîne de caractères ou d'un
|
||||
tableau de chaînes de caractères correspondant à la commande et ses arguments. Par défaut,
|
||||
les caractères spéciaux contenus dans les paramètres passés à la commande seront
|
||||
"é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
|
||||
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.
|
||||
Il est possible de fournir des données à passer à la commande via son entrée standard via
|
||||
le paramètre `$data_stdin`.
|
||||
|
||||
!!! 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
|
||||
sont fournies par la classe `LScli` pour les autocomplétions les plus courantes :
|
||||
- `LScli::confirm($question=null)`
|
||||
|
||||
- `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
|
||||
l'annuaire.
|
||||
- `$command_args`
|
||||
|
||||
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.
|
||||
Un tableau des arguments déjà reçus par la commande.
|
||||
|
||||
- `$comp_word_num`
|
||||
|
||||
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
|
||||
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 :**
|
||||
|
||||
```
|
||||
```php
|
||||
<?php
|
||||
function LSaddon_myaddon_support() {
|
||||
|
||||
$retval=true;
|
||||
|
||||
// Some check
|
||||
# Some other checks need to verify your addon support
|
||||
|
||||
if ($retval) {
|
||||
if (php_sapi_name() == 'cli') {
|
||||
LScli :: add_command(
|
||||
'my_custom_cli_cmd', // The CLI command name (required)
|
||||
'cli_my_custom_cli_cmd', // The CLI command handler (must be callable, required)
|
||||
'My custom CLI command', // A short description of what this command does (required)
|
||||
'[arg1] [arg2] [...]', // A short list of commands available arguments show in usage message
|
||||
// (optional, default: false)
|
||||
'This command permit to ...', // A long description of what this command does (optional, default:
|
||||
// false)
|
||||
true, // Permit to define if this command need connection to LDAP server
|
||||
// (optional, default: true)
|
||||
'cli_my_custom_cli_cmd_autocompleter', // Callable of the CLI command arguments autocompleter (optional,
|
||||
// default: null)
|
||||
true // Allow override if a command already exists with the same name
|
||||
// (optional, default: null)
|
||||
LScli::add_command(
|
||||
# The CLI command name (required)
|
||||
'my_custom_cli_cmd',
|
||||
# The CLI command handler (must be callable, required)
|
||||
'cli_my_custom_cli_cmd',
|
||||
# A short description of what this command does (required)
|
||||
'My custom CLI command',
|
||||
# A short list of commands available arguments show in usage message
|
||||
# (optional, default: false)
|
||||
'[arg1] [arg2] [...]',
|
||||
# A long description of what this command does
|
||||
# (optional, default: false)
|
||||
'This command permit to ...',
|
||||
# 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;
|
||||
}
|
||||
else
|
||||
LScli :: usage("Invalid $arg parameter.");
|
||||
LScli::usage("Invalid $arg parameter.");
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
$obj = new $objType();
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -186,7 +269,9 @@ function cli_my_custom_cli_cmd($command_args) {
|
|||
*
|
||||
* @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'));
|
||||
|
||||
// Handle positional args
|
||||
|
@ -200,33 +285,40 @@ public static function cli_my_custom_cli_cmd_autocompleter($command_args, $comp_
|
|||
if (is_null($objType)) {
|
||||
// Defined it
|
||||
$objType = $command_args[$i];
|
||||
LScli :: unquote_word($objType);
|
||||
LScli::unquote_word($objType);
|
||||
$objType_arg_num = $i;
|
||||
|
||||
// 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
|
||||
if (in_array($objType, $objTypes) && $i != $comp_word_num) {
|
||||
LSsession :: loadLSobject($objType, false);
|
||||
LSsession::loadLSobject($objType, false);
|
||||
}
|
||||
}
|
||||
elseif (is_null($dn)) {
|
||||
$dn = $command_args[$i];
|
||||
LScli :: unquote_word($dn);
|
||||
LScli::unquote_word($dn);
|
||||
$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)
|
||||
$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)
|
||||
$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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
@ -805,6 +827,17 @@ class LScli extends LSlog_staticLoggerClass {
|
|||
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
|
||||
*
|
||||
|
|
|
@ -114,11 +114,20 @@ class LSformRule extends LSlog_staticLoggerClass {
|
|||
* - values to test
|
||||
* - Optional arguments :
|
||||
* - -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
|
||||
**/
|
||||
public static function cli_test_form_rule($command_args) {
|
||||
$rule_name = null;
|
||||
$objType = null;
|
||||
$dn = null;
|
||||
$form = null;
|
||||
$attr = null;
|
||||
$values = array();
|
||||
$params = array();
|
||||
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.');
|
||||
$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)) {
|
||||
$rule_name = $command_args[$i];
|
||||
}
|
||||
|
@ -144,8 +173,41 @@ class LSformRule extends LSlog_staticLoggerClass {
|
|||
if (is_null($rule_name) || empty($values))
|
||||
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);
|
||||
if (is_array($errors)) {
|
||||
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
|
||||
**/
|
||||
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
|
||||
$rule_name = null;
|
||||
|
@ -176,10 +241,12 @@ class LSformRule extends LSlog_staticLoggerClass {
|
|||
$rule_name_arg_num = null;
|
||||
$rule_name_quote_char = null;
|
||||
$params = array();
|
||||
$objType = null;
|
||||
for ($i=0; $i < count($command_args); $i++) {
|
||||
switch ($command_args[$i]) {
|
||||
case '-p':
|
||||
case '--params':
|
||||
if ($comp_word_num == $i) return LScli :: autocomplete_opts([$comp_word], $comp_word);
|
||||
$i++;
|
||||
$quote_char = LScli :: unquote_word($command_args[$i]);
|
||||
$param_parts = explode('=', $command_args[$i]);
|
||||
|
@ -192,6 +259,42 @@ class LSformRule extends LSlog_staticLoggerClass {
|
|||
);
|
||||
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:
|
||||
// If rule name not defined
|
||||
if (is_null($rule_name)) {
|
||||
|
@ -319,6 +422,19 @@ LScli :: add_command(
|
|||
' param_name=param_value',
|
||||
' Multiple parameters could be specified by using this',
|
||||
' 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,
|
||||
array('LSformRule', 'cli_test_form_rule_args_autocompleter')
|
||||
|
|
|
@ -30,7 +30,10 @@ class LSformRule_zxcvbn extends LSformRule {
|
|||
// CLI parameters autocompleters
|
||||
protected static $cli_params_autocompleters = array(
|
||||
'minScore' => array('LScli', 'autocomplete_int'),
|
||||
'minGuessesLog10' => array('LScli', 'autocomplete_int'),
|
||||
'userDataAttrs' => null,
|
||||
'banPersonalInfo' => array('LScli', 'autocomplete_bool'),
|
||||
'banDictionaries' => null,
|
||||
'showWarning' => array('LScli', 'autocomplete_bool'),
|
||||
'showSuggestions' => array('LScli', 'autocomplete_bool'),
|
||||
'customDictionaries' => null,
|
||||
|
@ -82,14 +85,32 @@ class LSformRule_zxcvbn extends LSformRule {
|
|||
}
|
||||
self :: log_trace("User data: ".varDump($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 guesses log10: ".$result['guesses_log10']);
|
||||
|
||||
$minScore = LSconfig :: get('params.minScore', 4, 'int', $options);
|
||||
if($result['score'] >= $minScore) {
|
||||
return True;
|
||||
$minGuessesLog10 = LSconfig :: get('params.minGuessesLog10', 10, 'int', $options);
|
||||
$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();
|
||||
if (
|
||||
$result['feedback']['warning'] &&
|
||||
|
@ -97,6 +118,8 @@ class LSformRule_zxcvbn extends LSformRule {
|
|||
) {
|
||||
$errors[] = $result['feedback']['warning'];
|
||||
}
|
||||
if ($banned_tokens)
|
||||
$errors[] = _("Banned token found in this password.");
|
||||
if (!$errors)
|
||||
$errors[] = _('The security of this password is too weak.');
|
||||
|
||||
|
|
Loading…
Reference in a new issue