@@ -55,7 +55,7 @@ Future<Response> _handleGet(RequestContext context, String id) async {
5555Future <Response > _handlePut (RequestContext context, String id) async {
5656 final modelName = context.read <String >();
5757 final modelConfig = context.read <ModelConfig <dynamic >>();
58- final authenticatedUser = context.read <User >();
58+ final authenticatedUser = context.read <User ? >();
5959 final permissionService = context.read <PermissionService >();
6060 final userPreferenceLimitService = context.read <UserPreferenceLimitService >();
6161
@@ -92,6 +92,12 @@ Future<Response> _handlePut(RequestContext context, String id) async {
9292 }
9393
9494 if (modelName == 'user_content_preferences' ) {
95+ // User content preferences can only be updated by an authenticated user.
96+ if (authenticatedUser == null ) {
97+ throw const UnauthorizedException (
98+ 'Authentication required to update user content preferences.' ,
99+ );
100+ }
95101 if (itemToUpdate is UserContentPreferences ) {
96102 await userPreferenceLimitService.checkUpdatePreferences (
97103 authenticatedUser,
@@ -133,7 +139,7 @@ Future<Response> _handlePut(RequestContext context, String id) async {
133139Future <Response > _handleDelete (RequestContext context, String id) async {
134140 final modelName = context.read <String >();
135141 final modelConfig = context.read <ModelConfig <dynamic >>();
136- final authenticatedUser = context.read <User >();
142+ final authenticatedUser = context.read <User ? >();
137143 final permissionService = context.read <PermissionService >();
138144
139145 _logger.info ('Handling DELETE request for model "$modelName ", id "$id ".' );
@@ -155,12 +161,20 @@ Future<Response> _handleDelete(RequestContext context, String id) async {
155161
156162/// Determines the `userId` to be used for a repository call based on user
157163/// role and model configuration.
164+ ///
165+ /// If the model is user-owned and the authenticated user is not an admin,
166+ /// the authenticated user's ID is returned. Otherwise, `null` is returned,
167+ /// indicating a global operation or an admin-level bypass.
158168String ? _getUserIdForRepoCall ({
159169 required ModelConfig <dynamic > modelConfig,
160170 required PermissionService permissionService,
161- required User authenticatedUser,
171+ required User ? authenticatedUser,
162172}) {
173+ // If the model is user-owned and the user is authenticated and not an admin,
174+ // then the operation should be scoped to the authenticated user's ID.
175+ // Otherwise, it's a global operation or an admin bypass.
163176 return (modelConfig.getOwnerId != null &&
177+ authenticatedUser != null &&
164178 ! permissionService.isAdmin (authenticatedUser))
165179 ? authenticatedUser.id
166180 : null ;
0 commit comments