package model import ( "encoding/json" "time" ) // Grant gives access to one resource (see internal/auth). type Grant struct { Resource string `json:"resource"` // config, sets, log, audit, * Access string `json:"access"` // read or write (write implies read) // Sets limits a "sets" grant to these dynamic sets (none: all). Sets []string `json:"sets,omitempty"` } // User is a person or a service account. type User struct { ID int64 `json:"id"` Username string `json:"username"` PasswordHash string `json:"-"` HasPassword bool `json:"has_password"` Admin bool `json:"admin"` Grants []Grant `json:"grants"` Disabled bool `json:"disabled"` Comment string `json:"comment"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` LastLoginAt *time.Time `json:"last_login_at,omitempty"` } // Token is an API token. The secret is shown once, when it is made; only // its hash is stored. type Token struct { ID int64 `json:"id"` UserID int64 `json:"user_id"` Username string `json:"username,omitempty"` Name string `json:"name"` PublicID string `json:"public_id"` SecretHash string `json:"-"` // Grants restrict the token to part of its user's permissions; nil // means all of them. Grants []Grant `json:"grants"` ExpiresAt *time.Time `json:"expires_at,omitempty"` CreatedAt time.Time `json:"created_at"` LastUsedAt *time.Time `json:"last_used_at,omitempty"` LastUsedIP string `json:"last_used_ip,omitempty"` RevokedAt *time.Time `json:"revoked_at,omitempty"` // RotatedAt is when the token last got a new secret (nil: never). RotatedAt *time.Time `json:"rotated_at,omitempty"` // After a rotation with a grace period, the previous secret keeps // working until PrevExpiresAt. PrevSecretHash string `json:"-"` PrevExpiresAt *time.Time `json:"previous_secret_valid_until,omitempty"` } // IssuedAt is when the token's current secret was made: its last // rotation, or its creation. func (t *Token) IssuedAt() time.Time { if t.RotatedAt != nil { return *t.RotatedAt } return t.CreatedAt } // Session is a web UI login. type Session struct { IDHash string `json:"-"` UserID int64 `json:"user_id"` CSRFToken string `json:"-"` CreatedAt time.Time `json:"created_at"` ExpiresAt time.Time `json:"expires_at"` LastSeenAt time.Time `json:"last_seen_at"` IP string `json:"ip"` UserAgent string `json:"user_agent"` } // AuditEvent records an action: logins, users and tokens, changes, // dynamic set entries. type AuditEvent struct { ID int64 `json:"id"` Time time.Time `json:"time"` UserID int64 `json:"user_id,omitempty"` Username string `json:"username,omitempty"` Auth string `json:"auth,omitempty"` // session, token, socket TokenID int64 `json:"token_id,omitempty"` IP string `json:"ip,omitempty"` Action string `json:"action"` Object string `json:"object,omitempty"` Result string `json:"result"` // success, failure, denied Detail string `json:"detail,omitempty"` } // Change is one object's change: Before is nil for a create, After is nil // for a delete. Settings have ID 0. type Change struct { Kind string `json:"kind"` ID int64 `json:"id"` Label string `json:"label"` Before json.RawMessage `json:"before,omitempty"` After json.RawMessage `json:"after,omitempty"` } // Action describes a change in a word. func (c Change) Action() string { switch { case c.Before == nil: return "create" case c.After == nil: return "delete" } return "update" } // Inverse is the change that undoes c. func (c Change) Inverse() Change { c.Before, c.After = c.After, c.Before return c } // HistoryEntry is a saved configuration change. type HistoryEntry struct { ID int64 `json:"id"` Time time.Time `json:"time"` UserID int64 `json:"user_id,omitempty"` Username string `json:"username"` Via string `json:"via"` // web, cli, api Description string `json:"description"` Changes []Change `json:"changes"` // RevertOf is the entry this one undid; RevertedBy the entry that // undid this one. RevertOf int64 `json:"revert_of,omitempty"` RevertedBy int64 `json:"reverted_by,omitempty"` }