Make note/submission edit-own and edit-others' permissions explicit
Split note:edit/note:delete and submission:edit/submission:delete into four independent permissions each - edit_self/delete_self (acting on your own note or submission) and edit_other/delete_other (acting on someone else's). Previously "own" access was an unconditional, unrevokable ownership check with no permission behind it, and a prior round had accidentally granted coordinator submission:edit/delete by default (inconsistent with notes, which were correctly own-only) - both are fixed here: self-service now goes through a real, default-granted-to-everyone permission, and acting on someone else's note/submission is an explicit elevated grant that nobody gets by default. The Role Management permission editor now shows "Edit Own / Delete Own / Edit Others' / Delete Others'" as four clear, independently toggleable options instead of one ambiguous "Edit"/"Delete" checkbox. migrate_role_permissions.py renames the existing permission rows in place (rather than leaving orphaned duplicates) and includes a one-time, idempotent correction that revokes the earlier over-grant from coordinator. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+26
-16
@@ -1260,10 +1260,12 @@ async def update_task_note(
|
||||
if not note:
|
||||
raise HTTPException(status_code=404, detail="Note not found")
|
||||
|
||||
# Users can only update their own notes, unless they have admin permission or note:edit
|
||||
if (note.user_id != current_user.id and not current_user.is_admin
|
||||
and not user_has_permission(current_user, 'note', 'edit', db)):
|
||||
raise HTTPException(status_code=403, detail="Not authorized to update this note")
|
||||
# Editing your own note requires note:edit_self; editing someone else's requires note:edit_other
|
||||
if not current_user.is_admin:
|
||||
is_own = note.user_id == current_user.id
|
||||
action = 'edit_self' if is_own else 'edit_other'
|
||||
if not user_has_permission(current_user, 'note', action, db):
|
||||
raise HTTPException(status_code=403, detail="Not authorized to update this note")
|
||||
|
||||
note.content = note_update.content
|
||||
db.commit()
|
||||
@@ -1308,10 +1310,12 @@ async def delete_task_note(
|
||||
if not note:
|
||||
raise HTTPException(status_code=404, detail="Note not found")
|
||||
|
||||
# Users can only delete their own notes, unless they have admin permission or note:delete
|
||||
if (note.user_id != current_user.id and not current_user.is_admin
|
||||
and not user_has_permission(current_user, 'note', 'delete', db)):
|
||||
raise HTTPException(status_code=403, detail="Not authorized to delete this note")
|
||||
# Deleting your own note requires note:delete_self; deleting someone else's requires note:delete_other
|
||||
if not current_user.is_admin:
|
||||
is_own = note.user_id == current_user.id
|
||||
action = 'delete_self' if is_own else 'delete_other'
|
||||
if not user_has_permission(current_user, 'note', action, db):
|
||||
raise HTTPException(status_code=403, detail="Not authorized to delete this note")
|
||||
|
||||
db.delete(note)
|
||||
db.commit()
|
||||
@@ -1645,10 +1649,13 @@ async def update_task_submission(
|
||||
if not submission:
|
||||
raise HTTPException(status_code=404, detail="Submission not found")
|
||||
|
||||
# Users can only update their own submissions, unless they have admin permission or submission:edit
|
||||
if (submission.user_id != current_user.id and not current_user.is_admin
|
||||
and not user_has_permission(current_user, 'submission', 'edit', db)):
|
||||
raise HTTPException(status_code=403, detail="Not authorized to update this submission")
|
||||
# Editing your own submission requires submission:edit_self; editing
|
||||
# someone else's requires submission:edit_other
|
||||
if not current_user.is_admin:
|
||||
is_own = submission.user_id == current_user.id
|
||||
action = 'edit_self' if is_own else 'edit_other'
|
||||
if not user_has_permission(current_user, 'submission', action, db):
|
||||
raise HTTPException(status_code=403, detail="Not authorized to update this submission")
|
||||
|
||||
if submission_update.notes is not None:
|
||||
submission.notes = submission_update.notes
|
||||
@@ -1692,10 +1699,13 @@ async def delete_task_submission(
|
||||
if not submission:
|
||||
raise HTTPException(status_code=404, detail="Submission not found")
|
||||
|
||||
# Users can only delete their own submissions, unless they have admin permission or submission:delete
|
||||
if (submission.user_id != current_user.id and not current_user.is_admin
|
||||
and not user_has_permission(current_user, 'submission', 'delete', db)):
|
||||
raise HTTPException(status_code=403, detail="Not authorized to delete this submission")
|
||||
# Deleting your own submission requires submission:delete_self; deleting
|
||||
# someone else's requires submission:delete_other
|
||||
if not current_user.is_admin:
|
||||
is_own = submission.user_id == current_user.id
|
||||
action = 'delete_self' if is_own else 'delete_other'
|
||||
if not user_has_permission(current_user, 'submission', action, db):
|
||||
raise HTTPException(status_code=403, detail="Not authorized to delete this submission")
|
||||
|
||||
submission.deleted_at = datetime.utcnow()
|
||||
submission.deleted_by = current_user.id
|
||||
|
||||
Reference in New Issue
Block a user