Files
drive/docs/resource_server.md
Nathan Vasse 9f28cc61ac (back) add /users route to external api custom
We need to allow configuration of /users sub route via
the EXTERNAL_API configuration.
2025-12-18 16:13:07 +01:00

5.5 KiB

Use Drive as a Resource Server

Drive implements resource server, so it means it can be used from an external app to perform some operation using the dedicated API.

Note: This feature might be subject to future evolutions. The API endpoints, configuration options, and behavior may change in future versions.

Prerequisites

In order to activate the resource server on Drive you need to setup the following environement variables

OIDC_RESOURCE_SERVER_ENABLED=True
OIDC_OP_URL=
OIDC_OP_INTROSPECTION_ENDPOINT=
OIDC_RS_CLIENT_ID=
OIDC_RS_CLIENT_SECRET=
OIDC_RS_AUDIENCE_CLAIM=
OIDC_RS_ALLOWED_AUDIENCES=

It implements the resource server using django-lasuite, see the documentation

Customise allowed routes

Configure the EXTERNAL_API setting to control which routes and actions are available in the external API. Set it via the EXTERNAL_API environment variable (as JSON) or in Django settings.

Default configuration:

EXTERNAL_API = {
    "items": {
        "enabled": True,
        "actions": ["list", "retrieve", "children", "upload_ended"],
    },
    "item_access": {
        "enabled": False,
        "actions": [],
    },
    "item_invitation": {
        "enabled": False,
        "actions": [],
    },
    "users": {
        "enabled": True,
        "actions": ["get_me"],
    }
}

Endpoints:

  • items: Controls /external_api/v1.0/items/. Available actions: list, retrieve, create, update, partial_update, destroy, children, upload_ended, move, restore, trashbin, hard_delete, tree, breadcrumb, link_configuration, favorite, media_auth, wopi
  • item_access: Controls /external_api/v1.0/items/{id}/accesses/. Available actions: list, retrieve, create, update, partial_update, destroy
  • item_invitation: Controls /external_api/v1.0/items/{id}/invitations/. Available actions: list, retrieve, create, update, partial_update, destroy

Each endpoint has enabled (boolean) and actions (list of allowed actions). Only actions explicitly listed are accessible.

Request Drive

In order to request drive from an external resource provider, you need to implement the basic setup of django-lasuite Using the OIDC Authentication Backend to request a resource server

Then you can requests some routes that are available at /external_api/v1.0/*, here are some examples of what you can do.

Upload a file

Here is an example of a view that create a file on the main workspace in Drive.

    @method_decorator(refresh_oidc_access_token)
    def upload_file(self, request):
        """
        Create a new file in the main workspace.
        """

        # Get the access token from the session
        access_token = request.session.get('oidc_access_token')

        # Get the main workspace
        response = requests.get(
            f"{settings.DRIVE_API}/items/",
            headers={"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"},
        )
        response.raise_for_status()
        data = response.json()
        items = data['results']
        main_workspace = None
        for item in items:
            if item['main_workspace']:
                main_workspace = item
                break

        if not main_workspace:
            return drf.response.Response(status=404, data={"error": "No main workspace found"})

        # Create a new file in the main workspace
        response = requests.post(
            f"{settings.DRIVE_API}/items/{main_workspace['id']}/children/",
            json={
                "type": "file",
                "filename": "test.txt",
            },
            headers={"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"},
        )
        response.raise_for_status()
        item = response.json()
        policy = item['policy']

        # Upload file content using the presigned URL
        import os
        sample_file_path = os.path.join(os.path.dirname(__file__), "sample.txt")
        with open(sample_file_path, "rb") as f:
            upload_response = requests.put(
                policy,
                data=f.read(),
                headers={
                    "Content-Type": "text/plain",
                    "x-amz-acl": "private"
                }
            )
            upload_response.raise_for_status()

        # Tell the Drive API that the upload is ended
        response = requests.post(
            f"{settings.DRIVE_API}/items/{item['id']}/upload-ended/",
            json={},
            headers={"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"},
        )
        response.raise_for_status()

        return drf.response.Response(data)

Create a new folder

Using the same logic as the previous example, you can create a folder in the main workspace.

response = requests.post(
    f"{settings.DRIVE_API}/items/{main_workspace['id']}/children/",
    json={
        "type": "folder",
        "title": "My folder",
    },
    headers={"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"},
)

Get user information

The same way, you can use the /me endpoint to get user information.

response = requests.get(
    "{settings.DRIVE_API}/users/me/",
    headers={"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"},
)