common

package
v0.0.0-...-5f8c1fa Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2023 License: BSD-2-Clause Imports: 32 Imported by: 0

Documentation

Index

Constants

View Source
const Cost = 10

Cost is the cost of the bcrypt digest. This is hard-coded at 10 to match the value that Rails/Devise uses. We're porting a Rails database and we want to be able to use existing passwords instead of forcing users to reset them.

View Source
const EncryptedTokenPrefix = "$2a$10$"

EncryptedTokenPrefix is the prefix that should appear on all our encrypted passwords and tokens in the database. Note that it depends on common.Cost being set to 10.

Variables

View Source
var ErrAccountDeactivated = errors.New("account deactivated")

ErrAccountDeactivated means the user logged in to a deactivated account.

View Source
var ErrActiveFiles = errors.New("cannot delete object with active files")

ErrActiveFiles occurs when we try to delete an IntellectualObject that has active files. All of the object's files should first be deleted (set to State = "D").

View Source
var ErrAlreadyHasAuthyID = errors.New("user is already registered with authy")

ErrAlreadyHasAuthyID occurs when we try to register a user with Authy and they already have an Authy ID.

View Source
var ErrCountTypeNotSupported = errors.New("type is not supported for view count")

ErrCountTypeNotSupported indicates that we cannot get counts for the given type from the *_counts views. Use a regular SQL count() instead.

View Source
var ErrCrossOriginReferer = errors.New("csrf error: cross origin request forbidden")

ErrMissingReferer means we got a cross-site request on an unsafe methods such as POST, PUT, DELETE. See the CSRF middleware.

View Source
var ErrDecodeCookie = errors.New("error decoding cookie")

ErrDecodeCookie occurs when we get a bad authentication cookie. We consider it a 400/Bad Request because we don't set bad cookies.

View Source
var ErrIDMismatch = errors.New("resource or institution id mismatch")

ErrIDMismatch can indicate that the specified resource does not belong to the specified institition, or (more likely) that resource/institution IDs in a URL do not match resource/institution IDs submitted in the PUT/POST body of an HTML request.

View Source
var ErrIdentifierChange = errors.New("identifier cannot change")

ErrIdentifierChange occurs when someone tries to change the identifier of a resource.

View Source
var ErrInstIDChange = errors.New("institution id cannot change")

ErrInstIDChange occurs when someone tries to change the institution id of a resource.

View Source
var ErrInternal = errors.New("internal server error")

ErrInternal is a runtime error that is not the user's fault, hence probably the programmer's fault.

View Source
var ErrInvalidAPICredentials = errors.New("invalid api credentials")

ErrInvalidAPICredentials means the user supplied the wrong email or API token while trying to access a REST API endpoint.

View Source
var ErrInvalidCSRFToken = errors.New("invalid csrf token")

ErrInvalidCSRFToken is specifically for POST/PUT/DELETE where we have a missing or invalid CSRF token.

View Source
var ErrInvalidLogin = errors.New("invalid login or password")

ErrInvalidLogin means the user supplied the wrong login name or password while trying to sign in.

View Source
var ErrInvalidParam = errors.New("invalid parameter")

ErrInvalidParam means the HTTP request contained an invalid parameter.

View Source
var ErrInvalidToken = errors.New("invalid token")

ErrInvalidToken means that the token presented for an action like password reset or deletion confirmation does not match the encrypted token in the database. When this error occurs, the user may not proceed with the requested action.

View Source
var ErrMissingReferer = errors.New("csrf error: missing http referer")

ErrMissingReferer means the request had no http referer header, so we can't tell where it came from. We can't tell for sure if it's a cross-origin attack, so we throw an error. This happens only on unsafe methods (POST, PUT, DELETE). See the CSRF middleware.

View Source
var ErrMustCompleteReset = errors.New("you must complete your own password reset")

ErrMustCompleteReset occurs when a user is supposed to be resetting their own password but tries instead to reset someone else's. SysAdmin and Inst admins can legitimately reset others' passwords, but they shouldn't be doing it in this context.

View Source
var ErrNoAuthyID = errors.New("user does not have an authy id")

ErrNoAuthyID occurs when a user requests two-factor login via Authy but does not have an Authy ID.

View Source
var ErrNotSignedIn = errors.New("user is not signed in")

ErrNotSignedIn means user has not signed in.

View Source
var ErrNotSupported = errors.New("operation not supported")

ErrNotSupported is an internal error that occurs, for example, when we try to delete an object that does not support deletion. This represents a programmer error and should not occur.

View Source
var ErrParentRecordNotFound = errors.New("parent record not found")

ErrParentRecordNotFound occurs when we cannot find the parent record required to check a user's permission. For example, when a user requests a Checksum, we first need to know if the user is allowed to access the Checksum's parent, which is a Generic File. If that record is missing, we get this error.

View Source
var ErrPasswordReqs = errors.New("password does not meet minimum requirements")

ErrPasswordReqs indicates that the password the user is trying to set does not meet minimum requirements.

View Source
var ErrPendingWorkItems = errors.New("task cannot be completed because this object has pending work items")

ErrPendingWorkItems occurs when a user wants to restore or delete an object or file but the WorkItems list shows other operations are pending on that item. For example, we can't delete or restore an object or file while another version of that object/file is pending ingest. Doing so would cause newly ingested files to be deleted as soon as they're sent to preservation, or would cause a restoration to contain a mix of new and old versions of a bag's files.

View Source
var ErrPermissionDenied = errors.New("permission denied")

ErrPermissionDenied means the user tried to access a resource withouth sufficient permission.

View Source
var ErrResourcePermission = errors.New("cannot determine permission type for requested requested resource")

ErrResourcePermission occurs when Authorization middleware cannot determine which permission is required to access the specified resoruce.

View Source
var ErrStorageOptionChange = errors.New("cannot change storage option on active object")

ErrStorageOptionChange indicates someone tried to change the storage option on an active object. (It's OK to change storage option on a deleted object that you are re-depositing.)

View Source
var ErrSubclassMustImplement = errors.New("subclass must implement this method")

ErrSubclassMustImplement indicates that a subclass has not implemented a method inherited from a base class.

View Source
var ErrWrongAPI = errors.New("non-admins must use the member api")

ErrWrongAPI occurs when a non-admin user tries to access the admin API. While the member and admin APIs share some common handlers, and members do technically have access to a number of read-only operations in both APIs, we don't want members to get in the habit of accessing the wrong endpoints.

View Source
var ErrWrongDataType = errors.New("wrong data type")

ErrWrongDataType occurs when the user submits data of the wrong type, such string data that cannot be converted to a number, bool, date, or whatever type the application is expecting.

View Source
var TextTemplates map[string]*template.Template

Functions

func ComparePasswords

func ComparePasswords(hashed, plaintext string) bool

ComparePasswords compares a plaintext password against a hashed password, returning true if they match, false otherwise.

func ConsoleDebug

func ConsoleDebug(message string, args ...interface{})

ConsoleDebug prints a message to the console if the following we are running in the dev or test environment and we are not running automated tests. We want to see these messages in the console when we're doing interactive testing in the dev or test environments, but NOT when running automated tests because they clutter the test output.

We also don't want these messages to appear in production, which is why we have a hard-coded list of safe environment names.

func CopyFile

func CopyFile(src string, dst string, mode os.FileMode) error

CopyFile copies the file at src path to dst path. It applies the permissions specified in mode to the destination file. Mode values are 0644, 0755, etc.

func CountryCodeAndPhone

func CountryCodeAndPhone(phoneNumber string) (int32, string, error)

CountryCodeAndPhone returns the country code and phone number for a phoneNumber in format that begins with plus country code, e.g. "+12125551212"

func EncryptPassword

func EncryptPassword(password string) (string, error)

EncryptPassword returns the password run through bcrypt 2a with the specified salt and cost.

func ExpandTilde

func ExpandTilde(filePath string) (string, error)

Expands the tilde in a directory path to the current user's home directory. For example, on Linux, ~/data would expand to something like /home/josie/data

func FileExists

func FileExists(path string) bool

Returns true if the file at path exists, false if not.

func Hash

func Hash(plaintext string) string

Hash returns an encrypted version of plaintext that cannot be decrypted. This is suitable for encrypting passwords, reset-tokens, etc. The combined use of md5 plus plaintext salt plus sha256 provides some protection against rainbow tables.

TODO: Delete this if we're not using it. Looks like we're actually using bcrypt in common/password.go

func InterfaceList

func InterfaceList(items []string) []interface{}

InterfaceList converts a list of strings to a list of interfaces.

func IsEmptyString

func IsEmptyString(str string) bool

IsEmptyString returns true if str, stripped of leading and trailing whitespace, is empty.

func IsTrueString

func IsTrueString(s string) bool

IsTrueString returns true if param s is "true", "yes", or "1". The test is case-insensitive. Use this for parsing query string params.

func ListIsEmpty

func ListIsEmpty(list []string) bool

ListIsEmpty returns true if the slice contains no elements, or if all the elements are empty strings.

func LoadRelativeFile

func LoadRelativeFile(relpath string) ([]byte, error)

LoadRelativeFile loads the file at the specified path relative to ProjectRoot() and returns the contents as a byte array.

Example:

bytes, err := LoadRelativeFile("db/fixtures/work_items.csv")

func LooksEncrypted

func LooksEncrypted(s string) bool

LooksEncrypted returns true if string s looks like it's been through our EncryptePassword fuction. We use LooksEncrypted on some pgmodels to ensure we're not saving unencrypted passwords or tokens.

func LooksLikeUUID

func LooksLikeUUID(uuid string) bool

LooksLikeUUID returns true if uuid looks like a valid UUID.

func NewOTP

func NewOTP() (string, error)

NewOTP returns a six-digit code suitable for use as a one-time password. We return this as a string because we need to store a hashed version in the DB and then send a copy to the user.

func PasswordMeetsRequirements

func PasswordMeetsRequirements(pwd string) bool

PasswordMeetsRequirements returns true if param pwd meets our minimum password requirements.

func PrintAndExit

func PrintAndExit(message string)

PrintAndExit prints a message to STDERR and exits

func ProjectRoot

func ProjectRoot() string

ProjectRoot returns the project root.

func RandomToken

func RandomToken() string

RandomToken returns a string of random hex digits suitable for use as a secure token.

func SanitizeIdentifier

func SanitizeIdentifier(str string) string

SanitizeIdentifier strips everything but letters, numbers, underscores periods and double quotes from str. This is used primarily to sanitize SQL column names in queries. Column names may include things like "email", "user"."email", etc.

func SplitCamelCase

func SplitCamelCase(str string, max int) []string

SplitCamelCase splits camel-case identifiers into multiple words. Note that it does not split on multiple consecutive caps, so param CurrencyUSD would return ["Currency", "USD"].

If max is less than zero, this will split into all words. If max is > 0, this will split into max words.

func TestsAreRunning

func TestsAreRunning() bool

TestsAreRunning returns true when code is running under "go test"

func ToHumanSize

func ToHumanSize(size, unit int64) string

ToHumanSize converts a raw byte count (size) to a human-friendly representation.

Types

type APTContext

type APTContext struct {
	Config      *Config
	DB          *pg.DB
	Log         zerolog.Logger
	AuthyClient network.AuthyClientInterface
	NSQClient   *network.NSQClient
	RedisClient *network.RedisClient
	SESClient   *network.SESClient
	SNSClient   *network.SNSClient
}

func Context

func Context() *APTContext

Context returns an APTContext object, which includes global config settings and a connection to the postgres database. It requires the environment variable APT_ENV to be set to something valid, such as "test", "dev", "integration", "demo", "staging" or "production". It loads the .env file that corresponds to that setting. If APT_ENV is not set to a valid setting, the app dies immediately.

This will also exit if the app cannot connect to the database. If that happens, ensure the database is running and accepting connections at the specified location, and ensure that the db credentials are correct.

type Config

type Config struct {
	Cookies   *CookieConfig
	DB        *DBConfig
	EnvName   string
	Logging   *LoggingConfig
	NsqUrl    string
	TwoFactor *TwoFactorConfig
	Email     *EmailConfig
	Redis     *RedisConfig
}

func NewConfig

func NewConfig() *Config

Returns a new config based on APT_ENV

func (*Config) BucketQualifier

func (config *Config) BucketQualifier() string

BucketQualifier returns the S3 bucket qualifier for the current config. We could set this in the .env file, but we want to avoid the possibility of a config pointing to the wrong buckets. (For example, by someone carelessly copying and pasting config settings.) Our restrictive IAM permissions prevent the wrong environments from accessing the wrong buckets, but this is an extra layer of protection. This defaults to ".test", so if anything is misconfigured, we'll be reading from and writing to buckets in which we explicitly guarantee no permanance.

func (*Config) HTTPScheme

func (config *Config) HTTPScheme() string

HTTPScheme returns "http" for the dev, test, ci, and travis environments. It returns "https" for all other environments.

func (*Config) IsTestOrDevEnv

func (config *Config) IsTestOrDevEnv() bool

Returns true if we're in a test or dev environment.

func (*Config) ToJSON

func (config *Config) ToJSON() string

ToJSON serializes the config to JSON for logging purposes. It omits some sensitive data, such as the Pharos API key and AWS credentials.

type CookieConfig

type CookieConfig struct {
	Secure        *securecookie.SecureCookie
	Domain        string
	HTTPSOnly     bool
	MaxAge        int
	SessionCookie string
	FlashCookie   string
	PrefsCookie   string
}

type DBConfig

type DBConfig struct {
	Host     string
	Name     string
	User     string
	Password string
	Port     int
	Driver   string
	UseSSL   bool
}

type EmailConfig

type EmailConfig struct {
	AWSRegion   string
	Enabled     bool
	FromAddress string
	SesUser     string
	SesPassword string
}

type LoggingConfig

type LoggingConfig struct {
	File         string
	Level        zerolog.Level
	LogCaller    bool
	LogToConsole bool
	LogSql       bool
}

type Pager

type Pager struct {
	TotalItems       int
	ItemsInResultSet int
	ItemFirst        int
	ItemLast         int
	Page             int
	PerPage          int
	QueryOffset      int
	PreviousLink     string
	NextLink         string
	URL              *url.URL
}

func NewPager

func NewPager(c *gin.Context, baseURL string, defaultPerPage int) (*Pager, error)

func (*Pager) SetCounts

func (pager *Pager) SetCounts(totalItems, itemsInResultSet int)

type QueryLogger

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

func NewQueryLogger

func NewQueryLogger(logger zerolog.Logger) *QueryLogger

func (*QueryLogger) AfterQuery

func (l *QueryLogger) AfterQuery(c context.Context, qe *pg.QueryEvent) error

func (*QueryLogger) BeforeQuery

func (l *QueryLogger) BeforeQuery(c context.Context, qe *pg.QueryEvent) (context.Context, error)

type RedisConfig

type RedisConfig struct {
	URL       string
	Password  string
	DefaultDB int
}

type TwoFactorConfig

type TwoFactorConfig struct {
	AuthyEnabled  bool
	AuthyAPIKey   string `json:"-"`
	AWSRegion     string
	SMSEnabled    bool
	OTPExpiration time.Duration
}

type ValidationError

type ValidationError struct {
	Errors map[string]string
}

func NewValidationError

func NewValidationError() *ValidationError

func (*ValidationError) Error

func (v *ValidationError) Error() string

Jump to

Keyboard shortcuts

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