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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
6 from MySQLdb.cursors import DictCursor
33
6b7774cff458 Implement validation for duplicate usernames.
Daniele Nicolodi <daniele@grinta.net>
parents: 21
diff changeset
7
0
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
8 from ltpdarepo import connection
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
9 from ltpdarepo.form import Form
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
10
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
11
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
12 def _generate_password():
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
13 import random
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
14 import string
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
15 chars = string.letters + string.digits
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
16 return "".join([random.choice(chars) for i in range(8)])
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
17
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
18
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
19 class IUser(Form):
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
20 username = TextField("Username", validators=[validators.Required(),
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
21 validators.Regexp(r'^[a-zA-Z][0-9a-zA-Z\-\._]+$',
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
22 message=u'Invalid identifier.')])
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
23 name = TextField("Given name")
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
24 surname = TextField("Family name")
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
25 email = TextField("Email", validators=[validators.Required(),
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
26 validators.Email()])
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
27 telephone = TextField("Telephone")
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
28 institution = TextField("Institution")
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
29 admin = BooleanField("Admin")
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
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
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
38
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
39 class IPassword(Form):
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
40 password = PasswordField()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
41 confirm = PasswordField()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
42
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
43 def validate_password(form, field):
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
44 if not form.password.data == form.confirm.data:
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
45 raise validators.ValidationError(u"Passwords do not match.")
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
46
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
47
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
48 class User(object):
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
49 __slots__ = ('username', 'password', 'name', 'surname', 'email', 'telephone', 'institution', 'admin')
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
50
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
51 def __init__(self, username='', password='', name='', surname='', email='', telephone='', institution='', admin=False):
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
52 self.username = username
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
53 self.password = password
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
54 self.name = name
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
55 self.surname = surname
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
56 self.email = email
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
57 self.telephone = telephone
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
58 self.institution = institution
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
59 self.admin = bool(admin)
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
60
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
61 def __getitem__(self, name):
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
62 return getattr(self, name)
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
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
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
66 conn = connection()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
67 curs = conn.cursor(DictCursor)
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
68 curs.execute("""SELECT username,
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
69 given_name AS name,
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
70 family_name AS surname,
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
71 email, institution, telephone,
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
72 is_admin AS admin
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
73 FROM users WHERE username=%s""", username)
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
74 user = curs.fetchone()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
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
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
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
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
81
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
82 def create(self):
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
83 if not self.password:
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
84 self.password = _generate_password()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
85
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
86 conn = connection()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
87 curs = conn.cursor()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
88
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
89 for host in ('localhost', '%'):
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
90 curs.execute("""CREATE USER %s@%s IDENTIFIED BY %s""",
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
91 (self.username, host, self.password))
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
92
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
93 curs.execute("""INSERT INTO users (username, given_name, family_name,
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
94 email, telephone, institution, is_admin)
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
95 VALUES (%s, %s, %s, %s, %s, %s, %s)""",
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
96 (self.username, self.name, self.surname,
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
97 self.email, self.telephone, self.institution, self.admin))
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
98
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
99 conn.commit()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
100
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
101 def delete(self):
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
102 conn = connection()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
103 curs = conn.cursor()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
104
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
105 curs.execute("""DELETE FROM users WHERE username=%s""", self.username)
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
106 curs.execute("""SELECT Host FROM mysql.user WHERE User=%s""", self.username)
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
107 hosts = [row[0] for row in curs.fetchall()]
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
108 for host in hosts:
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
109 curs.execute("""DROP USER %s@%s""", (self.username, host))
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
110
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
111 conn.commit()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
112
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
113 def save(self):
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
114 conn = connection()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
115 curs = conn.cursor()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
116
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
117 curs.execute("""UPDATE users SET given_name=%s, family_name=%s, email=%s,
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
118 institution=%s, telephone=%s, is_admin=%s
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
119 WHERE username=%s""",
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
120 (self.name, self.surname, self.email,
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
121 self.telephone, self.institution, self.admin, self.username))
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
122
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
123 conn.commit()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
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
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
130
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
131 conn = connection()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
132 curs = conn.cursor()
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
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
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
135 hosts = [row[0] for row in curs.fetchall()]
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
136 for host in hosts:
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
137 curs.execute("""SET PASSWORD FOR %s@%s = PASSWORD(%s)""",
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
138 (self.username, host, self.password))
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
139
c812c3020b63 Initial import.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff changeset
140 conn.commit()