models

package
v0.12.6 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2024 License: BSD-3-Clause Imports: 22 Imported by: 0

Documentation

Index

Constants

View Source
const (
	APIKeyPermissionsSQL = "SELECT name, allow_roles FROM permissions WHERE allow_api_keys=true ORDER BY name"
)
View Source
const APIKeyStalenessThreshold = 90 * 24 * time.Hour
View Source
const (
	DefaultDomainLength = 8
)

Variables

View Source
var (
	ErrNotFound            = errors.New("object not found in the database")
	ErrInvalidOrganization = errors.New("organization model is not correctly populated")
	ErrUserOrganization    = errors.New("user is not associated with the organization")
	ErrUserOrgExists       = errors.New("user is already associated with the organization")
	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")
	ErrMissingRole         = errors.New("missing role")
	ErrInvalidRole         = errors.New("invalid role")
	ErrNoOwnerRole         = errors.New("organization is missing an owner")
	ErrOwnerRoleConstraint = errors.New("organization must have at least one owner")
	ErrInvalidEmail        = errors.New("invalid email")
	ErrMissingOrgID        = errors.New("model does not have an organization ID assigned")
	ErrMissingProjectID    = errors.New("model requires project id")
	ErrInvalidProjectID    = errors.New("invalid project id for apikey")
	ErrMissingKeyName      = errors.New("apikey model requires name")
	ErrMissingCreatedBy    = errors.New("apikey model requires created by")
	ErrNoPermissions       = errors.New("apikey model requires permissions")
	ErrInvalidPermission   = errors.New("invalid permission specified for apikey")
	ErrModifyPermissions   = errors.New("cannot modify permissions on an existing APIKey object")
	ErrInvalidToken        = errors.New("token is invalid or expired")
	ErrSubjectCollision    = errors.New("subject was identified as both user and apikey")
	ErrMissingPageSize     = errors.New("cannot list database without a page size")
	ErrInvalidCursor       = errors.New("could not compute the next page of results")
	ErrDuplicate           = errors.New("unique constraint violated on model")
	ErrMissingRelation     = errors.New("foreign key relation violated on model")
	ErrNotNull             = errors.New("not null constraint violated on model")
	ErrConstraint          = errors.New("database constraint violated")
)

Functions

func CountOrganizations added in v0.3.0

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

CountOrganizations returns the number of organizations currently in the database.

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.

func DeleteInvite added in v0.5.2

func DeleteInvite(ctx context.Context, token string) (err error)

Delete an invitation from the database by the token.

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
	Revoked   sql.NullString
	Partial   bool
	// 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, userID 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, partial, 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.

NOTE: the OrgID and ProjectID on the APIKey must be associated in the Quarterdeck database otherwise an ErrInvalidProjectID error is returned. Callers should populate the OrgID from the claims of the user and NOT from user submitted input.

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) GetRevoked added in v0.12.0

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

GetRevoked returns the parsed Revoked 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) SetRevoked added in v0.12.0

func (k *APIKey) SetRevoked()

Set the revoked timestamp on an API key. This only sets the timestamp and does not actually revoke the key.

func (*APIKey) Status added in v0.5.0

func (k *APIKey) Status() APIKeyStatus

Status of the APIKey based on the LastUsed timestamp if the api keys have not been revoked. If the keys have never been used the unused status is returned; if they have not been used in 90 days then the stale status is returned; otherwise the apikey is considered active unless it has been revoked.

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.

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 APIKeyStatus added in v0.5.0

type APIKeyStatus string
const (
	APIKeyStatusUnknown APIKeyStatus = ""
	APIKeyStatusUnused  APIKeyStatus = "Unused"
	APIKeyStatusActive  APIKeyStatus = "Active"
	APIKeyStatusStale   APIKeyStatus = "Stale"
	APIKeyStatusRevoked APIKeyStatus = "Revoked"
)

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 ConstraintError added in v0.3.0

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

ConstraintError attempts to parse a sqlite3.ErrConstraint error into a model error.

func (*ConstraintError) Error added in v0.3.0

func (e *ConstraintError) Error() string

func (*ConstraintError) Is added in v0.3.0

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

func (*ConstraintError) Unwrap added in v0.3.0

func (e *ConstraintError) Unwrap() error

type Organization

type Organization struct {
	Base
	ID     ulid.ULID
	Name   string
	Domain string
	// contains filtered or unexported fields
}

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.

func GetOrg added in v0.3.0

func GetOrg(ctx context.Context, id any) (org *Organization, err error)

func ListAllOrgs added in v0.10.0

func ListAllOrgs(ctx context.Context, prevPage *pagination.Cursor) (organizations []*Organization, cursor *pagination.Cursor, err error)

ListAllOrgs returns a paginated collection of all organizations in the database. This does not filter by user so ListUserOrgs should be used when only the organizations for a specific user are needed.

func ListUserOrgs added in v0.10.0

func ListUserOrgs(ctx context.Context, userID any, prevPage *pagination.Cursor) (organizations []*Organization, cursor *pagination.Cursor, err error)

ListUserOrgs returns a paginated collection of organizations filtered by the userID. The orgID must be a valid non-zero value of type ulid.ULID, a string representation of a type ulid.ULID, or a slice of bytes The number of organizations resturned 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.

A organizations 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 LookupWorkspace added in v0.10.0

func LookupWorkspace(ctx context.Context, domain string) (org *Organization, err error)

func (*Organization) Create added in v0.3.0

func (o *Organization) Create(ctx context.Context) (err error)

Create an organization, inserting the record into the database. If the record already exists or a uniqueness constraint is violated an error is returned. This method sets the ID, created, and modified timestamps even if the user has already set them.

If the organization name or domain are empty a validation error is returned.

func (*Organization) Delete added in v0.12.0

func (o *Organization) Delete(ctx context.Context) (err error)

Delete an organization from the database. If there are any API keys in the organization then this will return a constraint error.

func (*Organization) LastLogin added in v0.5.2

func (o *Organization) LastLogin() (time.Time, error)

Return the last login timestamp for the user this organization was loaded for.

func (*Organization) ProjectCount added in v0.5.0

func (o *Organization) ProjectCount() int

func (*Organization) Save added in v0.10.0

func (o *Organization) Save(ctx context.Context) (err error)

Save an organization to the database, updating the name and domain fields. This assumes that the organization already exists in the database.

func (*Organization) ToAPI added in v0.4.0

func (o *Organization) ToAPI() *api.Organization

func (*Organization) Validate added in v0.10.0

func (o *Organization) Validate() error

Validate that an organization is ready to be inserted or updated into the database.

type OrganizationProject added in v0.3.0

type OrganizationProject struct {
	Base
	OrgID     ulid.ULID
	ProjectID ulid.ULID
}

OrganizationProject is a model representing the many-to-one mapping between projects and organizations. The project model is not stored in the database (but rather in the tenant database) so only the projectID is stored, but it must be unique to prevent a security hole where a user issues APIKeys to a project in an organization that they do not belong to. Before issuing APIKeys with a projectID, Quarterdeck checks to ensure that the project actually belongs to the organization via a lookup in this table. Otherwise, all information about the project is stored in Tenant.

func (*OrganizationProject) Exists added in v0.3.0

func (op *OrganizationProject) Exists(ctx context.Context) (ok bool, err error)

Exists checks if an organization project mapping exists in order to verify that a project is allowed to be associated with an APIKey or other claims resource for the user with the specified OrgID claims. Only the OrgID and ProjectID are used for this so no preliminary fetch from the database is required to execute the query.

func (*OrganizationProject) Save added in v0.3.0

func (op *OrganizationProject) Save(ctx context.Context) (err error)

Save an organization project mapping to the database by creating a record. Organization project mappings can only be created and deleted, not updated, so if the mapping already exists an error is returned.

NOTE: because this is a security condition, the OrgID in the OrganizationProject model must come from the user claims and not from user input!

type OrganizationUser

type OrganizationUser struct {
	Base
	OrgID              ulid.ULID
	UserID             ulid.ULID
	RoleID             int64
	DeleteConfirmToken sql.NullString
	LastLogin          sql.NullString
	// contains filtered or unexported fields
}

OrganizationUser is a model representing a many-to-many mapping between users and organizations and describes the role each user has in their organization. This model is primarily used by the User and Organization models and is not intended for direct use generally.

NOTE: a user can only have one role in an organization, so roles must be defined as overlapping sets rather than as disjoint sets where users have multiple roles.

func GetOrgUser added in v0.3.0

func GetOrgUser(ctx context.Context, userID, orgID any) (ou *OrganizationUser, err error)

func (*OrganizationUser) Organization added in v0.3.0

func (o *OrganizationUser) Organization(ctx context.Context, refresh bool) (_ *Organization, err error)

Returns the organization associated with the OrganizationUser struct. The object is cached on the struct and can be refreshed on demand. TODO: fetch on GetOrgUser to reduce number of raft queries.

func (*OrganizationUser) Role added in v0.3.0

func (o *OrganizationUser) Role(ctx context.Context, refresh bool) (_ *Role, err error)

Returns the role associated with the organization and user. The object is cached on the struct and can be refreshed on demand. TODO: fetch on GetOrgUser to reduce number of raft queries.

func (*OrganizationUser) User added in v0.3.0

func (o *OrganizationUser) User(ctx context.Context, refresh bool) (_ *User, err error)

Returns the user associated with the OrganizationUser struct, ready to query with the given organization. This object is cached on the struct and can be refreshed. TODO: fetch on GetOrgUser to reduce number of raft queries.

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.

func GetAPIKeyPermissions added in v0.5.0

func GetAPIKeyPermissions(ctx context.Context) (permissions []Permission, err error)

Fetch all eligible API key permissions from the database.

func GetPermission added in v0.5.0

func GetPermission(ctx context.Context, name string) (p *Permission, err error)

type Project added in v0.7.0

type Project struct {
	OrganizationProject
	APIKeyCount  int64
	RevokedCount int64
}

Project is a read-only model that is used to fetch project statistics from the organization projects mapping table, the apikeys table, and the revoked apikeys table. This struct is used primarily for the project detail and list endpoints.

func FetchProject added in v0.7.0

func FetchProject(ctx context.Context, projectID, orgID ulid.ULID) (project *Project, err error)

Fetch the project detail along with the status for the given project/organization. This query is executed as a read-only transaction.

func ListProjects added in v0.7.0

func ListProjects(ctx context.Context, orgID ulid.ULID, cursor *pagination.Cursor) (projects []*Project, nextPage *pagination.Cursor, err error)

List the projects for the specified organization along with their key counts. Returns a paginated collection of projects filtered by the organization ID. The number of results returned is controlled by the cursor.

func (*Project) ToAPI added in v0.7.0

func (p *Project) ToAPI() *api.Project

type Role

type Role struct {
	Base
	ID          int64
	Name        string
	Description sql.NullString
	// contains filtered or unexported fields
}

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.

func GetRole added in v0.3.0

func GetRole(ctx context.Context, roleID int64) (role *Role, err error)

func (*Role) Permissions added in v0.3.0

func (r *Role) Permissions(ctx context.Context, refresh bool) (_ []*Permission, err error)

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 SubjectType added in v0.8.0

type SubjectType uint8
const (
	UnknownSubject SubjectType = iota
	UserSubject
	APIKeySubject
)

func IdentifySubject added in v0.8.0

func IdentifySubject(ctx context.Context, subjectID, orgID any) (_ SubjectType, err error)

IdentifySubject is a helper tool to check the database to determine if the specified subject from authentication claims refers to a user or to an apikey. This method relies on the fact that the database IDs are ULIDs, meaning that it is highly unlikely that a user id and an apikey id are the same (technically possible, but with the same collision probability as a UUID). This is made further unlikely by requiring an organization ID is specified to return the subject type.

type User

type User struct {
	Base
	ID                       ulid.ULID
	Name                     string
	Email                    string
	Password                 string
	AgreeToS                 sql.NullBool
	AgreePrivacy             sql.NullBool
	EmailVerified            bool
	EmailVerificationExpires sql.NullString
	EmailVerificationToken   sql.NullString
	EmailVerificationSecret  []byte
	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. Care should be taken to ensure this model stays secure.

Users are associated with one or more organizations. When the user model is loaded from the database one organization must be supplied so that permissions and role can be retrieved correctly. If no orgID is supplied then one of the user's organizations is selected from the database as the default organiztion. Use the SwitchOrganization method to switch the user model to a different organization to retrieve a different and permissions or use the UserRoles method to determine which organizations the user belongs to.

func GetUser

func GetUser(ctx context.Context, userID, orgID 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. An orgID can be specified to load the user in that organization. If the orgID is Null then one of the organizations the user belongs to is loaded (the default user organization).

func GetUserByDeleteToken added in v0.7.0

func GetUserByDeleteToken(ctx context.Context, userID, orgID any, token string) (u *User, err error)

GetUser by delete confirmation token by doing a join with the organization_users table. This returns an error if the token is invalid or expired.

func GetUserByToken added in v0.5.0

func GetUserByToken(ctx context.Context, token string, orgID any) (u *User, err error)

GetUser by verification token by executing a read-only transaction against the database. If an orgID is specified then the user is loaded in that organization.

func GetUserEmail

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

GetUser by Email. This query is executed as a read-only transaction. An orgID can be specified to load the user in that organization. If the orgID is Null then one of the organizations the user belongs to is loaded (the default user organization).

func ListAllUsers added in v0.10.0

func ListAllUsers(ctx context.Context, prevPage *pagination.Cursor) (users []*User, cursor *pagination.Cursor, err error)

ListAllUsers returns a paginated collection of all users in the database. This does not filter by organization so ListOrgUsers should be used when only the users in a specific organization are needed.

func ListOrgUsers added in v0.10.0

func ListOrgUsers(ctx context.Context, orgID any, prevPage *pagination.Cursor) (users []*User, cursor *pagination.Cursor, err error)

ListOrgUsers returns a paginated collection of users filtered by the orgID. The orgID must be a valid non-zero value of type ulid.ULID, a string representation of a type ulid.ULID, or a slice of bytes The number of users 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.

A users 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 (*User) AddOrganization added in v0.5.2

func (u *User) AddOrganization(ctx context.Context, org *Organization, role string) (err error)

AddOrganization adds the user to the specified organization with the specified role. An error is returned if the organization doesn't exist.

func (*User) ChangeRole added in v0.5.2

func (u *User) ChangeRole(ctx context.Context, orgID any, role string) (err error)

ChangeRole updates the role of the user in specified organization.

func (*User) Create

func (u *User) Create(ctx context.Context, org *Organization, 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 organization and the specified role name. If the organization doesn't exist, it will be created. If the role does not exist in the database, an error will be returned. This method sets the user ID, created and modified timestamps even if they are already set on the model.

func (*User) CreateInvite added in v0.5.2

func (u *User) CreateInvite(ctx context.Context, email, role string) (userInvite *UserInvitation, err error)

Create an invitation in the database from the user to the specified email address and return the invitation token to send to the user. This method returns an error if the invitee is already associated with the organization.

func (*User) CreateResetToken added in v0.11.0

func (u *User) CreateResetToken() (err error)

CreateResetToken creates a new password reset token for the user, setting the token and any necessary secret fields on the model.

func (*User) CreateVerificationToken added in v0.5.0

func (u *User) CreateVerificationToken() (err error)

CreateVerificationToken creates a new verification token for the user, setting the email verification fields on the model.

func (*User) Delete added in v0.12.0

func (u *User) Delete(tx *sql.Tx) (err error)

Delete the user from the database. This is normally not done directly but as a result of removing the user from all their organizations. TODO: Preserve the email address <> user ID mapping.

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) GetVerificationExpires added in v0.5.0

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

GetVerificationExpires returns the verification token expiration time for the user or a zero time if the token is null.

func (*User) GetVerificationToken added in v0.5.0

func (u *User) GetVerificationToken() string

GetVerificationToken returns the verification token for the user if it is not null.

func (*User) NewClaims added in v0.10.0

func (u *User) NewClaims(ctx context.Context) (claims *qd.Claims, err error)

Construct new claims for the user to be used in JWT tokens. This method assumes that the user has already been loaded into an organization, otherwise an error is returned.

func (*User) OrgID added in v0.3.0

func (u *User) OrgID() (ulid.ULID, error)

OrgID returns the organization id that the user was loaded for. If the model doesn't have an orgID then an error is returned. This method requires that the user was loaded using one of the fetch and catch methods such as GetUserID or that the SwitchOrganization method was used to load the user.

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) RemoveOrganization added in v0.5.2

func (u *User) RemoveOrganization(ctx context.Context, orgID any, force bool) (keys []APIKey, token string, err error)

RemoveOrganization attempts to remove the user from the specified organization. If the user does not own any resources then they are removed from the organization. If the user does own resources then this method returns the lists of resources that are owned by the user and a confirmation token that can be returned by endpoint handlers to request delete confirmation. If force is set to true then user resources are removed without confirmation. If a user is removed from their last organization, then their record in the database is also deleted.

func (*User) Role added in v0.3.0

func (u *User) Role() (role string, _ error)

Role returns the current role for the user in the organization the user was loaded for. If the model does not have an orgID or the user doesn't belong to the organization then an error is returned. This method requires that the UserRoles have been fetched and cached (e.g. that the user was retrieved from the database with an organization or that SwitchOrganization) was used.

func (*User) Save

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

Save a user's name, email, password, agreements, verification data, and last login. The modified timestamp is set to the current time and neither the ID nor the created timestamp are 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) SetAgreement added in v0.3.0

func (u *User) SetAgreement(agreeToS, agreePrivacy bool)

SetAgreement marks if the user has accepted the terms of service and privacy policy.

func (*User) SetLastLogin

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

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

func (*User) SetPassword added in v0.11.0

func (u *User) SetPassword(password string) (err error)

SetPassword sets the password for the user by creating a password hash from a user provided string.

func (*User) SwitchOrganization added in v0.3.0

func (u *User) SwitchOrganization(ctx context.Context, orgID any) (err error)

SwitchOrganization loads the user role and permissions for the specified organization returning an error if the user is not in the specified organization.

func (*User) ToAPI added in v0.3.0

func (u *User) ToAPI() (user *api.User, err error)

func (*User) Update added in v0.3.0

func (u *User) Update(ctx context.Context, orgID any) (err error)

Update a User in the database. The requester needs to be in the same orgID as the user. This check is performed by verifying that the orgID and the user_id exist in the organization_users table The orgID must be a valid non-zero value of type ulid.ULID, a string representation of a type ulid.ULID, or a slice of bytes

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, both on the user record and on the organization_user record that the user was loaded for. If the user was not loaded into an organization then this method returns an error.

func (*User) UserRole

func (u *User) UserRole(ctx context.Context, orgID ulid.ULID, refresh bool) (role string, err error)

Returns the name of the user role associated with the user for the specified organization. Queries the cached information when the user is fetched unless refresh is true, which reloads the cached information from the database on demand.

func (*User) Validate

func (u *User) Validate() error

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

type UserInvitation added in v0.5.2

type UserInvitation struct {
	Base
	UserID    ulid.ULID
	OrgID     ulid.ULID
	Email     string
	Role      string
	Expires   string
	Token     string
	Secret    []byte
	CreatedBy ulid.ULID
	// contains filtered or unexported fields
}

User invitations are used to invite users to organizations. Users may not exist at the point of invitation, so users are referenced by email address rather than by user ID. The crucial part of the invitation is the token, which is a cryptographically secure random string that is used to uniquely identify pending invitations in the database. Once invitations are accepted then they are deleted from the database.

func GetUserInvite added in v0.5.2

func GetUserInvite(ctx context.Context, token string) (invite *UserInvitation, err error)

Get an invitation from the database by the token.

func (*UserInvitation) Name added in v0.5.2

func (u *UserInvitation) Name() string

Name returns the name of the invited user if available. TODO: Should this be saved in the database?

func (*UserInvitation) Validate added in v0.5.2

func (u *UserInvitation) Validate(email string) (err error)

Validate the invitation against a user provided email address.

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