CodamAIDocs
Themafertig

Warum Unsichtbares 404 liefert

Ein Objekt, das man nicht sehen darf, gibt es aus Sicht des Aufrufers nicht. Das gilt auch beim Ändern und Löschen: Man kann nur schreiben, was man lesen kann.

Ausprägungen
LesenSuchenReferenzen und Listen in der responseÄndernLöschenRollbackHerunterladen

Worum es geht

Ein Objekt ist für dich unsichtbar, wenn einer der Filter der Zeilen-Ebene es ausschließt: Es gehört einer anderen Person (eigene Daten), es passt nicht zu deinem Profil (Attributfilter) oder ein eigener Filter des Projekts lässt es nicht durch.

Für ein unsichtbares Objekt antwortet CDMS genauso wie für ein Objekt, das es gar nicht gibt: 404.

Warum nicht 403?

403 oder 404
403
du darfst das nicht
  • sagt: es gibt das Objekt
  • ein Angreifer könnte fremde ids durchprobieren und lernen, welche existieren
  • CDMS nutzt 403 für fehlende Rollen: die gelten für alle Objekte gleich und verraten nichts über ein einzelnes
404
gibt es für dich nicht
  • sagt nichts darüber, ob das Objekt existiert
  • ein fremdes Objekt und eine erfundene id sehen gleich aus
  • CDMS nutzt 404 für unsichtbare Zeilen

Varianten

Unsichtbare Objekte bei jeder Operation

Wann: POST /read/{id}

  1. 1
    CDMS
    prüft die Leserolle
  2. 2
    CDMS→Database
    liest die Zeile mit id und allen Filtern
  3. 3
    CDMS
    keine Zeile → 404 not-found

Ergebnis: Beim Lesen kommt die Rolle zuerst: Ohne Leserolle bekommst du 403, auch für ein unsichtbares Objekt.

Wann: POST /query

Unsichtbare Zeilen fehlen in data und zählen nicht in totalCount. Es gibt keinen Fehler.

Ergebnis: Die Trefferzahl verrät nie, wie viele Objekte es insgesamt gibt.

Wann: Referenz oder Liste, die du mitliest

Eine unsichtbare Einzelreferenz kommt als null. In einer Liste fehlen unsichtbare Einträge.

Ergebnis: null kann also heißen: nicht gesetzt oder für dich unsichtbar.

Wann: PUT /update/{id}, PATCH /update/{id}

  1. 1
    CDMS→Database
    zählt die Zeile mit id und denselben Filtern wie beim Lesen
  2. 2
    CDMS
    0 → 404 not-found|<Dto>|<id>
  3. 3
    CDMS
    1 → prüft jetzt erst die Änderungsrolle

Ergebnis: Beim Schreiben kommt die Sichtbarkeit zuerst: unsichtbar ergibt 404, auch ohne Rolle.

Wann: Ein Kind mit id in einem verschachtelten Schreibvorgang

Dieselben Filter wie beim Lesen, angewandt auf das Ziel: Ist es für dich unsichtbar, kommt 404 missing-object|<id>|<Modell> – dieselbe Antwort wie für eine id, die es nie gab. Dazu braucht es die Leseberechtigung des Zielmodells.

Ergebnis: Verbinden kannst du dich nur mit dem, was du auch ansehen dürftest. Siehe Die vier Fälle.

Wann: DELETE /delete/{id}

Wie beim Ändern: erst Sichtbarkeit (404), dann Löschrolle (403). Eine Leserolle brauchst du nicht, die Filter des Lesens gelten trotzdem.

Ergebnis: Siehe Der Ablauf eines DELETE.

Wann: POST /{id}/rollback/{revision}

Wie beim Ändern: erst Sichtbarkeit (404), dann Rollback-Rolle (403). Ein gelöschtes Objekt gibt es nicht mehr, auch dafür kommt 404. Hängt der Rollback eine Einzelreferenz um, gilt für altes und neues Ziel dasselbe wie beim Verknüpfen.

Ergebnis: Zurücksetzen kannst du nur, was du jetzt sehen kannst.

Wann: GET /{id}/file

Der Download liest das Objekt zuerst wie ein read. Unsichtbar → 404, bevor eine Datei fließt.

Ergebnis: Siehe Herunterladen.

Wann: POST /{id}/history

Erst die beiden Rollen (403), dann die Sichtbarkeit: unsichtbar → 404 missing-object|<id>|<Modell>. Ist das Objekt gelöscht, zählt sein letzter Stand vor der Löschung. Bei einem Modell mit Filter ist eine unbekannte id von einer verborgenen nicht zu unterscheiden.

Ergebnis: Siehe Historie lesen.

Entscheidungstabelle

Antwort je nach Rolle und Sichtbarkeit
OperationRolle vorhandenObjekt sichtbarAntwort
lesennein–403 missing-permission|<leserolle>
lesenjanein404 not-found
ändern, löschen, rollback–nein404 not-found|<Dto>|<id>
ändern, löschen, rollbackneinja403 missing-permission|<rolle>
jedejajaerlaubt

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-system-layer – AbstractSystemLayer (readObject, updateObject, patchObject, deleteObject, historyRollback), AbstractLayer (recursiveRead, assertVisibleForWrite, fetchAndSetModel, fetchAndSetList)
  • CDMS/cdms-persistence-database – AbstractDatabasePersistence (count, queryObjects)
  • CDMS/cdms-commons – EntityNotFoundException
  • CDMS/cdms-generator – ApiProcessor (Download: readObject, dann downloadFile)
  • CDMS/cdms-integrationtest – AbstractDataFilterTest (readByIdWithNoAccessFilter, Update/Patch/Delete ohne Zugriff)
  • documentation/60-erweiterung/03-eigene-filter.md
Suchen