database

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2020 License: Apache-2.0 Imports: 31 Imported by: 0

Documentation

Overview

Package database manages database connections and ORM integration.

Index

Constants

View Source
const (
	SMSRegion        = "[region]"
	SMSCode          = "[code]"
	SMSExpires       = "[expires]"
	SMSLongCode      = "[longcode]"
	SMSLongExpires   = "[longexpires]"
	SMSENExpressLink = "[enslink]"
)
View Source
const (

	// MinCodeLength defines the minimum number of digits in a code.
	MinCodeLength = 6
)

Variables

View Source
var (
	ErrVerificationCodeNotFound = errors.New("verification code not found")
	ErrVerificationCodeExpired  = errors.New("verification code expired")
	ErrVerificationCodeUsed     = errors.New("verification code used")
	ErrTokenExpired             = errors.New("verification token expired")
	ErrTokenUsed                = errors.New("verification token used")
	ErrTokenMetadataMismatch    = errors.New("verification token test metadata mismatch")
	ErrUnsupportedTestType      = errors.New("verification code has unsupported test type")
)
View Source
var (
	// ValidTestTypes is a map containing the valid test types.
	ValidTestTypes = map[string]struct{}{
		"confirmed": {},
		"likely":    {},
		"negative":  {},
	}

	ErrInvalidTestType    = errors.New("invalid test type, must be confirmed, likely, or negative")
	ErrCodeAlreadyExpired = errors.New("code already expired")
	ErrCodeTooShort       = errors.New("verification code must be at least 6 digits")
	ErrTestTooOld         = errors.New("test date is more than 14 day ago")
)
View Source
var CleanupName = "cleanup"
View Source
var (
	ErrCleanupWrongGeneration = errors.New("cleanup wrong generation")
)
View Source
var (
	ErrNoSigningKeyManagement = errors.New("no signing key management")
)
View Source
var (
	ErrNoSigningKeyManager = errors.New("configured key manager cannot be used to manage per-realm keys")
)

Functions

func IsNotFound added in v0.3.0

func IsNotFound(err error) bool

IsNotFound determines if an error is a record not found.

func NewTestDatabaseWithConfig

func NewTestDatabaseWithConfig(tb testing.TB) (*Database, *Config)

NewTestDatabaseWithConfig creates a new database suitable for use in testing. This should not be used outside of testing, but it is exposed in the main package so it can be shared with other packages.

All database tests can be skipped by running `go test -short` or by setting the `SKIP_DATABASE_TESTS` environment variable.

Types

type APIUserType

type APIUserType int
const (
	APIUserTypeDevice APIUserType = 0
	APIUserTypeAdmin  APIUserType = 1
)

type AuthorizedApp

type AuthorizedApp struct {
	gorm.Model
	Errorable

	// AuthorizedApps belong to exactly one realm.
	RealmID uint `gorm:"unique_index:realm_apikey_name"`

	// Name is the name of the authorized app.
	Name string `gorm:"type:varchar(100);unique_index:realm_apikey_name"`

	// APIKeyPreview is the first few characters of the API key for display
	// purposes. This can help admins in the UI when determining which API key is
	// in use.
	APIKeyPreview string `gorm:"type:varchar(32)"`

	// APIKey is the HMACed API key.
	APIKey string `gorm:"type:varchar(512);unique_index"`

	// APIKeyType s the API key type.
	APIKeyType APIUserType `gorm:"default:0"`
}

AuthorizedApp represents an application that is authorized to verify verification codes and perform token exchanges. This is controlled via a generated API key.

Admin Keys are able to issue diagnosis keys and are not able to perticipate the verification protocol.

func (*AuthorizedApp) BeforeSave added in v0.4.0

func (a *AuthorizedApp) BeforeSave(tx *gorm.DB) error

BeforeSave runs validations. If there are errors, the save fails.

func (*AuthorizedApp) Disable added in v0.4.0

func (a *AuthorizedApp) Disable(db *Database) error

Disable disables the authorized app.

func (*AuthorizedApp) Enable added in v0.4.0

func (a *AuthorizedApp) Enable(db *Database) error

Enable enables the authorized app.

func (*AuthorizedApp) IsAdminType

func (a *AuthorizedApp) IsAdminType() bool

func (*AuthorizedApp) IsDeviceType

func (a *AuthorizedApp) IsDeviceType() bool

func (*AuthorizedApp) Realm

func (a *AuthorizedApp) Realm(db *Database) (*Realm, error)

Realm returns the associated realm for this app.

func (*AuthorizedApp) Stats added in v0.5.0

func (a *AuthorizedApp) Stats(db *Database, start, stop time.Time) ([]*AuthorizedAppStats, error)

Stats returns the usage statistics for this app. If no stats exist, it returns an empty array.

func (AuthorizedApp) TableName

func (AuthorizedApp) TableName() string

TableName definition for the authorized apps relation.

type AuthorizedAppStats added in v0.3.0

type AuthorizedAppStats struct {
	Date            time.Time `gorm:"date"`
	AuthorizedAppID uint      `gorm:"authorized_app_id"`
	CodesIssued     uint      `gorm:"codes_issued"`
}

AuthorizedAppStats represents statistics related to a user in the database.

func (AuthorizedAppStats) TableName added in v0.3.0

func (AuthorizedAppStats) TableName() string

TableName sets the AuthorizedAppStats table name

type CleanupStatus

type CleanupStatus struct {
	gorm.Model
	Type       string `gorm:"type:varchar(50);unique_index"`
	Generation uint
	NotBefore  time.Time
}

func (CleanupStatus) TableName

func (CleanupStatus) TableName() string

TableName sets the CleanupStatus table name

type Config

type Config struct {
	Name              string `env:"DB_NAME" json:",omitempty"`
	User              string `env:"DB_USER" json:",omitempty"`
	Host              string `env:"DB_HOST, default=localhost" json:",omitempty"`
	Port              string `env:"DB_PORT, default=5432" json:",omitempty"`
	SSLMode           string `env:"DB_SSLMODE, default=require" json:",omitempty"`
	ConnectionTimeout uint   `env:"DB_CONNECT_TIMEOUT" json:",omitempty"`
	Password          string `env:"DB_PASSWORD" json:"-"` // ignored by zap's JSON formatter
	SSLCertPath       string `env:"DB_SSLCERT" json:",omitempty"`
	SSLKeyPath        string `env:"DB_SSLKEY" json:",omitempty"`
	SSLRootCertPath   string `env:"DB_SSLROOTCERT" json:",omitempty"`

	// MaxConnectionLifetime and MaxConnectionIdleTime determine the connection
	// configuration. Note that MaxConnectionIdleTime must be less than
	// MaxConnectionLifetime.
	MaxConnectionLifetime time.Duration `env:"DB_MAX_CONN_LIFETIME, default=5m" json:",omitempty"`
	MaxConnectionIdleTime time.Duration `env:"DB_MAX_CONN_IDLE_TIME, default=1m" json:",omitempty"`

	// Debug is a boolean that indicates whether the database should log SQL
	// commands.
	Debug bool `env:"DB_DEBUG,default=false"`

	// Keys is the key management configuration. This is used to resolve values
	// that are encrypted via a KMS.
	Keys keys.Config `env:",prefix=DB_"`

	// The KMS managed KeyRing that per-realm certificate signing keys are
	// created on.
	CertificateSigningKeyRing string `env:"CERTIFICATE_SIGNING_KEYRING"`

	// EncryptionKey is the reference to an encryption/decryption key to use when
	// for application-layer encryption before values are persisted to the
	// database.
	EncryptionKey string `env:"DB_ENCRYPTION_KEY,required"`

	// APIKeyDatabaseHMAC is the HMAC key to use for API keys before storing them
	// in the database.
	APIKeyDatabaseHMAC []envconfig.Base64Bytes `env:"DB_APIKEY_DATABASE_KEY,required" json:"-"`

	// APIKeySignatureHMAC is the HMAC key to sign API keys before returning them
	// to the requestor.
	APIKeySignatureHMAC []envconfig.Base64Bytes `env:"DB_APIKEY_SIGNATURE_KEY,required" json:"-"`

	// VerificationCodeDatabaseHMAC is the HMAC key to hash codes before storing
	// them in the database.
	VerificationCodeDatabaseHMAC []envconfig.Base64Bytes `env:"DB_VERIFICATION_CODE_DATABASE_KEY,required"`

	// Secrets is the secret configuration. This is used to resolve values that
	// are actually pointers to secrets before returning them to the caller. The
	// table implementation is the source of truth for which values are secrets
	// and which are plaintext.
	Secrets secrets.Config
}

Config represents the env var based configuration for database connections.

func (*Config) ConnectionString

func (c *Config) ConnectionString() string

ConnectionString returns the postgresql connection string based on this config.

While this package could be adapted to different databases easily, this file and method in particular would need to change.

func (*Config) Load added in v0.4.0

func (c *Config) Load(ctx context.Context) (*Database, error)

Load loads the configuration and processes any dependencies like secret and key managers. It does NOT connect to the database.

type Database

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

Database is a handle to the database layer for the Exposure Notifications Verification Server.

func NewTestDatabase

func NewTestDatabase(tb testing.TB) *Database

func (*Database) ClaimCleanup

func (db *Database) ClaimCleanup(current *CleanupStatus, lockTime time.Duration) (*CleanupStatus, error)

ClaimCleanup attempts to obtain a lock for the specified `lockTime` so that that type of cleanup can be perofmed exclusively by the owner.

func (*Database) ClaimToken

func (db *Database) ClaimToken(realmID uint, tokenID string, subject *Subject) error

ClaimToken looks up the token by ID, verifies that it is not expired and that the specified subject matches the parameters that were configured when issued.

func (*Database) Close

func (db *Database) Close() error

Close will close the database connection. Should be deferred right after Open.

func (*Database) CreateCleanup

func (db *Database) CreateCleanup(cType string) (*CleanupStatus, error)

CreateCleanup is used to create a new 'cleanup' type/row in the database.

func (*Database) CreateRealm

func (db *Database) CreateRealm(name string) (*Realm, error)

func (*Database) DeleteSMSConfig

func (db *Database) DeleteSMSConfig(s *SMSConfig) error

DeleteSMSConfig removes an SMS configuration record.

func (*Database) DeleteVerificationCode

func (db *Database) DeleteVerificationCode(code string) error

DeleteVerificationCode deletes the code if it exists. This is a hard delete.

func (*Database) ExpireCode added in v0.5.1

func (db *Database) ExpireCode(uuid string) (*VerificationCode, error)

ExpireCode saves a verification code as expired.

func (*Database) FindAuthorizedAppByAPIKey

func (db *Database) FindAuthorizedAppByAPIKey(apiKey string) (*AuthorizedApp, error)

FindAuthorizedAppByAPIKey located an authorized app based on API key.

func (*Database) FindCleanupStatus

func (db *Database) FindCleanupStatus(cType string) (*CleanupStatus, error)

FindCleanupStatus looks up the current cleanup state in the database by cleanup type.

func (*Database) FindRealm added in v0.5.0

func (db *Database) FindRealm(id interface{}) (*Realm, error)

func (*Database) FindRealmByName added in v0.5.0

func (db *Database) FindRealmByName(name string) (*Realm, error)

func (*Database) FindTokenByID

func (db *Database) FindTokenByID(tokenID string) (*Token, error)

func (*Database) FindUser

func (db *Database) FindUser(id interface{}) (*User, error)

FindUser finds a user by the given id, if one exists. The id can be a string or integer value. It returns an error if the record is not found.

func (*Database) FindUserByEmail added in v0.4.0

func (db *Database) FindUserByEmail(email string) (*User, error)

FindUserByEmail reads back a User struct by email address. It returns an error if the record is not found.

func (*Database) FindVerificationCode

func (db *Database) FindVerificationCode(code string) (*VerificationCode, error)

FindVerificationCode find a verification code by the code number (can be short code or long code).

func (*Database) FindVerificationCodeByUUID added in v0.4.0

func (db *Database) FindVerificationCodeByUUID(uuid string) (*VerificationCode, error)

FindVerificationCodeByUUID find a verification codes by UUID.

func (*Database) GenerateAPIKey added in v0.3.0

func (db *Database) GenerateAPIKey(realmID uint) (string, error)

GenerateAPIKey generates a new API key that is bound to the given realm. This API key is NOT stored in the database. API keys are of the format:

key:realmID:hex(hmac)

func (*Database) GenerateAPIKeyHMAC added in v0.7.0

func (db *Database) GenerateAPIKeyHMAC(apiKey string) (string, error)

GenerateAPIKeyHMAC generates the HMAC of the provided API key using the latest HMAC key.

func (*Database) GenerateAPIKeySignature added in v0.3.0

func (db *Database) GenerateAPIKeySignature(apiKey string) ([]byte, error)

GenerateAPIKeySignature returns all possible signatures of the given key.

func (*Database) GenerateVerificationCodeHMAC added in v0.7.0

func (db *Database) GenerateVerificationCodeHMAC(verCode string) (string, error)

GenerateVerificationCodeHMAC generates the HMAC of the code using the latest key.

func (*Database) GetRealms added in v0.3.0

func (db *Database) GetRealms() ([]*Realm, error)

func (*Database) IsCodeExpired added in v0.5.0

func (db *Database) IsCodeExpired(v *VerificationCode, code string) (bool, error)

IsCodeExpired checks to see if the actual code provided is the short or long code, and determines if it is expired based on that.

func (*Database) KeyManager added in v0.5.0

func (db *Database) KeyManager() keys.KeyManager

func (*Database) MigrateTo

func (db *Database) MigrateTo(ctx context.Context, target string, rollback bool) error

MigrateTo migrates the database to a specific target migration ID.

func (*Database) Open added in v0.4.0

func (db *Database) Open(ctx context.Context) error

Open creates a database connection. This should only be called once.

func (*Database) OpenWithCacher added in v0.5.0

func (db *Database) OpenWithCacher(ctx context.Context, cacher cache.Cacher) error

OpenWithCacher creates a database connection with the cacher. This should only be called once.

func (*Database) Ping added in v0.3.0

func (db *Database) Ping(ctx context.Context) error

Ping attempts a connection and closes it to the database.

func (*Database) PurgeTokens

func (db *Database) PurgeTokens(maxAge time.Duration) (int64, error)

PurgeTokens will delete tokens that have expired since at least the provided maxAge ago. This is a hard delete, not a soft delete.

func (*Database) PurgeVerificationCodes

func (db *Database) PurgeVerificationCodes(maxAge time.Duration) (int64, error)

PurgeVerificationCodes will delete verifications that have expired since at least the provided maxAge ago. This is a hard delete, not a soft delete.

func (*Database) RunMigrations

func (db *Database) RunMigrations(ctx context.Context) error

RunMigrations will apply sequential, transactional migrations to the database

func (*Database) SaveAuthorizedApp added in v0.3.0

func (db *Database) SaveAuthorizedApp(r *AuthorizedApp) error

SaveAuthorizedApp saves the authorized app.

func (*Database) SaveRealm

func (db *Database) SaveRealm(r *Realm) error

func (*Database) SaveSMSConfig

func (db *Database) SaveSMSConfig(s *SMSConfig) error

SaveSMSConfig creates or updates an SMS configuration record.

func (*Database) SaveSigningKey added in v0.5.0

func (db *Database) SaveSigningKey(s *SigningKey) error

func (*Database) SaveUser

func (db *Database) SaveUser(u *User) error

SaveUser updates the user in the database.

func (*Database) SaveVerificationCode

func (db *Database) SaveVerificationCode(vc *VerificationCode, maxAge time.Duration) error

SaveVerificationCode created or updates a verification code in the database. Max age represents the maximum age of the test date [optional] in the record.

func (*Database) SupportsPerRealmSigning added in v0.5.0

func (db *Database) SupportsPerRealmSigning() bool

SupportsPerRealmSigning returns true if the configuration supports application managed signing keys.

func (*Database) TouchUserRevokeCheck added in v0.5.0

func (db *Database) TouchUserRevokeCheck(u *User) error

TouchUserRevokeCheck updates the revoke check time on the user. It updates the column directly and does not invoke callbacks.

func (*Database) VerifyAPIKeySignature added in v0.3.0

func (db *Database) VerifyAPIKeySignature(key string) (string, uint, error)

VerifyAPIKeySignature verifies the signature matches the expected value for the key. It does this by computing the expected signature and then doing a constant-time comparison against the provided signature.

func (*Database) VerifyCodeAndIssueToken

func (db *Database) VerifyCodeAndIssueToken(realmID uint, verCode string, acceptTypes api.AcceptTypes, expireAfter time.Duration) (*Token, error)

VerifyCodeAndIssueToken takes a previously issed verification code and exchanges it for a long term token. The verification code must not have expired and must not have been previously used. Both acctions are done in a single database transaction. The verCode can be the "short code" or the "long code" which impacts expiry time.

The long term token can be used later to sign keys when they are submitted.

type DurationSeconds added in v0.4.0

type DurationSeconds struct {
	Duration time.Duration

	// AsString allows this value to be updatd and parsed using the Update() method.
	AsString string
}

DurationSeconds is a custom type for writing and reating a time.Duration to be stored as seconds in the database.

func FromDuration added in v0.5.0

func FromDuration(d time.Duration) DurationSeconds

func (*DurationSeconds) Scan added in v0.4.0

func (d *DurationSeconds) Scan(src interface{}) error

Scan takes a int64 value in seconds and converts that to a time.Duration

func (*DurationSeconds) Update added in v0.5.0

func (d *DurationSeconds) Update() error

Update attempts to parse the AsString value and set is as the duration

func (DurationSeconds) Value added in v0.4.0

func (d DurationSeconds) Value() (driver.Value, error)

Value converts the internal time.Duration value to seconds and returns that value as an int64 for saving to the database.

type Errorable added in v0.4.0

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

Errorable defines an embeddable struct for managing errors on models.

func (*Errorable) AddError added in v0.4.0

func (e *Errorable) AddError(key, err string)

AddError adds a new error to the list.

func (*Errorable) ErrorMessages added in v0.4.0

func (e *Errorable) ErrorMessages() []string

ErrorMessages returns the list of error messages.

func (*Errorable) Errors added in v0.4.0

func (e *Errorable) Errors() map[string][]string

Errors returns the list of errors.

func (*Errorable) ErrorsFor added in v0.4.0

func (e *Errorable) ErrorsFor(key string) []string

ErrorsFor returns the list of errors for the key

type Realm

type Realm struct {
	gorm.Model
	Errorable

	// Name is the name of the realm.
	Name string `gorm:"type:varchar(200);unique_index"`

	// Code configuration
	RegionCode       string          `gorm:"type:varchar(10); not null; default: ''"`
	CodeLength       uint            `gorm:"type:smallint; not null; default: 8"`
	CodeDuration     DurationSeconds `gorm:"type:bigint; not null; default: 900"` // default 15m (in seconds)
	LongCodeLength   uint            `gorm:"type:smallint; not null; default: 16"`
	LongCodeDuration DurationSeconds `gorm:"type:bigint; not null; default: 86400"` // default 24h
	// SMS Content
	SMSTextTemplate string `` /* 164-byte string literal not displayed */

	// AllowedTestTypes is the type of tests that this realm permits. The default
	// value is to allow all test types.
	AllowedTestTypes TestType `gorm:"type:smallint; not null; default: 14"`

	// Signing Key Settings
	UseRealmCertificateKey bool            `gorm:"type:boolean; default: false"`
	CertificateIssuer      string          `gorm:"type:varchar(150); default: ''"`
	CertificateAudience    string          `gorm:"type:varchar(150); default: ''"`
	CertificateDuration    DurationSeconds `gorm:"type:bigint; default: 900"` // 15m

	// EN Express
	EnableENExpress bool `gorm:"type:boolean; default: false"`

	// These are here for gorm to setup the association. You should NOT call them
	// directly, ever. Use the ListUsers function instead. The have to be public
	// for reflection.
	RealmUsers  []*User `` /* 132-byte string literal not displayed */
	RealmAdmins []*User `` /* 133-byte string literal not displayed */

	// Relations to items that belong to a realm.
	Codes  []*VerificationCode `gorm:"PRELOAD:false; SAVE_ASSOCIATIONS:false; ASSOCIATION_AUTOUPDATE:false, ASSOCIATION_SAVE_REFERENCE:false"`
	Tokens []*Token            `gorm:"PRELOAD:false; SAVE_ASSOCIATIONS:false; ASSOCIATION_AUTOUPDATE:false, ASSOCIATION_SAVE_REFERENCE:false"`
}

Realm represents a tenant in the system. Typically this corresponds to a geography or a public health authority scope. This is used to manage user logins.

func NewRealmWithDefaults added in v0.4.0

func NewRealmWithDefaults(name string) *Realm

NewRealmWithDefaults initializes a new Realm with the default settings populated, and the provided name. It does NOT save the Realm to the database.

func (*Realm) BeforeSave added in v0.4.0

func (r *Realm) BeforeSave(tx *gorm.DB) error

BeforeSave runs validations. If there are errors, the save fails.

func (*Realm) BuildSMSText added in v0.4.0

func (r *Realm) BuildSMSText(code, longCode string) string

BuildSMSText replaces certain strings with the right values.

func (*Realm) CanUpgradeToRealmSigningKeys added in v0.5.0

func (r *Realm) CanUpgradeToRealmSigningKeys() bool

func (*Realm) CreateAuthorizedApp added in v0.4.0

func (r *Realm) CreateAuthorizedApp(db *Database, app *AuthorizedApp) (string, error)

CreateAuthorizedApp generates a new API key and assigns it to the specified app. Note that the API key is NOT stored in the database, only a hash. The only time the API key is available is as the string return parameter from invoking this function.

func (*Realm) CreateSigningKeyVersion added in v0.5.1

func (r *Realm) CreateSigningKeyVersion(ctx context.Context, db *Database) (string, error)

CreateSigningKeyVersion creates a new signing key version on the key manager and saves a reference to the new key version in the database. If creating the key in the key manager fails, the database is not updated. However, if updating the signing key in the database fails, the key is NOT deleted from the key manager.

func (*Realm) DestroySigningKeyVersion added in v0.5.1

func (r *Realm) DestroySigningKeyVersion(ctx context.Context, db *Database, id interface{}) error

DestroySigningKeyVersion destroys the given key version in both the database and the key manager. ID is the primary key ID from the database. If the id does not exist, it does nothing.

func (*Realm) FindAuthorizedApp added in v0.3.0

func (r *Realm) FindAuthorizedApp(db *Database, id interface{}) (*AuthorizedApp, error)

FindAuthorizedApp finds the authorized app by the given id associated to the realm.

func (*Realm) FindUser added in v0.4.0

func (r *Realm) FindUser(db *Database, id interface{}) (*User, error)

FindUser finds the given user in the realm by ID.

func (*Realm) GetCodeDurationMinutes added in v0.4.0

func (r *Realm) GetCodeDurationMinutes() int

GetCodeDurationMinutes is a helper for the HTML rendering to get a round minutes value.

func (*Realm) GetCurrentSigningKey added in v0.5.0

func (r *Realm) GetCurrentSigningKey(db *Database) (*SigningKey, error)

GetCurrentSigningKey returns the currently active signing key, the one marked active in the database. If there is more than one active, the most recently created one wins. Should not occur due to transactional update.

func (*Realm) GetLongCodeDurationHours added in v0.4.0

func (r *Realm) GetLongCodeDurationHours() int

GetLongCodeDurationHours is a helper for the HTML rendering to get a round hours value.

func (*Realm) HasSMSConfig added in v0.3.0

func (r *Realm) HasSMSConfig(db *Database) (bool, error)

HasSMSConfig returns true if the realm has an SMS config, false otherwise. This does not perform the KMS encryption/decryption, so it's more efficient that loading the full SMS config.

func (*Realm) ListAuthorizedApps added in v0.4.0

func (r *Realm) ListAuthorizedApps(db *Database) ([]*AuthorizedApp, error)

ListAuthorizedApps gets all the authorized apps for the realm.

func (*Realm) ListSigningKeys added in v0.5.0

func (r *Realm) ListSigningKeys(db *Database) ([]*SigningKey, error)

ListSigningKeys returns the non-deleted signing keys for a realm ordered by created_at desc.

func (*Realm) ListUsers added in v0.4.0

func (r *Realm) ListUsers(db *Database) ([]*User, error)

ListUsers returns the list of users on this realm.

func (*Realm) SMSConfig

func (r *Realm) SMSConfig(db *Database) (*SMSConfig, error)

SMSConfig returns the SMS configuration for this realm, if one exists.

func (*Realm) SMSProvider added in v0.3.0

func (r *Realm) SMSProvider(db *Database) (sms.Provider, error)

SMSProvider returns the SMS provider for the realm. If no sms configuration exists, it returns nil. If any errors occur creating the provider, they are returned.

func (*Realm) SetActiveSigningKey added in v0.5.0

func (r *Realm) SetActiveSigningKey(db *Database, id uint) (string, error)

SetActiveSigningKey sets a specific signing key to active=true for the realm, and transactionally sets all other signing keys to inactive. It accepts the database primary key ID but returns the KID of the now-active key.

func (*Realm) SigningKeyID added in v0.5.0

func (r *Realm) SigningKeyID() string

func (*Realm) ValidTestType added in v0.4.0

func (r *Realm) ValidTestType(typ string) bool

ValidTestType returns true if the given test type string is valid for this realm, false otherwise.

type SMSConfig

type SMSConfig struct {
	gorm.Model
	Errorable

	// SMS Config belongs to exactly one realm.
	RealmID uint `gorm:"unique_index"`

	// ProviderType is the SMS provider type - it's used to determine the
	// underlying configuration.
	ProviderType sms.ProviderType `gorm:"type:varchar(100)"`

	// Twilio configuration options.
	TwilioAccountSid string `gorm:"type:varchar(250)"`
	TwilioFromNumber string `gorm:"type:varchar(16)"`

	// TwilioAuthToken is encrypted/decrypted automatically by callbacks. The
	// cache fields exist as optimizations.
	TwilioAuthToken                string `gorm:"type:varchar(250)"`
	TwilioAuthTokenPlaintextCache  string `gorm:"-"`
	TwilioAuthTokenCiphertextCache string `gorm:"-"`
}

SMSConfig represents and SMS configuration.

type SigningKey added in v0.5.0

type SigningKey struct {
	gorm.Model
	Errorable

	// A signing key belongs to exactly one realm.
	RealmID uint `gorm:"index:realm"`

	// Reference to an exact version of a key in the KMS
	KeyID  string
	Active bool
}

SigningKey represents a reference to a KMS backed signing key version for verification certificate signing.

func (*SigningKey) Delete added in v0.5.0

func (s *SigningKey) Delete(db *Database) error

func (*SigningKey) GetKID added in v0.5.0

func (s *SigningKey) GetKID() string

GetKID returns the 'kid' field value to use in signing JWTs.

type Subject

type Subject struct {
	TestType    string
	SymptomDate *time.Time
}

Subject represents the data that is used in the 'sub' field of the token JWT.

func ParseSubject

func ParseSubject(sub string) (*Subject, error)

func (*Subject) String

func (s *Subject) String() string

func (*Subject) SymptomInterval

func (s *Subject) SymptomInterval() uint32

type TestType added in v0.4.0

type TestType int16

TestType is a test type in the database.

const (
	TestTypeConfirmed TestType
	TestTypeLikely
	TestTypeNegative
)

type Token

type Token struct {
	gorm.Model
	// Tokens belong to one realm.
	RealmID     uint
	TokenID     string `gorm:"type:varchar(200); unique_index"`
	TestType    string `gorm:"type:varchar(20)"`
	SymptomDate *time.Time
	Used        bool `gorm:"default:false"`
	ExpiresAt   time.Time
}

Token represents an issued "long term" from a validated verification code.

func (*Token) FormatSymptomDate

func (t *Token) FormatSymptomDate() string

FormatSymptomDate returns YYYY-MM-DD formatted test date, or "" if nil.

func (*Token) Subject

func (t *Token) Subject() *Subject

type User

type User struct {
	gorm.Model
	Errorable

	Email           string `gorm:"type:varchar(250);unique_index"`
	Name            string `gorm:"type:varchar(100)"`
	Admin           bool   `gorm:"default:false"`
	LastRevokeCheck time.Time
	Realms          []*Realm `gorm:"many2many:user_realms"`
	AdminRealms     []*Realm `gorm:"many2many:admin_realms"`
}

User represents a user of the system

func (*User) AddRealm added in v0.4.0

func (u *User) AddRealm(realm *Realm)

AddRealm adds the user to the realm.

func (*User) AddRealmAdmin added in v0.4.0

func (u *User) AddRealmAdmin(realm *Realm)

AddRealmAdmin adds the user to the realm as an admin.

func (*User) BeforeSave added in v0.4.0

func (u *User) BeforeSave(tx *gorm.DB) error

BeforeSave runs validations. If there are errors, the save fails.

func (*User) CanAdminRealm

func (u *User) CanAdminRealm(realmID uint) bool

func (*User) CanViewRealm

func (u *User) CanViewRealm(realmID uint) bool

func (*User) GetRealm

func (u *User) GetRealm(realmID uint) *Realm

func (*User) RemoveRealm added in v0.4.0

func (u *User) RemoveRealm(realm *Realm)

RemoveRealm removes the user from the realm. It also removes the user as an admin of that realm. You must save the user to persist the changes.

func (*User) RemoveRealmAdmin added in v0.4.0

func (u *User) RemoveRealmAdmin(realm *Realm)

RemoveRealmAdmin removes the user from the realm. You must save the user to persist the changes.

func (*User) Stats added in v0.5.0

func (u *User) Stats(db *Database, realmID uint, start, stop time.Time) ([]*UserStats, error)

Stats returns the usage statistics for this user at the provided realm. If no stats exist, it returns an empty array.

type UserStats added in v0.3.0

type UserStats struct {
	Date        time.Time `gorm:"date"`
	UserID      uint      `gorm:"user_id"`
	RealmID     uint      `gorm:"realm_id"`
	CodesIssued uint      `gorm:"codes_issued"`
}

UserStats represents statistics related to a user in the database.

func (UserStats) TableName added in v0.3.0

func (UserStats) TableName() string

TableName sets the UserStats table name

type VerificationCode

type VerificationCode struct {
	gorm.Model
	Errorable

	RealmID       uint   // VerificationCodes belong to exactly one realm when issued.
	Code          string `gorm:"type:varchar(512);unique_index"`
	LongCode      string `gorm:"type:varchar(512);unique_index"`
	UUID          string `gorm:"type:uuid;unique_index;default:null"`
	Claimed       bool   `gorm:"default:false"`
	TestType      string `gorm:"type:varchar(20)"`
	SymptomDate   *time.Time
	ExpiresAt     time.Time
	LongExpiresAt time.Time
	IssuingUserID uint
	IssuingAppID  uint
}

VerificationCode represents a verification code in the database.

func (*VerificationCode) AfterCreate added in v0.5.0

func (v *VerificationCode) AfterCreate(scope *gorm.Scope)

AfterCreate runs after the verification code has been saved, primarily used to update statistics about usage. If the executions fail, an error is logged but the transaction continues. This is called automatically by gorm.

func (*VerificationCode) FormatSymptomDate

func (v *VerificationCode) FormatSymptomDate() string

FormatSymptomDate returns YYYY-MM-DD formatted test date, or "" if nil.

func (*VerificationCode) HasLongExpiration added in v0.7.0

func (v *VerificationCode) HasLongExpiration() bool

func (*VerificationCode) IsExpired

func (v *VerificationCode) IsExpired() bool

IsExpired returns true if a verification code has expired.

func (VerificationCode) TableName

func (VerificationCode) TableName() string

TableName sets the VerificationCode table name

func (*VerificationCode) Validate

func (v *VerificationCode) Validate(maxAge time.Duration) error

Validate validates a verification code before save.

Jump to

Keyboard shortcuts

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