models

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 23, 2023 License: BSD-3-Clause Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotFound           = errors.New("object not found in the database")
	ErrInvalidUser        = errors.New("user model is not correctly populated")
	ErrInvalidPassword    = errors.New("user password should be stored as an argon2 derived key")
	ErrMissingModelID     = errors.New("model does not have an ID assigned")
	ErrMissingKeyMaterial = errors.New("apikey model requires client id and secret")
	ErrInvalidSecret      = errors.New("apikey secrets should be stored as argon2 derived keys")
	ErrMissingOrgID       = errors.New("model does not have an organization ID assigned")
	ErrMissingProjectID   = errors.New("apikey model requires project id")
	ErrMissingKeyName     = errors.New("apikey model requires name")
	ErrNoPermissions      = errors.New("apikey model requires permissions")
	ErrModifyPermissions  = errors.New("cannot modify permissions on an existing APIKey object")
	ErrMissingPageSize    = errors.New("cannot list database without a page size")
	ErrInvalidCursor      = errors.New("could not compute the next page of results")
)

Functions

func CountUsers

func CountUsers(ctx context.Context) (count int64, err error)

CountUsers returns the number of users currently in the database.

func DeleteAPIKey

func DeleteAPIKey(ctx context.Context, id, orgID ulid.ULID) (err error)

DeleteAPIKey by ID restricted to the organization ID supplied. E.g. in order to delete an API Key both the key ID and the organization ID must match otherwise an ErrNotFound is returned. This method expects to only delete one row at a time and rolls back the operation if multiple rows are deleted.

For auditing purposes the api key is deleted from the live api_keys table but then inserted without a secret into the revoked_api_keys table. This is because logs and other information like events may have API key IDs associated with them; in order to trace those keys back to its owners, some information must be preserved. The revoked table helps maintain those connections without a lot of constraints.

Types

type APIKey

type APIKey struct {
	Base
	ID        ulid.ULID
	KeyID     string
	Secret    string
	Name      string
	OrgID     ulid.ULID
	ProjectID ulid.ULID
	CreatedBy ulid.ULID
	Source    sql.NullString
	UserAgent sql.NullString
	LastUsed  sql.NullString
	// contains filtered or unexported fields
}

APIKey is a model that represents a row in the api_keys table and provides database functionality for interacting with api key data. It should not be used for API serialization.

func GetAPIKey

func GetAPIKey(ctx context.Context, clientID string) (key *APIKey, err error)

GetAPIKey by Client ID. This query is executed as a read-only transaction. When fetching by Client ID we expect that an authentication is being performed, so the secret is also fetched.

func ListAPIKeys

func ListAPIKeys(ctx context.Context, orgID, projectID ulid.ULID, prevPage *pagination.Cursor) (keys []*APIKey, cursor *pagination.Cursor, err error)

ListAPIKeys returns a paginated collection of APIKeys from the database filtered by the orgID and optionally by the projectID. To fetch all keys for an organization, pass a zero-valued ULID as the projectID. The number of results returned is controlled by the prevPage cursor. To return the first page with a default number of results pass nil for the prevPage; otherwise pass an empty page with the specified PageSize. If the prevPage contains an EndIndex then the next page is returned.

An apikeys slice with the maximum length of the page size will be returned or an empty (nil) slice if there are no results. If there is a next page of results, e.g. there is another row after the page returned, then a cursor will be returned to compute the next page token with.

func RetrieveAPIKey

func RetrieveAPIKey(ctx context.Context, id ulid.ULID) (key *APIKey, err error)

RetrieveAPIKey by ID. This query is executed as a read-only transaction. When retrieving a key by ID we expect that this is for informational purposes and not for authentication so the secret is not returned.

func (*APIKey) AddPermissions

func (k *APIKey) AddPermissions(permissions ...string) error

AddPermissions to an APIKey that has not been created yet. If the APIKey has an ID an error is returned since APIKey permissions cannot be modified. This method will append permissions to the uncreated Key.

func (*APIKey) Create

func (k *APIKey) Create(ctx context.Context) (err error)

Create an APIKey, inserting the record in the database. If the record already exists or a uniqueness constraint is violated an error is returned. Creating the APIKey will also associate the permissions with the key. If a permission does not exist in the database, an error will be returned. This method sets the ID, created, and modified timestamps even if the user has already set them on the model. If the APIKey does not have a client ID and secret, they're generated before the model is created.

func (*APIKey) GetLastUsed

func (k *APIKey) GetLastUsed() (time.Time, error)

GetLastUsed returns the parsed LastUsed timestamp if it is not null. If it is null then a zero-valued timestamp is returned without an error.

func (*APIKey) Permissions

func (k *APIKey) Permissions(ctx context.Context, refresh bool) (_ []string, err error)

Returns the Permissions associated with the user as a list of strings. The permissions are cached to prevent multiple queries; use the refresh bool to force a new database query to reload the permissions of the user.

func (*APIKey) SetLastUsed

func (k *APIKey) SetLastUsed(ts time.Time)

SetLastUsed ensures the LastUsed timestamp is serialized to a string correctly.

func (*APIKey) SetPermissions

func (k *APIKey) SetPermissions(permissions ...string) error

SetPermissions on an APIKey that has not been created yet. If the APIKey has an ID an error is returned since APIKey permissions cannot be modified. This method will overwrite any permissions already added to the APIKey.

func (*APIKey) ToAPI

func (k *APIKey) ToAPI(ctx context.Context) *api.APIKey

ToAPI creates a Quarterdeck API response from the model, populating all fields except for the ClientSecret since this is not returned in most API requests.

func (*APIKey) Update

func (k *APIKey) Update(ctx context.Context) (err error)

Update an APIKey, modifying the record in the database with the key's ID and OrgID. After the key is updated, it is populated with the latest results from the database and returned to the user.

NOTE: only the name field is updated so only limited validation is performed.

func (*APIKey) UpdateLastUsed

func (k *APIKey) UpdateLastUsed(ctx context.Context) (err error)

UpdateLastUsed is a quick helper to set the last_used and modified timestamp.

func (*APIKey) Validate

func (k *APIKey) Validate() error

Validate an API key is ready to be inserted into the database. Note that this validation does not perform database constraint validation such as if the permission foreign keys exist in the database, uniqueness, or not null checks. TODO: should we validate timestamps?

type APIKeyPermission

type APIKeyPermission struct {
	Base
	KeyID        ulid.ULID
	PermissionID int64
}

APIKeyPermission is a model representing a many-to-many mapping between api keys and permissions. This model is primarily used by the APIKey and Permission models and is not intended for direct use generally.

type Base

type Base struct {
	Created  string
	Modified string
}

The Base model provides model audit functionality for setting created and modified timestamps in the database so we can track how rows are being modified over time.

func (*Base) GetCreated

func (b *Base) GetCreated() (time.Time, error)

Return the parsed created timestamp.

func (*Base) GetModified

func (b *Base) GetModified() (time.Time, error)

Return the parsed modified timestamp.

func (*Base) SetCreated

func (b *Base) SetCreated(ts time.Time)

Sets the created timestamp as the string formatted representation of the ts.

func (*Base) SetModified

func (b *Base) SetModified(ts time.Time)

Sets the modified timestamp as the string formatted representation of the ts.

type Organization

type Organization struct {
	Base
	ID     ulid.ULID
	Name   string
	Domain string
}

Organization is a model that represents a row in the organizations table and provides database functionality for interacting with an organizations's data. It should not be used for API serialization.

type OrganizationUser

type OrganizationUser struct {
	Base
	OrgID  ulid.ULID
	UserID ulid.ULID
}

OrganizationUser is a model representing a many-to-many mapping between users and organizations. This model is primarily used by the User and Organization models and is not intended for direct use generally.

type Permission

type Permission struct {
	Base
	ID           int64
	Name         string
	Description  sql.NullString
	AllowAPIKeys bool
	AllowRoles   bool
}

Permission is a model that represents a row in the permissions table and provides database functionality for interacting with permission data. It should not be used for API serialization.

type Role

type Role struct {
	Base
	ID          int64
	Name        string
	Description sql.NullString
}

Role is a model that represents a row in the roles table and provides database functionality for interacting with role data. It should not be used for API serialization.

type RolePermission

type RolePermission struct {
	Base
	RoleID       int64
	PermissionID int64
}

RolePermission is a model representing a many-to-many mapping between roles and permissions. This model is primarily used by the Role and Permission models and is not intended for direct use generally.

type User

type User struct {
	Base
	ID        ulid.ULID
	Name      string
	Email     string
	Password  string
	LastLogin sql.NullString
	// contains filtered or unexported fields
}

User is a model that represents a row in the users table and provides database functionality for interacting with a user's data. It should not be used for API serialization. Users may be retrieved from the database either via their ID (e.g. from the sub claim in a JWT token) or via their email address (e.g. on login). The user password should be stored as an argon2 hash and should be verified using the argon2 hashing algorithm.

func GetUser

func GetUser(ctx context.Context, id any) (u *User, err error)

GetUser by ID. The ID can be either a string, which is parsed into a ULID or it can be a valid ULID. The query is then executed as a read-only transaction against the database and the user is returned.

func GetUserEmail

func GetUserEmail(ctx context.Context, email string) (u *User, err error)

GetUser by Email. This query is executed as a read-only transaction.

func (*User) Create

func (u *User) Create(ctx context.Context, role string) (err error)

Create a user, inserting the record in the database. If the record already exists or a uniqueness constraint is violated an error is returned. The user will also be associated with the specified role name. If the role does not exist in the database, an error will be returned. This method sets the user ID, created and modifed timestamps even if they are already set on the model.

func (*User) GetLastLogin

func (u *User) GetLastLogin() (time.Time, error)

GetLastLogin returns the parsed LastLogin timestamp if it is not null. If it is null then a zero-valued timestamp is returned without an error.

func (*User) Permissions

func (u *User) Permissions(ctx context.Context, refresh bool) (_ []string, err error)

Returns the Permissions associated with the user as a list of strings. The permissions are cached to prevent multiple queries; use the refresh bool to force a new database query to reload the permissions of the user.

func (*User) Save

func (u *User) Save(ctx context.Context) (err error)

Save a user's name, email, password, and last login. The modified timestamp is set to the current time and neither the ID nor the created timestamp is modified. This query is executed as a write-transaction. The user must be fully populated and exist in the database for this method to execute successfully.

func (*User) SetLastLogin

func (u *User) SetLastLogin(ts time.Time)

SetLastLogin ensures the LastLogin timestamp is serialized to a string correctly.

func (*User) UpdateLastLogin

func (u *User) UpdateLastLogin(ctx context.Context) (err error)

UpdateLastLogin is a quick helper method to set the last_login and modified timestamp.

func (*User) UserRole

func (u *User) UserRole(ctx context.Context) (ur *UserRole, err error)

Returns the UserRole object associated with the user TODO: cache on the user

func (*User) Validate

func (u *User) Validate() error

Validate that the user should be inserted or updated into the database.

type UserRole

type UserRole struct {
	Base
	UserID ulid.ULID
	RoleID int64
}

UserRole is a model representing a many-to-many mapping between users and roles This model is primarily used by the User and Permission models and is not intended for direct use generally.

type ValidationError

type ValidationError struct {
	// contains filtered or unexported fields
}

func (*ValidationError) Error

func (e *ValidationError) Error() string

func (*ValidationError) Is

func (e *ValidationError) Is(target error) bool

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL