Mitarbeiter-Zugang: --ohne-buckets (Server-Key ohne buckets-Scope, Buckets dann in der Konsole)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-03 11:10:09 +00:00
1 parent 10b393687c
commit 5077dd5a20
3 files changed
+15 -5

No files matched your search

+5 -2
View File
@@ -7,6 +7,7 @@
* ... --label <userId>[,<userId>...] [--yes] Label "mitarbeiter" vergeben (nur ausdrueckliche Konten)
* ... --eintrag-loeschen <employeeId> [--yes] employees-Eintrag eines Kunden loeschen (Konto bleibt)
* ... --rechte [--offen-lassen <id>[,<id>...]] Probelauf: welche Rechte sich aendern (IDs bleiben offen)
* [--ohne-buckets] Buckets auslassen (Key ohne buckets-Scope, dann in der Konsole)
* ... --rechte --anwenden [--sicherung <datei>] [--yes] Rechte umstellen, vorher Sicherung als JSON
* ... --rechte --zurueck <sicherung.json> [--yes] Rechte aus einer Sicherung wiederherstellen
*/
@@ -100,9 +101,11 @@ async function permissions() {
}
const keep = (flag('--offen-lassen') || '').split(',').map((id) => id.trim()).filter(Boolean)
const { changes, errors } = await planPermissionChanges(undefined, { keep })
const buckets = !args.includes('--ohne-buckets')
const { changes, errors } = await planPermissionChanges(undefined, { keep, buckets })
for (const e of errors) console.log(`NICHT LESBAR ${e.path}: ${e.error}`)
if (keep.length) console.log(`Bleiben offen: ${keep.join(', ')}`)
if (!buckets) console.log('Buckets übersprungen – deren Rechte bitte in der Appwrite-Konsole umstellen.')
if (!changes.length) return console.log('Keine offenen Rechte (any/guests/users) gefunden.')
printChanges(changes)
if (!args.includes('--anwenden')) return console.log(`Probelauf: ${changes.length} Stellen. Mit --anwenden umstellen.`)
@@ -123,7 +126,7 @@ async function main() {
const employeeId = flag('--eintrag-loeschen')
if (employeeId) return removeEntry(employeeId)
if (args.includes('--rechte')) return permissions()
console.log('Usage: --status | --label <userId>[,...] | --eintrag-loeschen <employeeId> | --rechte [--offen-lassen <id>,...] [--anwenden [--sicherung <datei>] | --zurueck <datei>] [--yes]')
console.log('Usage: --status | --label <userId>[,...] | --eintrag-loeschen <employeeId> | --rechte [--offen-lassen <id>,...] [--ohne-buckets] [--anwenden [--sicherung <datei>] | --zurueck <datei>] [--yes]')
}
main().catch((err) => {
+5 -3
View File
@@ -107,10 +107,11 @@ export async function removeEmployeeEntry(employeeId, request = appwriteAdminReq
/**
* Alle Stellen mit offenen Rechten: Collections und Buckets, bei Dokument- bzw. Datei-Sicherheit auch einzelne
* Dokumente und Dateien. Jede Aenderung traegt before/after, damit sie sich zuruecknehmen laesst. keep = IDs von
* Collections/Buckets, die bewusst offen bleiben (samt ihrer Dokumente/Dateien). Eine Liste, die sich nicht lesen
* Collections/Buckets, die bewusst offen bleiben (samt ihrer Dokumente/Dateien), buckets false laesst alle Buckets
* aus. Eine Liste, die sich nicht lesen
* laesst (z. B. fehlender Key-Scope), landet in errors statt den ganzen Lauf abzubrechen.
*/
export async function planPermissionChanges(request = appwriteAdminRequest, { keep = [] } = {}) {
export async function planPermissionChanges(request = appwriteAdminRequest, { keep = [], buckets = true } = {}) {
const changes = []
const errors = []
const kept = new Set(keep)
@@ -148,7 +149,8 @@ export async function planPermissionChanges(request = appwriteAdminRequest, { ke
}
}
for (const bucket of await tryList('/storage/buckets', 'buckets')) {
// buckets: false -> Buckets bleiben aussen vor (Key ohne buckets-Scope; dann von Hand in der Konsole)
for (const bucket of buckets ? await tryList('/storage/buckets', 'buckets') : []) {
if (kept.has(bucket.$id)) continue
add(
{
+5
View File
@@ -120,6 +120,11 @@ test('planPermissionChanges: liest ueber 100 Dokumente seitenweise, offen-lassen
const partial = await planPermissionChanges(failing)
assert.deepEqual(partial.errors, [{ path: '/storage/buckets', error: 'missing scope (buckets.read)' }])
assert.ok(partial.changes.some((c) => c.id === 'workorders'))
// --ohne-buckets: Buckets gar nicht erst lesen -> kein Fehler, nur Collections und Dokumente
const noBuckets = await planPermissionChanges(failing, { buckets: false })
assert.deepEqual(noBuckets.errors, [])
assert.deepEqual(noBuckets.changes.map((c) => c.kind).filter((k) => k === 'bucket'), [])
})
test('applyPermissionChanges: schreibt mit allen Einstellungen, meldet Fehler je Stelle, Ruecknahme schreibt before', async () => {