validators.py
2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import re
import colander
from pyramid.i18n import TranslationStringFactory
from ..models import DBSession
from ..models.ziggurat import User
_ = TranslationStringFactory('user')
class Validator:
def __init__(self, user):
self.user = user
class EmailValidator(colander.Email, Validator):
def __init__(self, user):
colander.Email.__init__(self)
Validator.__init__(self, user)
def __call__(self, node, value):
if self.match_object.match(value) is None:
raise colander.Invalid(node, _('Invalid email format'))
email = value.lower()
if self.user and self.user.email == email:
return
q = DBSession.query(User).filter_by(email=email)
found = q.first()
if not found:
return
data = dict(email=email, uid=found.id)
ts = _(
'email-already-used',
default='Email ${email} already used by user ID ${uid}',
mapping=data)
raise colander.Invalid(node, ts)
REGEX_ONLY_CONTAIN = re.compile('([a-z0-9-]*)')
REGEX_BEGIN_END_ALPHANUMERIC = re.compile('^[a-z0-9]+(?:[-][a-z0-9]+)*$')
class UsernameValidator(Validator):
def __call__(self, node, value):
username = value.lower()
if self.user and self.user.user_name == username:
return
match = REGEX_ONLY_CONTAIN.search(username)
if not match or match.group(1) != username or username != value:
ts = _(
'username-only-contain',
default='Only a-z, 0-9, and - characters are allowed')
raise colander.Invalid(node, ts)
match = REGEX_BEGIN_END_ALPHANUMERIC.search(username)
if not match:
ts = _(
'username-first-end-alphanumeric',
default='Only a-z or 0-9 at the start and end')
raise colander.Invalid(node, ts)
q = DBSession.query(User).filter_by(user_name=username)
found = q.first()
if not found:
return
data = dict(username=username, uid=found.id)
ts = _(
'username-already-used',
default='Username ${username} already used by ID ${uid}',
mapping=data)
raise colander.Invalid(node, ts)
@colander.deferred
def email_validator(node, kw):
return EmailValidator(kw['user'])
@colander.deferred
def username_validator(node, kw):
return UsernameValidator(kw['user'])