@@ -2200,7 +2200,6 @@ def delete(self, project_id, submission_id, file_id):
22002200 'message' : 'File deleted successfully' ,
22012201 'file_id' : file_id
22022202 }, 200
2203-
22042203 except Exception as e :
22052204 logger .exception (f"Error deleting file { file_id } from submission { submission_id } : { str (e )} " )
22062205 return {'error' : f'Deletion failed: { str (e )} ' }, 500
@@ -3174,59 +3173,105 @@ class ActivityLogs(Resource):
31743173
31753174 @study_ns .doc ('list_logs' )
31763175 @require_auth (keycloak_auth )
3177- @require_permission ('view_activity_log' , resource_type = 'project' , resource_id_arg = 'resource_id' )
31783176 def get (self , resource_id ):
31793177 try :
3178+ # Check what type of resource this is
3179+ with get_db_cursor () as cursor :
3180+ cursor .execute ("""
3181+ SELECT id FROM projects WHERE id = %s
3182+ """ , (resource_id ,))
3183+ is_project = cursor .fetchone () is not None
3184+
3185+ cursor .execute ("""
3186+ SELECT id FROM organisations WHERE id = %s
3187+ """ , (resource_id ,))
3188+ is_org = cursor .fetchone () is not None
3189+
3190+ cursor .execute ("""
3191+ SELECT id, project_id FROM submissions WHERE id = %s
3192+ """ , (resource_id ,))
3193+ submission = cursor .fetchone ()
3194+ is_submission = submission is not None
3195+
3196+ if not is_project and not is_org and not is_submission :
3197+ return {'error' : 'Resource not found' }, 404
3198+
3199+ # Check permissions based on resource type
3200+ user_info = extract_user_info (request .user )
3201+
3202+ if is_project :
3203+ has_perm , details = user_has_permission (
3204+ user_info ,
3205+ 'view_activity_log' ,
3206+ resource_type = 'project' ,
3207+ resource_id = resource_id
3208+ )
3209+ elif is_submission :
3210+ parent_project_id = submission ['project_id' ]
3211+ has_perm , details = user_has_permission (
3212+ user_info ,
3213+ 'view_activity_log' ,
3214+ resource_type = 'project' ,
3215+ resource_id = parent_project_id
3216+ )
3217+ else : # is_org
3218+ user_org_id = user_info .get ('organisation_id' )
3219+ user_roles = user_info .get ('roles' , [])
3220+ is_system_admin = 'system-admin' in user_roles
3221+ is_org_partial = 'agari-org-partial' in user_roles
3222+
3223+ # org-partial users cannot view organization logs
3224+ if is_org_partial :
3225+ return {'error' : 'Permission denied. Partial members cannot view organization activity logs.' }, 403
3226+
3227+ if isinstance (user_org_id , list ):
3228+ has_perm = resource_id in user_org_id or is_system_admin
3229+ else :
3230+ has_perm = user_org_id == resource_id or is_system_admin
3231+
3232+ details = {'checked' : 'organisation_membership' }
3233+
3234+ if not has_perm :
3235+ return {'error' : 'Permission denied' , 'details' : details }, 403
3236+
3237+ # Fetch logs with pagination
31803238 page = int (request .args .get ('page' , 1 ))
31813239 limit = min (int (request .args .get ('limit' , 10 )), 100 )
31823240 offset = (page - 1 ) * limit
31833241
31843242 with get_db_cursor () as cursor :
3185- paginate_activity_log = True
3243+ cursor .execute ("""
3244+ SELECT COUNT(*) as total
3245+ FROM logs
3246+ WHERE resource_id = %s
3247+ """ , (resource_id ,))
3248+ total_entries = cursor .fetchone ()['total' ]
31863249
3187- if not paginate_activity_log :
3188- cursor .execute ("""
3189- SELECT *
3190- FROM logs
3191- WHERE resource_id = %s
3192- ORDER BY created_at DESC
3193- """ , (resource_id ,))
3194- logs = cursor .fetchall ()
3195- return logs
3196- else :
3197- cursor .execute ("""
3198- SELECT COUNT(*) as total
3199- FROM logs
3200- WHERE resource_id = %s
3201- """ , (resource_id ,))
3202- total_entries = cursor .fetchone ()['total' ]
3250+ cursor .execute ("""
3251+ SELECT *
3252+ FROM logs
3253+ WHERE resource_id = %s
3254+ ORDER BY created_at DESC
3255+ LIMIT %s OFFSET %s
3256+ """ , (resource_id , limit , offset ))
3257+ logs = cursor .fetchall ()
32033258
3204- main_query = """
3205- SELECT *
3206- FROM logs
3207- WHERE resource_id = %s
3208- ORDER BY created_at DESC
3209- LIMIT %s OFFSET %s
3210- """
3211- cursor .execute (main_query , (resource_id , limit , offset ))
3212- logs = cursor .fetchall ()
3213-
3214- # Pagination metadata
3215- total_pages = (total_entries + limit - 1 ) // limit
3216- has_next = page < total_pages
3217- has_prev = page > 1
3259+ # Pagination metadata
3260+ total_pages = (total_entries + limit - 1 ) // limit
3261+ has_next = page < total_pages
3262+ has_prev = page > 1
32183263
3219- return {
3220- 'logs' : logs ,
3221- 'pagination' : {
3222- 'page' : page ,
3223- 'limit' : limit ,
3224- 'total_entries' : total_entries ,
3225- 'total_pages' : total_pages ,
3226- 'has_next' : has_next ,
3227- 'has_prev' : has_prev
3228- }
3264+ return {
3265+ 'logs' : logs ,
3266+ 'pagination' : {
3267+ 'page' : page ,
3268+ 'limit' : limit ,
3269+ 'total_entries' : total_entries ,
3270+ 'total_pages' : total_pages ,
3271+ 'has_next' : has_next ,
3272+ 'has_prev' : has_prev
32293273 }
3274+ }
32303275 except Exception as e :
32313276 logger .exception ("Error retrieving activity logs" )
32323277 return {'error' : f'Database error: { str (e )} ' }, 500
0 commit comments