Skip to content

Commit 9cf4984

Browse files
committed
Add bulk delete and OAuth 2.0 enhancements
1 parent 04ec564 commit 9cf4984

2 files changed

Lines changed: 166 additions & 4 deletions

File tree

docs/mongodb-rest/files.adoc

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,8 @@ NOTE: Update operators and aggregation pipelines cannot be used with file metada
472472

473473
=== Deleting Files
474474

475+
==== DELETE - Single File
476+
475477
To delete a file and all its chunks:
476478

477479
==== cURL
@@ -510,6 +512,59 @@ fetch('[RESTHEART-URL]/mybucket.files/my-custom-id', {
510512
.catch(error => console.error('Error:', error));
511513
----
512514

515+
==== DELETE - Bulk Delete by Filter
516+
517+
NOTE: Bulk delete for file buckets is available from RESTHeart v9.2.0.
518+
519+
To delete multiple files at once, use the wildcard `*` path with a `filter` query parameter. This atomically removes both the `.files` metadata documents and their associated `.chunks` data for each matching file.
520+
521+
==== cURL
522+
523+
[source,bash]
524+
----
525+
curl -i -X DELETE "[RESTHEART-URL]/mybucket.files/*?filter={\"metadata.todelete\":true}" \
526+
-H "Authorization: Basic [BASIC-AUTH]"
527+
----
528+
529+
==== HTTPie
530+
531+
[source,bash]
532+
----
533+
http DELETE [RESTHEART-URL]/mybucket.files/'*' \
534+
Authorization:"Basic [BASIC-AUTH]" \
535+
filter=='{"metadata.todelete":true}'
536+
----
537+
538+
==== JavaScript
539+
540+
[source,javascript]
541+
----
542+
const filter = encodeURIComponent(JSON.stringify({"metadata.todelete": true}));
543+
fetch(`[RESTHEART-URL]/mybucket.files/*?filter=${filter}`, {
544+
method: 'DELETE',
545+
headers: {
546+
'Authorization': 'Basic [BASIC-AUTH]'
547+
}
548+
})
549+
.then(response => response.json())
550+
.then(data => {
551+
console.log(`Deleted ${data.deleted} files`);
552+
})
553+
.catch(error => console.error('Error:', error));
554+
----
555+
556+
[source,http]
557+
----
558+
HTTP/1.1 200 OK
559+
Content-Type: application/json
560+
561+
{"deleted": 42}
562+
----
563+
564+
The response returns the count of deleted files. Omitting the `filter` parameter deletes all files in the bucket.
565+
566+
IMPORTANT: The `filter` applies to the `.files` collection, including `metadata.*` sub-fields (e.g., `{"metadata.category":"temp"}`).
567+
513568
=== Important Notes
514569

515570
1. RESTHeart automatically detects and sets the file's content type

docs/security/how-clients-authenticate.adoc

Lines changed: 111 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ In this guide, you'll learn how to:
1919

2020
. Authenticate using Basic Authentication with username and password
2121
. Understand how the Authorization header works
22-
. Use authentication tokens for subsequent requests
22+
. Use authentication tokens for subsequent requests (password and client_credentials grant types)
23+
. Auto-discover server metadata via the RFC 8414 discovery endpoint
2324
. Manage authentication tokens (retrieve and invalidate)
2425
. Check user credentials and roles
2526
. Avoid browser authentication popups
@@ -110,8 +111,9 @@ RESTHeart v9 introduces dedicated OAuth 2.0-compatible token endpoints for secur
110111

111112
**Available Endpoints:**
112113

113-
* `POST /token` - Returns JWT token in response body (OAuth 2.0 Resource Owner Password Credentials Grant)
114+
* `POST /token` - Returns JWT token in response body (supports `password` and `client_credentials` grant types)
114115
* `POST /token/cookie` - Sets JWT token as HttpOnly cookie (enhanced security for browser-based apps)
116+
* `GET /.well-known/oauth-authorization-server` - Returns server metadata for client auto-discovery (RFC 8414)
115117

116118
**Benefits:**
117119

@@ -173,9 +175,9 @@ fetch('[RESTHEART-URL]/token', {
173175
}
174176
----
175177

176-
===== OAuth 2.0 Form Data Method
178+
===== OAuth 2.0 Form Data Method (Resource Owner Password Credentials)
177179

178-
Send credentials using OAuth 2.0 form data (application/x-www-form-urlencoded):
180+
Send credentials using OAuth 2.0 form data (application/x-www-form-urlencoded) with `grant_type=password` (RFC 6749 §4.3):
179181

180182
==== cURL
181183
[source,bash]
@@ -218,6 +220,70 @@ fetch('[RESTHEART-URL]/token', {
218220
.catch(error => console.error('Error:', error));
219221
----
220222

223+
===== Client Credentials Grant
224+
225+
NOTE: `client_credentials` grant type support is available from RESTHeart v9.2.0.
226+
227+
For machine-to-machine or service-account authentication, use `grant_type=client_credentials` (RFC 6749 §4.4).
228+
Pass `client_id` and `client_secret` in the request body instead of `username` and `password`.
229+
This is the recommended approach for API gateways, CLI tools, and MCP clients.
230+
231+
==== cURL
232+
[source,bash]
233+
----
234+
curl -i -X POST [RESTHEART-URL]/token \
235+
-H "Content-Type: application/x-www-form-urlencoded" \
236+
-d "grant_type=client_credentials&client_id=myapp&client_secret=s3cret"
237+
----
238+
239+
==== HTTPie
240+
[source,bash]
241+
----
242+
http -f POST [RESTHEART-URL]/token \
243+
grant_type=client_credentials \
244+
client_id=myapp \
245+
client_secret=s3cret
246+
----
247+
248+
==== JavaScript
249+
[source,javascript]
250+
----
251+
const formData = new URLSearchParams({
252+
grant_type: 'client_credentials',
253+
client_id: 'your-client-id',
254+
client_secret: 'your-client-secret'
255+
});
256+
257+
fetch('[RESTHEART-URL]/token', {
258+
method: 'POST',
259+
headers: {
260+
'Content-Type': 'application/x-www-form-urlencoded'
261+
},
262+
body: formData
263+
})
264+
.then(response => response.json())
265+
.then(data => {
266+
console.log('Access token:', data.access_token);
267+
console.log('Expires in:', data.expires_in, 'seconds');
268+
})
269+
.catch(error => console.error('Error:', error));
270+
----
271+
272+
The response format is identical to the password grant:
273+
274+
[source,json]
275+
----
276+
{
277+
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
278+
"token_type": "Bearer",
279+
"expires_in": 900,
280+
"username": "myapp",
281+
"roles": ["service"]
282+
}
283+
----
284+
285+
NOTE: `client_id` and `client_secret` are mapped to the user credentials in the configured authenticator (e.g., `mongoRealmAuthenticator`). The client account must exist in the user store just like a regular user account.
286+
221287
===== Using the Token
222288

223289
Once you have the token, use it as a Bearer token in the Authorization header:
@@ -360,6 +426,47 @@ jwtTokenManager:
360426

361427
IMPORTANT: Always change the `key` value in production to a strong, random secret.
362428

429+
===== OAuth 2.0 Authorization Server Metadata Discovery (RFC 8414)
430+
431+
NOTE: The authorization server metadata discovery endpoint is available from RESTHeart v9.2.0.
432+
433+
RESTHeart exposes a standards-compliant metadata discovery endpoint at `GET /.well-known/oauth-authorization-server` (RFC 8414).
434+
This allows OAuth 2.0 clients to auto-configure themselves without hardcoded URLs.
435+
436+
==== cURL
437+
[source,bash]
438+
----
439+
curl -i [RESTHEART-URL]/.well-known/oauth-authorization-server
440+
----
441+
442+
==== HTTPie
443+
[source,bash]
444+
----
445+
http GET [RESTHEART-URL]/.well-known/oauth-authorization-server
446+
----
447+
448+
**Response:**
449+
450+
[source,json]
451+
----
452+
{
453+
"issuer": "http://localhost:8080",
454+
"token_endpoint": "http://localhost:8080/token",
455+
"token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post"],
456+
"grant_types_supported": ["password", "client_credentials"],
457+
"response_types_supported": ["token"]
458+
}
459+
----
460+
461+
The endpoint is publicly accessible (no authentication required) and the base URL is derived from the request `Host` header by default.
462+
You can override it with the `base-url` configuration option:
463+
464+
[source,yml]
465+
----
466+
oauthAuthorizationServerMetadataService:
467+
base-url: https://api.example.com # optional, falls back to request Host header
468+
----
469+
363470
==== Legacy Token Management (Automatic Injection)
364471

365472
NOTE: This is the legacy token management approach. For new applications, use the OAuth 2.0 `/token` endpoint described above.

0 commit comments

Comments
 (0)