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
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
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
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
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'
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)
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
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
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
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)
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
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
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
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
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
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
def admin_user(seeded_database): admin_user = User(email='*****@*****.**') admin_user.add_to_role(RoleTypes.ADMIN) admin_user.commit() return admin_user
def client_user(seeded_database): client_user = User(email='*****@*****.**') client_user.add_to_role(RoleTypes.CLIENT) client_user.commit() return client_user
def new_user(): return User( email='*****@*****.**', name='Test Name' )