Пример #1
0
    async def test_main(request):
        """
        The main route. Accepts POST requests with the following "Content-Type" headers:
        - application/json
        - octet-stream

        If the request has a json content type, then the request body should contain a "url" key
        with the location from where the resource should be downloaded. In case of the octet-stream,
        the binary data is considered a resource.
        """
        try:
            validate_request(request)  # TODO move to middleware
        except AssertionError:
            return json({'success': False, 'error': 'Wrong content type'}, 400)

        if is_binary_request(request):
            try:
                header, data, encoded_data = parse_raw_body(request.body)
            except Exception:
                return json({'success': False, 'error': 'Failed to parse request body'}, 400)
        elif is_json_request(request):
            data = request.load_json()
        else:
            return json({'success': False, 'error': 'Wrong content type'}, 400)

        try:
            await save_resource(app, request.content_type, data)
        except Exception as e:
            return json({'success': False, 'error': str(e)}, 400)

        return json({'success': True}, 201)
Пример #2
0
def new_product_movement():
    """
    docstring
    """
    try:
        request_data = request.get_json()
        schema = new_movement_schema()
        [valid, error] = validate_request(request_data, schema)
        if not valid:
            return {"success": False, "message": str(error)}, 400
        movement_id = generate_unique_code("PM-")
        duplicate_check = call_procedure("CALL get_one_product_movement(%s);",
                                         (movement_id))
        while duplicate_check:
            movement_id = generate_unique_code("PM-")
            duplicate_check = call_procedure(
                "CALL get_one_product_movement(%s);", (movement_id))
        timestamp = get_utcnow_time_string()
        from_location = request_data.get('from_location')
        to_location = request_data.get('to_location')
        # Check if from and to location => both are not null
        if from_location == to_location:
            return {
                "success":
                False,
                "message":
                "From And To Locations cannot be Same " +
                "OR Both cannot be Null (Need to specify either one in that case)"
            }, 400
        product_id = request_data.get('product_id')
        qty = request_data.get('qty')
        print("QTY", qty)
        # check sufficient qty available in from location if from_location is not null
        if from_location:
            check = call_procedure("CALL check_available_quantity(%s,%s)",
                                   (product_id, from_location))
            if not check:
                return {
                    "success": False,
                    "message": "Insufficient Qty in From Location"
                }, 400
            elif qty > check['qty']:
                return {
                    "success": False,
                    "message": "Insufficient Qty in From Location"
                }, 400
        result = call_procedure(
            "CALL add_product_movement(%s, %s, %s, %s, %s, %s);",
            (movement_id, timestamp, from_location, to_location, product_id,
             qty))
        return {"data": result, "success": True}, 200
    except Exception as e:
        print(e.args)
        return {"success": False, "message": str(e.args)}, 500
Пример #3
0
def edit_product_movement(product_movement_id):
    """
    docstring
    """
    try:
        request_data = request.get_json()

        schema = new_movement_schema()
        [valid, error] = validate_request(request_data, schema)
        if not valid:
            return {"success": False, "message": str(error)}, 400

        timestamp = get_utcnow_time_string()

        new_from_location = request_data.get('from_location')
        new_to_location = request_data.get('to_location')

        if new_from_location == new_to_location:
            return {
                "success":
                False,
                "message":
                "From And To Locations cannot be Same " +
                "OR Both cannot be Null (Need to specify either one in that case)"
            }, 400

        new_product_id = request_data.get('product_id')

        result = call_procedure("CALL get_one_product_movement(%s);",
                                (product_movement_id))

        if not result:
            return {"success": False, "message": "Not Found"}, 404

        new_qty = request_data.get('qty')

        old_from_location = result.get('from_location')
        old_to_location = result.get('to_location')
        old_product_id = result.get('product_id')
        old_qty = result.get('qty')

        print("product id", old_product_id)

        query_output = call_procedure(
            "CALL update_product_movement(%s,%s,%s,%s,%s,%s,%s,%s,%s)",
            (product_movement_id, old_from_location, old_to_location,
             old_product_id, old_qty, new_from_location, new_to_location,
             new_product_id, new_qty))
        return {"success": True, "data": query_output}, 200
    except MySQLError as e:
        return {"success": False, "message": e.args[1]}, 500
    except Exception as e:
        print(e.args)
        return {"success": False, "message": e.args}, 500
Пример #4
0
def reset_password_request():
    """Respond to existing user's request to reset their password."""
    class ResetPasswordSchema(Schema):
        email = email_field

    try:
        data = validate_request(request, ResetPasswordSchema)
        user = User.query.filter_by(email=data['email']).first()
        if not user:
            raise ValueError("No matching user for email.")
        else:
            send_reset_password_email(user, request.args.get('next'))
    except ValueError as e:
        return Response(str(e), 400)
Пример #5
0
def reset_password(token):
    """Reset an existing user's password."""
    class ResetPasswordSchema(Schema):
        password = password_field

    try:
        data = validate_request(request, ResetPasswordSchema)
        user = User.reset_password(token, data['password'])
        if not user:
            raise ValueError(
                "The password reset link is invalid or has expired")
        else:
            resp = authenticate(user)
            return resp, 200
    except ValueError as e:
        return Response(str(e), 400)
Пример #6
0
def balance_qty():
    """
    docstring
    """
    try:
        request_data = request.get_json()
        schema = balance_schema()
        [valid, error] = validate_request(request_data, schema)
        if not valid:
            return {"success": False, "message": str(error)}, 400
        product = request_data.get('product')
        location = request_data.get('location')
        result = call_procedure("CALL balance(%s,%s);", (product, location))
        result['total_qty'] = int(result['total_qty'])
        return {"success": True, "data": result}, 200
    except Exception as e:
        return {"success": False, "message": str(e.args)}, 500
Пример #7
0
def change_user_info(current_user):
    """Change an existing user's email."""
    class ChangeUserInfoSchema(Schema):
        first_name = fields.Str(required=False, validate=name_validate)
        last_name = fields.Str(required=False, validate=name_validate)

    try:
        data = validate_request(request, ChangeUserInfoSchema)
        if len(data) == 0:
            raise ValueError("Request didn't include any changes.")
        if 'first_name' in data:
            current_user.first_name = data['first_name']
        if 'last_name' in data:
            current_user.last_name = data['last_name']
        db_session.add(current_user)
        db_session.commit()
        return authenticate_payload(current_user), 200
    except ValueError as e:
        return Response(str(e), 400)
Пример #8
0
def change_password(current_user):
    """Change an existing user's password."""
    class ChangePasswordSchema(Schema):
        old_password = password_field
        new_password = password_field

    try:

        data = validate_request(request, ChangePasswordSchema)
        if current_user.verify_password(data['old_password']):
            current_user.password = data['new_password']
            db_session.add(current_user)
            db_session.commit()
            # TODO: send email confirming password change
            return jsonify({}), 200
        else:
            raise ValueError("Original password is invalid.")
    except ValueError as e:
        return Response(str(e), 400)
Пример #9
0
def edit_product(product_id):
    """
    docstring
    """
    try:
        request_data = request.get_json()
        schema = new_product_location_schema()
        [valid, error] = validate_request(request_data, schema)
        if not valid:
            return {"success": False, "message": str(error)}, 400
        name = request_data.get('name')
        check = call_procedure("CALL get_one_product(%s);", (product_id))
        if not check:
            return {"success": False, "message": "Not Found"}, 404
        result = call_procedure("CALL update_product(%s,%s);",
                                (product_id, name))
        return {"data": result, "success": True}, 200
    except Exception as e:
        print(e.args)
        return {"success": False, "message": str(e.args)}, 500
Пример #10
0
def change_email(current_user):
    """Change an existing user's email."""
    class ChangeEmailSchema(Schema):
        new_email = email_field

    try:
        data = validate_request(request, ChangeEmailSchema)
        if User.query.filter_by(email=data['new_email']).first() is not None:
            raise ValueError("Email already in use.")
        else:
            current_user.email = data['new_email']
            current_user.verified_email = not current_user.is_admin(
            )  # Don't lock out admins
            db_session.expire_on_commit = False
            db_session.add(current_user)
            db_session.commit()
            send_change_email(current_user)
            # TODO: send email to old email notifying email change
            return jsonify({}), 200
    except ValueError as e:
        return Response(str(e), 400)
Пример #11
0
def sign_up():
    """Register a new user, and send them a confirmation email."""
    class RegisterSchema(Schema):
        first_name = name_field
        last_name = name_field
        email = email_field
        password = password_field

    try:
        data = validate_request(request, RegisterSchema)
        if User.query.filter_by(email=data['email']).first() is not None:
            raise ValueError("Email already in use.")
        else:
            user = User(**data)
            db_session.expire_on_commit = False
            db_session.add(user)
            db_session.commit()
            send_confirm_email(user)
            resp = authenticate(user)
            return resp, 200
    except ValueError as e:
        return Response(str(e), 400)
Пример #12
0
def login():
    """Log in an existing user."""
    class LoginSchema(Schema):
        email = email_field
        password = password_field

    try:
        data = validate_request(request, LoginSchema)
        email, password = itemgetter('email', 'password')(data)
        user = User.query.filter_by(email=email).first()
        if user is None:
            raise ValueError("No matching user for email.")
        elif user.password_hash is None:
            raise ValueError(
                "Password not set. Please check for email invite.")
        elif not user.verify_password(password):
            raise ValueError("Incorrect password.")
        else:
            resp = authenticate(user)
            return resp, 200
    except ValueError as e:
        return Response(str(e), 400)
Пример #13
0
def new_product():
    """
    docstring
    """
    try:
        request_data = request.get_json()
        schema = new_product_location_schema()
        [valid, error] = validate_request(request_data, schema)
        if not valid:
            return {"success": False, "message": str(error)}, 400
        name = request_data.get('name')
        product_id = generate_unique_code("P-")
        duplicate_check = call_procedure("CALL get_one_product(%s);",
                                         (product_id))
        while duplicate_check:
            product_id = generate_unique_code("P-")
            duplicate_check = call_procedure("CALL get_one_product(%s);",
                                             (product_id))
        result = call_procedure("CALL add_product(%s,%s);", (product_id, name))
        return {"data": result, "success": True}, 200
    except Exception as e:
        print(e)
        return {"success": False, "message": str(e.args)}, 500
Пример #14
0
def update_user(user_id):
    """Update information on a user's account."""
    class UpdateUserSchema(Schema):
        first_name = fields.Str(required=False, validate=name_validate)
        last_name = fields.Str(required=False, validate=name_validate)
        email = fields.Email(required=False, validate=email_validate)
        role = fields.Str(required=False,
                          validate=validate.OneOf(Role.get_roles()))
        verified_email = fields.Boolean(required=False)

    try:
        user = User.query.filter_by(id=user_id).first()
        if user is None:
            abort(404)
        data = validate_request(request, UpdateUserSchema)
        user_updated = False
        email_updated = False
        if len(data) > 0:
            for field, new_value in data.items():
                old_value = getattr(user, field)
                if field == 'role':
                    new_value = Role(new_value)
                if old_value != new_value:
                    if field == 'email':
                        email_updated = True
                    setattr(user, field, new_value)
                    user_updated |= True
            if user_updated:
                if email_updated:
                    user.verified_email = not user.is_admin(
                    )  # Don't lock out admins
                db_session.add(user)
                db_session.commit()
                return jsonify(get_user_payload(user)), 200
        raise ValueError("Request didn't include any changes.")
    except ValueError as e:
        return Response(str(e), 400)
Пример #15
0
def join_from_invite(token):
    """Reset an existing user's password."""
    class JoinFromInviteSchema(Schema):
        password = password_field

    try:
        request_data = validate_request(request, JoinFromInviteSchema)
        token_data = deserialize_data(token)
        if token_data:
            user_id = token_data.get('id')
            user = User.query.filter_by(id=user_id).first()
            if not user:
                logging.warning(f"User with id {user_id} does not exist.")
            else:
                user.verified_email = True
                user.password = request_data['password']
                db_session.add(user)
                db_session.commit()
                resp = authenticate(user)
                return resp, 200
        raise ValueError(
            "The join from invite link is invalid or has expired.", 400)
    except ValueError as e:
        return Response(str(e), 400)
Пример #16
0
def invite_user():
    """Invites a new user to create an account and set their own password."""
    class InviteUserSchema(Schema):
        first_name = name_field
        last_name = name_field
        email = email_field
        role = fields.Str(validate=validate.OneOf(Role.get_roles()))

    try:
        data = validate_request(request, InviteUserSchema)
        if User.query.filter_by(email=data['email']).first() is not None:
            raise ValueError("Email already in use.")
        user = User(
            role=Role(data['role']),
            first_name=data['first_name'],
            last_name=data['last_name'],
            email=data['email'],
        )
        db_session.add(user)
        db_session.commit()
        send_join_from_invite_email(user)
        return jsonify({user.id: get_user_payload(user)}), 200
    except ValueError as e:
        return Response(str(e), 400)