This repository has been archived by the owner on Jan 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
google_login.go
95 lines (83 loc) · 2.48 KB
/
google_login.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
package awsconsoleauth
import (
"encoding/json"
"fmt"
"log"
"net/http"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/drone/config"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
var googleClientID = config.String("google-client-id", "")
var googleClientSecret = config.String("google-client-secret", "")
var googleDomain = config.String("google-domain", "")
var googleOauthConfig = &oauth2.Config{
Scopes: []string{"email"},
Endpoint: google.Endpoint,
}
var googleJWTSigningKeys = map[string]interface{}{}
func updateGoogleJWTSigningKeys() error {
// Fetch the google keys for oauth
googleCertsResponse, err := http.Get("https://www.googleapis.com/oauth2/v1/certs")
if err != nil {
return err
}
if err := json.NewDecoder(googleCertsResponse.Body).Decode(&googleJWTSigningKeys); err != nil {
return err
}
return nil
}
// InitializeGoogleLogin sets up access to the Google login service
func InitializeGoogleLogin() error {
if err := updateGoogleJWTSigningKeys(); err != nil {
return nil
}
// keep the JWT signing keys up to date by polling once per hour
go func() {
time.Sleep(60 * time.Minute)
for {
if err := updateGoogleJWTSigningKeys(); err != nil {
log.Printf("Google JWT signing keys: %s", err)
time.Sleep(time.Minute)
continue
}
log.Printf("updates google JWT signing keys")
time.Sleep(60 * time.Minute)
}
}()
// Configure OAuth
googleOauthConfig.ClientID = *googleClientID
googleOauthConfig.ClientSecret = *googleClientSecret
if *googleDomain != "" {
googleOauthConfig.Endpoint.AuthURL += fmt.Sprintf("?hd=%s", *googleDomain)
}
return nil
}
// GetUserFromGoogleOauthToken returns a user name (email address) from the
// provided ID token which we receive in the OAuth response. This function
// validates that the idToken is signed by a valid JWT public key.
func GetUserFromGoogleOauthToken(idToken string) (string, error) {
token, err := jwt.Parse(idToken, func(t *jwt.Token) (interface{}, error) {
keyString, ok := googleJWTSigningKeys[t.Header["kid"].(string)]
if !ok {
return nil, fmt.Errorf("Unknown key in token")
}
key, err := jwt.ParseRSAPublicKeyFromPEM([]byte(keyString.(string)))
if err != nil {
return nil, err
}
return key, nil
})
if err != nil {
return "", err
}
if *googleDomain != "" {
if token.Claims["hd"].(string) != *googleDomain {
return "", fmt.Errorf("expected domain %s, got domain %s",
*googleDomain, token.Claims["hd"].(string))
}
}
return token.Claims["email"].(string), nil
}