Example #1
0
def adduser(argv):
    import auth

    parser = argparse.ArgumentParser(
        description="Critic administration interface: adduser",
        prog="criticctl [options] adduser")

    parser.add_argument("--name", help="user name")
    parser.add_argument("--email", "-e", help="email address")
    parser.add_argument("--fullname", "-f", help="full name")
    parser.add_argument("--password", "-p", help="password")

    arguments = parser.parse_args(argv)

    name = use_argument_or_ask(arguments.name, "Username:"******"Full name:")
    email = use_argument_or_ask(arguments.email, "Email address:")

    if arguments.password is None:
        password = inpututils.password("Password:"******"%s: user added" % name
Example #2
0
    def process(self, db, user, user_id, new_pw, current_pw=None):
        import auth

        if (user.id != user_id or current_pw is None) and not user.hasRole(db, "administrator"):
            raise OperationFailure(code="notallowed",
                                   title="Not allowed!",
                                   message="Operation not permitted.")

        subject = dbutils.User.fromId(db, user_id)

        if current_pw is not None:
            try: auth.checkPassword(db, subject.name, current_pw)
            except auth.WrongPassword:
                raise OperationFailure(code="wrongpassword",
                                       title="Wrong password!",
                                       message="The provided current password is not correct.")

        if not new_pw:
            raise OperationFailure(code="emptypassword",
                                   title="Empty password!",
                                   message="Setting an empty password is not allowed.")

        cursor = db.cursor()
        cursor.execute("UPDATE users SET password=%s WHERE id=%s", (auth.hashPassword(new_pw), user_id))

        db.commit()

        return OperationResult()
Example #3
0
    def process(self, db, user, new_pw, subject=None, current_pw=None):
        import auth

        if subject is None:
            user_id = user.id
        elif isinstance(subject, basestring):
            user_id = dbutils.User.fromName(db, subject).id
        else:
            user_id = subject

        if user.id != user_id or current_pw is None:
            Operation.requireRole(db, "administrator", user)

        subject = dbutils.User.fromId(db, user_id)

        if current_pw is not None:
            try: auth.checkPassword(db, subject.name, current_pw)
            except auth.WrongPassword:
                raise OperationFailure(code="wrongpassword",
                                       title="Wrong password!",
                                       message="The provided current password is not correct.")

        if not new_pw:
            raise OperationFailure(code="emptypassword",
                                   title="Empty password!",
                                   message="Setting an empty password is not allowed.")

        cursor = db.cursor()
        cursor.execute("UPDATE users SET password=%s WHERE id=%s", (auth.hashPassword(new_pw), user_id))

        db.commit()

        return OperationResult()
Example #4
0
    def process(self, db, user, user_id, new_pw, current_pw=None):
        import auth

        if (user.id != user_id or current_pw is None) and not user.hasRole(db, "administrator"):
            raise OperationFailure(code="notallowed",
                                   title="Not allowed!",
                                   message="Operation not permitted.")

        subject = dbutils.User.fromId(db, user_id)

        if current_pw is not None:
            try: auth.checkPassword(db, subject.name, current_pw)
            except auth.WrongPassword:
                raise OperationFailure(code="wrongpassword",
                                       title="Wrong password!",
                                       message="The provided current password is not correct.")

        if not new_pw:
            raise OperationFailure(code="emptypassword",
                                   title="Empty password!",
                                   message="Setting an empty password is not allowed.")

        cursor = db.cursor()
        cursor.execute("UPDATE users SET password=%s WHERE id=%s", (auth.hashPassword(new_pw), user_id))

        db.commit()

        return OperationResult()
Example #5
0
def adduser(argv):
    class NoEmail:
        pass

    class NoPassword:
        pass

    parser = argparse.ArgumentParser(
        description="Critic administration interface: adduser",
        prog="criticctl [options] adduser")

    parser.add_argument("--name", help="user name")
    parser.add_argument("--email", "-e", help="email address")
    parser.add_argument("--no-email",
                        dest="email",
                        action="store_const",
                        const=NoEmail,
                        help="create user without email address")
    parser.add_argument("--fullname", "-f", help="full name")
    parser.add_argument("--password", "-p", help="password")
    parser.add_argument("--no-password",
                        dest="password",
                        action="store_const",
                        const=NoPassword,
                        help="create user without password")

    arguments = parser.parse_args(argv)

    name = use_argument_or_ask(arguments.name, "Username:"******"Full name:")

    if arguments.email is NoEmail:
        email = None
    else:
        email = use_argument_or_ask(arguments.email, "Email address:")
        if not email.strip():
            email = None

    if arguments.password is NoPassword:
        hashed_password = None
    else:
        if arguments.password is None:
            password = inpututils.password("Password:"******"%s: user added" % name
Example #6
0
def adduser(argv):
    class NoEmail:
        pass
    class NoPassword:
        pass

    parser = argparse.ArgumentParser(
        description="Critic administration interface: adduser",
        prog="criticctl [options] adduser")

    parser.add_argument("--name", help="user name")
    parser.add_argument("--email", "-e", help="email address")
    parser.add_argument("--no-email", dest="email", action="store_const",
                        const=NoEmail, help="create user without email address")
    parser.add_argument("--fullname", "-f", help="full name")
    parser.add_argument("--password", "-p", help="password")
    parser.add_argument("--no-password", dest="password", action="store_const",
                        const=NoPassword, help="create user without password")

    arguments = parser.parse_args(argv)

    name = use_argument_or_ask(arguments.name, "Username:"******"Full name:")

    if arguments.email is NoEmail:
        email = None
    else:
        email = use_argument_or_ask(arguments.email, "Email address:")
        if not email.strip():
            email = None

    if arguments.password is NoPassword:
        hashed_password = None
    else:
        if arguments.password is None:
            password = inpututils.password("Password:"******"%s: user added" % name
Example #7
0
def install(data):
    global password

    import psycopg2

    def adapt(value):
        return psycopg2.extensions.adapt(value).getquoted()

    if password is not None:
        try:
            import auth
        except ImportError:
            password = installation.process.check_input(
                [sys.executable, "-c",
                 "import sys, auth; sys.stdout.write(auth.hashPassword(sys.stdin.read()))"],
                stdin=password, stdout=subprocess.PIPE,
                env={ "PYTHONPATH": ":".join([os.path.join(installation.paths.etc_dir, "main"),
                                              installation.paths.install_dir]) })
        else:
            password = auth.hashPassword(password)

    installation.process.check_input(
        ["su", "-s", "/bin/sh", "-c", "psql -q -v ON_ERROR_STOP=1 -f -", installation.system.username],
        stdin=("""INSERT INTO users (name, email, password, fullname, status)
                       VALUES (%s, %s, %s, %s, 'current');"""
               % (adapt(username),
                  adapt(email),
                  adapt(password),
                  adapt(fullname))))

    for role in ["administrator", "repositories", "newswriter"]:
        installation.process.check_input(
            ["su", "-s", "/bin/sh", "-c", "psql -q -v ON_ERROR_STOP=1 -f -", installation.system.username],
            stdin=("""INSERT INTO userroles (uid, role)
                           SELECT id, %s
                             FROM users
                            WHERE name=%s;"""
                   % (adapt(role), adapt(username))))

    return True
Example #8
0
def passwd(argv):
    parser = argparse.ArgumentParser(
        description="Critic administration interface: passwd",
        prog="criticctl [options] passwd")

    class NoPassword:
        pass

    parser.add_argument("--name", help="user name")
    parser.add_argument("--password", help="password")
    parser.add_argument("--no-password",
                        dest="password",
                        action="store_const",
                        const=NoPassword,
                        help="delete the user's password")

    arguments = parser.parse_args(argv)

    name = use_argument_or_ask(arguments.name, "Username:"******"Password:"******"""UPDATE users
                         SET password=%s
                       WHERE name=%s""", (hashed_password, name))

    db.commit()

    if hashed_password:
        print "%s: password changed" % name
    else:
        print "%s: password deleted" % name
Example #9
0
    def changePassword(self, db, user, current_pw, new_pw):
        # If |current_pw| is True, then this is an administrator changing
        # another user's password. The usual rules do not apply.
        if current_pw is not True:
            cursor = db.readonly_cursor()
            cursor.execute("SELECT password FROM users WHERE id=%s", (user.id,))

            hashed_pw, = cursor.fetchone()

            if current_pw is not None:
                auth.checkPassword(db, user.name, current_pw)
            elif hashed_pw is not None:
                # This is mostly a sanity check; the only way to trigger this is
                # if the user has no password when he loads /home, sets a
                # password in another tab or using another browser, and then
                # tries to set (rather than change) the password using the old
                # stale /home.
                raise auth.WrongPassword

        with db.updating_cursor("users") as cursor:
            cursor.execute("UPDATE users SET password=%s WHERE id=%s",
                           (auth.hashPassword(new_pw), user.id))
Example #10
0
    def process(self, db, user, new_pw, subject=None, current_pw=None):
        if subject is None:
            subject = user

        cursor = db.cursor()

        if user != subject:
            Operation.requireRole(db, "administrator", user)
        elif current_pw is None:
            cursor.execute("SELECT password FROM users WHERE id=%s", (subject.id,))
            if cursor.fetchone()[0] is not None:
                # This is mostly a sanity check; the only way to trigger this is
                # if the user has no password when he loads /home, sets a
                # password in another tab or using another browser, and then
                # tries to set (rather than change) the password using the old
                # stale /home.
                raise OperationFailure(code="wrongpassword",
                                       title="Wrong password!",
                                       message="No current password provided.")

        if current_pw is not None:
            try: auth.checkPassword(db, subject.name, current_pw)
            except auth.WrongPassword:
                raise OperationFailure(code="wrongpassword",
                                       title="Wrong password!",
                                       message="The provided current password is not correct.")

        if not new_pw:
            raise OperationFailure(code="emptypassword",
                                   title="Empty password!",
                                   message="Setting an empty password is not allowed.")

        cursor.execute("UPDATE users SET password=%s WHERE id=%s",
                       (auth.hashPassword(new_pw), subject.id))

        db.commit()

        return OperationResult()
Example #11
0
def passwd(argv):
    parser = argparse.ArgumentParser(
        description="Critic administration interface: passwd",
        prog="criticctl [options] passwd")

    class NoPassword:
        pass

    parser.add_argument("--name", help="user name")
    parser.add_argument("--password", help="password")
    parser.add_argument("--no-password", dest="password", action="store_const",
                        const=NoPassword, help="delete the user's password")

    arguments = parser.parse_args(argv)

    name = use_argument_or_ask(arguments.name, "Username:"******"Password:"******"""UPDATE users
                         SET password=%s
                       WHERE name=%s""",
                   (hashed_password, name))

    db.commit()

    if hashed_password:
        print "%s: password changed" % name
    else:
        print "%s: password deleted" % name
Example #12
0
        db = dbutils.Database()
        db.cursor().execute(
            """INSERT INTO systemidentities (key, name, anonymous_scheme,
                                                             authenticated_scheme, hostname,
                                                             description, installed_sha1)
                                    VALUES ('main', 'main', 'http', 'http', 'localhost', 'Main', ?)""",
            (subprocess.check_output("git rev-parse HEAD",
                                     shell=True).strip(), ))

        admin = dbutils.User.create(db,
                                    name=arguments.admin_username,
                                    fullname=arguments.admin_fullname,
                                    email=arguments.admin_email,
                                    email_verified=None,
                                    password=auth.hashPassword(
                                        arguments.admin_password))

        if not arguments.testing:
            if not quiet:
                print

            print("Created administrator user %r with password '1234'" %
                  data["installation.admin.username"])

        db.cursor().execute(
            """INSERT INTO userroles (uid, role)
                                    SELECT %s, name
                                      FROM roles""", (admin.id, ))

        db.commit()
        db.close()
Example #13
0
        import auth

        db = dbutils.Database()
        db.cursor().execute("""INSERT INTO systemidentities (key, name, anonymous_scheme,
                                                             authenticated_scheme, hostname,
                                                             description, installed_sha1)
                                    VALUES ('main', 'main', 'http', 'http', 'localhost', 'Main', ?)""",
                            (subprocess.check_output("git rev-parse HEAD", shell=True).strip(),))

        admin = dbutils.User.create(
            db,
            name=arguments.admin_username,
            fullname=arguments.admin_fullname,
            email=arguments.admin_email,
            email_verified=None,
            password=auth.hashPassword(arguments.admin_password))

        if not arguments.testing:
            if not quiet:
                print

            print ("Created administrator user %r with password '1234'"
                   % data["installation.admin.username"])

        db.cursor().execute("""INSERT INTO userroles (uid, role)
                                    SELECT %s, name
                                      FROM roles""",
                            (admin.id,))

        db.commit()
        db.close()
Example #14
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()
Example #15
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()