Exemplo n.º 1
0
def confirm_email():
    code = request.values["code"]
    user = None
    new_email = None

    try:
        user, new_email, old_email = model.user.confirm_user_email(code)
    except model.DataModelException as ex:
        return index("",
                     error_info=dict(reason="confirmerror",
                                     error_message=ex.message))

    if new_email:
        send_email_changed(user.username, old_email, new_email)
        change_email_future = user_analytics.change_email(old_email, new_email)
        change_email_future.add_done_callback(
            build_error_callback("Change email failed"))

    success, _ = common_login(user.uuid)
    if not success:
        return index("",
                     error_info=dict(reason="confirmerror",
                                     error_message="Could not perform login"))

    if model.user.has_user_prompts(user):
        return redirect(url_for("web.updateuser"))
    elif new_email:
        return redirect(
            url_for("web.user_view", path=user.username, tab="settings"))
    else:
        return redirect(url_for("web.index"))
Exemplo n.º 2
0
def test_common_login(username, expect_success, app):
  uuid = model.get_namespace_uuid(username)
  with app.app_context():
    success, headers = common_login(uuid)
    assert success == expect_success
    if success:
      assert QUAY_CSRF_UPDATED_HEADER_NAME in headers
Exemplo n.º 3
0
def conduct_signin(username_or_email, password, invite_code=None):
    needs_email_verification = False
    invalid_credentials = False

    (found_user, error_message) = authentication.verify_and_link_user(username_or_email, password)
    if found_user:
        # If there is an attached invitation code, handle it here. This will mark the
        # user as verified if the code is valid.
        if invite_code:
            handle_invite_code(invite_code, found_user)

        success, headers = common_login(found_user.uuid)
        if success:
            return {"success": True}, 200, headers
        else:
            needs_email_verification = True

    else:
        invalid_credentials = True

    return (
        {
            "needsEmailVerification": needs_email_verification,
            "invalidCredentials": invalid_credentials,
            "message": error_message,
        },
        403,
        None,
    )
Exemplo n.º 4
0
def _perform_login(user_obj, service_name):
    """ Attempts to login the given user, returning the Flask result of whether the login succeeded.
  """
    success, _ = common_login(user_obj.uuid)
    if success:
        if model.user.has_user_prompts(user_obj):
            return redirect(url_for("web.updateuser"))
        else:
            return redirect(url_for("web.index"))
    else:
        return _render_ologin_error(
            service_name, "Could not login. Account may be disabled")
Exemplo n.º 5
0
def confirm_recovery():
  code = request.values['code']
  user = model.user.validate_reset_code(code)

  if user is not None:
    success, _ = common_login(user.uuid)
    if not success:
      message = 'Could not perform login.'
      return render_page_template_with_routedata('message.html', message=message)

    return redirect(url_for('web.user_view', path=user.username, tab='settings', action='password'))
  else:
    message = 'Invalid recovery code: This code is invalid or may have already been used.'
    return render_page_template_with_routedata('message.html', message=message)
Exemplo n.º 6
0
    def post(self):
        """ Verifies the signed in the user with the specified credentials. """
        signin_data = request.get_json()
        password = signin_data["password"]

        username = get_authenticated_user().username
        (result, error_message) = authentication.confirm_existing_user(username, password)
        if not result:
            return {"message": error_message, "invalidCredentials": True,}, 403

        success, headers = common_login(result.uuid)
        if not success:
            return {"message": "Could not verify user.",}, 403

        return {"success": True}, 200, headers
Exemplo n.º 7
0
Arquivo: web.py Projeto: rrati/quay
def confirm_recovery():
    code = request.values["code"]
    user = model.user.validate_reset_code(code)

    if user is not None:
        success, _ = common_login(user.uuid)
        if not success:
            message = "Could not perform login."
            return render_page_template_with_routedata("message.html", message=message)

        return redirect(
            url_for("web.user_view", path=user.username, tab="settings", action="password")
        )
    else:
        message = "Invalid recovery code: This code is invalid or may have already been used."
        return render_page_template_with_routedata("message.html", message=message)
Exemplo n.º 8
0
def _perform_login(user_obj, service_name):
    """
    Attempts to login the given user, returning the Flask result of whether the login succeeded.
    """
    success, _ = common_login(user_obj.uuid)
    if success:
        if model.user.has_user_prompts(user_obj):
            return redirect(
                url_for("web.updateuser",
                        _scheme=app.config["PREFERRED_URL_SCHEME"],
                        _external=True))
        else:
            return redirect(
                url_for("web.index",
                        _scheme=app.config["PREFERRED_URL_SCHEME"],
                        _external=True))
    else:
        return _render_ologin_error(
            service_name, "Could not login. Account may be disabled")
Exemplo n.º 9
0
def user_initialize():
    """
    Create initial user in an empty database
    """

    # Ensure that we are using database auth.
    if not features.USER_INITIALIZE:
        response = jsonify({
            "message":
            "Cannot initialize user, FEATURE_USER_INITIALIZE is False"
        })
        response.status_code = 400
        return response

    # Ensure that we are using database auth.
    if app.config["AUTHENTICATION_TYPE"] != "Database":
        response = jsonify({
            "message":
            "Cannot initialize user in a non-database auth system"
        })
        response.status_code = 400
        return response

    if has_users():
        response = jsonify(
            {"message": "Cannot initialize user in a non-empty database"})
        response.status_code = 400
        return response

    user_data = request.get_json()
    try:
        prompts = model.user.get_default_user_prompts(features)
        new_user = model.user.create_user(
            user_data["username"],
            user_data["password"],
            user_data.get("email"),
            auto_verify=True,
            email_required=features.MAILING,
            is_possible_abuser=False,
            prompts=prompts,
        )
        success, headers = common_login(new_user.uuid)
        if not success:
            response = jsonify(
                {"message": "Could not login. Failed to initialize user"})
            response.status_code = 403
            return response

        result = {
            "username":
            user_data["username"],
            "email":
            user_data.get("email"),
            "encrypted_password":
            authentication.encrypt_user_password(
                user_data["password"]).decode("ascii"),
        }

        if user_data.get("access_token"):
            model.oauth.create_application(
                new_user,
                "automation",
                "",
                "",
                client_id=user_data["username"],
                description=
                "Application token generated via /api/v1/user/initialize",
            )
            scope = "org:admin repo:admin repo:create repo:read repo:write super:user user:admin user:read"
            created, access_token = model.oauth.create_user_access_token(
                new_user, user_data["username"], scope)
            result["access_token"] = access_token

        return (result, 200, headers)
    except model.user.DataModelException as ex:
        response = jsonify(
            {"message": "Failed to initialize user: " + str(ex)})
        response.status_code = 400
        return response
Exemplo n.º 10
0
    def post(self):
        """
        Create a new user.
        """
        if app.config["AUTHENTICATION_TYPE"] != "Database":
            abort(404)

        user_data = request.get_json()

        invite_code = user_data.get("invite_code", "")
        existing_user = model.user.get_nonrobot_user(user_data["username"])
        if existing_user:
            raise request_error(message="The username already exists")

        # Ensure an e-mail address was specified if required.
        if features.MAILING and not user_data.get("email"):
            raise request_error(message="Email address is required")

        # If invite-only user creation is turned on and no invite code was sent, return an error.
        # Technically, this is handled by the can_create_user call below as well, but it makes
        # a nicer error.
        if features.INVITE_ONLY_USER_CREATION and not invite_code:
            raise request_error(message="Cannot create non-invited user")

        # Ensure that this user can be created.
        blacklisted_domains = app.config.get("BLACKLISTED_EMAIL_DOMAINS", [])
        if not can_create_user(user_data.get("email"), blacklisted_domains=blacklisted_domains):
            raise request_error(
                message="Creation of a user account for this e-mail is disabled; please contact an administrator"
            )

        # If recaptcha is enabled, then verify the user is a human.
        if features.RECAPTCHA:
            recaptcha_response = user_data.get("recaptcha_response", "")
            result = recaptcha2.verify(
                app.config["RECAPTCHA_SECRET_KEY"], recaptcha_response, get_request_ip()
            )

            if not result["success"]:
                return {"message": "Are you a bot? If not, please revalidate the captcha."}, 400

        is_possible_abuser = ip_resolver.is_ip_possible_threat(get_request_ip())
        try:
            prompts = model.user.get_default_user_prompts(features)
            new_user = model.user.create_user(
                user_data["username"],
                user_data["password"],
                user_data.get("email"),
                auto_verify=not features.MAILING,
                email_required=features.MAILING,
                is_possible_abuser=is_possible_abuser,
                prompts=prompts,
            )

            email_address_confirmed = handle_invite_code(invite_code, new_user)
            if features.MAILING and not email_address_confirmed:
                confirmation_code = model.user.create_confirm_email_code(new_user)
                send_confirmation_email(new_user.username, new_user.email, confirmation_code)
                return {"awaiting_verification": True}
            else:
                success, headers = common_login(new_user.uuid)
                if not success:
                    return {"message": "Could not login. Is your account inactive?"}, 403

                return user_view(new_user), 200, headers
        except model.user.DataModelException as ex:
            raise request_error(exception=ex)
Exemplo n.º 11
0
    def put(self):
        """
        Update a users details such as password or email.
        """
        user = get_authenticated_user()
        user_data = request.get_json()
        previous_username = None
        headers = None

        try:
            if "password" in user_data:
                logger.debug("Changing password for user: %s", user.username)
                log_action("account_change_password", user.username)

                # Change the user's password.
                model.user.change_password(user, user_data["password"])

                # Login again to reset their session cookie.
                success, headers = common_login(user.uuid)
                if not success:
                    raise request_error(message="Could not perform login action")

                if features.MAILING:
                    send_password_changed(user.username, user.email)

            if "invoice_email" in user_data:
                logger.debug("Changing invoice_email for user: %s", user.username)
                model.user.change_send_invoice_email(user, user_data["invoice_email"])

            if features.CHANGE_TAG_EXPIRATION and "tag_expiration_s" in user_data:
                logger.debug("Changing user tag expiration to: %ss", user_data["tag_expiration_s"])
                model.user.change_user_tag_expiration(user, user_data["tag_expiration_s"])

            if (
                "invoice_email_address" in user_data
                and user_data["invoice_email_address"] != user.invoice_email_address
            ):
                model.user.change_invoice_email_address(user, user_data["invoice_email_address"])

            if "email" in user_data and user_data["email"] != user.email:
                new_email = user_data["email"]
                if model.user.find_user_by_email(new_email):
                    # Email already used.
                    raise request_error(message="E-mail address already used")

                if features.MAILING:
                    logger.debug(
                        "Sending email to change email address for user: %s", user.username
                    )
                    confirmation_code = model.user.create_confirm_email_code(
                        user, new_email=new_email
                    )
                    send_change_email(user.username, user_data["email"], confirmation_code)
                else:
                    model.user.update_email(user, new_email, auto_verify=not features.MAILING)

            if features.USER_METADATA:
                metadata = {}

                for field in ("given_name", "family_name", "company", "location"):
                    if field in user_data:
                        metadata[field] = user_data.get(field)

                if len(metadata) > 0:
                    model.user.update_user_metadata(user, metadata)

            # Check for username rename. A username can be renamed if the feature is enabled OR the user
            # currently has a confirm_username prompt.
            if "username" in user_data:
                confirm_username = model.user.has_user_prompt(user, "confirm_username")
                new_username = user_data.get("username")
                previous_username = user.username

                rename_allowed = features.USER_RENAME or (
                    confirm_username and features.USERNAME_CONFIRMATION
                )
                username_changing = new_username and new_username != previous_username

                if rename_allowed and username_changing:
                    if model.user.get_user_or_org(new_username) is not None:
                        # Username already used.
                        raise request_error(message="Username is already in use")

                    user = model.user.change_username(user.id, new_username)
                elif confirm_username:
                    model.user.remove_user_prompt(user, "confirm_username")

        except model.user.InvalidPasswordException as ex:
            raise request_error(exception=ex)

        return user_view(user, previous_username=previous_username), 200, headers
Exemplo n.º 12
0
    def put(self):
        """ Update a users details such as password or email. """
        user = get_authenticated_user()
        user_data = request.get_json()
        previous_username = None
        headers = None

        try:
            if 'password' in user_data:
                logger.debug('Changing password for user: %s', user.username)
                log_action('account_change_password', user.username)

                # Change the user's password.
                model.user.change_password(user, user_data['password'])

                # Login again to reset their session cookie.
                success, headers = common_login(user.uuid)
                if not success:
                    raise request_error(
                        message='Could not perform login action')

                if features.MAILING:
                    send_password_changed(user.username, user.email)

            if 'invoice_email' in user_data:
                logger.debug('Changing invoice_email for user: %s',
                             user.username)
                model.user.change_send_invoice_email(
                    user, user_data['invoice_email'])

            if features.CHANGE_TAG_EXPIRATION and 'tag_expiration_s' in user_data:
                logger.debug('Changing user tag expiration to: %ss',
                             user_data['tag_expiration_s'])
                model.user.change_user_tag_expiration(
                    user, user_data['tag_expiration_s'])

            if ('invoice_email_address' in user_data
                    and user_data['invoice_email_address'] !=
                    user.invoice_email_address):
                model.user.change_invoice_email_address(
                    user, user_data['invoice_email_address'])

            if 'email' in user_data and user_data['email'] != user.email:
                new_email = user_data['email']
                if model.user.find_user_by_email(new_email):
                    # Email already used.
                    raise request_error(message='E-mail address already used')

                if features.MAILING:
                    logger.debug(
                        'Sending email to change email address for user: %s',
                        user.username)
                    confirmation_code = model.user.create_confirm_email_code(
                        user, new_email=new_email)
                    send_change_email(user.username, user_data['email'],
                                      confirmation_code)
                else:
                    ua_future = user_analytics.change_email(
                        user.email, new_email)
                    ua_future.add_done_callback(
                        build_error_callback('Change email failed'))
                    model.user.update_email(user,
                                            new_email,
                                            auto_verify=not features.MAILING)

            if features.USER_METADATA:
                metadata = {}

                for field in ('given_name', 'family_name', 'company',
                              'location'):
                    if field in user_data:
                        metadata[field] = user_data.get(field)

                if len(metadata) > 0:
                    model.user.update_user_metadata(user, metadata)

                    ua_mdata_future = user_analytics.change_metadata(
                        user.email, **metadata)
                    ua_mdata_future.add_done_callback(
                        build_error_callback('Change metadata failed'))

            # Check for username rename. A username can be renamed if the feature is enabled OR the user
            # currently has a confirm_username prompt.
            if 'username' in user_data:
                confirm_username = model.user.has_user_prompt(
                    user, 'confirm_username')
                new_username = user_data.get('username')
                previous_username = user.username

                rename_allowed = (features.USER_RENAME
                                  or (confirm_username
                                      and features.USERNAME_CONFIRMATION))
                username_changing = new_username and new_username != previous_username

                if rename_allowed and username_changing:
                    if model.user.get_user_or_org(new_username) is not None:
                        # Username already used.
                        raise request_error(
                            message='Username is already in use')

                    user = model.user.change_username(user.id, new_username)
                    username_future = user_analytics.change_username(
                        user.email, new_username)
                    username_future.add_done_callback(
                        build_error_callback('Change username failed'))

                elif confirm_username:
                    model.user.remove_user_prompt(user, 'confirm_username')

        except model.user.InvalidPasswordException, ex:
            raise request_error(exception=ex)