feat: add min_len, max_len, forbidden_char for password option
This commit is contained in:
parent
c3bb590415
commit
a3228fbf30
9 changed files with 85 additions and 4 deletions
|
@ -293,6 +293,9 @@ Unix options
|
|||
* - PasswordOption
|
||||
- Simple string with no other restriction:
|
||||
-
|
||||
- min_len: minimum length autorise for a password
|
||||
- max_len: maximum length autorise for a passwword
|
||||
- forbidden_char: list of forbidden characters for a password
|
||||
|
||||
* - FilenameOption
|
||||
- For this option, only lowercase and uppercas ASCII character, "-", ".", "_", "~", and "/" are allowed.
|
||||
|
|
|
@ -2,7 +2,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Tiramisu\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-10-30 13:15+0100\n"
|
||||
"POT-Creation-Date: 2024-11-05 08:49+0100\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n"
|
||||
"Language-Team: Tiramisu's team <egarette@cadoles.com>\n"
|
||||
|
@ -762,6 +762,18 @@ msgstr "ne peut changer group_type si déjà spécifié (ancien {0}, nouveau {1}
|
|||
msgid "group_type: {0} not allowed"
|
||||
msgstr "group_type : {0} non autorisé"
|
||||
|
||||
#: tiramisu/option/passwordoption.py:49
|
||||
msgid "at least {0} characters are required"
|
||||
msgstr "au moins {0} caractères sont requis"
|
||||
|
||||
#: tiramisu/option/passwordoption.py:52
|
||||
msgid "maximum {0} characters required"
|
||||
msgstr "un maximum de {0} caractères sont autorisés"
|
||||
|
||||
#: tiramisu/option/passwordoption.py:57
|
||||
msgid "must not have the characters {0}"
|
||||
msgstr "ne doit pas contenir les caractères {0}"
|
||||
|
||||
#: tiramisu/option/permissionsoption.py:52
|
||||
msgid "only 3 or 4 octal digits are allowed"
|
||||
msgstr "seulement 3 ou 4 chiffres octal sont autorisées"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2024-10-30 13:15+0100\n"
|
||||
"POT-Creation-Date: 2024-11-05 08:52+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -668,6 +668,18 @@ msgstr ""
|
|||
msgid "group_type: {0} not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/passwordoption.py:49
|
||||
msgid "at least {0} characters are required"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/passwordoption.py:52
|
||||
msgid "maximum {0} characters required"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/passwordoption.py:57
|
||||
msgid "must not have the characters {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/permissionsoption.py:52
|
||||
msgid "only 3 or 4 octal digits are allowed"
|
||||
msgstr ""
|
||||
|
|
|
@ -9,6 +9,7 @@ authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
|||
readme = "README.md"
|
||||
description = "an options controller tool"
|
||||
requires-python = ">=3.8"
|
||||
license = {file = "LICENSE"}
|
||||
classifiers = [
|
||||
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
|
||||
"Programming Language :: Python",
|
||||
|
|
|
@ -158,13 +158,38 @@ def test_with_many_subgroups(config_type):
|
|||
|
||||
def test_password_option(config_type):
|
||||
o = PasswordOption('o', '')
|
||||
od1 = OptionDescription('d', '', [o])
|
||||
o1 = PasswordOption('o1', '', min_len=4)
|
||||
o2 = PasswordOption('o2', '', max_len=4)
|
||||
o3 = PasswordOption('o3', '', forbidden_char=['p'])
|
||||
od1 = OptionDescription('d', '', [o, o1, o2, o3])
|
||||
cfg = Config(od1)
|
||||
cfg = get_config(cfg, config_type)
|
||||
|
||||
cfg.option('o').value.set('a_valid_password')
|
||||
with pytest.raises(ValueError):
|
||||
cfg.option('o').value.set(1)
|
||||
#
|
||||
assert cfg.option('o1').value.get() is None
|
||||
with pytest.raises(ValueError):
|
||||
cfg.option('o1').value.set("1")
|
||||
with pytest.raises(ValueError):
|
||||
cfg.option('o1').value.set("12")
|
||||
with pytest.raises(ValueError):
|
||||
cfg.option('o1').value.set("123")
|
||||
cfg.option('o1').value.set("1234")
|
||||
cfg.option('o1').value.set("12345")
|
||||
#
|
||||
assert cfg.option('o2').value.get() is None
|
||||
with pytest.raises(ValueError):
|
||||
cfg.option('o2').value.set("12345")
|
||||
cfg.option('o2').value.set("1")
|
||||
cfg.option('o2').value.set("12")
|
||||
cfg.option('o2').value.set("123")
|
||||
cfg.option('o2').value.set("1234")
|
||||
#
|
||||
with pytest.raises(ValueError):
|
||||
cfg.option('o3').value.set("password")
|
||||
cfg.option('o3').value.set("assword")
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,6 @@
|
|||
from gettext import translation
|
||||
from pathlib import Path
|
||||
|
||||
t = translation('tiramisu', str(Path(__file__).parent / 'locale'), fallback=True)
|
||||
t = translation("tiramisu", str(Path(__file__).parent / "locale"), fallback=True)
|
||||
|
||||
_ = t.gettext
|
||||
|
|
Binary file not shown.
|
@ -22,6 +22,7 @@
|
|||
"""
|
||||
|
||||
from ..i18n import _
|
||||
from ..error import display_list
|
||||
from .stroption import StrOption
|
||||
|
||||
|
||||
|
@ -30,3 +31,30 @@ class PasswordOption(StrOption):
|
|||
|
||||
__slots__ = tuple()
|
||||
_type = "password"
|
||||
|
||||
def __init__(self, *args, min_len=None, max_len=None, forbidden_char=[], **kwargs):
|
||||
extra = {}
|
||||
if min_len is not None:
|
||||
extra["min_len"] = min_len
|
||||
if max_len is not None:
|
||||
extra["max_len"] = max_len
|
||||
if forbidden_char:
|
||||
extra["forbidden_char"] = set(forbidden_char)
|
||||
super().__init__(*args, extra=extra, **kwargs)
|
||||
|
||||
def validate(self, value: str) -> None:
|
||||
super().validate(value)
|
||||
min_len = self.impl_get_extra("min_len")
|
||||
if min_len and len(value) < min_len:
|
||||
raise ValueError(_("at least {0} characters are required").format(min_len))
|
||||
max_len = self.impl_get_extra("max_len")
|
||||
if max_len and len(value) > max_len:
|
||||
raise ValueError(_("maximum {0} characters required").format(max_len))
|
||||
if self.impl_get_extra("forbidden_char"):
|
||||
forbidden_char = set(value) & self.impl_get_extra("forbidden_char")
|
||||
if forbidden_char:
|
||||
raise ValueError(
|
||||
_("must not have the characters {0}").format(
|
||||
display_list(list(forbidden_char), add_quote=True)
|
||||
)
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue