CodamAIDocs
Themafertig

Was eine Revision festhält

Nummer, Zeitpunkt, Person, IP-Adresse, Browser, und dass es pro Datenbank ein eigenes Revisionsprotokoll gibt.

Ausprägungen
RevisionsnummerZeitpunktPerson (ID und Name)handelnde Person bei einem BenutzerwechselIP-AdresseUser-AgentÄnderung ohne Benutzerein Revisionsprotokoll je Datenbank

Worum es geht

Eine Revision besteht aus zwei Teilen:

  • dem Stand des Objekts: alle Felder so, wie sie nach der Änderung waren,
  • den Revisionsdaten: Nummer, Zeitpunkt und wer die Änderung von wo gemacht hat.

Hier geht es um den zweiten Teil.

Eine Revision im Beispiel

So kommt eine Revision in der Historie an:

Ein Eintrag aus der Historie
Anfrage
POST /api/rest/order/7e1…/history
{ "response": ["orderNr", "price"] }
Antwort
{ "data": [
    { "revision": { "id": "7e1…", "orderNr": "A-1000", "price": 120.5 },
      "revisionMeta": {
        "ref": 42,
        "ts": 1790000200000,
        "ip": "203.0.113.7",
        "useragent": "Mozilla/5.0 (X11; Linux x86_64) …",
        "username": "Anna Muster",
        "actingUsername": null
      },
      "revisionType": "MOD" },
    …
  ],
  "meta": { … } }
Feld in der AntwortSpalte in revinfoBedeutung
revisionMeta.refidRevisionsnummer. Du brauchst sie für einen Rollback.
revisionMeta.tstimestampZeitpunkt in Millisekunden seit dem 1.1.1970 (UTC)
revisionMeta.usernameusernameName der Person, in deren Namen gehandelt wurde. Ohne Wechsel die Person aus dem Token.
revisionMeta.actingUsernameacting_usernameName der angemeldeten Person, bis 255 Zeichen. Nur nach einem Benutzerwechsel gefüllt, sonst null.
revisionMeta.ipip_addressIP-Adresse der Anfrage, bis 45 Zeichen, also auch IPv6
revisionMeta.useragentuser_agentBrowser oder Programm, bis 512 Zeichen
–user_idID der Person, in deren Namen gehandelt wurde (Claim sub). Sie steht in der Datenbank, die Historie liefert sie nicht aus.
–acting_user_idID der angemeldeten Person, bis 36 Zeichen. Nur nach einem Benutzerwechsel gefüllt. Die Historie liefert sie nicht aus.
revisionType–ADD, MOD oder DEL, siehe Was auditiert wird
revisionZeile in <tabelle>_AUDder Stand des Objekts, nur die angeforderten Felder

Woher die Werte kommen

CDMS erfindet keine dieser Angaben. Sie stammen aus der Anfrage, die die Änderung ausgelöst hat:

Vom Request zur Zeile in revinfo
  1. 1
    Client→CIAS
    schickt eine schreibende Anfrage mit Token
  2. 2
    CIAS
    Die Filterkette liest IP-Adresse und User-Agent aus der Anfrage.
    IP: erster Eintrag im Header X-Forwarded-For; fehlt er, X-Real-IP; fehlt auch der, die Absenderadresse der Verbindung. User-Agent: der Header User-Agent, sonst unknown.
  3. 3
    CIAS
    Sie liest Benutzer-ID und Namen aus dem Token.
    ID: Claim sub. Name: standardmäßig Claim name, sonst preferred_username. Welche Claims gelten, ist in CIAS einstellbar.
  4. 4
    CDMS→Datenbank
    Beim erfolgreichen Ende der Anfrage schreibt Envers die Revision und übernimmt diese vier Werte.
    Ergebnis: Nummer und Zeitpunkt vergibt die Datenbank beim Schreiben. Nach einem Benutzerwechsel kommen ID und Name der angemeldeten Person als handelnde Person dazu.
Wer steht in der Revision?

Wann: Eine Person ändert Daten über die API.

Benutzer-ID, Name, IP-Adresse und User-Agent dieser Anfrage.

Wann: Lena handelt per Header user im Namen von Ben.

user_id und username nennen Ben, acting_user_id und acting_username nennen Lena. In der Historie steht username: "Ben Beispiel" und actingUsername: "Lena Support". Das gilt mit eigenen Rollen genauso wie mit den Rollen der Zielperson.

Ergebnis: Siehe Benutzerwechsel per Header.

Wann: Code ändert Daten außerhalb einer API-Anfrage, etwa ein Hintergrundjob.

Die Revision wird trotzdem geschrieben. Fehlt der Anfragekontext ganz, bleiben die vier Felder leer. Läuft der Job mit eigenem Kontext, steht dort, was der Job setzt, zum Beispiel ein technischer Benutzer und internal.

Ein Revisionsprotokoll je Datenbank

Die Tabelle revinfo gibt es in jeder Datenbank, in der CDMS Daten ablegt. Die Nummern zählen in jeder Datenbank für sich.

flowchart TB
    subgraph S["System-Datenbank"]
      S1[("revinfo<br/>1, 2, 3 …")]
      S2[("&lt;systemmodell&gt;_AUD")]
    end
    subgraph A["Mandanten-Datenbank A"]
      A1[("revinfo<br/>1, 2, 3 …")]
      A2[("order_table_AUD")]
    end
    subgraph B["Mandanten-Datenbank B"]
      B1[("revinfo<br/>1, 2, 3 …")]
      B2[("order_table_AUD")]
    end

Welche Datenbank das ist, hängt an der Ebene des Modells: System-Modelle in der System-Datenbank, Mandanten- und Benutzer-Modelle in der Datenbank des Mandanten. Siehe Modell-Ebenen und Welche Datenbank? Das Persistenzziel.

In der Betriebsart SINGLE liegt alles in einer Datenbank, und es gibt nur ein revinfo. Siehe SINGLE und MULTI.

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-persistence-database – auditing/AuditRevisionEntity (Tabelle revinfo: id, timestamp, user_id, username, acting_user_id, acting_username, ip_address, user_agent), AuditRevisionListener (Werte aus dem RequestContext, ohne Kontext leer, handelnde Person nur bei einem Wechsel), AuditHistoryReader.queryHistory (AuditRevisionMeta ohne userId), EntityClassFilterService (AuditRevisionEntity in jeder Persistenzeinheit)
  • CDMS/cdms-commons – models/response/AuditRevision, AuditRevisionMeta (ref, ts, ip, useragent, username, actingUsername)
  • CIAS/cias-authentication – JwtSessionFilter (IP aus X-Forwarded-For, X-Real-IP, Absenderadresse; User-Agent oder „unknown“), TokenParser (userId aus sub, userName aus name/preferred_username), CiasTokenProperties, TenantScope (interne Läufe)
  • documentation/50-auditierung/01-auditing-und-historie.md
Suchen