Skip to content

Commit 543df42

Browse files
committed
feat(ModelActionPermission): add requiresAuthentication flag
- Add requiresAuthentication parameter to ModelActionPermission class - Update modelRegistry to include requiresAuthentication for all actions - Set default value to true for most actions, allowing unauthenticated access only to specific endpoints like remote_config GET
1 parent 5a372bc commit 543df42

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

lib/src/registry/model_registry.dart

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class ModelActionPermission {
3131
required this.type,
3232
this.permission,
3333
this.requiresOwnershipCheck = false,
34+
this.requiresAuthentication = true,
3435
}) : assert(
3536
type != RequiredPermissionType.specificPermission ||
3637
permission != null,
@@ -48,6 +49,13 @@ class ModelActionPermission {
4849
/// is the owner of the specific data item being accessed (for item-specific
4950
/// methods like GET, PUT, DELETE on `/[id]`).
5051
final bool requiresOwnershipCheck;
52+
53+
/// Whether this action requires an authenticated user.
54+
///
55+
/// If `true` (default), the `authenticationProvider` middleware will ensure
56+
/// a valid [User] is present in the context. If `false`, the action can
57+
/// be performed by unauthenticated clients.
58+
final bool requiresAuthentication;
5159
}
5260

5361
/// {@template model_config}
@@ -126,19 +134,24 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
126134
getCollectionPermission: const ModelActionPermission(
127135
type: RequiredPermissionType.specificPermission,
128136
permission: Permissions.headlineRead,
137+
requiresAuthentication: true,
129138
),
130139
getItemPermission: const ModelActionPermission(
131140
type: RequiredPermissionType.specificPermission,
132141
permission: Permissions.headlineRead,
142+
requiresAuthentication: true,
133143
),
134144
postPermission: const ModelActionPermission(
135145
type: RequiredPermissionType.adminOnly,
146+
requiresAuthentication: true,
136147
),
137148
putPermission: const ModelActionPermission(
138149
type: RequiredPermissionType.adminOnly,
150+
requiresAuthentication: true,
139151
),
140152
deletePermission: const ModelActionPermission(
141153
type: RequiredPermissionType.adminOnly,
154+
requiresAuthentication: true,
142155
),
143156
),
144157
'topic': ModelConfig<Topic>(
@@ -148,19 +161,24 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
148161
getCollectionPermission: const ModelActionPermission(
149162
type: RequiredPermissionType.specificPermission,
150163
permission: Permissions.topicRead,
164+
requiresAuthentication: true,
151165
),
152166
getItemPermission: const ModelActionPermission(
153167
type: RequiredPermissionType.specificPermission,
154168
permission: Permissions.topicRead,
169+
requiresAuthentication: true,
155170
),
156171
postPermission: const ModelActionPermission(
157172
type: RequiredPermissionType.adminOnly,
173+
requiresAuthentication: true,
158174
),
159175
putPermission: const ModelActionPermission(
160176
type: RequiredPermissionType.adminOnly,
177+
requiresAuthentication: true,
161178
),
162179
deletePermission: const ModelActionPermission(
163180
type: RequiredPermissionType.adminOnly,
181+
requiresAuthentication: true,
164182
),
165183
),
166184
'source': ModelConfig<Source>(
@@ -170,19 +188,24 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
170188
getCollectionPermission: const ModelActionPermission(
171189
type: RequiredPermissionType.specificPermission,
172190
permission: Permissions.sourceRead,
191+
requiresAuthentication: true,
173192
),
174193
getItemPermission: const ModelActionPermission(
175194
type: RequiredPermissionType.specificPermission,
176195
permission: Permissions.sourceRead,
196+
requiresAuthentication: true,
177197
),
178198
postPermission: const ModelActionPermission(
179199
type: RequiredPermissionType.adminOnly,
200+
requiresAuthentication: true,
180201
),
181202
putPermission: const ModelActionPermission(
182203
type: RequiredPermissionType.adminOnly,
204+
requiresAuthentication: true,
183205
),
184206
deletePermission: const ModelActionPermission(
185207
type: RequiredPermissionType.adminOnly,
208+
requiresAuthentication: true,
186209
),
187210
),
188211
'country': ModelConfig<Country>(
@@ -194,19 +217,24 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
194217
getCollectionPermission: const ModelActionPermission(
195218
type: RequiredPermissionType.specificPermission,
196219
permission: Permissions.countryRead,
220+
requiresAuthentication: true,
197221
),
198222
getItemPermission: const ModelActionPermission(
199223
type: RequiredPermissionType.specificPermission,
200224
permission: Permissions.countryRead,
225+
requiresAuthentication: true,
201226
),
202227
postPermission: const ModelActionPermission(
203228
type: RequiredPermissionType.unsupported,
229+
requiresAuthentication: true,
204230
),
205231
putPermission: const ModelActionPermission(
206232
type: RequiredPermissionType.unsupported,
233+
requiresAuthentication: true,
207234
),
208235
deletePermission: const ModelActionPermission(
209236
type: RequiredPermissionType.unsupported,
237+
requiresAuthentication: true,
210238
),
211239
),
212240
'language': ModelConfig<Language>(
@@ -218,19 +246,24 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
218246
getCollectionPermission: const ModelActionPermission(
219247
type: RequiredPermissionType.specificPermission,
220248
permission: Permissions.languageRead,
249+
requiresAuthentication: true,
221250
),
222251
getItemPermission: const ModelActionPermission(
223252
type: RequiredPermissionType.specificPermission,
224253
permission: Permissions.languageRead,
254+
requiresAuthentication: true,
225255
),
226256
postPermission: const ModelActionPermission(
227257
type: RequiredPermissionType.unsupported,
258+
requiresAuthentication: true,
228259
),
229260
putPermission: const ModelActionPermission(
230261
type: RequiredPermissionType.unsupported,
262+
requiresAuthentication: true,
231263
),
232264
deletePermission: const ModelActionPermission(
233265
type: RequiredPermissionType.unsupported,
266+
requiresAuthentication: true,
234267
),
235268
),
236269
'user': ModelConfig<User>(
@@ -240,25 +273,30 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
240273
(item as User).id as String?, // User is the owner of their profile
241274
getCollectionPermission: const ModelActionPermission(
242275
type: RequiredPermissionType.adminOnly, // Only admin can list all users
276+
requiresAuthentication: true,
243277
),
244278
getItemPermission: const ModelActionPermission(
245279
type: RequiredPermissionType.specificPermission,
246280
permission: Permissions.userReadOwned, // User can read their own
247281
requiresOwnershipCheck: true, // Must be the owner
282+
requiresAuthentication: true,
248283
),
249284
postPermission: const ModelActionPermission(
250285
type: RequiredPermissionType
251286
.unsupported, // User creation handled by auth routes
287+
requiresAuthentication: true,
252288
),
253289
putPermission: const ModelActionPermission(
254290
type: RequiredPermissionType.specificPermission,
255291
permission: Permissions.userUpdateOwned, // User can update their own
256292
requiresOwnershipCheck: true, // Must be the owner
293+
requiresAuthentication: true,
257294
),
258295
deletePermission: const ModelActionPermission(
259296
type: RequiredPermissionType.specificPermission,
260297
permission: Permissions.userDeleteOwned, // User can delete their own
261298
requiresOwnershipCheck: true, // Must be the owner
299+
requiresAuthentication: true,
262300
),
263301
),
264302
'user_app_settings': ModelConfig<UserAppSettings>(
@@ -268,24 +306,29 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
268306
(item as UserAppSettings).id as String?, // User ID is the owner ID
269307
getCollectionPermission: const ModelActionPermission(
270308
type: RequiredPermissionType.unsupported, // Not accessible via collection
309+
requiresAuthentication: true,
271310
),
272311
getItemPermission: const ModelActionPermission(
273312
type: RequiredPermissionType.specificPermission,
274313
permission: Permissions.userAppSettingsReadOwned,
275314
requiresOwnershipCheck: true,
315+
requiresAuthentication: true,
276316
),
277317
postPermission: const ModelActionPermission(
278318
type: RequiredPermissionType.unsupported,
319+
requiresAuthentication: true,
279320
// Creation of UserAppSettings is handled by the authentication service
280321
// during user creation, not via a direct POST to /api/v1/data.
281322
),
282323
putPermission: const ModelActionPermission(
283324
type: RequiredPermissionType.specificPermission,
284325
permission: Permissions.userAppSettingsUpdateOwned,
285326
requiresOwnershipCheck: true,
327+
requiresAuthentication: true,
286328
),
287329
deletePermission: const ModelActionPermission(
288330
type: RequiredPermissionType.unsupported,
331+
requiresAuthentication: true,
289332
// Deletion of UserAppSettings is handled by the authentication service
290333
// during account deletion, not via a direct DELETE to /api/v1/data.
291334
),
@@ -298,24 +341,29 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
298341
as String?, // User ID is the owner ID
299342
getCollectionPermission: const ModelActionPermission(
300343
type: RequiredPermissionType.unsupported, // Not accessible via collection
344+
requiresAuthentication: true,
301345
),
302346
getItemPermission: const ModelActionPermission(
303347
type: RequiredPermissionType.specificPermission,
304348
permission: Permissions.userContentPreferencesReadOwned,
305349
requiresOwnershipCheck: true,
350+
requiresAuthentication: true,
306351
),
307352
postPermission: const ModelActionPermission(
308353
type: RequiredPermissionType.unsupported,
354+
requiresAuthentication: true,
309355
// Creation of UserContentPreferences is handled by the authentication
310356
// service during user creation, not via a direct POST to /api/v1/data.
311357
),
312358
putPermission: const ModelActionPermission(
313359
type: RequiredPermissionType.specificPermission,
314360
permission: Permissions.userContentPreferencesUpdateOwned,
315361
requiresOwnershipCheck: true,
362+
requiresAuthentication: true,
316363
),
317364
deletePermission: const ModelActionPermission(
318365
type: RequiredPermissionType.unsupported,
366+
requiresAuthentication: true,
319367
// Deletion of UserContentPreferences is handled by the authentication
320368
// service during account deletion, not via a direct DELETE to /api/v1/data.
321369
),
@@ -326,19 +374,24 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
326374
getOwnerId: null, // RemoteConfig is a global resource, not user-owned
327375
getCollectionPermission: const ModelActionPermission(
328376
type: RequiredPermissionType.unsupported, // Not accessible via collection
377+
requiresAuthentication: true,
329378
),
330379
getItemPermission: const ModelActionPermission(
331380
type: RequiredPermissionType.specificPermission,
332381
permission: Permissions.remoteConfigRead,
382+
requiresAuthentication: false, // Make remote_config GET public
333383
),
334384
postPermission: const ModelActionPermission(
335385
type: RequiredPermissionType.adminOnly, // Only administrators can create
386+
requiresAuthentication: true,
336387
),
337388
putPermission: const ModelActionPermission(
338389
type: RequiredPermissionType.adminOnly, // Only administrators can update
390+
requiresAuthentication: true,
339391
),
340392
deletePermission: const ModelActionPermission(
341393
type: RequiredPermissionType.adminOnly, // Only administrators can delete
394+
requiresAuthentication: true,
342395
),
343396
),
344397
'dashboard_summary': ModelConfig<DashboardSummary>(
@@ -348,18 +401,23 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
348401
// Permissions: Read-only for admins, all other actions unsupported.
349402
getCollectionPermission: const ModelActionPermission(
350403
type: RequiredPermissionType.unsupported,
404+
requiresAuthentication: true,
351405
),
352406
getItemPermission: const ModelActionPermission(
353407
type: RequiredPermissionType.adminOnly,
408+
requiresAuthentication: true,
354409
),
355410
postPermission: const ModelActionPermission(
356411
type: RequiredPermissionType.unsupported,
412+
requiresAuthentication: true,
357413
),
358414
putPermission: const ModelActionPermission(
359415
type: RequiredPermissionType.unsupported,
416+
requiresAuthentication: true,
360417
),
361418
deletePermission: const ModelActionPermission(
362419
type: RequiredPermissionType.unsupported,
420+
requiresAuthentication: true,
363421
),
364422
),
365423
'local_ad': ModelConfig<LocalAd>(
@@ -369,22 +427,27 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
369427
getCollectionPermission: const ModelActionPermission(
370428
type: RequiredPermissionType.specificPermission,
371429
permission: Permissions.localAdRead,
430+
requiresAuthentication: true,
372431
),
373432
getItemPermission: const ModelActionPermission(
374433
type: RequiredPermissionType.specificPermission,
375434
permission: Permissions.localAdRead,
435+
requiresAuthentication: true,
376436
),
377437
postPermission: const ModelActionPermission(
378438
type: RequiredPermissionType.adminOnly,
379439
permission: Permissions.localAdCreate,
440+
requiresAuthentication: true,
380441
),
381442
putPermission: const ModelActionPermission(
382443
type: RequiredPermissionType.adminOnly,
383444
permission: Permissions.localAdUpdate,
445+
requiresAuthentication: true,
384446
),
385447
deletePermission: const ModelActionPermission(
386448
type: RequiredPermissionType.adminOnly,
387449
permission: Permissions.localAdDelete,
450+
requiresAuthentication: true,
388451
),
389452
),
390453
};

0 commit comments

Comments
 (0)