TokenChangeHistoryRecord

pydantic model gafaelfawr.models.history.TokenChangeHistoryRecord

A token change history entry populated from the database.

This model adds the unique row ID, which is not part of the public API but which is required for cursors to work correctly.

Parameters:

data (Any)

Show JSON schema
{
   "title": "TokenChangeHistoryRecord",
   "description": "A token change history entry populated from the database.\n\nThis model adds the unique row ID, which is not part of the public API but\nwhich is required for cursors to work correctly.",
   "type": "object",
   "properties": {
      "token": {
         "examples": [
            "dDQg_NTNS51GxeEteqnkag"
         ],
         "maxLength": 22,
         "minLength": 22,
         "title": "Token key",
         "type": "string"
      },
      "username": {
         "examples": [
            "someuser"
         ],
         "maxLength": 64,
         "minLength": 1,
         "title": "Username of the token",
         "type": "string"
      },
      "token_type": {
         "$ref": "#/$defs/TokenType",
         "examples": [
            "user"
         ],
         "title": "Type of the token"
      },
      "token_name": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "Only set for tokens of type user. If the name was changed, this will be the new name of the token.",
         "examples": [
            "a token"
         ],
         "title": "Name of the token"
      },
      "parent": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "examples": [
            "1NOV_8aPwhCWj6rM-p1XgQ"
         ],
         "title": "Key of parent token of this token"
      },
      "scopes": {
         "$ref": "#/$defs/Scopes",
         "examples": [
            [
               "read:all"
            ]
         ],
         "title": "Scopes of the token"
      },
      "service": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "Only set for tokens of type internal.",
         "examples": [
            "some-service"
         ],
         "title": "Service to which the token was issued"
      },
      "expires": {
         "anyOf": [
            {
               "$ref": "#/$defs/Timestamp"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "If the expiration was changed, this will be the new expiration of the token.",
         "examples": [
            1615785631
         ],
         "title": "Expiration of the token"
      },
      "actor": {
         "examples": [
            "adminuser"
         ],
         "maxLength": 64,
         "minLength": 1,
         "title": "Username of person making the change",
         "type": "string"
      },
      "action": {
         "$ref": "#/$defs/TokenChange",
         "examples": [
            "edit"
         ],
         "title": "Type of change that was made"
      },
      "old_token_name": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "This field will only be present for edit changes to user tokens that changed the token name.",
         "examples": [
            "old name"
         ],
         "title": "Previous name of the token"
      },
      "old_scopes": {
         "anyOf": [
            {
               "$ref": "#/$defs/Scopes"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "This field will only be present for edit changes that changed the token scopes.",
         "examples": [
            [
               "read:some"
            ]
         ],
         "title": "Previous scopes of the token"
      },
      "old_expires": {
         "anyOf": [
            {
               "$ref": "#/$defs/Timestamp"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "This field will only be present for edit changes that changed the expiration of the token.",
         "examples": [
            1614985631
         ],
         "title": "Previous expiration of the token"
      },
      "ip_address": {
         "anyOf": [
            {
               "$ref": "#/$defs/IpAddress"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "May be null if the change was made internally, such as token deletion due to expiration.",
         "examples": [
            "198.51.100.50"
         ],
         "title": "IP address from which the change was made"
      },
      "event_time": {
         "$ref": "#/$defs/Timestamp",
         "examples": [
            1614985631
         ],
         "title": "Whent he change was made"
      },
      "id": {
         "description": "Database unique row ID, not included in the API",
         "title": "Unique ID",
         "type": "integer"
      }
   },
   "$defs": {
      "IpAddress": {
         "type": "string"
      },
      "Scopes": {},
      "Timestamp": {
         "format": "date-time",
         "type": "string"
      },
      "TokenChange": {
         "description": "Type of change made to a token.",
         "enum": [
            "create",
            "revoke",
            "expire",
            "edit"
         ],
         "title": "TokenChange",
         "type": "string"
      },
      "TokenType": {
         "description": "The class of token.",
         "enum": [
            "session",
            "user",
            "notebook",
            "internal",
            "service",
            "oidc"
         ],
         "title": "TokenType",
         "type": "string"
      }
   },
   "required": [
      "token",
      "username",
      "token_type",
      "scopes",
      "actor",
      "action",
      "id"
   ]
}

Fields:
field action: TokenChange [Required]
field actor: str [Required]
Constraints:
  • min_length = 1

  • max_length = 64

field event_time: Timestamp [Optional]
field expires: Timestamp | None = None

If the expiration was changed, this will be the new expiration of the token.

field id: int [Required]

Database unique row ID, not included in the API

field ip_address: IpAddress | None = None

May be null if the change was made internally, such as token deletion due to expiration.

field old_expires: Timestamp | None = None

This field will only be present for edit changes that changed the expiration of the token.

field old_scopes: Scopes | None = None

This field will only be present for edit changes that changed the token scopes.

field old_token_name: str | None = None

This field will only be present for edit changes to user tokens that changed the token name.

field parent: str | None = None
field scopes: Scopes [Required]
field service: str | None = None

Only set for tokens of type internal.

field token: str [Required]
Constraints:
  • min_length = 22

  • max_length = 22

field token_name: str | None = None

Only set for tokens of type user. If the name was changed, this will be the new name of the token.

field token_type: TokenType [Required]
field username: str [Required]
Constraints:
  • min_length = 1

  • max_length = 64

model_dump_reduced()

Convert to a dictionary while suppressing some fields.

The same as the standard Pydantic model_dump method, but excludes the old_ fields for changes other than edits and when the edit doesn’t change those fields.

Returns:

Dictionary representation of the object.

Return type:

dict

Notes

Knowing which fields to exclude requires understanding the semantics of the change (particularly when deciding whether to drop old_expires) in ways that are too complex to do with the standard Pydantic filtering API, hence the hand-rolled method.