bad characters in DomainnameOption could be in warning level

This commit is contained in:
Emmanuel Garette 2014-10-26 09:38:17 +01:00
parent 8a59e27396
commit ed3373cff0
8 changed files with 203 additions and 98 deletions

View file

@ -1,6 +1,7 @@
Sun Oct 26 08:50:38 2014 +0200 Emmanuel Garette <egarette@cadoles.com>
* if option is frozen with force_default_on_freeze property, owner
must be 'default' check property when tried to change owner
* bad characters in DomainnameOption could be in warning level
Sat Oct 25 22:48:08 2014 +0200 Emmanuel Garette <egarette@cadoles.com>
* cannot add unvalaible consistency for an option

View file

@ -1,8 +1,10 @@
import autopath
import warnings
from py.test import raises
from tiramisu.config import Config
from tiramisu.option import DomainnameOption, EmailOption, URLOption, OptionDescription
from tiramisu.error import ValueWarning
def test_domainname():
@ -15,28 +17,63 @@ def test_domainname():
c.d = 'toto.com'
raises(ValueError, "c.d = 'toto'")
c.d = 'toto3.com'
raises(ValueError, "c.d = 'toto3.3la'")
#raises(ValueError, "c.d = '3toto.com'")
raises(ValueError, "c.d = 'toto.co3'")
raises(ValueError, "c.d = 'toto_super.com'")
c.d = 'toto-.com'
raises(ValueError, "c.d = 'toto..com'")
#
c.f = 'toto.com'
c.f = 'toto'
raises(ValueError, "c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnameanditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnametoolongthathavemorethanmaximumsizeforatruedomainnameanditsnoteasytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowiendityeah'")
c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea'
raises(ValueError, "c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean'")
c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd'
c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie'
raises(ValueError, "c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowien'")
raises(ValueError, "c.f = 'd'")
raises(ValueError, "c.f = 'd.t'")
#
c.g = 'toto.com'
c.g = '192.168.1.0'
c.g = '192.168.1.29'
def test_domainname_warning():
d = DomainnameOption('d', '', warnings_only=True)
f = DomainnameOption('f', '', allow_without_dot=True, warnings_only=True)
g = DomainnameOption('g', '', allow_ip=True, warnings_only=True)
od = OptionDescription('a', '', [d, f, g])
warnings.simplefilter("always", ValueWarning)
c = Config(od)
c.read_write()
c.d = 'toto.com'
raises(ValueError, "c.d = 'toto'")
c.d = 'toto3.com'
with warnings.catch_warnings(record=True) as w:
c.d = 'toto_super.com'
assert len(w) == 1
c.d = 'toto-.com'
raises(ValueError, "c.d = 'toto..com'")
#
c.f = 'toto.com'
c.f = 'toto'
c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea'
raises(ValueError, "c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean'")
c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd'
c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie'
raises(ValueError, "c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowien'")
raises(ValueError, "c.f = 'd'")
raises(ValueError, "c.f = 'd.t'")
#
c.g = 'toto.com'
c.g = '192.168.1.0'
c.g = '192.168.1.29'
def test_special_domain_name():
"""domain name option that starts with a number or not
"""
d = DomainnameOption('d', '')
e = DomainnameOption('e', '', type_='netbios')
od = OptionDescription('a', '', [d,e])
od = OptionDescription('a', '', [d, e])
c = Config(od)
c.read_write()
c.d = '1toto.com'

View file

@ -77,6 +77,11 @@ def test_force_default_on_freeze():
assert config.getowner(dummy2) == owners.user
raises(ConfigError, "config.cfgimpl_get_values().setowner(dummy1, owners.frozen)")
raises(PropertiesOptionError, "config.cfgimpl_get_values().setowner(dummy2, owners.frozen)")
raises(PropertiesOptionError, "del(config.dummy1)")
setting[dummy1].remove('frozen')
del(config.dummy1)
setting[dummy1].append('frozen')
raises(ConfigError, "config.cfgimpl_get_values().setowner(dummy1, owners.frozen)")
def test_force_default_on_freeze_multi():
@ -99,6 +104,11 @@ def test_force_default_on_freeze_multi():
assert config.getowner(dummy2) == owners.user
raises(ConfigError, "config.cfgimpl_get_values().setowner(dummy1, owners.frozenmulti)")
raises(PropertiesOptionError, "config.cfgimpl_get_values().setowner(dummy2, owners.frozenmulti)")
raises(PropertiesOptionError, "del(config.dummy1)")
setting[dummy1].remove('frozen')
del(config.dummy1)
setting[dummy1].append('frozen')
raises(ConfigError, "config.cfgimpl_get_values().setowner(dummy1, owners.frozenmulti)")
def test_overrides_changes_option_value():

View file

@ -408,23 +408,8 @@ class DomainnameOption(Option):
raise ValueError(_('allow_without_dot must be a boolean')) # pragma: optional cover
extra['_allow_ip'] = allow_ip
extra['_allow_without_dot'] = allow_without_dot
end = ''
extrachar = ''
extrachar_mandatory = ''
if extra['_dom_type'] == 'netbios':
length = 14 # pragma: optional cover
elif extra['_dom_type'] == 'hostname':
length = 62 # pragma: optional cover
elif extra['_dom_type'] == 'domainname':
length = 62
if allow_without_dot is False:
extrachar_mandatory = '\.'
else:
extrachar = '\.' # pragma: optional cover
end = '+[a-z]*'
extra['_domain_re'] = re.compile(r'^(?:[a-z\d][a-z\d\-{0}]{{,{1}}}{2}){3}$'
''.format(extrachar, length,
extrachar_mandatory, end))
extra['_domain_re'] = re.compile(r'^[a-z\d][a-z\d\-]*$')
super(DomainnameOption, self).__init__(name, doc, default=default,
default_multi=default_multi,
callback=callback,
@ -438,22 +423,52 @@ class DomainnameOption(Option):
extra=extra)
def _validate(self, value, context=undefined):
def _valid_length(val):
if len(val) < 2:
raise ValueError(_("invalid domainname's length (min 2)"))
if len(val) > part_name_length:
raise ValueError(_("invalid domainname's length (max {0})"
"").format(part_name_length))
if self._get_extra('_allow_ip') is True: # pragma: optional cover
try:
IP('{0}/32'.format(value))
return
except ValueError:
pass
if self._get_extra('_dom_type') == 'domainname' and \
not self._get_extra('_allow_without_dot') and \
'.' not in value: # pragma: optional cover
raise ValueError(_("invalid domainname, must have dot"))
if len(value) > 255:
raise ValueError(_("invalid domainname's length (max 255)")) # pragma: optional cover
if len(value) < 2:
raise ValueError(_("invalid domainname's length (min 2)")) # pragma: optional cover
if not self._get_extra('_domain_re').search(value):
raise ValueError(_('invalid domainname')) # pragma: optional cover
if self._get_extra('_dom_type') == 'netbios':
part_name_length = 15
else:
part_name_length = 63
if self._get_extra('_dom_type') == 'domainname':
if not self._get_extra('_allow_without_dot') and not "." in value:
raise ValueError(_("invalid domainname, must have dot"))
if len(value) > 255:
raise ValueError(_("invalid domainname's length (max 255)"))
for dom in value.split('.'):
_valid_length(dom)
else:
_valid_length(value)
def _second_level_validation(self, value, warnings_only):
def _valid_char(val):
if not self._get_extra('_domain_re').search(val):
if warnings_only:
raise ValueError(_('same characters may cause problems'))
else:
raise ValueError(_('invalid domainname'))
#not for IP
if self._get_extra('_allow_ip') is True:
try:
IP('{0}/32'.format(value))
return
except ValueError:
pass
if self._get_extra('_dom_type') == 'domainname':
for dom in value.split('.'):
_valid_char(dom)
else:
_valid_char(value)
class EmailOption(DomainnameOption):
@ -470,6 +485,10 @@ class EmailOption(DomainnameOption):
if not self.username_re.search(username):
raise ValueError(_('invalid username in email address')) # pragma: optional cover
super(EmailOption, self)._validate(domain)
super(EmailOption, self)._second_level_validation(domain, False)
def _second_level_validation(self, value, warnings_only):
pass
class URLOption(DomainnameOption):
@ -503,10 +522,14 @@ class URLOption(DomainnameOption):
'65536')) # pragma: optional cover
# validate domainname
super(URLOption, self)._validate(domain)
super(URLOption, self)._second_level_validation(domain, False)
# validate file
if files is not None and files != '' and not self.path_re.search(files):
raise ValueError(_('invalid url, must ends with filename')) # pragma: optional cover
def _second_level_validation(self, value, warnings_only):
pass
class UsernameOption(Option):
__slots__ = tuple()

View file

@ -338,7 +338,7 @@ class Settings(object):
return Property(self, self._getproperties(opt, path), opt, path)
def __setitem__(self, opt, value): # pragma: optional cover
raise ValueError('you should only append/remove properties')
raise ValueError(_('you should only append/remove properties'))
def reset(self, opt=None, _path=None, all_properties=False):
if all_properties and (_path or opt): # pragma: optional cover

View file

@ -149,8 +149,10 @@ class Values(object):
def reset(self, opt, path=None):
if path is None:
path = opt.impl_getpath(self._getcontext())
context = self._getcontext()
context.cfgimpl_get_settings().validate_properties(opt, False, True,
path)
if self._p_.hasvalue(path):
context = self._getcontext()
setting = context.cfgimpl_get_settings()
opt.impl_validate(opt.impl_getdefault(),
context, 'validator' in setting)

View file

@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Tiramisu\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-10-25 22:43+CEST\n"
"POT-Creation-Date: 2014-10-26 09:35+CET\n"
"PO-Revision-Date: \n"
"Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n"
"Language-Team: Tiramisu's team <egarette@cadoles.com>\n"
@ -30,7 +30,7 @@ msgid "unknown group_type: {0}"
msgstr "group_type inconnu: {0}"
#: tiramisu/config.py:176 tiramisu/setting.py:321 tiramisu/value.py:54
#: tiramisu/value.py:541
#: tiramisu/value.py:555
msgid "the context does not exist anymore"
msgstr "le context n'existe plus"
@ -481,47 +481,55 @@ msgstr "allow_ip doit être un booléen"
msgid "allow_without_dot must be a boolean"
msgstr "allow_without_dot doit être un booléen"
#: tiramisu/option/option.py:454
msgid "invalid domainname, must have dot"
msgstr "nom de domaine invalide, doit avoir un point"
#: tiramisu/option/option.py:456
msgid "invalid domainname's length (max 255)"
msgstr "longueur du nom de domaine invalide (maximum {1})"
#: tiramisu/option/option.py:458
#: tiramisu/option/option.py:428
msgid "invalid domainname's length (min 2)"
msgstr "longueur du nom de domaine invalide (minimum 2)"
#: tiramisu/option/option.py:460
#: tiramisu/option/option.py:430
msgid "invalid domainname's length (max {0})"
msgstr "longueur du nom de domaine invalide (maximum {0})"
#: tiramisu/option/option.py:445
msgid "invalid domainname, must have dot"
msgstr "nom de domaine invalide, doit avoir un point"
#: tiramisu/option/option.py:447
msgid "invalid domainname's length (max 255)"
msgstr "longueur du nom de domaine invalide (maximum {1})"
#: tiramisu/option/option.py:457
msgid "same characters may cause problems"
msgstr "des caractères peuvent poser problèmes"
#: tiramisu/option/option.py:459
msgid "invalid domainname"
msgstr "nom de domaine invalide"
#: tiramisu/option/option.py:472
#: tiramisu/option/option.py:483
msgid "invalid email address, must contains one @"
msgstr "adresse email invalide, doit contenir un @"
#: tiramisu/option/option.py:475
#: tiramisu/option/option.py:486
msgid "invalid username in email address"
msgstr "nom d'utilisateur invalide dans une adresse email"
#: tiramisu/option/option.py:487
#: tiramisu/option/option.py:502
msgid "invalid url, must start with http:// or https://"
msgstr "URL invalide, doit démarrer avec http:// ou https://"
#: tiramisu/option/option.py:506
#: tiramisu/option/option.py:521
msgid "invalid url, port must be an between 0 and 65536"
msgstr "URL invalide, port doit être entre 0 et 65536"
#: tiramisu/option/option.py:512
#: tiramisu/option/option.py:528
msgid "invalid url, must ends with filename"
msgstr "URL invalide, doit finir avec un nom de fichier"
#: tiramisu/option/option.py:523
#: tiramisu/option/option.py:542
msgid "invalid username"
msgstr "utilisateur invalide"
#: tiramisu/option/option.py:533
#: tiramisu/option/option.py:552
msgid "invalid filename"
msgstr "nom de fichier invalide"
@ -584,6 +592,10 @@ msgstr ""
"ne peut ajouter la propriété {0} dans l'option {1}: cette propriété est "
"calculée"
#: tiramisu/setting.py:341
msgid "you should only append/remove properties"
msgstr "pour pouvait seulement ajouter/supprimer des propriétés"
#: tiramisu/setting.py:345
msgid "opt and all_properties must not be set together in reset"
msgstr "opt et all_properties ne doit pas être renseigné ensemble dans reset"
@ -610,7 +622,7 @@ msgstr "tentative d'accès à une option nommée : {0} avec les propriétés {1}
msgid "permissive must be a tuple"
msgstr "permissive doit être un tuple"
#: tiramisu/setting.py:500 tiramisu/value.py:370
#: tiramisu/setting.py:500 tiramisu/value.py:379
msgid "invalid generic owner {0}"
msgstr "invalide owner générique {0}"
@ -642,7 +654,7 @@ msgstr "option {0} n'existe pas dans l'espace de stockage {1}"
msgid "invalid default_multi value {0} for option {1}: {2}"
msgstr "la valeur default_multi est invalide {0} pour l'option {1} : {2}"
#: tiramisu/storage/dictionary/option.py:131 tiramisu/value.py:427
#: tiramisu/storage/dictionary/option.py:131 tiramisu/value.py:441
msgid "information's item not found: {0}"
msgstr "aucune config spécifiée alors que c'est nécessaire"
@ -694,48 +706,52 @@ msgstr "un espace de stockage dictionary ne peut être persistant"
msgid "optiondescription has no value"
msgstr "une optiondescription n'a pas de valeur"
#: tiramisu/value.py:301
#: tiramisu/value.py:303
msgid "you should only set value with config"
msgstr "vous devez seul affecter une valeur avec un config"
#: tiramisu/value.py:377
#: tiramisu/value.py:356
msgid "owner only avalaible for an option"
msgstr "owner seulement possible pour une option"
#: tiramisu/value.py:386
msgid "no value for {0} cannot change owner to {1}"
msgstr "pas de valeur pour {0} ne peut changer d'utilisateur pour {1}"
#: tiramisu/value.py:467
#: tiramisu/value.py:481
msgid "can force cache only if cache is actived in config"
msgstr ""
"peut force la mise en cache seulement si le cache est activé dans la config"
#: tiramisu/value.py:506
#: tiramisu/value.py:520
msgid "{0} is already a Multi "
msgstr "{0} est déjà une Multi"
#: tiramisu/value.py:572
#: tiramisu/value.py:586
msgid "cannot append a value on a multi option {0} which is a slave"
msgstr "ne peut ajouter une valeur sur l'option multi {0} qui est une esclave"
#: tiramisu/value.py:591
#: tiramisu/value.py:605
msgid "cannot sort multi option {0} if master or slave"
msgstr "ne peut trier une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:595
#: tiramisu/value.py:609
msgid "cmp is not permitted in python v3 or greater"
msgstr "cmp n'est pas permis en python v3 ou supérieure"
#: tiramisu/value.py:604
#: tiramisu/value.py:618
msgid "cannot reverse multi option {0} if master or slave"
msgstr "ne peut inverser une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:612
#: tiramisu/value.py:626
msgid "cannot insert multi option {0} if master or slave"
msgstr "ne peut insérer une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:620
#: tiramisu/value.py:634
msgid "cannot extend multi option {0} if master or slave"
msgstr "ne peut étendre une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:648
#: tiramisu/value.py:662
msgid "cannot pop a value on a multi option {0} which is a slave"
msgstr "ne peut supprimer une valeur dans l'option multi {0} qui est esclave"

View file

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2014-10-25 22:43+CEST\n"
"POT-Creation-Date: 2014-10-26 09:35+CET\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"
@ -28,7 +28,7 @@ msgid "unknown group_type: {0}"
msgstr ""
#: tiramisu/config.py:176 tiramisu/setting.py:321 tiramisu/value.py:54
#: tiramisu/value.py:541
#: tiramisu/value.py:555
msgid "the context does not exist anymore"
msgstr ""
@ -433,47 +433,55 @@ msgstr ""
msgid "allow_without_dot must be a boolean"
msgstr ""
#: tiramisu/option/option.py:454
msgid "invalid domainname, must have dot"
msgstr ""
#: tiramisu/option/option.py:456
msgid "invalid domainname's length (max 255)"
msgstr ""
#: tiramisu/option/option.py:458
#: tiramisu/option/option.py:428
msgid "invalid domainname's length (min 2)"
msgstr ""
#: tiramisu/option/option.py:460
#: tiramisu/option/option.py:430
msgid "invalid domainname's length (max {0})"
msgstr ""
#: tiramisu/option/option.py:445
msgid "invalid domainname, must have dot"
msgstr ""
#: tiramisu/option/option.py:447
msgid "invalid domainname's length (max 255)"
msgstr ""
#: tiramisu/option/option.py:457
msgid "same characters may cause problems"
msgstr ""
#: tiramisu/option/option.py:459
msgid "invalid domainname"
msgstr ""
#: tiramisu/option/option.py:472
#: tiramisu/option/option.py:483
msgid "invalid email address, must contains one @"
msgstr ""
#: tiramisu/option/option.py:475
#: tiramisu/option/option.py:486
msgid "invalid username in email address"
msgstr ""
#: tiramisu/option/option.py:487
#: tiramisu/option/option.py:502
msgid "invalid url, must start with http:// or https://"
msgstr ""
#: tiramisu/option/option.py:506
#: tiramisu/option/option.py:521
msgid "invalid url, port must be an between 0 and 65536"
msgstr ""
#: tiramisu/option/option.py:512
#: tiramisu/option/option.py:528
msgid "invalid url, must ends with filename"
msgstr ""
#: tiramisu/option/option.py:523
#: tiramisu/option/option.py:542
msgid "invalid username"
msgstr ""
#: tiramisu/option/option.py:533
#: tiramisu/option/option.py:552
msgid "invalid filename"
msgstr ""
@ -533,6 +541,10 @@ msgstr ""
msgid "cannot append {0} property for option {1}: this property is calculated"
msgstr ""
#: tiramisu/setting.py:341
msgid "you should only append/remove properties"
msgstr ""
#: tiramisu/setting.py:345
msgid "opt and all_properties must not be set together in reset"
msgstr ""
@ -557,7 +569,7 @@ msgstr ""
msgid "permissive must be a tuple"
msgstr ""
#: tiramisu/setting.py:500 tiramisu/value.py:370
#: tiramisu/setting.py:500 tiramisu/value.py:379
msgid "invalid generic owner {0}"
msgstr ""
@ -585,7 +597,7 @@ msgstr ""
msgid "invalid default_multi value {0} for option {1}: {2}"
msgstr ""
#: tiramisu/storage/dictionary/option.py:131 tiramisu/value.py:427
#: tiramisu/storage/dictionary/option.py:131 tiramisu/value.py:441
msgid "information's item not found: {0}"
msgstr ""
@ -636,47 +648,51 @@ msgstr ""
msgid "optiondescription has no value"
msgstr ""
#: tiramisu/value.py:301
#: tiramisu/value.py:303
msgid "you should only set value with config"
msgstr ""
#: tiramisu/value.py:377
#: tiramisu/value.py:356
msgid "owner only avalaible for an option"
msgstr ""
#: tiramisu/value.py:386
msgid "no value for {0} cannot change owner to {1}"
msgstr ""
#: tiramisu/value.py:467
#: tiramisu/value.py:481
msgid "can force cache only if cache is actived in config"
msgstr ""
#: tiramisu/value.py:506
#: tiramisu/value.py:520
msgid "{0} is already a Multi "
msgstr ""
#: tiramisu/value.py:572
#: tiramisu/value.py:586
msgid "cannot append a value on a multi option {0} which is a slave"
msgstr ""
#: tiramisu/value.py:591
#: tiramisu/value.py:605
msgid "cannot sort multi option {0} if master or slave"
msgstr ""
#: tiramisu/value.py:595
#: tiramisu/value.py:609
msgid "cmp is not permitted in python v3 or greater"
msgstr ""
#: tiramisu/value.py:604
#: tiramisu/value.py:618
msgid "cannot reverse multi option {0} if master or slave"
msgstr ""
#: tiramisu/value.py:612
#: tiramisu/value.py:626
msgid "cannot insert multi option {0} if master or slave"
msgstr ""
#: tiramisu/value.py:620
#: tiramisu/value.py:634
msgid "cannot extend multi option {0} if master or slave"
msgstr ""
#: tiramisu/value.py:648
#: tiramisu/value.py:662
msgid "cannot pop a value on a multi option {0} which is a slave"
msgstr ""