-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpolicy.go
More file actions
107 lines (90 loc) · 2.3 KB
/
Copy pathpolicy.go
File metadata and controls
107 lines (90 loc) · 2.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package authflow
import (
"context"
"fmt"
"strings"
"time"
)
type Factor string
const (
FactorEmailOTP Factor = Factor(ProviderEmailOTP)
FactorGoogle Factor = Factor(ProviderGoogle)
)
type AuthEvent struct {
User User
Identity Identity
CompletedFactors []Factor
Time time.Time
}
type StepUpPolicy interface {
RequiredFactors(ctx context.Context, event AuthEvent) ([]Factor, error)
}
type NoStepUpPolicy struct{}
func (NoStepUpPolicy) RequiredFactors(context.Context, AuthEvent) ([]Factor, error) {
return nil, nil
}
type StaticPolicy []Factor
func (p StaticPolicy) RequiredFactors(context.Context, AuthEvent) ([]Factor, error) {
return append([]Factor(nil), p...), nil
}
type StepUpRequiredError struct {
ContinuationToken string
MissingFactors []Factor
CompletedFactors []Factor
ExpiresAt time.Time
}
func (e StepUpRequiredError) Error() string {
if len(e.MissingFactors) == 0 {
return ErrStepUpRequired.Error()
}
parts := make([]string, 0, len(e.MissingFactors))
for _, factor := range e.MissingFactors {
parts = append(parts, string(factor))
}
return fmt.Sprintf("%s: %s", ErrStepUpRequired, strings.Join(parts, ", "))
}
func (e StepUpRequiredError) Unwrap() error {
return ErrStepUpRequired
}
type AccountLinkingEvent struct {
ExistingUser User
Identity Identity
Time time.Time
}
type AccountLinkingPolicy interface {
AllowLink(ctx context.Context, event AccountLinkingEvent) error
}
type TrustedProviderLinkingPolicy map[string]bool
func (p TrustedProviderLinkingPolicy) AllowLink(_ context.Context, event AccountLinkingEvent) error {
if p[event.Identity.Provider] {
return nil
}
return ErrAccountLinkingDenied
}
func MissingFactors(required []Factor, completed []Factor) []Factor {
if len(required) == 0 {
return nil
}
completedSet := make(map[Factor]struct{}, len(completed))
for _, factor := range completed {
if factor == "" {
continue
}
completedSet[factor] = struct{}{}
}
missing := make([]Factor, 0, len(required))
seen := make(map[Factor]struct{}, len(required))
for _, factor := range required {
if factor == "" {
continue
}
if _, ok := seen[factor]; ok {
continue
}
seen[factor] = struct{}{}
if _, ok := completedSet[factor]; !ok {
missing = append(missing, factor)
}
}
return missing
}