示例#1
0
    def post(self):

        # Find user trying to save article
        user = User.find_by_uuid(get_jwt_identity())

        # Check if article is valid
        try:
            article = self.create_article_schema.load(request.form.to_dict())
        except ValidationError as err:
            error_response = self.error_schema.dump(
                ErrorResponse(details=err.messages, error='validation errors'))
            log.info(
                f'Validation errors during article creation: {error_response}')
            return error_response, 400

        # Try to save images to AWS
        saved_images = upload_request_files(request.files)
        article.images = saved_images

        # Add user to article
        article.user = user

        # Save article
        article.commit()

        # Send notification that there is new article
        users_to_notify = User.find_with_mail_notifications_enabled()
        send_notification_mail([user.email for user in users_to_notify],
                               article.title, article.uuid)

        # Return article model
        return self.article_schema.dump(article), 201
示例#2
0
    def make_user(self, data, **kwargs):
        if not data['password']:
            raise ValidationError('Please provide password')

        password = data['password']
        del data['password']
        user = User(**data)
        user.set_password(password)

        return user
示例#3
0
    def seed_application_users(self):
        try:
            admin_role = Role(
                role_type=RoleTypes.ADMIN,
                description="Admin role for belisce dev agency platform")
            admin_role.commit()

            client_role = Role(
                role_type=RoleTypes.CLIENT,
                description="Client role for belisce dev agency platform")
            client_role.commit()

            # Define application users
            admin_user = User(
                # TODO load from config
                email="*****@*****.**",
                confirmed=True,
                confirmed_date=datetime.utcnow())

            admin_user.set_password('password')
            admin_user.add_to_role(RoleTypes.ADMIN)
            admin_user.commit()

        except IntegrityError:
            log.info('Data is already present in database')
            pass
示例#4
0
    def get(self, uuid):
        # Try to find user
        try:
            uuid = UUID(uuid)
        except ValueError:
            return self.incorrect_uuid(uuid), 404

        user = User.find_by_uuid(uuid)

        # If user is requesting details for another user
        user_claims = self.user_claims_schema.load(get_jwt_claims())
        if user_claims.is_client() and user.uuid != UUID(get_jwt_identity()):
            error_schema = ErrorResponseSchema()
            error_response = error_schema.dump(
                ErrorResponse(
                    details={'uuid': f'Access to that resource is forbidden'},
                    error='User not found'))
            log.info(f'User not found: {error_response}')
            return error_response, 403

        # If there is no user with given id
        if not user:
            error_schema = ErrorResponseSchema()
            error_response = error_schema.dump(
                ErrorResponse(
                    details={'uuid': f'User with {uuid} uuid does not exist'},
                    error='User not found'))
            log.info(f'User not found: {error_response}')
            return error_response, 404

        # Return user
        return self.user_schema.dump(user), 200
示例#5
0
def test_user_login_incorrect(app):
    # Given
    user = User(email='*****@*****.**', name='test user')
    user.add_to_role(RoleTypes.CLIENT)
    user.set_password('password')
    user.confirm_account()
    user.commit()

    login_info = {'email': '*****@*****.**', 'password': '******'}

    # When
    response = app.test_client().post('/api/auth/login',
                                      data=dumps(login_info),
                                      content_type='application/json')
    response_body = loads(response.data)

    # Then
    assert response.status_code == 400
    assert response_body['error'] == 'wrong password'
示例#6
0
def test_user_delete(app, admin_access_token_header, client_user):
    # Given
    # Clinet user

    # When
    response = app.test_client().delete(f'/api/user/{client_user.uuid}',
                                        headers=admin_access_token_header)

    # Then
    assert response.status_code == 204
    assert not User.find_by_email('*****@*****.**')
def test_database_seeder_inserts_admin(app):
    # Given
    # seeded_database

    # When
    user = User.find_by_email('*****@*****.**')

    # Then
    assert user
    assert user.email == '*****@*****.**'
    assert any(role for role in user.roles
               if role.role_type == RoleTypes.ADMIN)
示例#8
0
    def post(self):
        # Serialize login model
        try:
            login_dto = self.login_schema.load(api.payload)
        except ValidationError as err:
            error_response = self.error_schema.dump(
                ErrorResponse(details=err.messages, error='validation errors'))
            log.info(f'Validation errors during login: {error_response}')
            return error_response, 400

        # Find user in database
        user = User.find_by_email(login_dto.email)
        if not user:
            error_response = self.error_schema.dump(
                ErrorResponse(details={
                    'user': [f'There is no user with {login_dto.email} email']
                },
                              error='not existing user'))
            log.info(f'Trying to log in non existing user: {error_response}')
            return error_response, 404

        # Chcek if user is confirmed
        if not user.confirmed:
            error_response = self.error_schema.dump(
                ErrorResponse(
                    details={'user': [f'User {user.name} is unconfirmed']},
                    error='user not confirmed'))
            log.info(f'Trying to log in unconfirmed user: {error_response}')
            return error_response, 400

        # Check user password
        if not user.check_password(login_dto.password):
            error_response = self.error_schema.dump(
                ErrorResponse(
                    details={'password': ['You provided wrong password']},
                    error='wrong password'))
            log.info(f'Wrong password used during login: {error_response}')
            return error_response, 400

        # Create JWT from user data
        token = TokenDto(create_access_token(identity=user),
                         create_refresh_token(identity=user))

        # Return token
        log.info('User login sucessful')
        return self.token_schema.dump(token), 200
示例#9
0
    def get(self):

        # Get optional page number
        try:
            page = int(request.args.get('page'))
        except ValueError:
            error_schema = ErrorResponseSchema()
            error_response = error_schema.dump(
                ErrorResponse(details={'page': 'Page should be number'},
                              error='validation errors'))
            log.info(f'Invalid page query argument: {error_response}')
            return error_response, 400

        # Find all users on that page
        users = User.find_all_users(page or 1, 20)

        # Map users to schema
        paginated_user_schema = PaginatedUserSchema()
        return paginated_user_schema.dump(users), 200
示例#10
0
    def post(self):
        # Map request body to user model
        try:
            user = self.user_schema.load(api.payload)
        except ValidationError as err:
            error_schema = ErrorResponseSchema()
            error_response = error_schema.dump(
                ErrorResponse(details=err.messages, error='validation errors'))
            log.info(
                f'Validation errors during user creation: {error_response}')
            return error_response, 400

        # Check if user with same email already exists
        if User.find_by_email(user.email) is not None:
            error_schema = ErrorResponseSchema()
            error_response = error_schema.dump(
                ErrorResponse(details={
                    'user': ['User with provided email already exists']
                },
                              error='duplicate email'))
            log.info(f'trying to create user with existing email {user.email}')
            return error_response, 400

        # If caller was ADMIN create ADMIN if caller was CLIENT create CLIENT
        user_claims = self.user_claims_schema.load(get_jwt_claims())
        if user_claims.is_admin():
            user.add_to_role(RoleTypes.ADMIN)
        else:
            user.add_to_role(RoleTypes.CLIENT)

        # Send confirmation mail that user was created
        if app.config['REQUIRE_MAIL_CONFIRMATION']:
            send_confirmation_token(user.email)
        else:
            user.confirm_account()

        # Save model to DB
        user.commit()

        # Map saved user to response body
        log.info(f'Sucessfuly created new user')
        return self.user_schema.dump(user), 201
示例#11
0
def test_non_admin_creates_user(app, seeded_database):
    # Given
    new_user_info = {
        'email': '*****@*****.**',
        'name': 'Test User',
        'password': '******'
    }

    # When
    response = app.test_client().post('/api/user',
                                      data=dumps(new_user_info),
                                      content_type='application/json')
    response_body = loads(response.data)

    created_user = User.find_by_email('*****@*****.**')

    # Then
    assert response.status_code == 201
    assert created_user.uuid == UUID(response_body['uuid'])
    assert not created_user.confirmed
    assert next(role for role in created_user.roles
                if role.role_type == RoleTypes.CLIENT)
示例#12
0
    def get(self, token):
        # Confirm token
        try:
            email = ConfirmationMailHandler.confirm_token(token)
        except InvalidConfirmationToken:
            error_response = self.error_schema.dump(
                ErrorResponse(
                    details={'token': f'{email} is invalid or expired'},
                    error='Invalid or expired token'))
            log.info(f'Invalid token: {error_response}')
            return error_response, 403

        # Find user that token belongs to
        user = User.find_by_email(email)
        if not user:
            error_response = self.error_schema.dump(
                ErrorResponse(
                    details={'user': [f'There is no user with {email} email']},
                    error='not existing user'))
            log.info(f'Trying to confirm non existing user: {error_response}')
            return error_response, 404

        # Check if user was already confirmed
        if user.confirmed:
            error_response = self.error_schema.dump(
                ErrorResponse(details={
                    'user': [f'User "{user.name}" is already confirmed']
                },
                              error='User already confirmed'))
            log.info(
                f'Trying to confirm already confirmed user: {error_response}')
            return error_response, 404

        # Confirm user
        user.confirm_account()
        user.commit()

        return '', 204
示例#13
0
    def delete(self, uuid):
        # Try to find user
        try:
            uuid = UUID(uuid)
        except ValueError:
            return self.incorrect_uuid(uuid), 404

        user = User.find_by_uuid(uuid)

        # If there is no user with given id
        if not user:
            error_schema = ErrorResponseSchema()
            error_response = error_schema.dump(
                ErrorResponse(
                    details={'uuid': f'User with {uuid} uuid does not exist'},
                    error='User not found'))
            log.info(f'User not found: {error_response}')
            return error_response, 404

        # delete user
        user.remove()

        return '', 204
示例#14
0
    def post(self):
        # Find user
        uuid = get_jwt_identity()
        user = User.find_by_uuid(uuid)
        if not user:
            error_response = self.error_schema.dump(
                ErrorResponse(
                    details={'uuid': f'User with {uuid} uuid does not exist'},
                    error='User not found'))
            log.info(f'User not found: {error_response}')
            return error_response, 404

        # Deserialize input
        notification_preferences = self.notification_preferences_schema.load(
            api.payload)

        # update notification preferences
        for key, value in notification_preferences.items():
            setattr(user, key, value)
        user.commit()

        # return updated user
        return self.user_schema.dump(user), 200
示例#15
0
    def get(self):
        # Get identity of user from refresh token
        current_user_uuid = get_jwt_identity()

        # Try to find user in db
        user = User.find_by_uuid(UUID(current_user_uuid))
        if not user:
            error_schema = ErrorResponseSchema()
            error_response = error_schema.dump(
                ErrorResponse(
                    details={'user': ['There is no user with given email']},
                    error='not existing user'))
            log.warn(f'Non existing user {current_user_uuid}' +
                     f' trying to refresh token: {error_response}')
            return error_response, 404

        # Generate new access token with user
        token = TokenDto(create_access_token(identity=user))

        # Return only access token
        token_schema = TokenSchema(only=['access_token'])
        log.info(f'Access token refresh successful')
        return token_schema.dump(token), 200
示例#16
0
def test_clients_can_only_get_own_data(app, client_access_token_header,
                                       client_user):
    # Given
    another_user = User(email='*****@*****.**',
                        name='Another test user')
    another_user.add_to_role(RoleTypes.CLIENT)
    another_user.commit()

    # When
    response = app.test_client().get(
        f'/api/user/{another_user.uuid}',
        headers=client_access_token_header,
    )
    response_body = loads(response.data)

    # Then
    assert response.status_code == 403
    assert 'error' in response_body
示例#17
0
    def put(self, uuid):
        # Map input data
        try:
            user_update_schema = UpdateUserSchema()
            update_info = user_update_schema.load(api.payload)
        except ValidationError as err:
            error_schema = ErrorResponseSchema()
            error_response = error_schema.dump(
                ErrorResponse(details=err.messages, error='validation errors'))
            log.info(f'Validation errors during user update: {error_response}')
            return error_response, 400

        # Try to find user
        try:
            uuid = UUID(uuid)
        except ValueError:
            return self.incorrect_uuid(uuid), 404

        user = User.find_by_uuid(uuid)

        # If there is no user with given id
        if not user:
            error_schema = ErrorResponseSchema()
            error_response = error_schema.dump(
                ErrorResponse(
                    details={'uuid': f'User with {uuid} uuid does not exist'},
                    error='User not found'))
            log.info(f'User not found: {error_response}')
            return error_response, 404

        # update user properties
        for key, value in update_info.items():
            setattr(user, key, value)
        user.commit()

        # return updated user
        return self.user_schema.dump(user), 200
示例#18
0
def admin_user(seeded_database):
    admin_user = User(email='*****@*****.**')
    admin_user.add_to_role(RoleTypes.ADMIN)
    admin_user.commit()
    return admin_user
示例#19
0
def client_user(seeded_database):
    client_user = User(email='*****@*****.**')
    client_user.add_to_role(RoleTypes.CLIENT)
    client_user.commit()
    return client_user
示例#20
0
def new_user():
    return User(
        email='*****@*****.**',
        name='Test Name'
    )