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(ctx context.Context, intent Intent, sessionOptions *SessionOptions) (output *ServiceOutput, err error)
- func (s *Service) FeedInput(ctx context.Context, workflowID string, instanceID string, userAgentID string, ...) (output *ServiceOutput, err error)
- func (s *Service) Get(ctx context.Context, 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(ctx context.Context, session *Session) error
- func (s *StoreImpl) CreateWorkflow(ctx context.Context, workflow *Workflow) error
- func (s *StoreImpl) DeleteSession(ctx context.Context, session *Session) error
- func (s *StoreImpl) DeleteWorkflow(ctx context.Context, workflow *Workflow) error
- func (s *StoreImpl) GetSession(ctx context.Context, workflowID string) (*Session, error)
- func (s *StoreImpl) GetWorkflowByInstanceID(ctx context.Context, 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, IsNonHostOnly: true, }
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(ctx context.Context, 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(ctx context.Context, entry *authenticationinfo.Entry) error
}
type AuthenticatorService ¶
type AuthenticatorService interface { NewWithAuthenticatorID(ctx context.Context, authenticatorID string, spec *authenticator.Spec) (*authenticator.Info, error) UpdatePassword(ctx context.Context, authenticatorInfo *authenticator.Info, options *service.UpdatePasswordOptions) (changed bool, info *authenticator.Info, err error) Get(ctx context.Context, authenticatorID string) (*authenticator.Info, error) Create(ctx context.Context, authenticatorInfo *authenticator.Info, markVerified bool) error Update(ctx context.Context, authenticatorInfo *authenticator.Info) error List(ctx context.Context, userID string, filters ...authenticator.Filter) ([]*authenticator.Info, error) VerifyWithSpec(ctx context.Context, info *authenticator.Info, spec *authenticator.Spec, options *facade.VerifyOptions) (verifyResult *service.VerifyResult, err error) VerifyOneWithSpec(ctx context.Context, userID string, authenticatorType model.AuthenticatorType, infos []*authenticator.Info, spec *authenticator.Spec, options *facade.VerifyOptions) (info *authenticator.Info, verifyResult *service.VerifyResult, err error) ClearLockoutAttempts(ctx context.Context, 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 ¶
type ForgotPasswordService ¶
type ForgotPasswordService interface {
SendCode(ctx context.Context, loginID string, options *forgotpassword.CodeOptions) error
}
type IDPSessionService ¶
type IDPSessionService interface { MakeSession(*session.Attrs) (*idpsession.IDPSession, string) Create(ctx context.Context, s *idpsession.IDPSession) error Reauthenticate(ctx context.Context, idpSessionID string, amr []string) error }
type IdentityService ¶
type IdentityService interface { New(ctx context.Context, userID string, spec *identity.Spec, options identity.NewIdentityOptions) (*identity.Info, error) UpdateWithSpec(ctx context.Context, is *identity.Info, spec *identity.Spec, options identity.NewIdentityOptions) (*identity.Info, error) Get(ctx context.Context, id string) (*identity.Info, error) SearchBySpec(ctx context.Context, spec *identity.Spec) (exactMatch *identity.Info, otherMatches []*identity.Info, err error) ListByClaim(ctx context.Context, name string, value string) ([]*identity.Info, error) ListByUser(ctx context.Context, userID string) ([]*identity.Info, error) CheckDuplicated(ctx context.Context, info *identity.Info) (*identity.Info, error) Create(ctx context.Context, is *identity.Info) error Update(ctx context.Context, 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(ctx context.Context) []string ReplaceRecoveryCodes(ctx context.Context, userID string, codes []string) ([]*mfa.RecoveryCode, error) VerifyRecoveryCode(ctx context.Context, userID string, code string) (*mfa.RecoveryCode, error) ConsumeRecoveryCode(ctx context.Context, c *mfa.RecoveryCode) error GenerateDeviceToken(ctx context.Context) string CreateDeviceToken(ctx context.Context, userID string, token string) (*mfa.DeviceToken, error) VerifyDeviceToken(ctx context.Context, 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(ctx context.Context, kind otp.Kind, target string, form otp.Form, opt *otp.GenerateOptions) (string, error) VerifyOTP(ctx context.Context, kind otp.Kind, target string, otp string, opts *otp.VerifyOptions) error InspectState(ctx context.Context, kind otp.Kind, target string) (*otp.State, error) LookupCode(ctx context.Context, purpose otp.Purpose, code string) (target string, err error) SetSubmittedCode(ctx context.Context, kind otp.Kind, target string, code string) (*otp.State, error) }
type OfflineGrantStore ¶
type OnCommitEffect ¶
type OnCommitEffect func(ctx context.Context, deps *Dependencies) error
type RateLimiter ¶
type RateLimiter interface { Allow(ctx context.Context, spec ratelimit.BucketSpec) (*ratelimit.FailedReservation, error) Reserve(ctx context.Context, spec ratelimit.BucketSpec) (*ratelimit.Reservation, *ratelimit.FailedReservation, error) Cancel(ctx context.Context, r *ratelimit.Reservation) }
type ResetPasswordService ¶
type Service ¶
type Service struct { Deps *Dependencies Logger ServiceLogger Store Store Database ServiceDatabase UIInfoResolver ServiceUIInfoResolver }
func (*Service) CreateNewWorkflow ¶
func (s *Service) CreateNewWorkflow(ctx context.Context, 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 SessionService interface {
RevokeWithoutEvent(ctx context.Context, s session.SessionBase) error
}
type StdAttrsService ¶
type Store ¶
type Store interface { CreateSession(ctx context.Context, session *Session) error GetSession(ctx context.Context, workflowID string) (*Session, error) DeleteSession(ctx context.Context, session *Session) error CreateWorkflow(ctx context.Context, workflow *Workflow) error GetWorkflowByInstanceID(ctx context.Context, instanceID string) (*Workflow, error) DeleteWorkflow(ctx context.Context, workflow *Workflow) error }
type StoreImpl ¶
func (*StoreImpl) CreateSession ¶
func (*StoreImpl) CreateWorkflow ¶
func (*StoreImpl) DeleteSession ¶
func (*StoreImpl) DeleteWorkflow ¶
func (*StoreImpl) GetSession ¶
type UserService ¶
type UserService interface { GetRaw(ctx context.Context, id string) (*user.User, error) Create(ctx context.Context, userID string) (*user.User, error) UpdateLoginTime(ctx context.Context, userID string, t time.Time) error AfterCreate( ctx context.Context, user *user.User, identities []*identity.Info, authenticators []*authenticator.Info, isAdminAPI bool, ) error }
type VerificationService ¶
type VerificationService interface { NewVerifiedClaim(ctx context.Context, userID string, claimName string, claimValue string) *verification.Claim GetIdentityVerificationStatus(ctx context.Context, i *identity.Info) ([]verification.ClaimStatus, error) MarkClaimVerified(ctx context.Context, 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"` }