OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package server | 5 package server |
6 | 6 |
7 import ( | 7 import ( |
8 "fmt" | 8 "fmt" |
9 "net/http" | 9 "net/http" |
10 "strings" | 10 "strings" |
11 "time" | 11 "time" |
12 | 12 |
13 "golang.org/x/net/context" | 13 "golang.org/x/net/context" |
14 | 14 |
15 "github.com/luci/gae/service/info" | 15 "github.com/luci/gae/service/info" |
16 "github.com/luci/gae/service/urlfetch" | 16 "github.com/luci/gae/service/urlfetch" |
17 "github.com/luci/gae/service/user" | 17 "github.com/luci/gae/service/user" |
18 | 18 |
19 "github.com/luci/luci-go/common/data/caching/proccache" | 19 "github.com/luci/luci-go/common/data/caching/proccache" |
20 "github.com/luci/luci-go/common/errors" | 20 "github.com/luci/luci-go/common/errors" |
21 "github.com/luci/luci-go/common/gcloud/googleoauth" | 21 "github.com/luci/luci-go/common/gcloud/googleoauth" |
22 "github.com/luci/luci-go/common/logging" | 22 "github.com/luci/luci-go/common/logging" |
| 23 "github.com/luci/luci-go/common/retry/transient" |
23 "github.com/luci/luci-go/server/auth" | 24 "github.com/luci/luci-go/server/auth" |
24 "github.com/luci/luci-go/server/auth/identity" | 25 "github.com/luci/luci-go/server/auth/identity" |
25 ) | 26 ) |
26 | 27 |
27 // EmailScope is a scope used to identifies user's email. Present in most tokens | 28 // EmailScope is a scope used to identifies user's email. Present in most tokens |
28 // by default. Can be used as a base scope for authentication. | 29 // by default. Can be used as a base scope for authentication. |
29 const EmailScope = "https://www.googleapis.com/auth/userinfo.email" | 30 const EmailScope = "https://www.googleapis.com/auth/userinfo.email" |
30 | 31 |
31 // OAuth2Method implements auth.Method on top of GAE OAuth2 API. It doesn't | 32 // OAuth2Method implements auth.Method on top of GAE OAuth2 API. It doesn't |
32 // implement auth.UsersAPI. | 33 // implement auth.UsersAPI. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 if idErr != nil { | 72 if idErr != nil { |
72 return nil, idErr | 73 return nil, idErr |
73 } | 74 } |
74 return &auth.User{ | 75 return &auth.User{ |
75 Identity: id, | 76 Identity: id, |
76 Superuser: u.Admin, | 77 Superuser: u.Admin, |
77 Email: u.Email, | 78 Email: u.Email, |
78 ClientID: u.ClientID, | 79 ClientID: u.ClientID, |
79 }, nil | 80 }, nil |
80 } | 81 } |
81 » return nil, errors.WrapTransient(err) | 82 » return nil, transient.Tag.Apply(err) |
82 } | 83 } |
83 | 84 |
84 type tokenCheckCache string | 85 type tokenCheckCache string |
85 | 86 |
86 // authenticateDevServer is called on dev server. It is using OAuth2 tokeninfo | 87 // authenticateDevServer is called on dev server. It is using OAuth2 tokeninfo |
87 // endpoint via URL fetch. It is slow as hell, but good enough for local manual | 88 // endpoint via URL fetch. It is slow as hell, but good enough for local manual |
88 // testing. | 89 // testing. |
89 func (m *OAuth2Method) authenticateDevServer(c context.Context, header string, s
copes []string) (*auth.User, error) { | 90 func (m *OAuth2Method) authenticateDevServer(c context.Context, header string, s
copes []string) (*auth.User, error) { |
90 chunks := strings.SplitN(header, " ", 2) | 91 chunks := strings.SplitN(header, " ", 2) |
91 if len(chunks) != 2 || (chunks[0] != "OAuth" && chunks[0] != "Bearer") { | 92 if len(chunks) != 2 || (chunks[0] != "OAuth" && chunks[0] != "Bearer") { |
(...skipping 10 matching lines...) Expand all Loading... |
102 logging.Infof(c, "oauth: Querying tokeninfo endpoint") | 103 logging.Infof(c, "oauth: Querying tokeninfo endpoint") |
103 tokenInfo, err := googleoauth.GetTokenInfo(c, googleoauth.TokenInfoParam
s{ | 104 tokenInfo, err := googleoauth.GetTokenInfo(c, googleoauth.TokenInfoParam
s{ |
104 AccessToken: accessToken, | 105 AccessToken: accessToken, |
105 Client: &http.Client{Transport: urlfetch.Get(c)}, | 106 Client: &http.Client{Transport: urlfetch.Get(c)}, |
106 Endpoint: m.tokenInfoEndpoint, | 107 Endpoint: m.tokenInfoEndpoint, |
107 }) | 108 }) |
108 if err != nil { | 109 if err != nil { |
109 if err == googleoauth.ErrBadToken { | 110 if err == googleoauth.ErrBadToken { |
110 return nil, err | 111 return nil, err |
111 } | 112 } |
112 » » return nil, errors.WrapTransient(fmt.Errorf("oauth: transient er
ror when validating token - %s", err)) | 113 » » return nil, errors.Annotate(err).Reason("oauth: transient error
when validating token"). |
| 114 » » » Tag(transient.Tag).Err() |
113 } | 115 } |
114 | 116 |
115 // Verify the token contains a validated email. | 117 // Verify the token contains a validated email. |
116 switch { | 118 switch { |
117 case tokenInfo.Email == "": | 119 case tokenInfo.Email == "": |
118 return nil, fmt.Errorf("oauth: token is not associated with an e
mail") | 120 return nil, fmt.Errorf("oauth: token is not associated with an e
mail") |
119 case !tokenInfo.EmailVerified: | 121 case !tokenInfo.EmailVerified: |
120 return nil, fmt.Errorf("oauth: email %s is not verified", tokenI
nfo.Email) | 122 return nil, fmt.Errorf("oauth: email %s is not verified", tokenI
nfo.Email) |
121 } | 123 } |
122 if tokenInfo.ExpiresIn <= 0 { | 124 if tokenInfo.ExpiresIn <= 0 { |
(...skipping 17 matching lines...) Expand all Loading... |
140 return nil, err | 142 return nil, err |
141 } | 143 } |
142 u := &auth.User{ | 144 u := &auth.User{ |
143 Identity: id, | 145 Identity: id, |
144 Email: tokenInfo.Email, | 146 Email: tokenInfo.Email, |
145 ClientID: tokenInfo.Aud, | 147 ClientID: tokenInfo.Aud, |
146 } | 148 } |
147 proccache.Put(c, tokenCheckCache(accessToken), u, time.Duration(tokenInf
o.ExpiresIn)*time.Second) | 149 proccache.Put(c, tokenCheckCache(accessToken), u, time.Duration(tokenInf
o.ExpiresIn)*time.Second) |
148 return u, nil | 150 return u, nil |
149 } | 151 } |
OLD | NEW |