0001-add-user-phone-field-subsequent-migration-69838.patch
tests/test_sql.py | ||
---|---|---|
2209 | 2209 |
assert len(objects) == 2 |
2210 | 2210 | |
2211 | 2211 | |
2212 |
def test_migration_68_add_user_phone_field(pub): |
|
2213 |
conn, cur = sql.get_connection_and_cursor() |
|
2214 |
cur.execute('UPDATE wcs_meta SET value = 67 WHERE key = %s', ('sql_level',)) |
|
2215 |
conn.commit() |
|
2216 |
cur.close() |
|
2217 | ||
2218 |
sql.SqlUser.wipe() |
|
2219 |
user = sql.SqlUser() |
|
2220 |
user.name = 'Jean Sénisme' |
|
2221 |
user.store() |
|
2222 | ||
2223 |
user2 = sql.SqlUser() |
|
2224 |
user2.name = 'Jean II' |
|
2225 |
user2.store() |
|
2226 |
assert sql.SqlUser.count() == 2 |
|
2227 | ||
2228 |
conn, cur = sql.get_connection_and_cursor() |
|
2229 |
cur.execute('ALTER TABLE users DROP COLUMN phone') |
|
2230 |
assert not column_exists_in_table(cur, 'users', 'phone') |
|
2231 |
sql.migrate() |
|
2232 |
assert column_exists_in_table(cur, 'users', 'phone') |
|
2233 |
assert migration_level(cur) >= 68 |
|
2234 | ||
2235 |
assert sql.SqlUser.count() == 2 |
|
2236 |
assert sql.SqlUser.get(id=user.id).phone is None |
|
2237 |
assert sql.SqlUser.get(id=user2.id).phone is None |
|
2238 | ||
2239 | ||
2212 | 2240 |
def test_logged_error_store_without_integrity_error(pub, sql_queries): |
2213 | 2241 |
sql.LoggedError.record('there was an error') |
2214 | 2242 |
tests/test_users.py | ||
---|---|---|
42 | 42 |
assert pub.user_class.get_users_with_name_identifier('foo')[0].name == 'Pierre' |
43 | 43 | |
44 | 44 | |
45 |
def test_get_users_with_phone(pub): |
|
46 |
pub.user_class.wipe() |
|
47 | ||
48 |
user = pub.user_class() |
|
49 |
user.name = 'Pierre' |
|
50 |
user.phone = '+33123456789' |
|
51 |
user.store() |
|
52 | ||
53 |
user = pub.user_class() |
|
54 |
user.name = 'Papier' |
|
55 |
user.phone = '+33987654321' |
|
56 |
user.store() |
|
57 | ||
58 |
assert len(pub.user_class.get_users_with_phone('+33123456789')) == 1 |
|
59 |
assert pub.user_class.get_users_with_phone('+33123456789')[0].name == 'Pierre' |
|
60 | ||
61 | ||
45 | 62 |
def test_user_substitution_variables(pub): |
46 | 63 |
pub.user_class.wipe() |
47 | 64 |
wcs/sql.py | ||
---|---|---|
1118 | 1118 |
name varchar, |
1119 | 1119 |
ascii_name varchar, |
1120 | 1120 |
email varchar, |
1121 |
phone varchar, |
|
1121 | 1122 |
roles text[], |
1122 | 1123 |
is_active bool, |
1123 | 1124 |
is_admin bool, |
... | ... | |
1142 | 1143 |
'id', |
1143 | 1144 |
'name', |
1144 | 1145 |
'email', |
1146 |
'phone', |
|
1145 | 1147 |
'roles', |
1146 | 1148 |
'is_admin', |
1147 | 1149 |
'anonymous', |
... | ... | |
1200 | 1202 |
cur.execute('ALTER TABLE %s ADD COLUMN is_active bool DEFAULT TRUE' % table_name) |
1201 | 1203 |
cur.execute('UPDATE %s SET is_active = FALSE WHERE deleted_timestamp IS NOT NULL' % table_name) |
1202 | 1204 | |
1205 |
if 'phone' not in existing_fields: |
|
1206 |
cur.execute('ALTER TABLE %s ADD COLUMN phone varchar' % table_name) |
|
1207 | ||
1203 | 1208 |
# delete obsolete fields |
1204 | 1209 |
for field in existing_fields - needed_fields: |
1205 | 1210 |
cur.execute('''ALTER TABLE %s DROP COLUMN %s''' % (table_name, field)) |
... | ... | |
3138 | 3143 |
('id', 'serial'), |
3139 | 3144 |
('name', 'varchar'), |
3140 | 3145 |
('email', 'varchar'), |
3146 |
('phone', 'varchar'), |
|
3141 | 3147 |
('roles', 'varchar[]'), |
3142 | 3148 |
('is_admin', 'bool'), |
3143 | 3149 |
('anonymous', 'bool'), |
... | ... | |
3165 | 3171 |
'name': self.name, |
3166 | 3172 |
'ascii_name': self.ascii_name, |
3167 | 3173 |
'email': self.email, |
3174 |
'phone': self.phone, |
|
3168 | 3175 |
'roles': self.roles, |
3169 | 3176 |
'is_admin': self.is_admin, |
3170 | 3177 |
'anonymous': self.anonymous, |
... | ... | |
3261 | 3268 |
o.id, |
3262 | 3269 |
o.name, |
3263 | 3270 |
o.email, |
3271 |
o.phone, |
|
3264 | 3272 |
o.roles, |
3265 | 3273 |
o.is_admin, |
3266 | 3274 |
o.anonymous, |
... | ... | |
3271 | 3279 |
ascii_name, # XXX what's this ? pylint: disable=unused-variable |
3272 | 3280 |
o.deleted_timestamp, |
3273 | 3281 |
o.is_active, |
3274 |
) = (str_encode(x) for x in tuple(row[:13]))
|
|
3282 |
) = (str_encode(x) for x in tuple(row[:14]))
|
|
3275 | 3283 |
if o.last_seen: |
3276 | 3284 |
o.last_seen = time.mktime(o.last_seen.timetuple()) |
3277 | 3285 |
if o.roles: |
... | ... | |
4462 | 4470 |
# latest migration, number + description (description is not used |
4463 | 4471 |
# programmaticaly but will make sure git conflicts if two migrations are |
4464 | 4472 |
# separately added with the same number) |
4465 |
SQL_LEVEL = (67, 're-migrate legacy tokens')
|
|
4473 |
SQL_LEVEL = (68, 'add user phone field')
|
|
4466 | 4474 | |
4467 | 4475 | |
4468 | 4476 |
def migrate_global_views(conn, cur): |
... | ... | |
4614 | 4622 |
# 48: remove acked attribute from LoggedError |
4615 | 4623 |
# 53: add kind column to logged_errors table |
4616 | 4624 |
do_loggederrors_table() |
4617 |
if sql_level < 65:
|
|
4625 |
if sql_level < 68:
|
|
4618 | 4626 |
# 3: introduction of _structured for user fields |
4619 | 4627 |
# 4: removal of identification_token |
4620 | 4628 |
# 12: (first part) add fts to users |
... | ... | |
4623 | 4631 |
# 39: add deleted_timestamp |
4624 | 4632 |
# 40: add is_active to users |
4625 | 4633 |
# 65: index users(name_identifiers) |
4634 |
# 68: add user phone field |
|
4626 | 4635 |
do_user_table() |
4627 | 4636 |
if sql_level < 32: |
4628 | 4637 |
# 25: create session_table |
wcs/users.py | ||
---|---|---|
35 | 35 | |
36 | 36 |
name = None |
37 | 37 |
email = None |
38 |
phone = None |
|
38 | 39 |
roles = None |
39 | 40 |
is_active = True |
40 | 41 |
is_admin = False |
... | ... | |
109 | 110 |
return self.name |
110 | 111 |
if self.email: |
111 | 112 |
return self.email |
113 |
if self.phone: |
|
114 |
return self.phone |
|
112 | 115 |
return str(_('Unknown User')) |
113 | 116 | |
114 | 117 |
display_name = property(get_display_name) |
... | ... | |
133 | 136 |
if field_email: |
134 | 137 |
self.email = formdata.get(field_email) |
135 | 138 | |
139 |
if formdata.get('phone'): |
|
140 |
self.phone = formdata.get('phone') |
|
141 | ||
142 |
field_phone = users_cfg.get('field_phone') |
|
143 |
if field_phone: |
|
144 |
self.phone = formdata.get(field_phone) |
|
145 | ||
136 | 146 |
if users_cfg.get('fullname_template'): |
137 | 147 |
# apply template |
138 | 148 |
user_ctx = self.get_substitution_variables(prefix='') |
... | ... | |
221 | 231 |
def get_users_with_email(cls, email): |
222 | 232 |
return cls.select([st.Null('deleted_timestamp'), st.Equal('email', email)]) |
223 | 233 | |
234 |
@classmethod |
|
235 |
def get_users_with_phone(cls, phone): |
|
236 |
return cls.select([st.Null('deleted_timestamp'), st.Equal('phone', phone)]) |
|
237 | ||
224 | 238 |
@classmethod |
225 | 239 |
def get_users_with_name(cls, name): |
226 | 240 |
return cls.select([st.Null('deleted_timestamp'), st.Equal('name', name)]) |
... | ... | |
230 | 244 |
prefix + 'user': self, |
231 | 245 |
prefix + 'user_display_name': self.display_name, |
232 | 246 |
prefix + 'user_email': self.email, |
247 |
prefix + 'user_phone': self.phone, |
|
233 | 248 |
} |
234 | 249 |
formdef = self.get_formdef() |
235 | 250 |
if formdef: |
... | ... | |
310 | 325 |
} |
311 | 326 |
if self.email: |
312 | 327 |
data['email'] = self.email |
328 |
if self.phone: |
|
329 |
data['phone'] = self.phone |
|
313 | 330 |
if self.name_identifiers: |
314 | 331 |
data['NameID'] = self.name_identifiers |
315 | 332 |
if full: |
... | ... | |
386 | 403 |
comment=_('Session User Display Name'), |
387 | 404 |
) |
388 | 405 |
Substitutions.register('session_user_email', category=_('User'), comment=_('Session User Email')) |
406 |
Substitutions.register('session_user_phone', category=_('User'), comment=_('Session User Phone')) |
|
389 | 407 |
Substitutions.register_dynamic_source(User) |
390 |
- |