mirror of
https://github.com/suitenumerique/drive.git
synced 2026-08-25 15:42:23 +02:00
We need to allow configuration of /users sub route via the EXTERNAL_API configuration.
158 lines
5.5 KiB
Markdown
158 lines
5.5 KiB
Markdown
# 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](https://github.com/suitenumerique/django-lasuite/blob/main/documentation/how-to-use-oidc-resource-server-backend.md)
|
|
|
|
## 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:
|
|
|
|
```python
|
|
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](https://github.com/suitenumerique/django-lasuite/blob/main/documentation/how-to-use-oidc-call-to-resource-server.md)
|
|
|
|
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.
|
|
|
|
```python
|
|
@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.
|
|
|
|
```python
|
|
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.
|
|
|
|
```python
|
|
response = requests.get(
|
|
"{settings.DRIVE_API}/users/me/",
|
|
headers={"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"},
|
|
)
|
|
```
|