def get_rate_limit_data(request):
    '''Fetch key for the given request. If an Authorization header is provided,
       the caller will get a better and personalized rate limit. If no header is provided,
       the caller will be rate limited by IP, which gets an overall lower rate limit.
       This should encourage callers to always provide the Authorization token
    '''

    auth_header = request.headers.get('Authorization')
    if auth_header:
        auth_token = auth_header[6:]
        user = db_user.get_by_token(auth_token)
        if user:
            values = get_per_token_limits()
            values['key'] = auth_token
            return values

    # no valid auth token provided. Look for a remote addr header provided a the proxy
    # or if that isn't available use the IP address from the header
    ip = request.headers.get('X-LB-Remote-Addr')
    if not ip:
        ip = request.remote_addr

    values = get_per_ip_limits()
    values['key'] = ip
    return values
def validate_auth_header(*, optional: bool = False, fetch_email: bool = False):
    """ Examine the current request headers for an Authorization: Token <uuid>
        header that identifies a LB user and then load the corresponding user
        object from the database and return it, if succesful. Otherwise raise
        APIUnauthorized() exception.

    Args:
        optional: If the optional flag is given, do not raise an exception
            if the Authorization header is not set.
        fetch_email: if True, include email in the returned dict
    """

    auth_token = request.headers.get('Authorization')
    if not auth_token:
        if optional:
            return None
        raise APIUnauthorized("You need to provide an Authorization header.")
    try:
        auth_token = auth_token.split(" ")[1]
    except IndexError:
        raise APIUnauthorized("Provided Authorization header is invalid.")

    user = db_user.get_by_token(auth_token, fetch_email=fetch_email)
    if user is None:
        raise APIUnauthorized("Invalid authorization token.")

    return user
def get_rate_limit_data(request):
    '''Fetch key for the given request. If an Authorization header is provided,
       the caller will get a better and personalized rate limit. If no header is provided,
       the caller will be rate limited by IP, which gets an overall lower rate limit.
       This should encourage callers to always provide the Authorization token
    '''

    auth_header = request.headers.get('Authorization')
    if auth_header:
        auth_token = auth_header[6:]
        user = db_user.get_by_token(auth_token)
        if user:
            values = get_per_token_limits()
            values['key'] = auth_token
            return values

    # no valid auth token provided. Look for a remote addr header provided a the proxy
    # or if that isn't available use the IP address from the header
    ip = request.headers.get('X-LB-Remote-Addr')
    if not ip:
        ip = request.remote_addr

    values = get_per_ip_limits()
    values['key'] = ip
    return values
def validate_token():
    """
    Check whether a User Token is a valid entry in the database.

    In order to query this endpoint, send a GET request with the token to check
    as the `token` argument (example: /validate-token?token=token-to-check)

    A JSON response will be returned, with one of two codes.

    :statuscode 200: The user token is valid/invalid.
    :statuscode 400: No token was sent to the endpoint.
    """
    auth_token = request.args.get('token', '')
    if not auth_token:
        raise APIBadRequest("You need to provide an Authorization token.")
    user = db_user.get_by_token(auth_token)
    if user is None:
        return jsonify({
            'code': 200,
            'message': 'Token invalid.',
            'valid': False,
        })
    else:
        return jsonify({
            'code': 200,
            'message': 'Token valid.',
            'valid': True,
            'user_name': user['musicbrainz_id'],
        })
    def test_fetch_email(self):
        musicbrainz_id = "one"
        email = "*****@*****.**"
        user_id = db_user.create(1, musicbrainz_id, email)
        self.assertNotIn("email", db_user.get(user_id))
        self.assertEqual(email,
                         db_user.get(user_id, fetch_email=True)["email"])

        token = db_user.get(user_id)["auth_token"]
        self.assertNotIn("email", db_user.get_by_token(token))
        self.assertEqual(
            email,
            db_user.get_by_token(token, fetch_email=True)["email"])

        self.assertNotIn("email", db_user.get_by_mb_id(musicbrainz_id))
        self.assertEqual(
            email,
            db_user.get_by_mb_id(musicbrainz_id, fetch_email=True)["email"])
Example #6
0
def _validate_auth_header():
    auth_token = request.headers.get('Authorization')
    if not auth_token:
        raise APIUnauthorized("You need to provide an Authorization header.")
    try:
        auth_token = auth_token.split(" ")[1]
    except IndexError:
        raise APIUnauthorized("Provided Authorization header is invalid.")

    user = db_user.get_by_token(auth_token)
    if user is None:
        raise APIUnauthorized("Invalid authorization token.")

    return user
Example #7
0
def _validate_auth_header():
    auth_token = request.headers.get('Authorization')
    if not auth_token:
        raise Unauthorized("You need to provide an Authorization header.")
    try:
        auth_token = auth_token.split(" ")[1]
    except IndexError:
        raise Unauthorized("Provided Authorization header is invalid.")

    user = db_user.get_by_token(auth_token)
    if user is None:
        raise Unauthorized("Invalid authorization token.")

    return user
Example #8
0
def validate_token():
    """
    Check whether a User Token is a valid entry in the database.

    In order to query this endpoint, send a GET request.
    A JSON response will be returned, with one of three codes.

    :statuscode 200: The user token is valid/invalid.
    :statuscode 400: No token was sent to the endpoint.
    """
    auth_token = request.args.get('token', '')
    if not auth_token:
        raise APIBadRequest("You need to provide an Authorization token.")
    user = db_user.get_by_token(auth_token)
    if user is None:
        return jsonify({'code': 200, 'message': 'Token invalid.'})
    else:
        return jsonify({'code': 200, 'message': 'Token valid.'})
Example #9
0
def validate_token():
    """
    Check whether a User Token is a valid entry in the database.

    In order to query this endpoint, send a GET request with the Authorization
    header set to the value ``Token [the token value]``.

    .. note::

        This endpoint also checks for `token` argument in query params
        (example: /validate-token?token=token-to-check) if the Authorization
        header is missing for backward compatibility.

    A JSON response, with the following format, will be returned.

    - If the given token is valid:

    .. code-block:: json

        {
            "code": 200,
            "message": "Token valid.",
            "valid": true,
            "user_name": "MusicBrainz ID of the user with the passed token"
        }

    - If the given token is invalid:

    .. code-block:: json

        {
            "code": 200,
            "message": "Token invalid.",
            "valid": false,
        }

    :statuscode 200: The user token is valid/invalid.
    :statuscode 400: No token was sent to the endpoint.
    """
    header = request.headers.get('Authorization')
    if header and header.lower().startswith("token "):
        auth_token = header.split(" ")[1]
    else:
        # for backwards compatibility, check for auth token in query parameters as well
        auth_token = request.args.get('token', '')

    if not auth_token:
        raise APIBadRequest("You need to provide an Authorization token.")
    user = db_user.get_by_token(auth_token)
    if user is None:
        return jsonify({
            'code': 200,
            'message': 'Token invalid.',
            'valid': False,
        })
    else:
        return jsonify({
            'code': 200,
            'message': 'Token valid.',
            'valid': True,
            'user_name': user['musicbrainz_id'],
        })