@@ -36,22 +36,40 @@ import '../../../_middleware.dart';
36
36
Future <Response > onRequest (RequestContext context, String id) async {
37
37
// Read dependencies provided by middleware
38
38
final modelName = context.read <String >();
39
- // Read ModelConfig for fromJson (needed for PUT)
40
39
final modelConfig = context.read <ModelConfig <dynamic >>();
41
- // Read the unique RequestId provided by the root middleware
42
40
final requestId = context.read <RequestId >().id;
41
+ // Since requireAuthentication is used, User is guaranteed to be non-null.
42
+ final authenticatedUser = context.read <User >();
43
43
44
44
try {
45
45
switch (context.request.method) {
46
46
case HttpMethod .get :
47
- // Pass requestId down to the handler
48
- return await _handleGet (context, id, modelName, requestId);
47
+ return await _handleGet (
48
+ context,
49
+ id,
50
+ modelName,
51
+ modelConfig, // Pass modelConfig
52
+ authenticatedUser,
53
+ requestId,
54
+ );
49
55
case HttpMethod .put:
50
- // Pass requestId down to the handler
51
- return await _handlePut (context, id, modelName, modelConfig, requestId);
56
+ return await _handlePut (
57
+ context,
58
+ id,
59
+ modelName,
60
+ modelConfig,
61
+ authenticatedUser,
62
+ requestId,
63
+ );
52
64
case HttpMethod .delete:
53
- // DELETE doesn't return a body, so no metadata needed here
54
- return await _handleDelete (context, id, modelName, requestId);
65
+ return await _handleDelete (
66
+ context,
67
+ id,
68
+ modelName,
69
+ modelConfig, // Pass modelConfig
70
+ authenticatedUser,
71
+ requestId,
72
+ );
55
73
// Add cases for other methods if needed in the future
56
74
default :
57
75
// Methods not allowed on the item endpoint
@@ -83,24 +101,34 @@ Future<Response> _handleGet(
83
101
RequestContext context,
84
102
String id,
85
103
String modelName,
86
- String requestId, // Receive requestId
104
+ ModelConfig <dynamic > modelConfig, // Receive modelConfig
105
+ User authenticatedUser, // Receive authenticatedUser
106
+ String requestId,
87
107
) async {
88
108
dynamic item; // Use dynamic
109
+
110
+ String ? userIdForRepoCall;
111
+ if (modelConfig.ownership == ModelOwnership .userOwned) {
112
+ userIdForRepoCall = authenticatedUser.id;
113
+ } else {
114
+ userIdForRepoCall = null ;
115
+ }
116
+
89
117
// Repository exceptions (like NotFoundException) will propagate up.
90
118
try {
91
119
switch (modelName) {
92
120
case 'headline' :
93
121
final repo = context.read <HtDataRepository <Headline >>();
94
- item = await repo.read (id);
122
+ item = await repo.read (id: id, userId : userIdForRepoCall );
95
123
case 'category' :
96
124
final repo = context.read <HtDataRepository <Category >>();
97
- item = await repo.read (id);
125
+ item = await repo.read (id: id, userId : userIdForRepoCall );
98
126
case 'source' :
99
127
final repo = context.read <HtDataRepository <Source >>();
100
- item = await repo.read (id);
128
+ item = await repo.read (id: id, userId : userIdForRepoCall );
101
129
case 'country' :
102
130
final repo = context.read <HtDataRepository <Country >>();
103
- item = await repo.read (id);
131
+ item = await repo.read (id: id, userId : userIdForRepoCall );
104
132
default :
105
133
// This case should ideally be caught by middleware, but added for safety
106
134
return Response (
@@ -151,7 +179,8 @@ Future<Response> _handlePut(
151
179
String id,
152
180
String modelName,
153
181
ModelConfig <dynamic > modelConfig,
154
- String requestId, // Receive requestId
182
+ User authenticatedUser, // Receive authenticatedUser
183
+ String requestId,
155
184
) async {
156
185
final requestBody = await context.request.json () as Map <String , dynamic >? ;
157
186
if (requestBody == null ) {
@@ -185,6 +214,16 @@ Future<Response> _handlePut(
185
214
}
186
215
187
216
dynamic updatedItem; // Use dynamic
217
+
218
+ String ? userIdForRepoCall;
219
+ if (modelConfig.ownership == ModelOwnership .userOwned) {
220
+ userIdForRepoCall = authenticatedUser.id;
221
+ } else {
222
+ // For global models, update might imply admin rights.
223
+ // For now, pass null, assuming repo handles global updates or has other checks.
224
+ userIdForRepoCall = null ;
225
+ }
226
+
188
227
// Repository exceptions (like NotFoundException, BadRequestException)
189
228
// will propagate up.
190
229
try {
@@ -193,57 +232,69 @@ Future<Response> _handlePut(
193
232
{
194
233
final repo = context.read <HtDataRepository <Headline >>();
195
234
final typedItem = itemToUpdate as Headline ;
196
- // Validate ID match between path and body
197
235
if (typedItem.id != id) {
198
236
return Response (
199
237
statusCode: HttpStatus .badRequest,
200
238
body:
201
239
'Bad Request: ID in request body ("${typedItem .id }") does not match ID in path ("$id ").' ,
202
240
);
203
241
}
204
- updatedItem = await repo.update (id, typedItem);
242
+ updatedItem = await repo.update (
243
+ id: id,
244
+ item: typedItem,
245
+ userId: userIdForRepoCall,
246
+ );
205
247
}
206
248
case 'category' :
207
249
{
208
250
final repo = context.read <HtDataRepository <Category >>();
209
251
final typedItem = itemToUpdate as Category ;
210
- // Validate ID match between path and body
211
252
if (typedItem.id != id) {
212
253
return Response (
213
254
statusCode: HttpStatus .badRequest,
214
255
body:
215
256
'Bad Request: ID in request body ("${typedItem .id }") does not match ID in path ("$id ").' ,
216
257
);
217
258
}
218
- updatedItem = await repo.update (id, typedItem);
259
+ updatedItem = await repo.update (
260
+ id: id,
261
+ item: typedItem,
262
+ userId: userIdForRepoCall,
263
+ );
219
264
}
220
265
case 'source' :
221
266
{
222
267
final repo = context.read <HtDataRepository <Source >>();
223
268
final typedItem = itemToUpdate as Source ;
224
- // Validate ID match between path and body
225
269
if (typedItem.id != id) {
226
270
return Response (
227
271
statusCode: HttpStatus .badRequest,
228
272
body:
229
273
'Bad Request: ID in request body ("${typedItem .id }") does not match ID in path ("$id ").' ,
230
274
);
231
275
}
232
- updatedItem = await repo.update (id, typedItem);
276
+ updatedItem = await repo.update (
277
+ id: id,
278
+ item: typedItem,
279
+ userId: userIdForRepoCall,
280
+ );
233
281
}
234
282
case 'country' :
235
283
{
236
284
final repo = context.read <HtDataRepository <Country >>();
237
285
final typedItem = itemToUpdate as Country ;
238
- // Validate ID match between path and body
239
286
if (typedItem.id != id) {
240
287
return Response (
241
288
statusCode: HttpStatus .badRequest,
242
289
body:
243
290
'Bad Request: ID in request body ("${typedItem .id }") does not match ID in path ("$id ").' ,
244
291
);
245
292
}
246
- updatedItem = await repo.update (id, typedItem);
293
+ updatedItem = await repo.update (
294
+ id: id,
295
+ item: typedItem,
296
+ userId: userIdForRepoCall,
297
+ );
247
298
}
248
299
default :
249
300
// This case should ideally be caught by middleware, but added for safety
@@ -293,20 +344,38 @@ Future<Response> _handleDelete(
293
344
RequestContext context,
294
345
String id,
295
346
String modelName,
296
- String requestId, // Receive requestId for logging
347
+ ModelConfig <dynamic > modelConfig, // Receive modelConfig
348
+ User authenticatedUser, // Receive authenticatedUser
349
+ String requestId,
297
350
) async {
351
+ String ? userIdForRepoCall;
352
+ if (modelConfig.ownership == ModelOwnership .userOwned) {
353
+ userIdForRepoCall = authenticatedUser.id;
354
+ } else {
355
+ // For global models, delete might imply admin rights.
356
+ // For now, pass null.
357
+ userIdForRepoCall = null ;
358
+ }
359
+
298
360
// Allow repository exceptions (e.g., NotFoundException) to propagate
299
361
// upwards to be handled by the standard error handling mechanism.
300
- // (Removed the overly broad try-catch block that was previously here).
301
362
switch (modelName) {
302
363
case 'headline' :
303
- await context.read <HtDataRepository <Headline >>().delete (id);
364
+ await context
365
+ .read <HtDataRepository <Headline >>()
366
+ .delete (id: id, userId: userIdForRepoCall);
304
367
case 'category' :
305
- await context.read <HtDataRepository <Category >>().delete (id);
368
+ await context
369
+ .read <HtDataRepository <Category >>()
370
+ .delete (id: id, userId: userIdForRepoCall);
306
371
case 'source' :
307
- await context.read <HtDataRepository <Source >>().delete (id);
372
+ await context
373
+ .read <HtDataRepository <Source >>()
374
+ .delete (id: id, userId: userIdForRepoCall);
308
375
case 'country' :
309
- await context.read <HtDataRepository <Country >>().delete (id);
376
+ await context
377
+ .read <HtDataRepository <Country >>()
378
+ .delete (id: id, userId: userIdForRepoCall);
310
379
default :
311
380
// This case should ideally be caught by the data/_middleware.dart,
312
381
// but added for safety. Consider logging this unexpected state.
0 commit comments