CodamAIDocs
Themafertig

Nur die eigenen Daten (Owner-Filter)

Bei Benutzer-Modellen sieht jede Person nur ihre eigenen Zeilen. Wie _userId gesetzt und geprüft wird.

Ausprägungen
AnlegenLesenSuchenÄndern und Löschenmitangelegte KinderTechnischer Client ohne Personim Auftrag einer anderen Person

Worum es geht

Manche Daten gehören einer einzelnen Person: Notizen, Entwürfe, persönliche Einstellungen. Dafür gibt es Benutzer-Modelle (Ebene USER). Jede Zeile eines Benutzer-Modells hat ein Systemfeld _userId, die ID der Person, der sie gehört.

CDMS hängt an jede Anfrage auf ein Benutzer-Modell eine Bedingung an: _userId = angemeldete Person. Diese Bedingung heißt Owner-Filter. Du siehst sie nicht in deiner Anfrage und kannst sie nicht abschalten.

Wann du ein Modell auf die Ebene USER setzt, steht unter Modell-Ebenen.

Zwei Personen, eine Tabelle

flowchart LR
    subgraph T["Tabelle note in der Datenbank des Mandanten"]
        R1["Einkaufsliste<br/>_userId = anna"]
        R2["Urlaubsplan<br/>_userId = anna"]
        R3["Projektideen<br/>_userId = ben"]
    end
    A(["Anna: POST /note/query"]) --> F1{"_userId = anna"}
    B(["Ben: POST /note/query"]) --> F2{"_userId = ben"}
    F1 --> R1
    F1 --> R2
    F2 --> R3

Beide schicken dieselbe Suche. Anna bekommt zwei Treffer, Ben einen. totalCount zählt jeweils nur die eigenen Zeilen.

Woher die ID kommt

Die ID der Person steht im Token, standardmäßig im Claim sub. CIAS liest sie bei jeder Anfrage aus und gibt sie an CDMS weiter. Der Client schickt sie nie selbst mit.

Varianten

Der Owner-Filter bei jeder Operation

Wann: POST /note/create

  1. 1
    Client→CDMS
    schickt die Notiz, mit oder ohne _userId
  2. 2
    CDMS
    setzt _userId auf die ID der angemeldeten Person, ein mitgeschickter Wert zählt nicht
  3. 3
    CDMS→Database
    speichert die Notiz

Ergebnis: Die Notiz gehört immer der Person, die sie anlegt.

Wann: POST /note/read/{id}

  1. 1
    CDMS→Database
    liest die Zeile mit id und _userId = angemeldete Person
  2. 2
    CDMS
    keine Zeile gefunden → 404 not-found

Ergebnis: Eine fremde Notiz sieht aus wie eine, die es nicht gibt.

Wann: POST /note/query

CDMS verbindet deine Filter mit UND mit _userId = angemeldete Person. Fremde Zeilen fehlen in data und zählen nicht in totalCount.

Ergebnis: Auch Listen in einer response, z. B. die Notizen an einem anderen Objekt, zeigen nur die eigenen Zeilen.

Wann: PUT, PATCH, DELETE, rollback

  1. 1
    CDMS→Database
    zählt die Zeile mit id und _userId = angemeldete Person
  2. 2
    CDMS
    0 → 404 not-found|<Dto>|<id>, noch vor der Rollenprüfung
  3. 3
    CDMS
    1 → weiter wie gewohnt; _userId bleibt unverändert, auch wenn der Client einen anderen Wert schickt

Ergebnis: Niemand kann eine Zeile einer anderen Person übernehmen oder sich selbst eine Zeile zuschieben.

Wann: Ein Create legt über eine Beziehung Objekte eines Benutzer-Modells mit an.

Jedes mitangelegte Objekt eines Benutzer-Modells bekommt ebenfalls die ID der angemeldeten Person als _userId.

Ergebnis: Alles, was eine Anfrage anlegt, gehört derselben Person.

Entscheidungstabelle

Was Anna mit einer Notiz tun kann
_userId der NotizRolle für die OperationErgebnis
annajaerlaubt
annanein403 missing-permission|<rolle>
ben–lesen, ändern, löschen: 404; suchen: fehlt in der Liste

Technische Clients

Ein Server, der sich mit Client Credentials anmeldet, hat keine echte Person. Im Token steht dann die ID seines Dienstkontos. Für den Owner-Filter ist das Dienstkonto eine Person wie jede andere:

  • Was der Server anlegt, gehört dem Dienstkonto.
  • Der Server sieht nur Zeilen, die das Dienstkonto selbst angelegt hat, keine Zeilen echter Personen.

Soll ein Dienst Daten echter Personen bearbeiten, ist ein Benutzer-Modell meist die falsche Wahl. Nimm dann ein Mandanten-Modell und schränke es mit einem Attributfilter oder einem eigenen Filter ein.

Im Auftrag einer anderen Person

In CDMS gibt es keine Rolle, die den Owner-Filter aufhebt, auch für Administratoren nicht. Muss jemand die Daten einer bestimmten Person sehen, nutzt er den Benutzerwechsel von CIAS: Wer die Realm-Rolle allowed-user-context-switch hat, schickt im Header user die ID der anderen Person. Die Person muss es geben, sie muss, wenn die Anfrage unter einem Mandanten läuft, zu diesem Mandanten gehören, und sie muss den Wechsel freigegeben haben. Sonst antwortet CIAS mit 403. Der Owner-Filter arbeitet danach mit ihrer ID und zeigt genau ihre Zeilen. Ob dabei deine Rollen gelten oder ihre, wählst du mit dem Header user-roles. Mehr unter Benutzerwechsel per Header.

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-system-layer – AbstractLayer (recursivePrepare: set_userId, addSecurityFilters, buildSearchRoot, assertVisibleForWrite, recursiveCreate/Update/Patch: Felder mit _ übersprungen)
  • CDMS/cdms-persistence-database – AbstractUserModel
  • CDMS/cdms-generator – CdmsYamlLoader (modelType USER), EntityProcessor, DtoProcessor
  • CIAS/cias-authentication – TokenParser (userId), CiasTokenProperties (Claim sub), TokenParser.switchUser
  • CDMS/cdms-integrationtest – AbstractDataFilterTest
  • documentation/10-cdms-grundlagen/02-modelle-und-metadaten.md
Suchen