-
Notifications
You must be signed in to change notification settings - Fork 1
/
oauth.go
82 lines (71 loc) · 1.8 KB
/
oauth.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
package main
import (
"context"
"fmt"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
type OAuthManager struct {
config *oauth2.Config
tokenRepo TokenRepository
}
func NewOAuthManager(clientID, clientSecret string, tokenRepo TokenRepository) *OAuthManager {
config := &oauth2.Config{
ClientID: clientID,
ClientSecret: clientSecret,
Endpoint: google.Endpoint,
RedirectURL: "urn:ietf:wg:oauth:2.0:oob",
Scopes: []string{
"https://www.googleapis.com/auth/youtube",
"https://www.googleapis.com/auth/youtube.readonly",
"https://www.googleapis.com/auth/youtube.force-ssl",
},
}
return &OAuthManager{
config: config,
tokenRepo: tokenRepo,
}
}
func (oa *OAuthManager) requestOAuthToken(ctx context.Context) (*oauth2.Token, error) {
fmt.Println("Access to this URL and get auth code.")
fmt.Println(oa.config.AuthCodeURL(""))
fmt.Print("Input auth code: ")
var code string
_, err := fmt.Scanf("%s\n", &code)
if err != nil {
return nil, fmt.Errorf("failed to scan auth code: %v", err)
}
return oa.config.Exchange(ctx, code)
}
type TokenRepository interface {
Save(*oauth2.Token) error
Load() (*oauth2.Token, error)
}
type cachedTokenSource struct {
base oauth2.TokenSource
repo TokenRepository
}
func (cts *cachedTokenSource) Token() (*oauth2.Token, error) {
t, err := cts.base.Token()
if err != nil {
return nil, err
}
if err := cts.repo.Save(t); err != nil {
return nil, err
}
return t, nil
}
func (oa *OAuthManager) TokenSource(ctx context.Context) (oauth2.TokenSource, error) {
t, err := oa.tokenRepo.Load()
if err != nil {
// if cached token doesn't exist, request new token
t, err = oa.requestOAuthToken(ctx)
if err != nil {
return nil, err
}
}
return &cachedTokenSource{
base: oa.config.TokenSource(ctx, t),
repo: oa.tokenRepo,
}, nil
}