Show More
@@ -48,6 +48,7 b' from rhodecode.lib.caching_query import ' | |||
|
48 | 48 | |
|
49 | 49 | from rhodecode.model.meta import Base, Session |
|
50 | 50 | import hashlib |
|
51 | from sqlalchemy.exc import DatabaseError | |
|
51 | 52 | |
|
52 | 53 | |
|
53 | 54 | log = logging.getLogger(__name__) |
@@ -381,8 +382,23 b' class User(Base, BaseModel):' | |||
|
381 | 382 | |
|
382 | 383 | if cache: |
|
383 | 384 | q = q.options(FromCache("sql_cache_short", |
|
384 |
"get_a |
|
|
385 | return q.scalar() | |
|
385 | "get_email_key_%s" % email)) | |
|
386 | ||
|
387 | ret = q.scalar() | |
|
388 | if ret is None: | |
|
389 | q = UserEmailMap.query() | |
|
390 | # try fetching in alternate email map | |
|
391 | if case_insensitive: | |
|
392 | q = q.filter(UserEmailMap.email.ilike(email)) | |
|
393 | else: | |
|
394 | q = q.filter(UserEmailMap.email == email) | |
|
395 | q = q.options(joinedload(UserEmailMap.user)) | |
|
396 | if cache: | |
|
397 | q = q.options(FromCache("sql_cache_short", | |
|
398 | "get_email_map_key_%s" % email)) | |
|
399 | ret = getattr(q.scalar(), 'user', None) | |
|
400 | ||
|
401 | return ret | |
|
386 | 402 | |
|
387 | 403 | def update_lastlogin(self): |
|
388 | 404 | """Update user lastlogin""" |
@@ -403,6 +419,38 b' class User(Base, BaseModel):' | |||
|
403 | 419 | ) |
|
404 | 420 | |
|
405 | 421 | |
|
422 | class UserEmailMap(Base, BaseModel): | |
|
423 | __tablename__ = 'user_email_map' | |
|
424 | __table_args__ = ( | |
|
425 | UniqueConstraint('email'), | |
|
426 | {'extend_existing': True, 'mysql_engine':'InnoDB', | |
|
427 | 'mysql_charset': 'utf8'} | |
|
428 | ) | |
|
429 | __mapper_args__ = {} | |
|
430 | ||
|
431 | email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) | |
|
432 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) | |
|
433 | _email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None) | |
|
434 | ||
|
435 | user = relationship('User') | |
|
436 | ||
|
437 | @validates('_email') | |
|
438 | def validate_email(self, key, email): | |
|
439 | # check if this email is not main one | |
|
440 | main_email = Session.query(User).filter(User.email == email).scalar() | |
|
441 | if main_email is not None: | |
|
442 | raise AttributeError('email %s is present is user table' % email) | |
|
443 | return email | |
|
444 | ||
|
445 | @hybrid_property | |
|
446 | def email(self): | |
|
447 | return self._email | |
|
448 | ||
|
449 | @email.setter | |
|
450 | def email(self, val): | |
|
451 | self._email = val.lower() if val else None | |
|
452 | ||
|
453 | ||
|
406 | 454 | class UserLog(Base, BaseModel): |
|
407 | 455 | __tablename__ = 'user_logs' |
|
408 | 456 | __table_args__ = ( |
@@ -6,8 +6,8 b' from rhodecode.model.repos_group import ' | |||
|
6 | 6 | from rhodecode.model.repo import RepoModel |
|
7 | 7 | from rhodecode.model.db import RepoGroup, User, Notification, UserNotification, \ |
|
8 | 8 | UsersGroup, UsersGroupMember, Permission, UsersGroupRepoGroupToPerm,\ |
|
9 | Repository | |
|
10 | from sqlalchemy.exc import IntegrityError | |
|
9 | Repository, UserEmailMap | |
|
10 | from sqlalchemy.exc import IntegrityError, DatabaseError | |
|
11 | 11 | from rhodecode.model.user import UserModel |
|
12 | 12 | |
|
13 | 13 | from rhodecode.model.meta import Session |
@@ -181,7 +181,8 b' class TestUser(unittest.TestCase):' | |||
|
181 | 181 | super(TestUser, self).__init__(methodName=methodName) |
|
182 | 182 | |
|
183 | 183 | def test_create_and_remove(self): |
|
184 |
usr = UserModel().create_or_update(username=u'test_user', |
|
|
184 | usr = UserModel().create_or_update(username=u'test_user', | |
|
185 | password=u'qweqwe', | |
|
185 | 186 | email=u'u232@rhodecode.org', |
|
186 | 187 | name=u'u1', lastname=u'u1') |
|
187 | 188 | Session.commit() |
@@ -201,6 +202,50 b' class TestUser(unittest.TestCase):' | |||
|
201 | 202 | |
|
202 | 203 | self.assertEqual(UsersGroupMember.query().all(), []) |
|
203 | 204 | |
|
205 | def test_additonal_email_as_main(self): | |
|
206 | usr = UserModel().create_or_update(username=u'test_user', | |
|
207 | password=u'qweqwe', | |
|
208 | email=u'main_email@rhodecode.org', | |
|
209 | name=u'u1', lastname=u'u1') | |
|
210 | Session.commit() | |
|
211 | ||
|
212 | def do(): | |
|
213 | m = UserEmailMap() | |
|
214 | m.email = u'main_email@rhodecode.org' | |
|
215 | m.user = usr | |
|
216 | Session.add(m) | |
|
217 | Session.commit() | |
|
218 | self.assertRaises(AttributeError, do) | |
|
219 | ||
|
220 | UserModel().delete(usr.user_id) | |
|
221 | Session.commit() | |
|
222 | ||
|
223 | def test_extra_email_map(self): | |
|
224 | usr = UserModel().create_or_update(username=u'test_user', | |
|
225 | password=u'qweqwe', | |
|
226 | email=u'main_email@rhodecode.org', | |
|
227 | name=u'u1', lastname=u'u1') | |
|
228 | Session.commit() | |
|
229 | ||
|
230 | m = UserEmailMap() | |
|
231 | m.email = u'main_email2@rhodecode.org' | |
|
232 | m.user = usr | |
|
233 | Session.add(m) | |
|
234 | Session.commit() | |
|
235 | ||
|
236 | u = User.get_by_email(email='main_email@rhodecode.org') | |
|
237 | self.assertEqual(usr.user_id, u.user_id) | |
|
238 | self.assertEqual(usr.username, u.username) | |
|
239 | ||
|
240 | u = User.get_by_email(email='main_email2@rhodecode.org') | |
|
241 | self.assertEqual(usr.user_id, u.user_id) | |
|
242 | self.assertEqual(usr.username, u.username) | |
|
243 | u = User.get_by_email(email='main_email3@rhodecode.org') | |
|
244 | self.assertEqual(None, u) | |
|
245 | ||
|
246 | UserModel().delete(usr.user_id) | |
|
247 | Session.commit() | |
|
248 | ||
|
204 | 249 | |
|
205 | 250 | class TestNotifications(unittest.TestCase): |
|
206 | 251 |
General Comments 0
You need to be logged in to leave comments.
Login now