예제 #1
0
def disable_client(client_id):
    """Disable a user using the Lowball application auth provider."""
    if current_app.auth_provider is None:
        raise AuthenticationNotInitializedException
    client = current_app.auth_provider.get_client(client_id)
    if client is None:
        raise NotFoundException(
            description=f"client_id '{client_id}' not found")
    current_app.auth_provider.disable_client(client_id)
    return "", 204
예제 #2
0
def remove_client_role(client_id, role):
    """remove the specified role from the specified client

    """
    if current_app.auth_provider is None:
        raise AuthenticationNotInitializedException
    client = current_app.auth_provider.get_client(client_id)
    if client is None:
        raise NotFoundException(
            description=f"client_id '{client_id}' not found in auth provider")

    current_app.auth_provider.delete_roles(client_id, [role])

    return "", 204
예제 #3
0
def get_current_client():
    """Return client data for requesting client

    """
    client_id = g.client_data.client_id

    if current_app.auth_provider is None:
        raise AuthenticationNotInitializedException

    client_data = current_app.auth_provider.get_client(client_id)
    if not client_data or not isinstance(client_data, ClientData):
        raise NotFoundException("Client not found")

    return json.dumps(client_data.to_dict()), 200, _JSON_HEADER
예제 #4
0
def client_self_update():
    """Allow a client to update their client in the application.

        Allows a client to change certain attributes of their client
        using the application auth provider. The client of the
        client that is being updated is pulled from the token that
        authenticated the request. This means that you cannot update
        the client for the client with this route, otherwise
        :meth:`client_self_update` will throw an error because the
        `client` kwarg was passed in more than once.

        :rtype: tuple
        :return: updated client, status code, headers
        """
    post_data = request.get_json()
    client_id = g.client_data.client_id

    if current_app.auth_provider is None:
        raise AuthenticationNotInitializedException

    client_data = current_app.auth_provider.get_client(client_id)
    if not client_data or not isinstance(client_data, ClientData):
        raise NotFoundException("Client not found")

    client_self_update_package_class = current_app.auth_provider.self_update_client_package_class

    try:
        client_self_update_package = client_self_update_package_class(
            **post_data)
    except Exception as err:
        raise MalformedProviderPackageException(str(err))

    updated_client = current_app.auth_provider.client_self_update(
        client_self_update_package, client_id=client_id)

    if isinstance(updated_client, ClientData):
        updated_client = updated_client.to_dict()

    if isinstance(updated_client, dict):
        updated_client = json.dumps(updated_client)
    return updated_client, 200, _JSON_HEADER
예제 #5
0
def update_client(client_id):
    """Update information for the specified user.

        This route simply takes whatever is in the PATCH body and
        passed it into the auth provider instance's :meth:`update_client`
        method.

        :type client_id: str
        :param client_id: The client to update.
        :rtype: tuple
        :return: updated user, status code, headers
        """

    if current_app.auth_provider is None:
        raise AuthenticationNotInitializedException

    patch_body = request.get_json()
    client = current_app.auth_provider.get_client(client_id)

    if client is None:
        raise NotFoundException(
            description=f"client_id '{client_id}' not found")
    update_client_package_class = current_app.auth_provider.update_client_package_class

    try:
        update_client_package = update_client_package_class(**patch_body)
    except Exception as err:
        raise MalformedProviderPackageException(str(err))

    client = current_app.auth_provider.update_client(update_client_package,
                                                     client_id)
    if isinstance(client, ClientData):
        client = json.dumps(client.to_dict())

    elif isinstance(client, dict):
        client = json.dumps(client)

    return client, 200, _JSON_HEADER
예제 #6
0
def get_client(client_id):
    """Get data for the specified user.

           :type client_id: str
           :param client_id: The client_id to get data for
           :rtype: tuple
           :return: user data dictionary, status code, json content header
           """

    if current_app.auth_provider is None:
        raise AuthenticationNotInitializedException

    client = current_app.auth_provider.get_client(client_id)

    if client is None:
        raise NotFoundException(
            description=f"client_id '{client_id}' not found")

    if not isinstance(client, ClientData):
        raise InternalServerErrorException(
            "auth_provider.get_client did not return a client data object")

    return json.dumps(client.to_dict()), 200, _JSON_HEADER
예제 #7
0
def create_token():
    """Create a new token for the specified user or self user

        Things to note:
            - A client_id is required to make a token
            - If no roles are supplied in the POST body, then the roles for the
              user will be assigned to an empty array (no roles)
            - If no token life is present in the POST body, then the configured default
              token life will be used.
            - Token life must be a positive integer greater than 9.

        :rtype: tuple
        :return: token data, status code
        """
    post_data = request.get_json()
    if post_data is None:
        post_data = {}
    default_token_life = current_app.lowball_config.authentication.default_token_life
    max_token_life = current_app.lowball_config.authentication.max_token_life
    requesting_client_data = g.client_data
    requesting_client_roles = requesting_client_data.roles
    admin_user = "******" in requesting_client_roles
    requesting_user = requesting_client_data.client_id
    client_id = post_data.get("client_id")

    if client_id and not admin_user and requesting_client_data.client_id != client_id:
        raise InadequateRolesException(
            "Unable to create tokens for another client")

    if not client_id:
        client_id = requesting_user

    requested_roles = post_data.get("roles", [])
    try:
        token_life = default_token_life if post_data.get(
            "token_life") is None else int(post_data["token_life"])
    except:
        raise BadRequestException(
            f"token_life must be a positive integer greater than 10 and less than {max_token_life}"
        )

    if not isinstance(token_life,
                      int) or token_life < 10 or token_life > max_token_life:
        raise BadRequestException(
            f"token_life must be a positive integer greater than 10 and less than {max_token_life}"
        )

    if not admin_user:
        if current_app.auth_provider is None:
            raise AuthenticationNotInitializedException

        try:
            target_client = current_app.auth_provider.get_client(client_id)
        except NotImplementedException as err:
            err.code = 409
            err.description = "get_client is not implemented in this auth provider. " \
                              "Non admin clients are unable to create tokens"
            raise err

        if not target_client:
            raise NotFoundException(
                "Client ID for requesting token not found in auth provider")
        target_client_roles = target_client.roles
        if any(role not in target_client_roles for role in requested_roles):
            raise InadequateRolesException(
                "Unable to create token with requested roles")
    roles = requested_roles

    expiration_time = datetime.datetime.utcnow() + datetime.timedelta(
        seconds=token_life)

    token, token_data = current_app.authenticator.create_token(
        client_id, roles, requesting_user, expiration_time)
    current_app.auth_db.add_token(token_data)

    return json.dumps({
        "token": token,
        "token_data": token_data.to_dict()
    }), 201, _JSON_HEADER