Documentation ¶
Index ¶
- Constants
- Variables
- func CountOrganizations(ctx context.Context) (count int64, err error)
- func CountUsers(ctx context.Context) (count int64, err error)
- func DeleteAPIKey(ctx context.Context, id, orgID ulid.ULID) (err error)
- func DeleteInvite(ctx context.Context, token string) (err error)
- type APIKey
- func (k *APIKey) AddPermissions(permissions ...string) error
- func (k *APIKey) Create(ctx context.Context) (err error)
- func (k *APIKey) GetLastUsed() (time.Time, error)
- func (k *APIKey) GetRevoked() (time.Time, error)
- func (k *APIKey) Permissions(ctx context.Context, refresh bool) (_ []string, err error)
- func (k *APIKey) SetLastUsed(ts time.Time)
- func (k *APIKey) SetPermissions(permissions ...string) error
- func (k *APIKey) SetRevoked()
- func (k *APIKey) Status() APIKeyStatus
- func (k *APIKey) ToAPI(ctx context.Context) *api.APIKey
- func (k *APIKey) Update(ctx context.Context) (err error)
- func (k *APIKey) UpdateLastUsed(ctx context.Context) (err error)
- func (k *APIKey) Validate() error
- type APIKeyPermission
- type APIKeyStatus
- type Base
- type ConstraintError
- type Organization
- func GetOrg(ctx context.Context, id any) (org *Organization, err error)
- func ListAllOrgs(ctx context.Context, prevPage *pagination.Cursor) (organizations []*Organization, cursor *pagination.Cursor, err error)
- func ListUserOrgs(ctx context.Context, userID any, prevPage *pagination.Cursor) (organizations []*Organization, cursor *pagination.Cursor, err error)
- func LookupWorkspace(ctx context.Context, domain string) (org *Organization, err error)
- func (o *Organization) Create(ctx context.Context) (err error)
- func (o *Organization) Delete(ctx context.Context) (err error)
- func (o *Organization) LastLogin() (time.Time, error)
- func (o *Organization) ProjectCount() int
- func (o *Organization) Save(ctx context.Context) (err error)
- func (o *Organization) ToAPI() *api.Organization
- func (o *Organization) Validate() error
- type OrganizationProject
- type OrganizationUser
- type Permission
- type Project
- type Role
- type RolePermission
- type SubjectType
- type User
- func GetUser(ctx context.Context, userID, orgID any) (u *User, err error)
- func GetUserByDeleteToken(ctx context.Context, userID, orgID any, token string) (u *User, err error)
- func GetUserByToken(ctx context.Context, token string, orgID any) (u *User, err error)
- func GetUserEmail(ctx context.Context, email string, orgID any) (u *User, err error)
- func ListAllUsers(ctx context.Context, prevPage *pagination.Cursor) (users []*User, cursor *pagination.Cursor, err error)
- func ListOrgUsers(ctx context.Context, orgID any, prevPage *pagination.Cursor) (users []*User, cursor *pagination.Cursor, err error)
- func (u *User) AddOrganization(ctx context.Context, org *Organization, role string) (err error)
- func (u *User) ChangeRole(ctx context.Context, orgID any, role string) (err error)
- func (u *User) Create(ctx context.Context, org *Organization, role string) (err error)
- func (u *User) CreateInvite(ctx context.Context, email, role string) (userInvite *UserInvitation, err error)
- func (u *User) CreateResetToken() (err error)
- func (u *User) CreateVerificationToken() (err error)
- func (u *User) Delete(tx *sql.Tx) (err error)
- func (u *User) GetLastLogin() (time.Time, error)
- func (u *User) GetVerificationExpires() (time.Time, error)
- func (u *User) GetVerificationToken() string
- func (u *User) NewClaims(ctx context.Context) (claims *qd.Claims, err error)
- func (u *User) OrgID() (ulid.ULID, error)
- func (u *User) Permissions(ctx context.Context, refresh bool) (_ []string, err error)
- func (u *User) RemoveOrganization(ctx context.Context, orgID any, force bool) (keys []APIKey, token string, err error)
- func (u *User) Role() (role string, _ error)
- func (u *User) Save(ctx context.Context) (err error)
- func (u *User) SetAgreement(agreeToS, agreePrivacy bool)
- func (u *User) SetLastLogin(ts time.Time)
- func (u *User) SetPassword(password string) (err error)
- func (u *User) SwitchOrganization(ctx context.Context, orgID any) (err error)
- func (u *User) ToAPI() (user *api.User, err error)
- func (u *User) Update(ctx context.Context, orgID any) (err error)
- func (u *User) UpdateLastLogin(ctx context.Context) (err error)
- func (u *User) UserRole(ctx context.Context, orgID ulid.ULID, refresh bool) (role string, err error)
- func (u *User) Validate() error
- type UserInvitation
- type ValidationError
Constants ¶
const (
APIKeyPermissionsSQL = "SELECT name, allow_roles FROM permissions WHERE allow_api_keys=true ORDER BY name"
)
const APIKeyStalenessThreshold = 90 * 24 * time.Hour
const (
DefaultDomainLength = 8
)
Variables ¶
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
CountOrganizations returns the number of organizations currently in the database.
func CountUsers ¶
CountUsers returns the number of users currently in the database.
func DeleteAPIKey ¶
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 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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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
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 ¶
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 ¶
SetLastUsed ensures the LastUsed timestamp is serialized to a string correctly.
func (*APIKey) SetPermissions ¶
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 ¶
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 ¶
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 ¶
UpdateLastUsed is a quick helper to set the last_used and modified timestamp.
type APIKeyPermission ¶
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 ¶
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 ¶
Return the parsed created timestamp.
func (*Base) GetModified ¶
Return the parsed modified timestamp.
func (*Base) SetCreated ¶
Sets the created timestamp as the string formatted representation of the ts.
func (*Base) SetModified ¶
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
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.
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
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.
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 (*Role) Permissions ¶ added in v0.3.0
type RolePermission ¶
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 ¶
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
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 ¶
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
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
ChangeRole updates the role of the user in specified organization.
func (*User) Create ¶
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
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
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
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 ¶
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
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
GetVerificationToken returns the verification token for the user if it is not null.
func (*User) NewClaims ¶ added in v0.10.0
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
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 ¶
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
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 ¶
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
SetAgreement marks if the user has accepted the terms of service and privacy policy.
func (*User) SetLastLogin ¶
SetLastLogin ensures the LastLogin timestamp is serialized to a string correctly.
func (*User) SetPassword ¶ added in v0.11.0
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
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) Update ¶ added in v0.3.0
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 ¶
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.
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