cloudy

package module
v0.0.5-dev.1 Latest Latest
Warning

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

Go to latest
Published: Mar 10, 2023 License: MIT Imports: 32 Imported by: 13

README

Cloudy

IN WORK -- DO NOT USE

Planned to be an open source library that is a runtime adapter for AWS and Azure cloud capablilies. This library tries to provide simple capalbities instead of trying for a full-coverage. As you ned to use more complex capalbities they you should be able to tie into the underlying APIs from each of the Cloud Vendors.

Capablities

  • User Management
  • Group Management
  • Blob / Bucket
  • Mail
  • SMS / Notification
  • JSON Data storage / query
  • Binary Data storage

Providers

AWS

Amazon Web Services

  • User Management - Cognito
  • Group Management - Cognito
  • Blob / Bucket - S3
  • Mail - SES
  • SMS - SNS
  • JsonDataStorage - OpenSearch
  • BinaryDataStorage - S3
Azure

Microsoft Azure

  • User Management - AAD
  • Group Management - AAD
  • Blob / Bucket - Azure Blob Storage
  • Mail - Azure Communication Services
  • SMS - Azure Communication Services
  • JsonDataStorage - Cosmos
  • BinaryDataStorage - Azure Blob Storage
ElasticSearch
  • JsonDataStorage
Keycloak
  • User Management
  • Group Management

Documentation

Index

Constants

View Source
const UserAnonymous = "ANONYMOUS"

Variables

View Source
var DefaultEnvironment = NewEnvironment(NewOsEnvironmentService())
View Source
var EmailerProviders = NewProviderRegistry[Emailer]()
View Source
var EnvironmentProviders = NewProviderRegistry[EnvironmentService]()
View Source
var ErrDriverNotFound = errors.New("driver not found")
View Source
var ErrInvalidConfiguration = errors.New("invalid configuration object")
View Source
var ErrKeyNotFound = errors.New("key not found")
View Source
var ErrOperationNotImplemented = errors.New("operation not implemented")
View Source
var GroupProviders = NewProviderRegistry[GroupManager]()
View Source
var IDKey userkey = userkey("id")
View Source
var Log logkey
View Source
var UserKey userkey = userkey("userkey")

Functions

func AddEnvPrefix

func AddEnvPrefix(prefix string, name string) string

func ArrayDisjoint added in v0.0.2

func ArrayDisjoint[T comparable](all []T, arr []T) []T

Determines the items that are NOT in this set and returns those

func ArrayFindIndex added in v0.0.2

func ArrayFindIndex[T comparable](all []T, fn func(item T) bool) int

func ArrayFirst added in v0.0.2

func ArrayFirst[T comparable](all []T, fn func(item T) bool) (found T, ok bool)

func ArrayIncludes added in v0.0.2

func ArrayIncludes[T comparable](arr []T, item T) bool

func ArrayIncludesAll added in v0.0.2

func ArrayIncludesAll[T comparable](all []T, arr []T) []T

Detemines the items that are in this set

func ArrayRemove added in v0.0.2

func ArrayRemove[T comparable](all []T, fn func(item T) bool) ([]T, bool)

func ArrayRemoveAll added in v0.0.2

func ArrayRemoveAll[T comparable](arr []T, matches func(item T) bool) []T

func ArrayRemoveIndex added in v0.0.2

func ArrayRemoveIndex[T comparable](all []T, i int) []T

func BoolFromP added in v0.0.2

func BoolFromP(b *bool) bool

func BoolP

func BoolP(v bool) *bool

func CamelToSeparated

func CamelToSeparated(v string, sep string) string

func CheckAddress

func CheckAddress(address string, timeout time.Duration) bool

func DeferableClose

func DeferableClose(ctx context.Context, closeme io.Closer)

func EnvJoin

func EnvJoin(envParts ...string) string

func EnvKeyStr

func EnvKeyStr(data map[string]interface{}, key string) (string, bool)

func Error

func Error(ctx context.Context, msg string, args ...interface{}) error

func Exists added in v0.0.4

func Exists(path string) (bool, error)

func FindMatchingUser

func FindMatchingUser(ctx context.Context, username string, mode DuplicateUserMode, manager UserManager, userDomain string) (string, error)

func FixName

func FixName(name string) string

func ForceEnv

func ForceEnv(name string, prefix string) string

ForceEnv Fails if the env is not present

func FromEnv

func FromEnv(prefix string, driverKey string) (string, map[string]interface{}, error)

func FromGabs

func FromGabs(c *gabs.Container, v interface{}) error

func GenerateId

func GenerateId(prefix string, num int) string

Generate an ID. The ID will follow the pattern {prefix}-{id} where the id is a randomly generated string of alphanumeric characters

func GenerateIdLower

func GenerateIdLower(prefix string, num int) string

Generate an ID. The ID will follow the pattern {prefix}-{id} where the id is a randomly generated string of alphanumeric characters

func GeneratePassword

func GeneratePassword(passwordLength, minSpecialChar, minNum, minUpperCase int) string

func GeneratePasswordFromOptions

func GeneratePasswordFromOptions(po PasswordOptions) string

func GeneratePasswordNoSpecial

func GeneratePasswordNoSpecial(passwordLength, minNum, minUpperCase int) string

func GenerateRandom

func GenerateRandom(num int) string

func GetEnv

func GetEnv(name string, prefix string) string

func GetFieldString

func GetFieldString(v interface{}, field string) string

func GetID

func GetID(ctx context.Context) string

func GetLog

func GetLog(ctx context.Context) string

func GetUserTokenFromRequest

func GetUserTokenFromRequest(ctx context.Context, request *http.Request) (string, error)

func HashId

func HashId(prefix string, parts ...string) string

func Info

func Info(ctx context.Context, msg string, args ...interface{})

func IntEnv added in v0.0.4

func IntEnv(name string) int

func IntP added in v0.0.4

func IntP(v int) *int

func IsAdmin

func IsAdmin(user *UserJWT) bool

func IsMap

func IsMap(suspect interface{}) bool

func IsPointer

func IsPointer(item interface{}) bool

func IsRequestorAdmin

func IsRequestorAdmin(ctx context.Context, request *http.Request) (bool, error)

func IsValidPassword

func IsValidPassword(password string) bool

func IsValidPasswordNoSpecial

func IsValidPasswordNoSpecial(password string) bool

func IsValidPasswordWithOptions

func IsValidPasswordWithOptions(password string, options PasswordOptions) bool

func IsZeroDate

func IsZeroDate(dt strfmt.DateTime) bool

func LoadEnv

func LoadEnv(file string) error

func LoadEnvPrefixMap

func LoadEnvPrefixMap(prefix string) map[string]interface{}

Loads all the environment variables with the given prefix. This normalizes the env variable names to all uppercase without underscores. This means that POOL_ID == POOLID == PoolId == pool_id

func MapKey

func MapKey[T any](data map[string]T, key string, caseInsensitive bool) (T, bool)

func MapKeyStr

func MapKeyStr(data map[string]interface{}, key string, caseInsensitive bool) (string, bool)

MapKeyStr is used for dealing with JSON...

func NewByteReadCloser

func NewByteReadCloser(data []byte) io.ReadCloser

func NewContext

func NewContext(ctx context.Context) context.Context

func NewInstance

func NewInstance(v interface{}) interface{}

func NewInstanceT

func NewInstanceT[T any](v interface{}) (T, error)

func NewMailer added in v0.0.2

func NewMailer(ctx context.Context, provider string, cfg interface{})

func NewT

func NewT[T any]() (T, error)

func NormalizeEnvName

func NormalizeEnvName(v string) string

Normalized an env name MY_VAR => MY_VAR my-var => MY_VAR MyVar => MY_VAR myVar => MY_VAR my-vAR => MY_VAR myVAR => MY_VAR my var => MY_VAR IF there are no dashes or underscores then the first letter and virst capital in a sequence are used to have underscores

func PrintLog

func PrintLog(ctx context.Context)

func RemoveDomain

func RemoveDomain(email string) string

func RemoveEnvPrefix

func RemoveEnvPrefix(prefix string, name string) string

func SetDefaultEnvironment

func SetDefaultEnvironment(env *Environment)

func SetFieldString

func SetFieldString(v interface{}, field string, value string)

func ShutdownDocker added in v0.0.2

func ShutdownDocker(name string) error

func StartContext

func StartContext() context.Context

func StartDocker added in v0.0.2

func StartDocker(name string, args []string, waitFor string) (bool, error)

func StrContains

func StrContains(str string, arr []string) bool

func StringFromP added in v0.0.2

func StringFromP(val *string) string

func StringFromPWithDefault

func StringFromPWithDefault(s *string, missing string) string

func StringP

func StringP(s string) *string

func ToEnvName

func ToEnvName(name string, prefix string) string

func ToGabs

func ToGabs(item interface{}) (*gabs.Container, error)

func TrimDomain added in v0.0.4

func TrimDomain(v string) string

func UnmarshallT

func UnmarshallT[T any](data []byte) (*T, error)

func WaitForAddress

func WaitForAddress(address string, timeout time.Duration) bool

func Warn

func Warn(ctx context.Context, msg string, args ...interface{})

func WithID

func WithID(ctx context.Context, ID string) context.Context

func WithLogging

func WithLogging(ctx context.Context) context.Context

func WithUser

func WithUser(ctx context.Context, user *UserJWT) context.Context

Types

type AfterInterceptor added in v0.0.2

type AfterInterceptor[T any] interface {
	AfterAction(ctx context.Context, item *T) (*T, error)
}

type Attachment added in v0.0.2

type Attachment struct {
	Name   string
	Path   string
	Data   []byte
	Reader io.Reader
}

type BeforeInterceptor added in v0.0.2

type BeforeInterceptor[T any] interface {
	BeforeAction(ctx context.Context, item *T) (*T, error)
}

type ByteCounter

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

func NewByteCounter

func NewByteCounter(stream io.ReadCloser) *ByteCounter

func (*ByteCounter) Close

func (bc *ByteCounter) Close() error

func (*ByteCounter) Read

func (bc *ByteCounter) Read(buf []byte) (n int, err error)

func (*ByteCounter) Total

func (bc *ByteCounter) Total() int64

type CachedEnvironment

type CachedEnvironment struct {
	Source EnvironmentService
	// contains filtered or unexported fields
}

func NewCachedEnvironment

func NewCachedEnvironment(source EnvironmentService) *CachedEnvironment

func (*CachedEnvironment) Get

func (ce *CachedEnvironment) Get(name string) (string, error)

type DuplicateUserMode

type DuplicateUserMode int
const UserAny DuplicateUserMode = 1
const UserDoesNotExist DuplicateUserMode = 3
const UserExists DuplicateUserMode = 2

type Email added in v0.0.2

type Email struct {
	To      []string
	CC      []string
	BCC     []string
	From    string
	Body    string
	HTML    bool
	Subject string

	Attachments []Attachment
}

func (*Email) Send added in v0.0.2

func (e *Email) Send(ctx context.Context) error

type Emailer added in v0.0.2

type Emailer interface {
	Send(ctx context.Context, message *gomail.Message) error
}

type Environment

type Environment struct {
	EnvSvc EnvironmentService
}

func CreateCompleteEnvironment

func CreateCompleteEnvironment(envVar string, PrefixVar string) *Environment

func NewEnvironment

func NewEnvironment(envSvc EnvironmentService) *Environment

func (*Environment) Default

func (env *Environment) Default(name string, defaultValue string) string

func (*Environment) Force

func (env *Environment) Force(name ...string) string

func (*Environment) Get

func (env *Environment) Get(name string) string

func (*Environment) GetInt

func (env *Environment) GetInt(name string) (int, bool)

func (*Environment) Segment

func (env *Environment) Segment(name ...string) *Environment

type EnvironmentService

type EnvironmentService interface {
	Get(name string) (string, error)
}

type FirstDotLastUsernameStrategy

type FirstDotLastUsernameStrategy struct{}

func (*FirstDotLastUsernameStrategy) GuessUsername

func (strat *FirstDotLastUsernameStrategy) GuessUsername(ctx context.Context, user *models.User, mode DuplicateUserMode, manager UserManager, userDomain string) (string, error)

type FirstInitialLastUsernameStrategy

type FirstInitialLastUsernameStrategy struct{}

func (*FirstInitialLastUsernameStrategy) GuessUsername

func (strat *FirstInitialLastUsernameStrategy) GuessUsername(ctx context.Context, user *models.User, mode DuplicateUserMode, manager UserManager, userDomain string) (string, error)

type GroupManager added in v0.0.2

type GroupManager interface {

	// List all the groups available
	ListGroups(ctx context.Context) ([]*models.Group, error)

	// Get a specific group by id
	GetGroup(ctx context.Context, id string) (*models.Group, error)

	// Get all the groups for a single user
	GetUserGroups(ctx context.Context, uid string) ([]*models.Group, error)

	// Create a new Group
	NewGroup(ctx context.Context, grp *models.Group) (*models.Group, error)

	// Update a group. This is generally just the name of the group.
	UpdateGroup(ctx context.Context, grp *models.Group) (bool, error)

	// Get all the members of a group. This returns partial users only,
	// typically just the user id, name and email fields
	GetGroupMembers(ctx context.Context, grpId string) ([]*models.User, error)

	// Remove members from a group
	RemoveMembers(ctx context.Context, groupId string, userIds []string) error

	// Add member(s) to a group
	AddMembers(ctx context.Context, groupId string, userIds []string) error

	DeleteGroup(ctx context.Context, groupId string) error
}

Manages groups that users are part of.This can be seperate from the user manager or it can be the same.

type HierarchicalEnvironment

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

HierarchicalEnvironment understands that the envrionment can be split into heirarchical segments (a tree) that can be used to provide overrides. For isntance, ARKLOUD_V1 and ARKLOUD_SERVICE1_V1 are both possible keys with segements being ARKLOUD and ARKLOUD_SERVICE1. So a call to GetCascade("V1")

func NewHierarchicalEnvironment

func NewHierarchicalEnvironment(env EnvironmentService, segments ...string) *HierarchicalEnvironment

func (*HierarchicalEnvironment) Default

func (segEnv *HierarchicalEnvironment) Default(name string, defaultValue string) (string, bool)

func (*HierarchicalEnvironment) Force

func (segEnv *HierarchicalEnvironment) Force(name string) string

func (*HierarchicalEnvironment) ForceNoCascadee

func (segEnv *HierarchicalEnvironment) ForceNoCascadee(name string) string

func (*HierarchicalEnvironment) Get

func (segEnv *HierarchicalEnvironment) Get(name string) (string, error)

func (*HierarchicalEnvironment) GetNoCascade

func (segEnv *HierarchicalEnvironment) GetNoCascade(name string) (string, bool)

func (*HierarchicalEnvironment) S

type Logs

type Logs struct {
	Info   *log.Logger
	Warn   *log.Logger
	Error  *log.Logger
	Buffer *bytes.Buffer
}

type Mailer added in v0.0.2

type Mailer struct {
	Before  []BeforeInterceptor[Email]
	After   []AfterInterceptor[Email]
	Emailer Emailer
}
var DefaultEmailer *Mailer

func (*Mailer) Send added in v0.0.2

func (m *Mailer) Send(ctx context.Context, item *Email) (err error)

func (*Mailer) ToGoMailMessage added in v0.0.2

func (m *Mailer) ToGoMailMessage(ctx context.Context, message *Email) *gomail.Message

type MapEnvironment

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

func LoadEnvironmentService

func LoadEnvironmentService(file string) (*MapEnvironment, error)

func NewMapEnvironment

func NewMapEnvironment() *MapEnvironment

func NewTestFileEnvironmentService

func NewTestFileEnvironmentService() *MapEnvironment

func (*MapEnvironment) Get

func (te *MapEnvironment) Get(name string) (string, error)

func (*MapEnvironment) Set

func (te *MapEnvironment) Set(name string, v string)

type MultiErrors added in v0.0.2

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

Error Type

func MultiError added in v0.0.2

func MultiError() *MultiErrors

Initiate Error Instance

func (*MultiErrors) Append added in v0.0.2

func (e *MultiErrors) Append(err ...error)

Append new error

func (*MultiErrors) AsErr added in v0.0.2

func (e *MultiErrors) AsErr() error

func (*MultiErrors) Clear added in v0.0.2

func (e *MultiErrors) Clear()

Clear all error items

func (*MultiErrors) Error added in v0.0.2

func (e *MultiErrors) Error() string

func (*MultiErrors) HasError added in v0.0.2

func (e *MultiErrors) HasError() bool

Check if it has errors

func (*MultiErrors) Len added in v0.0.2

func (e *MultiErrors) Len() int

Total lent of error in list

func (*MultiErrors) Line added in v0.0.2

func (e *MultiErrors) Line(w io.Writer)

Display errors in Line format

func (*MultiErrors) List added in v0.0.2

func (e *MultiErrors) List() []error

List all error items

func (*MultiErrors) Merge added in v0.0.2

func (e *MultiErrors) Merge(err *MultiErrors)

Merge Errors

func (*MultiErrors) String added in v0.0.2

func (e *MultiErrors) String() string

Return Stringer interface

func (*MultiErrors) Tab added in v0.0.2

func (e *MultiErrors) Tab(w io.Writer)

Display errors in tabulated format

type PasswordOptions

type PasswordOptions struct {
	Length int

	MinUpperCase   int
	MinNum         int
	MinSpecialChar int

	HasUpperCase   bool
	HasNum         bool
	HasSpecialChar bool
}

func (PasswordOptions) GetCharSet

func (po PasswordOptions) GetCharSet() string

type ProviderFactory

type ProviderFactory[T any] interface {
	Create(cfg interface{}) (T, error)
	FromEnv(env *Environment) (interface{}, error)
}

type ProvidersRegistry

type ProvidersRegistry[T any] struct {
	Providers map[string]ProviderFactory[T]
}

func NewProviderRegistry

func NewProviderRegistry[T any]() *ProvidersRegistry[T]

func (*ProvidersRegistry[T]) New

func (pr *ProvidersRegistry[T]) New(name string, cfg interface{}) (T, error)

func (*ProvidersRegistry[T]) NewFromEnv

func (pr *ProvidersRegistry[T]) NewFromEnv(env *Environment, driverKey string) (T, error)

func (*ProvidersRegistry[T]) NewFromEnvWith

func (pr *ProvidersRegistry[T]) NewFromEnvWith(env *Environment, driver string) (T, error)

func (*ProvidersRegistry[T]) Print

func (pr *ProvidersRegistry[T]) Print()

func (*ProvidersRegistry[T]) Register

func (pr *ProvidersRegistry[T]) Register(name string, factory ProviderFactory[T])

type SeekingBuffer

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

func NewSeekingBuffer

func NewSeekingBuffer(b []byte) *SeekingBuffer

func (*SeekingBuffer) Read

func (fb *SeekingBuffer) Read(p []byte) (n int, err error)

func (*SeekingBuffer) Seek

func (fb *SeekingBuffer) Seek(offset int64, whence int) (ret int64, err error)

type Storage

type Storage interface {
}

type SystemEnvironmentVariables

type SystemEnvironmentVariables struct{}

System Environment Variables Services

func NewOsEnvironmentService

func NewOsEnvironmentService() *SystemEnvironmentVariables

func (*SystemEnvironmentVariables) Get

func (ce *SystemEnvironmentVariables) Get(name string) (string, error)

type SystemEnvironmentVariablesFactory

type SystemEnvironmentVariablesFactory struct{}

func (*SystemEnvironmentVariablesFactory) Create

func (f *SystemEnvironmentVariablesFactory) Create(cfg interface{}) (EnvironmentService, error)

func (*SystemEnvironmentVariablesFactory) FromEnv

func (f *SystemEnvironmentVariablesFactory) FromEnv(env *Environment) (interface{}, error)

type TemplatedEmail added in v0.0.2

type TemplatedEmail struct {
	Email
	BodyTemplate    *template.Template
	SubjectTemplate *template.Template
	InlineStyles    bool
}

func (*TemplatedEmail) Render added in v0.0.2

func (t *TemplatedEmail) Render(ctx context.Context, data interface{}) (email *Email, err error)

func (*TemplatedEmail) RenderRaw added in v0.0.2

func (t *TemplatedEmail) RenderRaw(ctx context.Context, data interface{}) (body string, subject string, err error)

func (*TemplatedEmail) Send added in v0.0.2

func (t *TemplatedEmail) Send(ctx context.Context, data interface{}) error

type TestEnvFileFactory

type TestEnvFileFactory struct{}

func (*TestEnvFileFactory) Create

func (f *TestEnvFileFactory) Create(cfg interface{}) (EnvironmentService, error)

func (*TestEnvFileFactory) FromEnv

func (f *TestEnvFileFactory) FromEnv(env *Environment) (interface{}, error)

type TieredEnvironment

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

TieredEnvironment provides an EnvironmentService that looks for configuration values in a chain of environments, starting at the first.

For Example, consider the following

env := NewTieredEnvironment(
	NewSystemEnvironmentVariables(),
	NewCachedEnvironment(NewKeyVaultEnvironmentService(myazconfig))
)

val, err := env.Get("A-Value")

In this example. The cached tier is used first

func NewTieredEnvironment

func NewTieredEnvironment(sources ...EnvironmentService) *TieredEnvironment

func (*TieredEnvironment) Force

func (te *TieredEnvironment) Force(name string) (string, error)

func (*TieredEnvironment) Get

func (te *TieredEnvironment) Get(name string) (string, error)

type UserJWT

type UserJWT struct {
	EXP               int64                  `json:"exp"`
	IAT               int64                  `json:"iat"`
	AuthTime          int64                  `json:"auth_time"`
	JTI               string                 `json:"jti"`
	ISS               string                 `json:"iss"`
	AUD               string                 `json:"aud"`
	TYP               string                 `json:"typ"`
	AZP               string                 `json:"azp"`
	Nonce             string                 `json:"nonce"`
	SessionState      string                 `json:"session_state"`
	ACR               string                 `json:"acr"`
	AllowedOrigins    []string               `json:"allowed-origins"`
	RealmAccess       *UserJWTRealmAccess    `json:"realm_access"`
	ResourceAccess    *UserJWTResourceAccess `json:"resource_access"`
	Scope             string                 `json:"scope"`
	EmailVerified     bool                   `json:"email_verified"`
	Name              string                 `json:"name"`
	PreferredUserName string                 `json:"preferred_username"`
	GivenName         string                 `json:"given_name"`
	FamilyName        string                 `json:"family_name"`
	Email             string                 `json:"email"`
	UPN               string                 `json:"upn"`
	Groups            []string               `json:"groups"`
}

func GetUser

func GetUser(ctx context.Context) *UserJWT

func GetUserFromRequest

func GetUserFromRequest(ctx context.Context, request *http.Request) (*UserJWT, error)

func GetUserInfoFromToken

func GetUserInfoFromToken(ctx context.Context, token string) *UserJWT

GetUserInfoFromToken Gets a user information from the JWT (Authorization Header)

func ParseToken

func ParseToken(tokenstr string) (*UserJWT, error)

ParseToken Parses the id token from cognito

func (*UserJWT) IsAuthenticated

func (jwt *UserJWT) IsAuthenticated() bool

func (UserJWT) Valid

func (jwt UserJWT) Valid() error

Valid determines if the claims are valid

type UserJWTRealmAccess

type UserJWTRealmAccess struct {
	Roles []string `json:"roles"`
}

type UserJWTResourceAccess

type UserJWTResourceAccess struct {
	Account *UserJWTResourceAccessAccount `json:"account"`
}

type UserJWTResourceAccessAccount

type UserJWTResourceAccessAccount struct {
	Roles []string `json:"roles"`
}

type UserManager added in v0.0.2

type UserManager interface {
	// ForceUserName takes a proposed user name, validates it and transforms it.
	// Then it checks to see if it is a real user
	// Returns: string - updated user name, bool - if the user exists, error - if an error is encountered
	ForceUserName(ctx context.Context, name string) (string, bool, error)

	ListUsers(ctx context.Context, page interface{}, filter interface{}) ([]*models.User, interface{}, error)

	// Retrieves a specific user.
	GetUser(ctx context.Context, uid string) (*models.User, error)

	// NewUser creates a new user with the given information and returns the new user with any additional
	// fields populated
	NewUser(ctx context.Context, newUser *models.User) (*models.User, error)

	UpdateUser(ctx context.Context, usr *models.User) error

	Enable(ctx context.Context, uid string) error

	Disable(ctx context.Context, uid string) error

	DeleteUser(ctx context.Context, uid string) error
}

User interface manager

type UsernameStrategy

type UsernameStrategy interface {
	// GuessUsername provides the best username for a given user object. The pattern should contain
	GuessUsername(ctx context.Context, user *models.User, mode DuplicateUserMode, manager UserManager) (string, error)
}

Directories

Path Synopsis
Packages storage manages storage in cloud services.
Packages storage manages storage in cloud services.

Jump to

Keyboard shortcuts

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