Mercurial > hg > ltpdarepo
annotate src/ltpdarepo/user.py @ 33:6b7774cff458
Implement validation for duplicate usernames.
author | Daniele Nicolodi <daniele@grinta.net> |
---|---|
date | Mon, 27 Jun 2011 19:31:25 +0200 |
parents | 19f233ab545f |
children | ce7734a6b6ad |
rev | line source |
---|---|
33
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
1 from flask import g |
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
2 from wtforms import validators |
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
3 from wtforms.fields import TextField, PasswordField, BooleanField |
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
4 from wtforms.validators import ValidationError |
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
5 |
0 | 6 from MySQLdb.cursors import DictCursor |
33
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
7 |
0 | 8 from ltpdarepo import connection |
9 from ltpdarepo.form import Form | |
10 | |
11 | |
12 def _generate_password(): | |
13 import random | |
14 import string | |
15 chars = string.letters + string.digits | |
16 return "".join([random.choice(chars) for i in range(8)]) | |
17 | |
18 | |
19 class IUser(Form): | |
20 username = TextField("Username", validators=[validators.Required(), | |
21 validators.Regexp(r'^[a-zA-Z][0-9a-zA-Z\-\._]+$', | |
22 message=u'Invalid identifier.')]) | |
23 name = TextField("Given name") | |
24 surname = TextField("Family name") | |
25 email = TextField("Email", validators=[validators.Required(), | |
26 validators.Email()]) | |
27 telephone = TextField("Telephone") | |
28 institution = TextField("Institution") | |
29 admin = BooleanField("Admin") | |
30 | |
33
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
31 def validate_username(form, field): |
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
32 curs = g.db.cursor() |
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
33 curs.execute("SELECT DISTINCT user FROM mysql.user WHERE user <> ''") |
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
34 users = [r[0] for r in curs.fetchall()] |
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
35 if field.data in users: |
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
36 raise ValidationError(u"MySQL already contains an user with this username.") |
6b7774cff458
Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents:
21
diff
changeset
|
37 |
0 | 38 |
39 class IPassword(Form): | |
40 password = PasswordField() | |
41 confirm = PasswordField() | |
42 | |
43 def validate_password(form, field): | |
44 if not form.password.data == form.confirm.data: | |
45 raise validators.ValidationError(u"Passwords do not match.") | |
46 | |
47 | |
48 class User(object): | |
49 __slots__ = ('username', 'password', 'name', 'surname', 'email', 'telephone', 'institution', 'admin') | |
50 | |
51 def __init__(self, username='', password='', name='', surname='', email='', telephone='', institution='', admin=False): | |
52 self.username = username | |
53 self.password = password | |
54 self.name = name | |
55 self.surname = surname | |
56 self.email = email | |
57 self.telephone = telephone | |
58 self.institution = institution | |
59 self.admin = bool(admin) | |
60 | |
61 def __getitem__(self, name): | |
62 return getattr(self, name) | |
63 | |
20
d19c5ae165de
Make load() method of the User class into a static method.
Daniele Nicolodi <daniele@grinta.net>
parents:
0
diff
changeset
|
64 @staticmethod |
d19c5ae165de
Make load() method of the User class into a static method.
Daniele Nicolodi <daniele@grinta.net>
parents:
0
diff
changeset
|
65 def load(username): |
0 | 66 conn = connection() |
67 curs = conn.cursor(DictCursor) | |
68 curs.execute("""SELECT username, | |
69 given_name AS name, | |
70 family_name AS surname, | |
71 email, institution, telephone, | |
72 is_admin AS admin | |
73 FROM users WHERE username=%s""", username) | |
74 user = curs.fetchone() | |
75 if user is None: | |
20
d19c5ae165de
Make load() method of the User class into a static method.
Daniele Nicolodi <daniele@grinta.net>
parents:
0
diff
changeset
|
76 return None |
d19c5ae165de
Make load() method of the User class into a static method.
Daniele Nicolodi <daniele@grinta.net>
parents:
0
diff
changeset
|
77 obj = User() |
0 | 78 for key, value in user.iteritems(): |
20
d19c5ae165de
Make load() method of the User class into a static method.
Daniele Nicolodi <daniele@grinta.net>
parents:
0
diff
changeset
|
79 setattr(obj, key, value) |
d19c5ae165de
Make load() method of the User class into a static method.
Daniele Nicolodi <daniele@grinta.net>
parents:
0
diff
changeset
|
80 return obj |
0 | 81 |
82 def create(self): | |
83 if not self.password: | |
84 self.password = _generate_password() | |
85 | |
86 conn = connection() | |
87 curs = conn.cursor() | |
88 | |
89 for host in ('localhost', '%'): | |
90 curs.execute("""CREATE USER %s@%s IDENTIFIED BY %s""", | |
91 (self.username, host, self.password)) | |
92 | |
93 curs.execute("""INSERT INTO users (username, given_name, family_name, | |
94 email, telephone, institution, is_admin) | |
95 VALUES (%s, %s, %s, %s, %s, %s, %s)""", | |
96 (self.username, self.name, self.surname, | |
97 self.email, self.telephone, self.institution, self.admin)) | |
98 | |
99 conn.commit() | |
100 | |
101 def delete(self): | |
102 conn = connection() | |
103 curs = conn.cursor() | |
104 | |
105 curs.execute("""DELETE FROM users WHERE username=%s""", self.username) | |
106 curs.execute("""SELECT Host FROM mysql.user WHERE User=%s""", self.username) | |
107 hosts = [row[0] for row in curs.fetchall()] | |
108 for host in hosts: | |
109 curs.execute("""DROP USER %s@%s""", (self.username, host)) | |
110 | |
111 conn.commit() | |
112 | |
113 def save(self): | |
114 conn = connection() | |
115 curs = conn.cursor() | |
116 | |
117 curs.execute("""UPDATE users SET given_name=%s, family_name=%s, email=%s, | |
118 institution=%s, telephone=%s, is_admin=%s | |
119 WHERE username=%s""", | |
120 (self.name, self.surname, self.email, | |
121 self.telephone, self.institution, self.admin, self.username)) | |
122 | |
123 conn.commit() | |
124 | |
21
19f233ab545f
Fix empty passwords handling.
Daniele Nicolodi <daniele@grinta.net>
parents:
20
diff
changeset
|
125 def passwd(self, password=None): |
19f233ab545f
Fix empty passwords handling.
Daniele Nicolodi <daniele@grinta.net>
parents:
20
diff
changeset
|
126 if password is not None: |
19f233ab545f
Fix empty passwords handling.
Daniele Nicolodi <daniele@grinta.net>
parents:
20
diff
changeset
|
127 self.password = password |
19f233ab545f
Fix empty passwords handling.
Daniele Nicolodi <daniele@grinta.net>
parents:
20
diff
changeset
|
128 if not self.password: |
19f233ab545f
Fix empty passwords handling.
Daniele Nicolodi <daniele@grinta.net>
parents:
20
diff
changeset
|
129 self.password = _generate_password() |
0 | 130 |
131 conn = connection() | |
132 curs = conn.cursor() | |
133 | |
21
19f233ab545f
Fix empty passwords handling.
Daniele Nicolodi <daniele@grinta.net>
parents:
20
diff
changeset
|
134 curs.execute("""SELECT Host FROM mysql.user WHERE User=%s""", self.username) |
0 | 135 hosts = [row[0] for row in curs.fetchall()] |
136 for host in hosts: | |
137 curs.execute("""SET PASSWORD FOR %s@%s = PASSWORD(%s)""", | |
138 (self.username, host, self.password)) | |
139 | |
140 conn.commit() |