-
Notifications
You must be signed in to change notification settings - Fork 110
/
provider.go
97 lines (80 loc) · 2.37 KB
/
provider.go
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
package oauth
import (
"net/http"
"golang.org/x/oauth2"
)
// Provider is a struct wrapping the necessary bits to integrate an OAuth2 provider with AuthN
type Provider struct {
config *oauth2.Config
UserInfo UserInfoFetcher
secretGenerator SecretGenerator
authCodeOptions []oauth2.AuthCodeOption
returnMethod string
}
// UserInfo returns the information needed from an OAuth Provider to connect with AuthN accounts
type UserInfo struct {
ID string `json:"id"`
Email string `json:"email"`
}
// UserInfoFetcher is the function signature for fetching UserInfo from a Provider
type UserInfoFetcher = func(t *oauth2.Token) (*UserInfo, error)
type override func(*Provider)
// SecretGenerator is the function signature for calculating a dynamic client secret.
type SecretGenerator = func() (string, error)
func WithSecretGenerator(so SecretGenerator) override {
return func(p *Provider) {
p.secretGenerator = so
}
}
// WithAuthCodeOptions sets additional options to use when requesting an auth code.
func WithAuthCodeOptions(ao ...oauth2.AuthCodeOption) override {
return func(p *Provider) {
p.authCodeOptions = ao
}
}
// WithReturnMethod sets the HTTP method to use when returning from the OAuth provider.
func WithReturnMethod(method string) override {
return func(p *Provider) {
p.returnMethod = method
}
}
// NewProvider returns a properly configured Provider
func NewProvider(config *oauth2.Config, userInfo UserInfoFetcher, overrides ...override) *Provider {
p := &Provider{config: config, UserInfo: userInfo}
for _, o := range overrides {
o(p)
}
return p
}
// Config returns a complete oauth2.Config after injecting the RedirectURL
func (p *Provider) Config(redirectURL string) (*oauth2.Config, error) {
secret, err := p.Secret()
if err != nil {
return nil, err
}
return &oauth2.Config{
ClientID: p.config.ClientID,
ClientSecret: secret,
Scopes: p.config.Scopes,
Endpoint: p.config.Endpoint,
RedirectURL: redirectURL,
}, nil
}
func (p *Provider) Secret() (string, error) {
if p.secretGenerator != nil {
return p.secretGenerator()
}
return p.config.ClientSecret, nil
}
func (p *Provider) AuthCodeOptions() []oauth2.AuthCodeOption {
if p.authCodeOptions != nil {
return p.authCodeOptions
}
return nil
}
func (p *Provider) ReturnMethod() string {
if p.returnMethod != "" {
return p.returnMethod
}
return http.MethodGet
}