# HG changeset patch # User Marcin Kuzminski # Date 2011-12-05 23:18:27 # Node ID 2aa7f454204e8da2bca0e14c3635fbb11e075df8 # Parent 60a00fd76d5881f412ca8c85477a4da3af791df7 fixes #298, ldap email addresses created by rhodecode automatically during first login didn't get converted to lower case, which lead to lookup failures and than wrong checks for uniqueness. Fixed that by putting a setter on db model column that will enforce converting to lowercase. diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -265,7 +265,7 @@ class User(Base, BaseModel): admin = Column("admin", Boolean(), nullable=True, unique=None, default=False) name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) - email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) + _email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) @@ -281,6 +281,14 @@ class User(Base, BaseModel): notifications = relationship('UserNotification',) + @hybrid_property + def email(self): + return self._email + + @email.setter + def email(self, val): + self._email = val.lower() if val else None + @property def full_name(self): return '%s %s' % (self.name, self.lastname) @@ -324,8 +332,11 @@ class User(Base, BaseModel): return q.scalar() @classmethod - def get_by_email(cls, email, cache=False): - q = cls.query().filter(cls.email == email) + def get_by_email(cls, email, case_insensitive=False, cache=False): + if case_insensitive: + q = cls.query().filter(cls.email.ilike(email)) + else: + q = cls.query().filter(cls.email == email) if cache: q = q.options(FromCache("sql_cache_short", diff --git a/rhodecode/model/forms.py b/rhodecode/model/forms.py --- a/rhodecode/model/forms.py +++ b/rhodecode/model/forms.py @@ -396,7 +396,7 @@ class ValidPerms(formencode.validators.F class ValidSettings(formencode.validators.FancyValidator): def to_python(self, value, state): - #settings form can't edit user + # settings form can't edit user if value.has_key('user'): del['value']['user'] @@ -416,7 +416,7 @@ def UniqSystemEmail(old_data): def to_python(self, value, state): value = value.lower() if old_data.get('email') != value: - user = User.query().filter(User.email == value).scalar() + user = User.get_by_email(value, case_insensitive=True) if user: raise formencode.Invalid( _("This e-mail address is already taken"), @@ -428,7 +428,7 @@ def UniqSystemEmail(old_data): class ValidSystemEmail(formencode.validators.FancyValidator): def to_python(self, value, state): value = value.lower() - user = User.query().filter(User.email == value).scalar() + user = User.get_by_email(value, case_insensitive=True) if user is None: raise formencode.Invalid(_("This e-mail address doesn't exist.") , value, state)