Esempio n. 1
0
        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")
Esempio n. 2
0
    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()
Esempio n. 3
0
    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()