Skip to content

Commit d470576

Browse files
committed
feat(users): implement rate limiting for users endpoint
- Add `configured_rate_limiter` import to middleware dependencies - Refactor `permissionSetter` to `rateAndPermissionSetter` to include rate limiting - Apply rate limiting to GET, PUT, and DELETE requests on users endpoints - Update middleware documentation to reflect new rate limiting functionality
1 parent 6228ce2 commit d470576

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

routes/api/v1/users/_middleware.dart

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
import 'package:dart_frog/dart_frog.dart';
22
import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/authentication_middleware.dart';
33
import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/authorization_middleware.dart';
4+
import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/configured_rate_limiter.dart';
45
import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permissions.dart';
56

67
/// Middleware for the `/api/v1/users` route group.
78
///
89
/// This middleware performs the following actions:
910
/// 1. `requireAuthentication()`: Ensures a user is authenticated for all
1011
/// /users/* routes.
11-
/// 2. `permissionSetter`: A middleware that provides the correct permission string
12-
/// into the context *only* for the `/users` and `/users/{id}` endpoints.
13-
/// It ignores sub-routes like `/users/{id}/settings`, leaving them to be
14-
/// handled by their own more specific middleware.
12+
/// 2. `rateAndPermissionSetter`: A middleware that applies rate limiting and
13+
/// provides the correct permission string into the context *only* for the
14+
/// `/users` and `/users/{id}` endpoints. It ignores sub-routes like
15+
/// `/users/{id}/settings`, leaving them to be handled by their own more
16+
/// specific middleware.
1517
/// 3. `authorizationMiddleware()`: Checks if the authenticated user has the
16-
/// permission provided by the `permissionSetter`.
18+
/// permission provided by the `rateAndPermissionSetter`.
1719
Handler middleware(Handler handler) {
18-
// This middleware provides the required permission string into the context.
20+
// This middleware applies rate limiting and provides the required permission.
1921
// It is scoped to only handle `/users` and `/users/{id}`.
2022
// ignore: prefer_function_declarations_over_variables
21-
final permissionSetter = (Handler handler) {
23+
final rateAndPermissionSetter = (Handler handler) {
2224
return (RequestContext context) {
2325
final request = context.request;
2426
final pathSegments = request.uri.pathSegments;
@@ -31,36 +33,43 @@ Handler middleware(Handler handler) {
3133
}
3234

3335
final String permission;
36+
final Middleware rateLimiter;
3437
final isItemRequest = pathSegments.length == 4;
3538

3639
switch (request.method) {
3740
case HttpMethod.get:
3841
// Admins can list all users; users can read their own profile.
3942
permission =
4043
isItemRequest ? Permissions.userReadOwned : Permissions.userRead;
44+
rateLimiter = createReadRateLimiter();
4145
case HttpMethod.put:
4246
// Users can update their own profile.
4347
permission = Permissions.userUpdateOwned;
48+
rateLimiter = createWriteRateLimiter();
4449
case HttpMethod.delete:
4550
// Users can delete their own profile.
4651
permission = Permissions.userDeleteOwned;
52+
rateLimiter = createWriteRateLimiter();
4753
default:
4854
// Disallow any other methods (e.g., POST) on this route group.
4955
// User creation is handled by the /auth routes.
5056
return Response(statusCode: 405);
5157
}
52-
// Provide the required permission to the authorization middleware.
53-
return handler(
54-
context.provide<String>(() => permission),
55-
);
58+
59+
// Apply the selected rate limiter and then provide the permission.
60+
return rateLimiter(
61+
(context) => handler(
62+
context.provide<String>(() => permission),
63+
),
64+
)(context);
5665
};
5766
};
5867

5968
return handler
6069
// The authorization middleware runs after the permission has been set.
6170
.use(authorizationMiddleware())
62-
// The permission setter runs after authentication is confirmed.
63-
.use(permissionSetter)
71+
// The rate limiter and permission setter runs after authentication.
72+
.use(rateAndPermissionSetter)
6473
// Authentication is the first check for all /users/* routes.
6574
.use(requireAuthentication());
6675
}

0 commit comments

Comments
 (0)