def get_user(admin, user_id): """ Returns the user with the requested id. :param admin: Is the administrator user, determined by @adminOptional. :param user_id: Is the user id. :return: The requested user as JSON object. """ # Query user user = User.query.filter(User.id == user_id).first() if not user: raise exc.EntryNotFound() if admin is None: # Check if the user has been verified. if not user.is_verified: raise exc.UserIsNotVerified() # Check if the user is inactive if not user.active: raise exc.UserIsInactive() fields = ['id', 'firstname', 'lastname', 'fullname', 'credit', 'rank_id', 'imagename', 'active', 'is_admin', 'creation_date', 'verification_date', 'is_verified'] user = convert_minimal(user, fields)[0] return jsonify(user), 200
def login(): """ Registered users can log in on this route. :return: A temporary valid token, which users can use to identify themselves when making requests to the API. :raises DataIsMissing: If the id or password (or both) is not included in the request. :raises UnknownField: If an unknown parameter exists in the request data. :raises InvalidType: If one or more parameters have an invalid type. :raises InvalidCredentials: If no user can be found with the given data. :raises UserIsNotVerified: If the user has not yet been verified. """ data = json_body() # Check all items in the json body. required = {'id': int, 'password': str} check_fields_and_types(data, required) # Try to get the user with the id user = User.query.filter_by(id=data['id']).first() # If no user with this data exists cancel the authentication. if not user: raise exc.InvalidCredentials() # Check if the user has already been verified. if not user.is_verified: raise exc.UserIsNotVerified() # Check if the user is inactive if not user.active: raise exc.UserIsInactive() # Check if the user has set a password. if not user.password: raise exc.InvalidCredentials() # Check if the password matches the user's password. if not bcrypt.check_password_hash(user.password, str(data['password'])): raise exc.InvalidCredentials() # Create a dictionary object of the user. fields = ['id', 'firstname', 'lastname', 'credit', 'is_admin'] d_user = convert_minimal(user, fields)[0] # Create a token. exp = datetime.datetime.utcnow() + datetime.timedelta(minutes=60) token = jwt.encode({'user': d_user, 'exp': exp}, app.config['SECRET_KEY']) # Return the result. return jsonify({'result': True, 'token': token.decode('UTF-8')}), 200
def decorator(*args, **kwargs): user = User.query.filter_by(id=kwargs['user_id']).first() if not user: raise exc.EntryNotFound() # Check if the user has been verified. if not user.is_verified: raise exc.UserIsNotVerified() # Check if the user is inactive if not user.active: raise exc.UserIsInactive() # If all criteria are met, the requested function can be executed. return f(user, *args, **kwargs)
def create_refund(admin): """ Insert a new refund. :param admin: Is the administrator user, determined by @adminRequired. :return: A message that the creation was successful. :raises DataIsMissing: If not all required data is available. :raises WrongType: If one or more data is of the wrong type. :raises EntryNotFound: If the user with this ID does not exist. :raises UserIsNotVerified: If the user has not yet been verified. :raises InvalidAmount: If amount is equal to zero. :raises CouldNotCreateEntry: If any other error occurs. """ data = json_body() required = {'user_id': int, 'total_price': int, 'comment': str} check_fields_and_types(data, required) user = User.query.filter_by(id=data['user_id']).first() if not user: raise exc.EntryNotFound() # Check if the user has been verified. if not user.is_verified: raise exc.UserIsNotVerified() # Check if the user is inactive if not user.active: raise exc.UserIsInactive() # Check amount if data['total_price'] <= 0: raise exc.InvalidAmount() # Create and insert refund try: refund = Refund(**data) refund.admin_id = admin.id db.session.add(refund) db.session.commit() except IntegrityError: raise exc.CouldNotCreateEntry() return jsonify({'message': 'Created refund.'}), 200
def insert_deposit(data, admin): """ This help function creates a new deposit with the given data. :raises DataIsMissing: If not all required data is available. :raises WrongType: If one or more data is of the wrong type. :raises EntryNotFound: If the user with this ID does not exist. :raises UserIsNotVerified: If the user has not yet been verified. :raises InvalidAmount: If amount is equal to zero. :raises CouldNotCreateEntry: If any other error occurs. """ required = {'user_id': int, 'amount': int, 'comment': str} check_fields_and_types(data, required) # Check user user = User.query.filter_by(id=data['user_id']).first() if not user: raise exc.EntryNotFound() # Check if the user has been verified. if not user.is_verified: raise exc.UserIsNotVerified() # Check if the user is inactive if not user.active: raise exc.UserIsInactive() # Check amount if data['amount'] == 0: raise exc.InvalidAmount() # Create and insert deposit try: deposit = Deposit(**data) deposit.admin_id = admin.id db.session.add(deposit) except IntegrityError: raise exc.CouldNotCreateEntry()
def create_purchase(admin): """ Insert a new purchase. :param admin: Is the administrator user, determined by @adminOptional. :return: A message that the creation was successful. :raises DataIsMissing: If not all required data is available. :raises WrongType: If one or more data is of the wrong type. :raises EntryNotFound: If the user with this ID does not exist. :raises UserIsNotVerified: If the user has not yet been verified. :raises EntryNotFound: If the product with this ID does not exist. :raises EntryIsInactive: If the product is inactive. :raises InvalidAmount: If amount is less than or equal to zero. :raises InsufficientCredit: If the credit balance of the user is not sufficient. :raises CouldNotCreateEntry: If any other error occurs. """ data = json_body() required = {'user_id': int, 'product_id': int, 'amount': int} check_fields_and_types(data, required) # Check user user = User.query.filter_by(id=data['user_id']).first() if not user: raise exc.EntryNotFound() # Check if the user has been verified. if not user.is_verified: raise exc.UserIsNotVerified() # Check if the user is inactive if not user.active: raise exc.UserIsInactive() # Check product product = Product.query.filter_by(id=data['product_id']).first() if not product: raise exc.EntryNotFound() if not product.active: raise exc.EntryIsInactive() # Check amount if data['amount'] <= 0: raise exc.InvalidAmount() # If the purchase is made by an administrator, the credit limit # may be exceeded. if not admin: limit = Rank.query.filter_by(id=user.rank_id).first().debt_limit current_credit = user.credit future_credit = current_credit - (product.price * data['amount']) if future_credit < limit: raise exc.InsufficientCredit() try: purchase = Purchase(**data) db.session.add(purchase) db.session.commit() except IntegrityError: raise exc.CouldNotCreateEntry() return jsonify({'message': 'Purchase created.'}), 200
def insert_purchase(admin: Optional[User], data: dict) -> None: """ This helper function creates a single purchase without doing a commit. :param admin: Is the administrator user, determined by @adminOptional. :param data: Is the purchase data. :return: None """ required = {'user_id': int, 'product_id': int, 'amount': int} optional = {'timestamp': str} # If the request is not made by an administrator, the timestamp can't be set if admin is None and 'timestamp' in data: raise exc.ForbiddenField() check_fields_and_types(data, required, optional) # Check user user = User.query.filter_by(id=data['user_id']).first() if not user: raise exc.EntryNotFound() # Check if the user has been verified. if not user.is_verified: raise exc.UserIsNotVerified() # Check if the user is inactive if not user.active: raise exc.UserIsInactive() # Check the user rank. If it is a system user, only administrators are allowed to insert purchases if user.rank.is_system_user and admin is None: raise exc.UnauthorizedAccess() # Parse the timestamp data = parse_timestamp(data, required=False) # Check product product = Product.query.filter_by(id=data['product_id']).first() if not product: raise exc.EntryNotFound() if not admin and not product.active: raise exc.EntryIsInactive() # Check weather the product is for sale if the request is not made by an administrator if not admin and any(map(lambda tag: not tag.is_for_sale, product.tags)): raise exc.EntryIsNotForSale() # Check amount if data['amount'] <= 0: raise exc.InvalidAmount() # If the purchase is made by an administrator, the credit limit # may be exceeded. if not admin: limit = Rank.query.filter_by(id=user.rank_id).first().debt_limit current_credit = user.credit future_credit = current_credit - (product.price * data['amount']) if future_credit < limit: raise exc.InsufficientCredit() try: if admin: purchase = Purchase(admin_id=admin.id, **data) else: purchase = Purchase(**data) db.session.add(purchase) except IntegrityError: raise exc.CouldNotCreateEntry()