Documentation ¶
Index ¶
- Constants
- Variables
- func AsInput(i Input, iface interface{}) bool
- func FindSingleNode[T NodeSimple](w *Workflow) (T, bool)
- func GetOAuthSessionID(ctx context.Context) string
- func GetSuppressIDPSessionCookie(ctx context.Context) bool
- func GetUserIDHint(ctx context.Context) string
- func GetWorkflowID(ctx context.Context) string
- func NewUserAgentID() string
- func RegisterNode(node NodeSimple)
- func RegisterPrivateIntent(intent Intent)
- func RegisterPublicInput(input Input)
- func RegisterPublicIntent(intent Intent)
- type AccountMigrationService
- type AuthenticationInfoEntryGetter
- type AuthenticationInfoService
- type AuthenticatorService
- type CaptchaService
- type CookieGetter
- type CookieManager
- type CustomAttrsService
- type Dependencies
- type Effect
- type EffectGetter
- type Event
- type EventKind
- type EventRefresh
- type EventService
- type EventStore
- type EventStoreImpl
- type ForgotPasswordService
- type IDPSessionService
- type IdentityService
- type Input
- type InputFactory
- type InputJSON
- type InputReactor
- type Intent
- type IntentFactory
- type IntentJSON
- type IntentOutput
- type IntlMiddleware
- type MFAService
- type Node
- func (n *Node) Clone() *Node
- func (n *Node) FindInputReactor(ctx context.Context, deps *Dependencies, workflows Workflows) (*Workflow, InputReactor, error)
- func (n *Node) MarshalJSON() ([]byte, error)
- func (n *Node) ToOutput(ctx context.Context, deps *Dependencies, workflows Workflows) (*NodeOutput, error)
- func (n *Node) Traverse(t WorkflowTraverser, w *Workflow) error
- func (n *Node) UnmarshalJSON(d []byte) (err error)
- type NodeFactory
- type NodeOutput
- type NodeSimple
- type NodeSimpleOutput
- type NodeType
- type OTPCodeService
- type OTPSender
- type OfflineGrantStore
- type OnCommitEffect
- type RateLimiter
- type ResetPasswordService
- type RunEffect
- type Service
- func (s *Service) CreateNewWorkflow(intent Intent, sessionOptions *SessionOptions) (output *ServiceOutput, err error)
- func (s *Service) FeedInput(workflowID string, instanceID string, userAgentID string, input Input) (output *ServiceOutput, err error)
- func (s *Service) Get(workflowID string, instanceID string, userAgentID string) (output *ServiceOutput, err error)
- type ServiceDatabase
- type ServiceLogger
- type ServiceOutput
- type ServiceUIInfoResolver
- type Session
- type SessionOptions
- type SessionOutput
- type SessionService
- type StdAttrsService
- type Store
- type StoreImpl
- func (s *StoreImpl) CreateSession(session *Session) error
- func (s *StoreImpl) CreateWorkflow(workflow *Workflow) error
- func (s *StoreImpl) DeleteSession(session *Session) error
- func (s *StoreImpl) DeleteWorkflow(workflow *Workflow) error
- func (s *StoreImpl) GetSession(workflowID string) (*Session, error)
- func (s *StoreImpl) GetWorkflowByInstanceID(instanceID string) (*Workflow, error)
- type UserService
- type VerificationService
- type Workflow
- func (w *Workflow) Accept(ctx context.Context, deps *Dependencies, workflows Workflows, input Input) (err error)
- func (w *Workflow) ApplyAllEffects(ctx context.Context, deps *Dependencies, workflows Workflows) error
- func (w *Workflow) ApplyRunEffects(ctx context.Context, deps *Dependencies, workflows Workflows) error
- func (w *Workflow) Clone() *Workflow
- func (w *Workflow) CollectCookies(ctx context.Context, deps *Dependencies, workflows Workflows) (cookies []*http.Cookie, err error)
- func (w *Workflow) FindInputReactor(ctx context.Context, deps *Dependencies, workflows Workflows) (*Workflow, InputReactor, error)
- func (w *Workflow) GetAuthenticationInfoEntry(ctx context.Context, deps *Dependencies, workflows Workflows) (*authenticationinfo.Entry, bool)
- func (w *Workflow) IsEOF(ctx context.Context, deps *Dependencies, workflows Workflows) (bool, error)
- func (w *Workflow) MarshalJSON() ([]byte, error)
- func (w *Workflow) ToOutput(ctx context.Context, deps *Dependencies, workflows Workflows) (*WorkflowOutput, error)
- func (w *Workflow) Traverse(t WorkflowTraverser) error
- func (w *Workflow) UnmarshalJSON(d []byte) (err error)
- type WorkflowAction
- type WorkflowActionType
- type WorkflowOutput
- type WorkflowTraverser
- type Workflows
Constants ¶
const Lifetime = duration.UserInteraction
Variables ¶
var DependencySet = wire.NewSet( wire.Struct(new(Dependencies), "*"), NewServiceLogger, wire.Struct(new(Service), "*"), wire.Struct(new(StoreImpl), "*"), wire.Bind(new(Store), new(*StoreImpl)), wire.Bind(new(EventStore), new(*EventStoreImpl)), wire.Struct(new(IntlMiddleware), "*"), NewEventStore, )
var ErrEOF = errors.New("eof")
ErrEOF means end of workflow. This error originates from CanReactTo and will be propagated to public API.
var ErrIncompatibleInput = errors.New("incompatible input")
ErrIncompatibleInput means the input reactor cannot react to the input. This error can only be returned by ReactTo.
var ErrInvalidInputKind = apierrors.BadRequest.WithReason("WorkflowInvalidInputKind").New("invalid input kind")
var ErrNoChange = errors.New("no change")
ErrNoChange means the input does not cause the workflow to change. This error originates from Accept and will be propagated to public API.
var ErrSameNode = errors.New("same node")
ErrSameNode means the input is reacted to, but no node is produced. This typically means the node has performed some immediate side effects. This error can only be returned by ReactTo.
var ErrUnknownInput = apierrors.BadRequest.WithReason("WorkflowUnknownInput").New("unknown input")
var ErrUnknownIntent = apierrors.BadRequest.WithReason("WorkflowUnknownIntent").New("unknown intent")
var ErrUpdateNode = errors.New("update node")
ErrUpdateNode means the input is reacted to, but instead of producing a new node to be appended, the returned node should replace the node. This error can only be returned by ReactTo.
var ErrUserAgentUnmatched = apierrors.Forbidden.WithReason("UserAgentUnmatched").New("workflow cannot be used in other user agent")
var ErrWorkflowNotFound = apierrors.NotFound.WithReason("WorkflowNotFound").New("workflow not found")
var UserAgentIDCookieDef = &httputil.CookieDef{ NameSuffix: "workflow_ua_id", Path: "/", AllowScriptAccess: false, SameSite: http.SameSiteNoneMode, }
Functions ¶
func FindSingleNode ¶
func FindSingleNode[T NodeSimple](w *Workflow) (T, bool)
func GetOAuthSessionID ¶
func GetUserIDHint ¶
func GetWorkflowID ¶
func NewUserAgentID ¶
func NewUserAgentID() string
func RegisterNode ¶
func RegisterNode(node NodeSimple)
func RegisterPrivateIntent ¶
func RegisterPrivateIntent(intent Intent)
func RegisterPublicInput ¶
func RegisterPublicInput(input Input)
func RegisterPublicIntent ¶
func RegisterPublicIntent(intent Intent)
Types ¶
type AccountMigrationService ¶
type AccountMigrationService interface {
Run(migrationTokenString string) (*accountmigration.HookResponse, error)
}
type AuthenticationInfoEntryGetter ¶
type AuthenticationInfoEntryGetter interface {
GetAuthenticationInfoEntry(ctx context.Context, deps *Dependencies, flows Workflows) *authenticationinfo.Entry
}
type AuthenticationInfoService ¶
type AuthenticationInfoService interface {
Save(entry *authenticationinfo.Entry) error
}
type AuthenticatorService ¶
type AuthenticatorService interface { NewWithAuthenticatorID(authenticatorID string, spec *authenticator.Spec) (*authenticator.Info, error) Get(authenticatorID string) (*authenticator.Info, error) Create(authenticatorInfo *authenticator.Info, markVerified bool) error Update(authenticatorInfo *authenticator.Info) error List(userID string, filters ...authenticator.Filter) ([]*authenticator.Info, error) WithSpec(authenticatorInfo *authenticator.Info, spec *authenticator.Spec) (changed bool, info *authenticator.Info, err error) VerifyWithSpec(info *authenticator.Info, spec *authenticator.Spec, options *facade.VerifyOptions) (verifyResult *service.VerifyResult, err error) VerifyOneWithSpec(userID string, authenticatorType model.AuthenticatorType, infos []*authenticator.Info, spec *authenticator.Spec, options *facade.VerifyOptions) (info *authenticator.Info, verifyResult *service.VerifyResult, err error) ClearLockoutAttempts(userID string, usedMethods []config.AuthenticationLockoutMethod) error }
type CaptchaService ¶
type CookieGetter ¶
type CookieManager ¶
type CustomAttrsService ¶
type Dependencies ¶
type Dependencies struct { Config *config.AppConfig FeatureConfig *config.FeatureConfig Clock clock.Clock RemoteIP httputil.RemoteIP HTTPRequest *http.Request Users UserService Identities IdentityService Authenticators AuthenticatorService MFA MFAService StdAttrsService StdAttrsService CustomAttrsService CustomAttrsService OTPCodes OTPCodeService OTPSender OTPSender Verification VerificationService ForgotPassword ForgotPasswordService ResetPassword ResetPasswordService AccountMigrations AccountMigrationService Captcha CaptchaService IDPSessions IDPSessionService Sessions SessionService AuthenticationInfos AuthenticationInfoService SessionCookie session.CookieDef MFADeviceTokenCookie mfa.CookieDef Cookies CookieManager Events EventService RateLimiter RateLimiter WorkflowEvents EventStore OfflineGrants OfflineGrantStore }
type EffectGetter ¶
type EventKind ¶
type EventKind string
const ( // WorkflowEventKindRefresh indicates client should re-fetch current instance of workflow for updated state. EventKindRefresh EventKind = "refresh" )
type EventRefresh ¶
type EventRefresh struct {
Kind EventKind `json:"kind"`
}
func NewEventRefresh ¶
func NewEventRefresh() *EventRefresh
type EventService ¶
type EventStore ¶
type EventStoreImpl ¶
type EventStoreImpl struct { AppID config.AppID RedisHandle *appredis.Handle Store Store // contains filtered or unexported fields }
func NewEventStore ¶
func (*EventStoreImpl) ChannelName ¶
func (s *EventStoreImpl) ChannelName(workflowID string) (string, error)
type ForgotPasswordService ¶
type ForgotPasswordService interface {
SendCode(loginID string, options *forgotpassword.CodeOptions) error
}
type IDPSessionService ¶
type IDPSessionService interface { MakeSession(*session.Attrs) (*idpsession.IDPSession, string) Create(*idpsession.IDPSession) error Reauthenticate(idpSessionID string, amr []string) error }
type IdentityService ¶
type IdentityService interface { Get(id string) (*identity.Info, error) SearchBySpec(spec *identity.Spec) (exactMatch *identity.Info, otherMatches []*identity.Info, err error) ListByClaim(name string, value string) ([]*identity.Info, error) ListByUser(userID string) ([]*identity.Info, error) New(userID string, spec *identity.Spec, options identity.NewIdentityOptions) (*identity.Info, error) UpdateWithSpec(is *identity.Info, spec *identity.Spec, options identity.NewIdentityOptions) (*identity.Info, error) CheckDuplicated(info *identity.Info) (*identity.Info, error) Create(is *identity.Info) error Update(oldIs *identity.Info, newIs *identity.Info) error }
type Input ¶
type Input interface { Kind() string JSONSchema() *validation.SimpleSchema }
type InputFactory ¶
type InputFactory func() Input
type InputJSON ¶
type InputJSON struct { Kind string `json:"kind"` Data json.RawMessage `json:"data"` }
type InputReactor ¶
type Intent ¶
type Intent interface { InputReactor EffectGetter Kind() string JSONSchema() *validation.SimpleSchema OutputData(ctx context.Context, deps *Dependencies, workflows Workflows) (interface{}, error) }
Intent can optionally implement CookieGetter.
func InstantiateIntentFromPrivateRegistry ¶
func InstantiateIntentFromPrivateRegistry(j IntentJSON) (Intent, error)
func InstantiateIntentFromPublicRegistry ¶
func InstantiateIntentFromPublicRegistry(j IntentJSON) (Intent, error)
type IntentFactory ¶
type IntentFactory func() Intent
type IntentJSON ¶
type IntentJSON struct { Kind string `json:"kind"` Data json.RawMessage `json:"data"` }
type IntentOutput ¶
type IntentOutput struct { Kind string `json:"kind"` Data interface{} `json:"data,omitempty"` }
type IntlMiddleware ¶
type IntlMiddleware struct{}
type MFAService ¶
type MFAService interface { GenerateRecoveryCodes() []string ReplaceRecoveryCodes(userID string, codes []string) ([]*mfa.RecoveryCode, error) VerifyRecoveryCode(userID string, code string) (*mfa.RecoveryCode, error) ConsumeRecoveryCode(c *mfa.RecoveryCode) error GenerateDeviceToken() string CreateDeviceToken(userID string, token string) (*mfa.DeviceToken, error) VerifyDeviceToken(userID string, deviceToken string) error }
type Node ¶
type Node struct { Type NodeType `json:"type"` Simple NodeSimple `json:"simple,omitempty"` SubWorkflow *Workflow `json:"workflow,omitempty"` }
func NewNodeSimple ¶
func NewNodeSimple(simple NodeSimple) *Node
func NewSubWorkflow ¶
func (*Node) FindInputReactor ¶
func (n *Node) FindInputReactor(ctx context.Context, deps *Dependencies, workflows Workflows) (*Workflow, InputReactor, error)
func (*Node) MarshalJSON ¶
func (*Node) ToOutput ¶
func (n *Node) ToOutput(ctx context.Context, deps *Dependencies, workflows Workflows) (*NodeOutput, error)
func (*Node) UnmarshalJSON ¶
type NodeFactory ¶
type NodeFactory func() NodeSimple
type NodeOutput ¶
type NodeOutput struct { Type NodeType `json:"type"` Simple *NodeSimpleOutput `json:"simple,omitempty"` SubWorkflow *WorkflowOutput `json:"workflow,omitempty"` }
type NodeSimple ¶
type NodeSimple interface { InputReactor EffectGetter Kind() string OutputData(ctx context.Context, deps *Dependencies, workflows Workflows) (interface{}, error) }
NodeSimple can optionally implement CookieGetter.
func InstantiateNode ¶
func InstantiateNode(kind string) (NodeSimple, error)
type NodeSimpleOutput ¶
type NodeSimpleOutput struct { Kind string `json:"kind"` Data interface{} `json:"data,omitempty"` }
type OTPCodeService ¶
type OTPCodeService interface { GenerateOTP(kind otp.Kind, target string, form otp.Form, opt *otp.GenerateOptions) (string, error) VerifyOTP(kind otp.Kind, target string, otp string, opts *otp.VerifyOptions) error InspectState(kind otp.Kind, target string) (*otp.State, error) LookupCode(purpose otp.Purpose, code string) (target string, err error) SetSubmittedCode(kind otp.Kind, target string, code string) (*otp.State, error) }
type OTPSender ¶
type OTPSender interface { Prepare(channel model.AuthenticatorOOBChannel, target string, form otp.Form, typ otp.MessageType) (*otp.PreparedMessage, error) Send(msg *otp.PreparedMessage, opts otp.SendOptions) error }
type OfflineGrantStore ¶
type OfflineGrantStore interface {
ListClientOfflineGrants(clientID string, userID string) ([]*oauth.OfflineGrant, error)
}
type OnCommitEffect ¶
type OnCommitEffect func(ctx context.Context, deps *Dependencies) error
type RateLimiter ¶
type RateLimiter interface { Allow(spec ratelimit.BucketSpec) error Reserve(spec ratelimit.BucketSpec) *ratelimit.Reservation Cancel(r *ratelimit.Reservation) }
type ResetPasswordService ¶
type Service ¶
type Service struct { ContextDoNotUseDirectly context.Context Deps *Dependencies Logger ServiceLogger Store Store Database ServiceDatabase UIInfoResolver ServiceUIInfoResolver }
func (*Service) CreateNewWorkflow ¶
func (s *Service) CreateNewWorkflow(intent Intent, sessionOptions *SessionOptions) (output *ServiceOutput, err error)
type ServiceDatabase ¶
type ServiceLogger ¶
func NewServiceLogger ¶
func NewServiceLogger(lf *log.Factory) ServiceLogger
type ServiceOutput ¶
type ServiceOutput struct { Session *Session SessionOutput *SessionOutput Workflow *Workflow WorkflowOutput *WorkflowOutput Action *WorkflowAction Cookies []*http.Cookie }
type ServiceUIInfoResolver ¶
type ServiceUIInfoResolver interface {
SetAuthenticationInfoInQuery(redirectURI string, e *authenticationinfo.Entry) string
}
type Session ¶
type Session struct { WorkflowID string `json:"workflow_id"` OAuthSessionID string `json:"oauth_session_id,omitempty"` ClientID string `json:"client_id,omitempty"` RedirectURI string `json:"redirect_uri,omitempty"` SuppressIDPSessionCookie bool `json:"suppress_idp_session_cookie,omitempty"` State string `json:"state,omitempty"` XState string `json:"x_state,omitempty"` UILocales string `json:"ui_locales,omitempty"` UserAgentID string `json:"user_agent_id,omitempty"` // UserIDHint is for reauthentication. UserIDHint string `json:"user_id_hint,omitempty"` }
func NewSession ¶
func NewSession(opts *SessionOptions) *Session
func (*Session) ToOutput ¶
func (s *Session) ToOutput() *SessionOutput
type SessionOptions ¶
type SessionOptions struct { OAuthSessionID string ClientID string RedirectURI string SuppressIDPSessionCookie bool State string XState string UILocales string UserAgentID string // UserIDHint is for reauthentication. UserIDHint string }
func (*SessionOptions) PartiallyMergeFrom ¶
func (s *SessionOptions) PartiallyMergeFrom(o *SessionOptions) *SessionOptions
type SessionOutput ¶
type SessionService ¶
type StdAttrsService ¶
type StoreImpl ¶
func (*StoreImpl) CreateSession ¶
func (*StoreImpl) CreateWorkflow ¶
func (*StoreImpl) DeleteSession ¶
func (*StoreImpl) DeleteWorkflow ¶
type UserService ¶
type VerificationService ¶
type VerificationService interface { GetIdentityVerificationStatus(i *identity.Info) ([]verification.ClaimStatus, error) NewVerifiedClaim(userID string, claimName string, claimValue string) *verification.Claim MarkClaimVerified(claim *verification.Claim) error }
type Workflow ¶
func FindSubWorkflows ¶
func MustFindSubWorkflow ¶
func NewWorkflow ¶
func (*Workflow) Accept ¶
func (w *Workflow) Accept(ctx context.Context, deps *Dependencies, workflows Workflows, input Input) (err error)
Accept executes the workflow to the deepest using input. In addition to the errors caused by intents and nodes, ErrEOF and ErrNoChange can be returned.
func (*Workflow) ApplyAllEffects ¶
func (*Workflow) ApplyRunEffects ¶
func (*Workflow) CollectCookies ¶
func (*Workflow) FindInputReactor ¶
func (w *Workflow) FindInputReactor(ctx context.Context, deps *Dependencies, workflows Workflows) (*Workflow, InputReactor, error)
func (*Workflow) GetAuthenticationInfoEntry ¶
func (w *Workflow) GetAuthenticationInfoEntry(ctx context.Context, deps *Dependencies, workflows Workflows) (*authenticationinfo.Entry, bool)
func (*Workflow) MarshalJSON ¶
func (*Workflow) ToOutput ¶
func (w *Workflow) ToOutput(ctx context.Context, deps *Dependencies, workflows Workflows) (*WorkflowOutput, error)
func (*Workflow) Traverse ¶
func (w *Workflow) Traverse(t WorkflowTraverser) error
func (*Workflow) UnmarshalJSON ¶
type WorkflowAction ¶
type WorkflowAction struct { Type WorkflowActionType `json:"type"` RedirectURI string `json:"redirect_uri,omitempty"` }
type WorkflowActionType ¶
type WorkflowActionType string
const ( WorkflowActionTypeContinue WorkflowActionType = "continue" WorkflowActionTypeFinish WorkflowActionType = "finish" WorkflowActionTypeRedirect WorkflowActionType = "redirect" )
type WorkflowOutput ¶
type WorkflowOutput struct { WorkflowID string `json:"workflow_id,omitempty"` InstanceID string `json:"instance_id,omitempty"` Intent IntentOutput `json:"intent"` Nodes []NodeOutput `json:"nodes,omitempty"` }