Walter Danilo Galante  committed e2727de

Fixed a possible incoherence when two or more users attempt a registration with the same username, reduced expiration time

  • Participants
  • Parent commits 70c9557

Comments (0)

Files changed (3)

File registration/controllers/

 # -*- coding: utf-8 -*-
 """Main Controller"""
+from _sqlite3 import IntegrityError
 from tg import TGController
 from tg import expose, flash, require, url, lurl, request, redirect, validate, config, predicates
         hooks = config['hooks'].get('registration.before_activation', [])
         for func in hooks:
             func(reg, u)
-        DBSession.add(u)
+        try:
+            DBSession.add(u)
+        except IntegrityError:
+            flash(_('Registration not found or already activated'))
+            return redirect(self.mount_point)
         reg.user = u
         reg.password = '******'

File registration/lib/

         super(UniqueUserValidator, self).validate_python(value, state)
         if re.match("^[a-zA-Z0-9_-]*[a-zA-Z_-][a-zA-Z0-9_-]*$", value):
             user = DBSession.query(app_model.User).filter_by(user_name=value).first()
+            if not user:
+                user = DBSession.query(Registration).filter_by(user_name=value).first()
  1. Alessandro Molina

    Should probably check that in you already performed a change that removed exactly that line to fix an issue with registration collisions.

    What's the expected behavior? It is probably correct that it doesn't checked collisions for Registrations to prevent users from blocking other from registering. The first that activates the registration link should win and "activate" should be in charge of making sure there are not collisions (through a forced flush and check for IntegrityError as stated on the previous comment).

             if user:
                 raise Invalid(_('Username already in use.'), value, state)
         super(UniqueEmailValidator, self).validate_python(value, state)
         if re.match("^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$", value):
             user = DBSession.query(app_model.User).filter_by(email_address=value).first()
+            if not user:
+                user = DBSession.query(Registration).filter_by(email_address=value).first()
             if user:
                 raise Invalid(_('Email address has already been taken'), value, state)

File registration/model/

     def clear_expired(cls):
         expired = DBSession.query(cls).filter_by(activated=None)\
-                                      .filter(Registration.time<
+                                      .filter(Registration.time<
     def get_inactive(cls, code):