def render(target): table = target.table("createuser", align="center") def header(label): row = table.tr("header") row.td(colspan=2).text(label) def item(key): row = table.tr("item") row.td("key").text("%s:" % key) return row.td("value") def button(class_name): row = table.tr("button") return row.td(colspan=2).button(class_name) def separator(): table.tr("separator1").td(colspan=2) table.tr("separator2").td(colspan=2) if provider: self.document.addInternalScript( "var external = { provider: %s, account: %s, token: %s };" % (htmlutils.jsify(self.provider), htmlutils.jsify(self.account), htmlutils.jsify(self.token))) url = provider.getAccountURL(self.account) item(provider.getTitle()).a("external", href=url).text(self.account) separator() else: self.document.addInternalScript("var external = null;") message = table.tr("status disabled").td(colspan=2).div("message") if self.username: try: dbutils.User.fromName(self.db, self.username) except dbutils.NoSuchUser: try: auth.validateUserName(self.username) except auth.InvalidUserName as error: message.u("Invalid user name") message.br() message.text(str(error)) else: message.text("A user named '%s' already exists!" % self.username) item("New user name").input(id="newusername", value=self.username, size=40) item("Display name").input(id="fullname", value=self.fullname, size=40) item("Email").input(id="email", value=self.email, size=40) if not provider: separator() item("Password").input(id="password1", type="password", size=40) item("Password (again)").input(id="password2", type="password", size=40) button("create").text("Create user")
def process(self, db, user, req, username, fullname, email, password=None, external=None): cursor = db.cursor() if not fullname: fullname = username if not email: email = None if not password: # Empty password => disabled. password = None if external: provider_config = configuration.auth.PROVIDERS[ external["provider"]] provider = auth.PROVIDERS[external["provider"]] # Check that user registration is actually enabled. This would also # disable the UI for user registration, of course, but the UI could be # bypassed, so we should check here as well. if not configuration.base.ALLOW_USER_REGISTRATION: if not external or not provider_config["allow_user_registration"]: return OperationResult( message="User registration is not enabled.") # Check that the user name is valid. try: auth.validateUserName(username) except auth.InvalidUserName as error: return OperationResult(message="<u>Invalid user name</u><br>" + str(error), focus="#newusername") # Check that the user name is not already taken. cursor.execute("SELECT 1 FROM users WHERE name=%s", (username, )) if cursor.fetchone(): return OperationResult( message="A user named '%s' already exists!" % username, focus="#newusername") # Check that the email address has some hope of being valid. if email and not checkEmailAddressSyntax(email): return OperationResult( message=("<u>Invalid email address</u><br>" "Please provide an address on the form user@host!"), focus="#email") # Check that we have either a password or an external authentication # provider. If we have neither, the user wouldn't be able to sign in. if password is None and external is None: return OperationResult(message="Empty password.", focus="#password1") if password: password = auth.hashPassword(password) verify_email_address = configuration.base.VERIFY_EMAIL_ADDRESSES if external: # Check that the external authentication token is valid. if not provider.validateToken(db, external["account"], external["token"]): return OperationResult( message="Invalid external authentication state.") cursor.execute( """SELECT id, uid, email FROM externalusers WHERE provider=%s AND account=%s""", (external["provider"], external["account"])) # Note: the token validation above implicitly checks that there's a # matching row in the 'externalusers' table. external_user_id, existing_user_id, external_email = cursor.fetchone( ) # Check that we don't already have a Critic user associated with # this external user. if existing_user_id is not None: existing_user = dbutils.User.fromId(db, existing_user_id) return OperationResult( message=("There is already a Critic user ('%s') connected " "to the %s '%s'" % (existing_user.name, provider.getTitle(), external["account"]))) if email == external_email: verify_email_address = provider.configuration[ "verify_email_addresses"] # Reset 'email' column in 'externalusers': we only need it to detect # if the user changed the email address in the "Create user" form. # Also reset the 'token' column, which serves no further purpose # beyond this point. cursor.execute( """UPDATE externalusers SET email=NULL, token=NULL WHERE id=%s""", (external_user_id, )) email_verified = False if email and verify_email_address else None user = dbutils.User.create(db, username, fullname, email, email_verified, password) if external: cursor.execute( """UPDATE externalusers SET uid=%s WHERE id=%s""", (user.id, external_user_id)) auth.startSession(db, req, user) if email_verified is False: sendVerificationMail(db, user) db.commit() user.sendUserCreatedMail("wsgi[registeruser]", external) return OperationResult()
def process(self, db, user, req, username, fullname, email, password=None, external=None): cursor = db.cursor() if not fullname: fullname = username if not email: email = None if not password: # Empty password => disabled. password = None if external: provider_config = configuration.auth.PROVIDERS[external["provider"]] provider = auth.PROVIDERS[external["provider"]] # Check that user registration is actually enabled. This would also # disable the UI for user registration, of course, but the UI could be # bypassed, so we should check here as well. if not configuration.base.ALLOW_USER_REGISTRATION: if not external or not provider_config["allow_user_registration"]: return OperationResult( message="User registration is not enabled.") # Check that the user name is valid. try: auth.validateUserName(username) except auth.InvalidUserName as error: return OperationResult( message="<u>Invalid user name</u><br>" + str(error), focus="#newusername") # Check that the user name is not already taken. cursor.execute("SELECT 1 FROM users WHERE name=%s", (username,)) if cursor.fetchone(): return OperationResult( message="A user named '%s' already exists!" % username, focus="#newusername") # Check that the email address has some hope of being valid. if email and not checkEmailAddressSyntax(email): return OperationResult( message=("<u>Invalid email address</u><br>" "Please provide an address on the form user@host!"), focus="#email") # Check that we have either a password or an external authentication # provider. If we have neither, the user wouldn't be able to sign in. if password is None and external is None: return OperationResult( message="Empty password.", focus="#password1") if password: password = auth.hashPassword(password) verify_email_address = configuration.base.VERIFY_EMAIL_ADDRESSES if external: # Check that the external authentication token is valid. if not provider.validateToken(db, external["account"], external["token"]): return OperationResult( message="Invalid external authentication state.") cursor.execute("""SELECT id, uid, email FROM externalusers WHERE provider=%s AND account=%s""", (external["provider"], external["account"])) # Note: the token validation above implicitly checks that there's a # matching row in the 'externalusers' table. external_user_id, existing_user_id, external_email = cursor.fetchone() # Check that we don't already have a Critic user associated with # this external user. if existing_user_id is not None: existing_user = dbutils.User.fromId(db, existing_user_id) return OperationResult( message=("There is already a Critic user ('%s') connected " "to the %s '%s'" % (existing_user.name, provider.getTitle(), external["account"]))) if email == external_email: verify_email_address = provider.configuration["verify_email_addresses"] # Reset 'email' column in 'externalusers': we only need it to detect # if the user changed the email address in the "Create user" form. # Also reset the 'token' column, which serves no further purpose # beyond this point. with db.updating_cursor("externalusers") as cursor: cursor.execute("""UPDATE externalusers SET email=NULL, token=NULL WHERE id=%s""", (external_user_id,)) email_verified = False if email and verify_email_address else None user = dbutils.User.create( db, username, fullname, email, email_verified, password, external_user_id=external_user_id) if email_verified is False: sendVerificationMail(db, user) user.sendUserCreatedMail("wsgi[registeruser]", external) auth.createSessionId(db, req, user) return OperationResult()