@@ -281,24 +281,71 @@ async def import_models(
281281 model .id : model for model in (await Models .get_models_by_ids (model_ids , db = db ) if model_ids else [])
282282 }
283283
284+ # Batch-resolve write permissions in one query instead of
285+ # per-model has_access calls (N+1 avoidance).
286+ existing_model_ids = list (existing_models .keys ())
287+ if user .role != 'admin' and existing_model_ids :
288+ groups = await Groups .get_groups_by_member_id (user .id , db = db )
289+ user_group_ids = {group .id for group in groups }
290+ writable_model_ids = await AccessGrants .get_accessible_resource_ids (
291+ user_id = user .id ,
292+ resource_type = 'model' ,
293+ resource_ids = existing_model_ids ,
294+ permission = 'write' ,
295+ user_group_ids = user_group_ids ,
296+ db = db ,
297+ )
298+ else :
299+ writable_model_ids = set (existing_model_ids )
300+
284301 for model_data in data :
285- # Here, you can add logic to validate model_data if needed
286302 model_id = model_data .get ('id' )
287303
288304 if model_id and is_valid_model_id (model_id ):
289305 existing_model = existing_models .get (model_id )
290306 if existing_model :
307+ # Enforce ownership/write-access before allowing overwrite
308+ if (
309+ user .role != 'admin'
310+ and existing_model .user_id != user .id
311+ and model_id not in writable_model_ids
312+ ):
313+ log .warning (
314+ 'import_models: user %s skipped model %s (no write access)' ,
315+ user .id ,
316+ model_id ,
317+ )
318+ continue
319+
291320 # Update existing model
292321 model_data ['meta' ] = model_data .get ('meta' , {})
293322 model_data ['params' ] = model_data .get ('params' , {})
294323
295324 updated_model = ModelForm (** {** existing_model .model_dump (), ** model_data })
325+ # Only filter access_grants when explicitly provided
326+ # in the payload to avoid altering existing ACLs on
327+ # metadata-only imports.
328+ if 'access_grants' in model_data :
329+ updated_model .access_grants = await filter_allowed_access_grants (
330+ request .app .state .config .USER_PERMISSIONS ,
331+ user .id ,
332+ user .role ,
333+ updated_model .access_grants ,
334+ 'sharing.public_models' ,
335+ )
296336 await Models .update_model_by_id (model_id , updated_model , db = db )
297337 else :
298338 # Insert new model
299339 model_data ['meta' ] = model_data .get ('meta' , {})
300340 model_data ['params' ] = model_data .get ('params' , {})
301341 new_model = ModelForm (** model_data )
342+ new_model .access_grants = await filter_allowed_access_grants (
343+ request .app .state .config .USER_PERMISSIONS ,
344+ user .id ,
345+ user .role ,
346+ new_model .access_grants ,
347+ 'sharing.public_models' ,
348+ )
302349 await Models .insert_new_model (user_id = user .id , form_data = new_model , db = db )
303350 return True
304351 else :
0 commit comments