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:
2026-07-18 21:17:47 +08:00
parent db2c414c1a
commit 960753b3d6
5 changed files with 108 additions and 33 deletions
@@ -150,8 +150,14 @@ const authStore = useAuthStore()
const { hasPermission } = usePermission()
const isOwnSubmission = computed(() => authStore.user?.id === props.submission.user_id)
const canEdit = computed(() => isOwnSubmission.value || authStore.user?.is_admin || hasPermission('submission', 'edit'))
const canDelete = computed(() => isOwnSubmission.value || authStore.user?.is_admin || hasPermission('submission', 'delete'))
const canEdit = computed(() => {
if (authStore.user?.is_admin) return true
return isOwnSubmission.value ? hasPermission('submission', 'edit_self') : hasPermission('submission', 'edit_other')
})
const canDelete = computed(() => {
if (authStore.user?.is_admin) return true
return isOwnSubmission.value ? hasPermission('submission', 'delete_self') : hasPermission('submission', 'delete_other')
})
const editing = ref(false)
const editNotes = ref('')