Ejemplo n.º 1
0
    def delete(self, login):
        user_login_obj = UserLoginSchemaBase().load({"login": login})
        if user_login_obj.errors:
            return {"errors": user_login_obj.errors}, 400

        user = db.session.query(User).filter(User.login == login, User.pending == true()).first()
        if not user:
            raise NotFound("User doesn't exist or is already rejected")
        group = db.session.query(Group).filter(Group.name == login).first()
        user.groups.remove(group)
        db.session.delete(group)
        db.session.delete(user)
        db.session.commit()

        try:
            send_email_notification("rejection",
                                    "Malwarecage account request has been rejected",
                                    user.email,
                                    base_url=app_config.malwarecage.base_url,
                                    login=user.login,
                                    set_password_token=user.generate_set_password_token().decode("utf-8"))
        except MailError:
            logger.exception("Can't send e-mail notification")
            raise InternalServerError("SMTP server needed to fulfill this request is not configured or unavailable.")

        logger.info('User rejected', extra={'user': login})
        schema = UserSuccessSchema()
        return schema.dump({"login": login})
Ejemplo n.º 2
0
    def post(self, login):
        user_login_obj = UserLoginSchemaBase().load({"login": login})
        if user_login_obj.errors:
            return {"errors": user_login_obj.errors}, 400

        user = db.session.query(User).filter(User.login == login, User.pending == true()).first()
        user.pending = False
        user.registered_on = datetime.datetime.now()
        user.registered_by = g.auth_user.id
        db.session.add(user)

        try:
            send_email_notification("register",
                                    "New account registered in Malwarecage",
                                    user.email,
                                    base_url=app_config.malwarecage.base_url,
                                    login=user.login,
                                    set_password_token=user.generate_set_password_token().decode("utf-8"))
        except MailError:
            logger.exception("Can't send e-mail notification")
            raise InternalServerError("SMTP server needed to fulfill this request is not configured or unavailable.")

        db.session.commit()

        logger.info('User accepted', extra={'user': user.login})
        schema = UserSuccessSchema()
        return schema.dump({"login": user.login})
Ejemplo n.º 3
0
    def post(self):
        """
        ---
        summary: Get password change link for the current user
        description: |
            Requests password change link for currently authenticated user.

            Link expires after setting a new password or after 14 days.

            Link is sent to the e-mail address set in user's profile.
        security:
            - bearerAuth: []
        tags:
            - auth
        responses:
            200:
              description: When password change link was successfully sent to the user's e-mail
              content:
                application/json:
                  schema: UserSuccessSchema
            500:
              description: When SMTP server is unavailable or not properly configured on the server.
        """
        login = g.auth_user.login
        email = g.auth_user.email

        try:
            send_email_notification(
                "recover",
                "Change password in Malwarecage",
                email,
                base_url=app_config.malwarecage.base_url,
                login=login,
                set_password_token=g.auth_user.generate_set_password_token(
                ).decode("utf-8"))
        except MailError:
            logger.exception("Can't send e-mail notification")
            raise InternalServerError(
                "SMTP server needed to fulfill this request is"
                " not configured or unavailable.")

        schema = UserSuccessSchema()
        logger.info('request change password', extra={'user': login})
        return schema.dump({"login": login})
Ejemplo n.º 4
0
    def post(self, login):
        schema = UserProfileManageInfoSchema()

        obj = schema.loads(request.get_data(as_text=True))
        if obj.errors:
            return {"errors": obj.errors}, 400

        user_login_obj = UserLoginSchemaBase().load({"login": login})
        if user_login_obj.errors:
            return {"errors": user_login_obj.errors}, 400

        if db.session.query(exists().where(User.login == login)).scalar():
            raise Conflict("User exists yet")

        if db.session.query(exists().where(Group.name == login)).scalar():
            raise Conflict("Group exists yet")

        user = User()
        user.login = login
        user.email = obj.data.get("email")
        user.additional_info = obj.data.get("additional_info")
        user.feed_quality = obj.data.get("feed_quality")
        user.disabled = False
        user.pending = False
        user.registered_by = g.auth_user.id
        user.registered_on = datetime.datetime.now()
        user.groups.append(Group.public_group())
        user.reset_sessions()
        db.session.add(user)

        group = Group()
        group.name = login
        group.private = True
        group.users.append(user)
        db.session.add(group)

        if obj.data.get("send_email", False):
            try:
                send_email_notification("register",
                                        "New account registered in Malwarecage",
                                        user.email,
                                        base_url=app_config.malwarecage.base_url,
                                        login=user.login,
                                        set_password_token=user.generate_set_password_token().decode("utf-8"))
            except MailError:
                logger.exception("Can't send e-mail notification")
                raise InternalServerError("SMTP server needed to fulfill this request is"
                                          " not configured or unavailable.")

        db.session.commit()

        logger.info('User created', extra={'user': user.login})
        schema = UserSuccessSchema()
        return schema.dump({"login": user.login})
Ejemplo n.º 5
0
    def post(self):
        """
        ---
        summary: Set a new password for user
        description: Sets a new password for user using password change token.
        tags:
            - auth
        requestBody:
            description: |
                User set password token and new password.

                Password must be longer than 8 chars.
            content:
              application/json:
                schema: UserSetPasswordSchema
        responses:
            200:
              description: User login on successful password set
              content:
                application/json:
                  schema: UserSuccessSchema
            400:
                description: When request body is invalid or provided password doesn't match the policy
            403:
                description: When set password token is no longer valid
        """
        MIN_PASSWORD_LENGTH = 8
        MAX_PASSWORD_LENGTH = 72  #UTF-8 bytes
        schema = UserSetPasswordSchema()
        obj = schema.loads(request.get_data(as_text=True))
        if obj.errors:
            return {"errors": obj.errors}, 400
        user = User.verify_set_password_token(obj.data.get("token"))
        if user is None:
            raise Forbidden("Set password token expired")
        password = obj.data.get("password")
        if password == "":
            raise BadRequest("Empty password is not allowed")
        if len(password) < MIN_PASSWORD_LENGTH:
            raise BadRequest("Password is too short")
        if len(password.encode()) > MAX_PASSWORD_LENGTH:
            raise BadRequest(
                "The password should contain no more than 72 bytes of UTF-8 characters, your password is too long."
            )

        user.set_password(password)
        db.session.add(user)
        db.session.commit()
        schema = UserSuccessSchema()
        logger.info('change password', extra={'user': user.login})
        return schema.dump({"login": user.login})
Ejemplo n.º 6
0
    def post(self):
        """
        ---
        description: Generates new token for session continuation
        security:
            - bearerAuth: []
        tags:
            - auth
        responses:
            200:
              description: Regenerated authorization token with information about user capabilities
              content:
                application/json:
                  schema: UserLoginSuccessSchema
        """
        login = g.auth_user.login
        email = g.auth_user.email

        try:
            send_email_notification(
                "recover",
                "Change password in Malwarecage",
                email,
                base_url=app_config.malwarecage.base_url,
                login=login,
                set_password_token=g.auth_user.generate_set_password_token(
                ).decode("utf-8"))
        except MailError:
            logger.exception("Can't send e-mail notification")
            raise InternalServerError(
                "SMTP server needed to fulfill this request is"
                " not configured or unavailable.")

        schema = UserSuccessSchema()
        logger.info('request change password', extra={'user': login})
        return schema.dump({"login": login})
Ejemplo n.º 7
0
    def put(self, login):
        schema = UserProfileManageInfoSchema()

        obj = schema.loads(request.get_data(as_text=True))
        if obj.errors:
            return {"errors": obj.errors}, 400

        user_login_obj = UserLoginSchemaBase().load({"login": login})
        if user_login_obj.errors:
            return {"errors": user_login_obj.errors}, 400

        user = db.session.query(User).filter(User.login == login).first()
        if user is None:
            raise NotFound("No such user")

        if user.pending:
            raise Forbidden("User is pending and need to be accepted first")

        email = obj.data.get("email")
        if email is not None:
            user.email = email

        additional_info = obj.data.get("additional_info")
        if additional_info is not None:
            user.additional_info = additional_info

        feed_quality = obj.data.get("feed_quality")
        if feed_quality is not None:
            user.feed_quality = feed_quality

        disabled = obj.data.get("disabled")
        if disabled is not None:
            user.disabled = disabled
            user.reset_sessions()

        db.session.add(user)
        db.session.commit()
        logger.info('user updated', extra=obj.data)

        schema = UserSuccessSchema()
        return schema.dump({"login": login})
Ejemplo n.º 8
0
    def post(self):
        """
        ---
        description: Set password via authorization token
        tags:
            - auth
        requestBody:
            description: User auth token and new password
            content:
              application/json:
                schema: UserSetPasswordSchema
        responses:
            200:
              description: User login on successful password set
              content:
                application/json:
                  schema: UserSuccessSchema
        """
        MIN_PASSWORD_LENGTH = 8
        schema = UserSetPasswordSchema()
        obj = schema.loads(request.get_data(as_text=True))
        if obj.errors:
            return {"errors": obj.errors}, 400
        user = User.verify_set_password_token(obj.data.get("token"))
        if user is None:
            raise Forbidden("Set password token expired")
        password = obj.data.get("password")
        if password == "":
            raise BadRequest("Empty password is not allowed")
        if len(password) < MIN_PASSWORD_LENGTH:
            raise BadRequest("Password is too short")

        user.set_password(password)
        db.session.add(user)
        db.session.commit()
        schema = UserSuccessSchema()
        logger.info('change password', extra={'user': user.login})
        return schema.dump({"login": user.login})
Ejemplo n.º 9
0
    def post(self):
        """
        ---
        description: Request new user account
        tags:
            - auth
        requestBody:
            description: User basic information
            content:
              application/json:
                schema: UserRegisterSchema
        responses:
            200:
                description: User login on successful registration
                content:
                  application/json:
                    schema: UserSuccessSchema
        """
        if not app_config.malwarecage.enable_registration:
            raise Forbidden("User registration is not enabled.")

        schema = UserRegisterSchema()
        obj = schema.loads(request.get_data(as_text=True))

        if obj.errors:
            return {"errors": obj.errors}, 400

        login = obj.data.get("login")

        if db.session.query(exists().where(User.login == login)).scalar():
            raise Conflict("Name already exists")

        if db.session.query(exists().where(Group.name == login)).scalar():
            raise Conflict("Name already exists")

        recaptcha_secret = app_config.malwarecage.recaptcha_secret

        if recaptcha_secret:
            try:
                recaptcha_token = obj.data.get("recaptcha")
                recaptcha_response = requests.post(
                    'https://www.google.com/recaptcha/api/siteverify',
                    data={
                        'secret': recaptcha_secret,
                        'response': recaptcha_token
                    })
                recaptcha_response.raise_for_status()
            except Exception as e:
                logger.exception("Temporary problem with ReCAPTCHA.")
                raise InternalServerError(
                    "Temporary problem with ReCAPTCHA.") from e

            if not recaptcha_response.json().get('success'):
                raise Forbidden("Wrong ReCAPTCHA, please try again.")

        user = User()
        user.login = login
        user.email = obj.data.get("email")
        user.additional_info = obj.data.get("additional_info")
        user.pending = True
        user.disabled = False
        user.requested_on = datetime.datetime.now()
        user.groups.append(Group.public_group())
        user.reset_sessions()
        db.session.add(user)

        group = Group()
        group.name = login
        group.private = True
        group.users.append(user)
        db.session.add(group)
        db.session.commit()

        try:
            send_email_notification("pending",
                                    "Pending registration in Malwarecage",
                                    user.email,
                                    base_url=app_config.malwarecage.base_url,
                                    login=user.login)
        except MailError:
            logger.exception("Can't send e-mail notification")

        logger.info('User registered', extra={'user': user.login})
        schema = UserSuccessSchema()
        return schema.dump({"login": user.login})
Ejemplo n.º 10
0
    def post(self, login):
        """
        ---
        summary: Accept a pending registration
        description: |
            Accepts pending user registration.

            Requires `manage_users` capability.
        security:
            - bearerAuth: []
        tags:
            - user
        parameters:
            - in: path
              name: login
              schema:
                type: string
              description: Login of pending account
        responses:
            200:
                description: When user is successfully accepted
                content:
                  application/json:
                    schema: UserSuccessSchema
            400:
                description: When invalid login is provided.
            403:
                description: When user doesn't have `manage_users` capability.
            500:
                description: When SMTP server is unavailable or not properly configured on the server.
        """
        user_login_obj = UserLoginSchemaBase().load({"login": login})
        if user_login_obj.errors:
            return {"errors": user_login_obj.errors}, 400

        user = db.session.query(User).filter(User.login == login,
                                             User.pending == true()).first()
        user.pending = False
        user.registered_on = datetime.datetime.now()
        user.registered_by = g.auth_user.id
        db.session.add(user)

        try:
            send_email_notification(
                "register",
                "New account registered in Malwarecage",
                user.email,
                base_url=app_config.malwarecage.base_url,
                login=user.login,
                set_password_token=user.generate_set_password_token().decode(
                    "utf-8"))
        except MailError:
            logger.exception("Can't send e-mail notification")
            raise InternalServerError(
                "SMTP server needed to fulfill this request is not configured or unavailable."
            )

        db.session.commit()

        logger.info('User accepted', extra={'user': user.login})
        schema = UserSuccessSchema()
        return schema.dump({"login": user.login})
Ejemplo n.º 11
0
    def put(self, login):
        """
        ---
        summary: Update existing user
        description: |
            Updates existing user account.

            Requires `manage_users` capability.
        security:
            - bearerAuth: []
        tags:
            - user
        parameters:
            - in: path
              name: login
              schema:
                type: string
              description: User login
        requestBody:
            description: User information
            content:
              application/json:
                schema: UserProfileManageInfoSchema
        responses:
            200:
                description: When user was updated successfully
                content:
                  application/json:
                    schema: UserSuccessSchema
            400:
                description: When request body is invalid
            403:
                description: When user doesn't have `manage_users` capability or modified user is pending.
            404:
                description: When user doesn't exist.
        """
        schema = UserProfileManageInfoSchema()

        obj = schema.loads(request.get_data(as_text=True))
        if obj.errors:
            return {"errors": obj.errors}, 400

        user_login_obj = UserLoginSchemaBase().load({"login": login})
        if user_login_obj.errors:
            return {"errors": user_login_obj.errors}, 400

        user = db.session.query(User).filter(User.login == login).first()
        if user is None:
            raise NotFound("No such user")

        if user.pending:
            raise Forbidden("User is pending and need to be accepted first")

        email = obj.data.get("email")
        if email is not None:
            user.email = email

        additional_info = obj.data.get("additional_info")
        if additional_info is not None:
            user.additional_info = additional_info

        feed_quality = obj.data.get("feed_quality")
        if feed_quality is not None:
            user.feed_quality = feed_quality

        disabled = obj.data.get("disabled")
        if disabled is not None:
            user.disabled = disabled
            user.reset_sessions()

        db.session.add(user)
        db.session.commit()
        logger.info('user updated', extra=obj.data)

        schema = UserSuccessSchema()
        return schema.dump({"login": login})
Ejemplo n.º 12
0
    def post(self, login):
        """
        ---
        summary: Create a new user
        description: |
            Creates new user account

            Requires `manage_users` capability.
        security:
            - bearerAuth: []
        tags:
            - user
        parameters:
            - in: path
              name: login
              schema:
                type: string
              description: New user login
        requestBody:
            description: User information
            content:
              application/json:
                schema: UserProfileManageInfoSchema
        responses:
            200:
                description: When user was created successfully
                content:
                  application/json:
                    schema: UserSuccessSchema
            400:
                description: When request body is invalid
            403:
                description: When user doesn't have `manage_users` capability.
            409:
                description: When user or group with provided name already exists.
            500:
                description: When SMTP server is unavailable or not properly configured on the server.
        """
        schema = UserProfileManageInfoSchema()

        obj = schema.loads(request.get_data(as_text=True))
        if obj.errors:
            return {"errors": obj.errors}, 400

        user_login_obj = UserLoginSchemaBase().load({"login": login})
        if user_login_obj.errors:
            return {"errors": user_login_obj.errors}, 400

        if db.session.query(exists().where(User.login == login)).scalar():
            raise Conflict("User exists yet")

        if db.session.query(exists().where(Group.name == login)).scalar():
            raise Conflict("Group exists yet")

        user = User()
        user.login = login
        user.email = obj.data.get("email")
        user.additional_info = obj.data.get("additional_info")
        user.feed_quality = obj.data.get("feed_quality")
        user.disabled = False
        user.pending = False
        user.registered_by = g.auth_user.id
        user.registered_on = datetime.datetime.now()
        user.groups.append(Group.public_group())
        user.reset_sessions()
        db.session.add(user)

        group = Group()
        group.name = login
        group.private = True
        group.users.append(user)
        db.session.add(group)

        if obj.data.get("send_email", False):
            try:
                send_email_notification(
                    "register",
                    "New account registered in Malwarecage",
                    user.email,
                    base_url=app_config.malwarecage.base_url,
                    login=user.login,
                    set_password_token=user.generate_set_password_token(
                    ).decode("utf-8"))
            except MailError:
                logger.exception("Can't send e-mail notification")
                raise InternalServerError(
                    "SMTP server needed to fulfill this request is"
                    " not configured or unavailable.")

        db.session.commit()

        logger.info('User created', extra={'user': user.login})
        schema = UserSuccessSchema()
        return schema.dump({"login": user.login})
Ejemplo n.º 13
0
    def delete(self, login):
        """
        ---
        summary: Reject a pending registration
        description: |
            Rejects pending user registration.

            Requires `manage_users` capability.
        security:
            - bearerAuth: []
        tags:
            - user
        parameters:
            - in: path
              name: login
              schema:
                type: string
              description: Login of pending account
        responses:
            200:
                description: When user is successfully rejected
                content:
                  application/json:
                    schema: UserSuccessSchema
            400:
                description: When invalid login is provided.
            403:
                description: When user doesn't have `manage_users` capability.
            404:
                description: When user doesn't exist or is already accepted/rejected.
            500:
                description: When SMTP server is unavailable or not properly configured on the server.
        """
        user_login_obj = UserLoginSchemaBase().load({"login": login})
        if user_login_obj.errors:
            return {"errors": user_login_obj.errors}, 400

        user = db.session.query(User).filter(User.login == login,
                                             User.pending == true()).first()
        if not user:
            raise NotFound("User doesn't exist or is already rejected")
        group = db.session.query(Group).filter(Group.name == login).first()
        user.groups.remove(group)
        db.session.delete(group)
        db.session.delete(user)
        db.session.commit()

        try:
            send_email_notification(
                "rejection",
                "Malwarecage account request has been rejected",
                user.email,
                base_url=app_config.malwarecage.base_url,
                login=user.login,
                set_password_token=user.generate_set_password_token().decode(
                    "utf-8"))
        except MailError:
            logger.exception("Can't send e-mail notification")
            raise InternalServerError(
                "SMTP server needed to fulfill this request is not configured or unavailable."
            )

        logger.info('User rejected', extra={'user': login})
        schema = UserSuccessSchema()
        return schema.dump({"login": login})