Skip to content

Commit d029255

Browse files
Merge pull request #184 from OpenUpSA/project-perms
Activity log perms
2 parents 990be7f + 923a33e commit d029255

File tree

1 file changed

+88
-43
lines changed

1 file changed

+88
-43
lines changed

app.py

Lines changed: 88 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)