git.iko.soy/typeable/oauth2-proxy
on 976dc35 help sign in
396 lines 12 kB history raw
1package providers
3import (
4 "context"
5 "net/http"
6 "net/http/httptest"
7 "net/url"
8 "testing"
10 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
11 . "github.com/onsi/gomega"
12 "github.com/stretchr/testify/assert"
15func testGitHubProvider(hostname string) *GitHubProvider {
16 p := NewGitHubProvider(
17 &ProviderData{
18 ProviderName: "",
19 LoginURL: &url.URL{},
20 RedeemURL: &url.URL{},
21 ProfileURL: &url.URL{},
22 ValidateURL: &url.URL{},
23 Scope: ""})
24 if hostname != "" {
25 updateURL(p.Data().LoginURL, hostname)
26 updateURL(p.Data().RedeemURL, hostname)
27 updateURL(p.Data().ProfileURL, hostname)
28 updateURL(p.Data().ValidateURL, hostname)
29 }
30 return p
33func testGitHubBackend(payloads map[string][]string) *httptest.Server {
34 pathToQueryMap := map[string][]string{
35 "/repo/oauth2-proxy/oauth2-proxy": {""},
36 "/repos/oauth2-proxy/oauth2-proxy/collaborators/mbland": {""},
37 "/user": {""},
38 "/user/emails": {""},
39 "/user/orgs": {"page=1&per_page=100", "page=2&per_page=100", "page=3&per_page=100"},
40 }
42 return httptest.NewServer(http.HandlerFunc(
43 func(w http.ResponseWriter, r *http.Request) {
44 query, ok := pathToQueryMap[r.URL.Path]
45 validQuery := false
46 index := 0
47 for i, q := range query {
48 if q == r.URL.RawQuery {
49 validQuery = true
50 index = i
51 }
52 }
53 payload := []string{}
54 if ok && validQuery {
55 payload, ok = payloads[r.URL.Path]
56 }
57 if !ok {
58 w.WriteHeader(404)
59 } else if !validQuery {
60 w.WriteHeader(404)
61 } else if payload[index] == "" {
62 w.WriteHeader(204)
63 } else {
64 w.WriteHeader(200)
65 w.Write([]byte(payload[index]))
66 }
67 }))
70func TestNewGitHubProvider(t *testing.T) {
71 g := NewWithT(t)
73 // Test that defaults are set when calling for a new provider with nothing set
74 providerData := NewGitHubProvider(&ProviderData{}).Data()
75 g.Expect(providerData.ProviderName).To(Equal("GitHub"))
76 g.Expect(providerData.LoginURL.String()).To(Equal("https://github.com/login/oauth/authorize"))
77 g.Expect(providerData.RedeemURL.String()).To(Equal("https://github.com/login/oauth/access_token"))
78 g.Expect(providerData.ProfileURL.String()).To(Equal(""))
79 g.Expect(providerData.ValidateURL.String()).To(Equal("https://api.github.com/"))
80 g.Expect(providerData.Scope).To(Equal("user:email"))
83func TestGitHubProviderOverrides(t *testing.T) {
84 p := NewGitHubProvider(
85 &ProviderData{
86 LoginURL: &url.URL{
87 Scheme: "https",
88 Host: "example.com",
89 Path: "/login/oauth/authorize"},
90 RedeemURL: &url.URL{
91 Scheme: "https",
92 Host: "example.com",
93 Path: "/login/oauth/access_token"},
94 ValidateURL: &url.URL{
95 Scheme: "https",
96 Host: "api.example.com",
97 Path: "/"},
98 Scope: "profile"})
99 assert.NotEqual(t, nil, p)
100 assert.Equal(t, "GitHub", p.Data().ProviderName)
101 assert.Equal(t, "https://example.com/login/oauth/authorize",
102 p.Data().LoginURL.String())
103 assert.Equal(t, "https://example.com/login/oauth/access_token",
104 p.Data().RedeemURL.String())
105 assert.Equal(t, "https://api.example.com/",
106 p.Data().ValidateURL.String())
107 assert.Equal(t, "profile", p.Data().Scope)
110func TestGitHubProvider_getEmail(t *testing.T) {
111 b := testGitHubBackend(map[string][]string{
112 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
113 })
114 defer b.Close()
116 bURL, _ := url.Parse(b.URL)
117 p := testGitHubProvider(bURL.Host)
119 session := CreateAuthorizedSession()
120 err := p.getEmail(context.Background(), session)
121 assert.NoError(t, err)
122 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
125func TestGitHubProvider_getEmailNotVerified(t *testing.T) {
126 b := testGitHubBackend(map[string][]string{
127 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": false, "primary": true} ]`},
128 })
129 defer b.Close()
131 bURL, _ := url.Parse(b.URL)
132 p := testGitHubProvider(bURL.Host)
134 session := CreateAuthorizedSession()
135 err := p.getEmail(context.Background(), session)
136 assert.NoError(t, err)
137 assert.Empty(t, session.Email)
140func TestGitHubProvider_getEmailWithOrg(t *testing.T) {
141 b := testGitHubBackend(map[string][]string{
142 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
143 "/user/orgs": {
144 `[ {"login":"testorg"} ]`,
145 `[ {"login":"testorg1"} ]`,
146 `[ ]`,
147 },
148 })
149 defer b.Close()
151 bURL, _ := url.Parse(b.URL)
152 p := testGitHubProvider(bURL.Host)
153 p.Org = "testorg1"
155 session := CreateAuthorizedSession()
156 err := p.getEmail(context.Background(), session)
157 assert.NoError(t, err)
158 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
161func TestGitHubProvider_getEmailWithWriteAccessToPublicRepo(t *testing.T) {
162 b := testGitHubBackend(map[string][]string{
163 "/repo/oauth2-proxy/oauth2-proxy": {`{"permissions": {"pull": true, "push": true}, "private": false}`},
164 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
165 })
166 defer b.Close()
168 bURL, _ := url.Parse(b.URL)
169 p := testGitHubProvider(bURL.Host)
170 p.SetRepo("oauth2-proxy/oauth2-proxy", "")
172 session := CreateAuthorizedSession()
173 err := p.getEmail(context.Background(), session)
174 assert.NoError(t, err)
175 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
178func TestGitHubProvider_getEmailWithReadOnlyAccessToPrivateRepo(t *testing.T) {
179 b := testGitHubBackend(map[string][]string{
180 "/repo/oauth2-proxy/oauth2-proxy": {`{"permissions": {"pull": true, "push": false}, "private": true}`},
181 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
182 })
183 defer b.Close()
185 bURL, _ := url.Parse(b.URL)
186 p := testGitHubProvider(bURL.Host)
187 p.SetRepo("oauth2-proxy/oauth2-proxy", "")
189 session := CreateAuthorizedSession()
190 err := p.getEmail(context.Background(), session)
191 assert.NoError(t, err)
192 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
195func TestGitHubProvider_getEmailWithWriteAccessToPrivateRepo(t *testing.T) {
196 b := testGitHubBackend(map[string][]string{
197 "/repo/oauth2-proxy/oauth2-proxy": {`{"permissions": {"pull": true, "push": true}, "private": true}`},
198 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
199 })
200 defer b.Close()
202 bURL, _ := url.Parse(b.URL)
203 p := testGitHubProvider(bURL.Host)
204 p.SetRepo("oauth2-proxy/oauth2-proxy", "")
206 session := CreateAuthorizedSession()
207 err := p.getEmail(context.Background(), session)
208 assert.NoError(t, err)
209 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
212func TestGitHubProvider_getEmailWithNoAccessToPrivateRepo(t *testing.T) {
213 b := testGitHubBackend(map[string][]string{
214 "/repo/oauth2-proxy/oauth2-proxy": {`{}`},
215 })
216 defer b.Close()
218 bURL, _ := url.Parse(b.URL)
219 p := testGitHubProvider(bURL.Host)
220 p.SetRepo("oauth2-proxy/oauth2-proxy", "")
222 session := CreateAuthorizedSession()
223 err := p.getEmail(context.Background(), session)
224 assert.NoError(t, err)
225 assert.Empty(t, session.Email)
228func TestGitHubProvider_getEmailWithToken(t *testing.T) {
229 b := testGitHubBackend(map[string][]string{
230 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
231 })
232 defer b.Close()
234 bURL, _ := url.Parse(b.URL)
235 p := testGitHubProvider(bURL.Host)
236 p.SetRepo("oauth2-proxy/oauth2-proxy", "token")
238 session := CreateAuthorizedSession()
239 err := p.getEmail(context.Background(), session)
240 assert.NoError(t, err)
241 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
244// Note that trying to trigger the "failed building request" case is not
245// practical, since the only way it can fail is if the URL fails to parse.
246func TestGitHubProvider_getEmailFailedRequest(t *testing.T) {
247 b := testGitHubBackend(map[string][]string{})
248 defer b.Close()
250 bURL, _ := url.Parse(b.URL)
251 p := testGitHubProvider(bURL.Host)
253 // We'll trigger a request failure by using an unexpected access
254 // token. Alternatively, we could allow the parsing of the payload as
255 // JSON to fail.
256 session := &sessions.SessionState{AccessToken: "unexpected_access_token"}
257 err := p.getEmail(context.Background(), session)
258 assert.Error(t, err)
259 assert.Empty(t, session.Email)
262func TestGitHubProvider_getEmailNotPresentInPayload(t *testing.T) {
263 b := testGitHubBackend(map[string][]string{
264 "/user/emails": {`{"foo": "bar"}`},
265 })
266 defer b.Close()
268 bURL, _ := url.Parse(b.URL)
269 p := testGitHubProvider(bURL.Host)
271 session := CreateAuthorizedSession()
272 err := p.getEmail(context.Background(), session)
273 assert.Error(t, err)
274 assert.Empty(t, session.Email)
277func TestGitHubProvider_getUser(t *testing.T) {
278 b := testGitHubBackend(map[string][]string{
279 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
280 })
281 defer b.Close()
283 bURL, _ := url.Parse(b.URL)
284 p := testGitHubProvider(bURL.Host)
286 session := CreateAuthorizedSession()
287 err := p.getUser(context.Background(), session)
288 assert.NoError(t, err)
289 assert.Equal(t, "mbland", session.User)
292func TestGitHubProvider_getUserWithRepoAndToken(t *testing.T) {
293 b := testGitHubBackend(map[string][]string{
294 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
295 "/repos/oauth2-proxy/oauth2-proxy/collaborators/mbland": {""},
296 })
297 defer b.Close()
299 bURL, _ := url.Parse(b.URL)
300 p := testGitHubProvider(bURL.Host)
301 p.SetRepo("oauth2-proxy/oauth2-proxy", "token")
303 session := CreateAuthorizedSession()
304 err := p.getUser(context.Background(), session)
305 assert.NoError(t, err)
306 assert.Equal(t, "mbland", session.User)
309func TestGitHubProvider_getUserWithRepoAndTokenWithoutPushAccess(t *testing.T) {
310 b := testGitHubBackend(map[string][]string{})
311 defer b.Close()
313 bURL, _ := url.Parse(b.URL)
314 p := testGitHubProvider(bURL.Host)
315 p.SetRepo("oauth2-proxy/oauth2-proxy", "token")
317 session := CreateAuthorizedSession()
318 err := p.getUser(context.Background(), session)
319 assert.Error(t, err)
320 assert.Empty(t, session.User)
323func TestGitHubProvider_getEmailWithUsername(t *testing.T) {
324 b := testGitHubBackend(map[string][]string{
325 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
326 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
327 })
328 defer b.Close()
330 bURL, _ := url.Parse(b.URL)
331 p := testGitHubProvider(bURL.Host)
332 p.SetUsers([]string{"mbland", "octocat"})
334 session := CreateAuthorizedSession()
335 err := p.getEmail(context.Background(), session)
336 assert.NoError(t, err)
337 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
340func TestGitHubProvider_getEmailWithNotAllowedUsername(t *testing.T) {
341 b := testGitHubBackend(map[string][]string{
342 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
343 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
344 })
345 defer b.Close()
347 bURL, _ := url.Parse(b.URL)
348 p := testGitHubProvider(bURL.Host)
349 p.SetUsers([]string{"octocat"})
351 session := CreateAuthorizedSession()
352 err := p.getEmail(context.Background(), session)
353 assert.Error(t, err)
354 assert.Empty(t, session.Email)
357func TestGitHubProvider_getEmailWithUsernameAndNotBelongToOrg(t *testing.T) {
358 b := testGitHubBackend(map[string][]string{
359 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
360 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
361 "/user/orgs": {
362 `[ {"login":"testorg"} ]`,
363 `[ ]`,
364 },
365 })
366 defer b.Close()
368 bURL, _ := url.Parse(b.URL)
369 p := testGitHubProvider(bURL.Host)
370 p.SetOrgTeam("not_belong_to", "")
371 p.SetUsers([]string{"mbland"})
373 session := CreateAuthorizedSession()
374 err := p.getEmail(context.Background(), session)
375 assert.NoError(t, err)
376 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
379func TestGitHubProvider_getEmailWithUsernameAndNoAccessToPrivateRepo(t *testing.T) {
380 b := testGitHubBackend(map[string][]string{
381 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
382 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
383 "/repo/oauth2-proxy/oauth2-proxy": {`{}`},
384 })
385 defer b.Close()
387 bURL, _ := url.Parse(b.URL)
388 p := testGitHubProvider(bURL.Host)
389 p.SetRepo("oauth2-proxy/oauth2-proxy", "")
390 p.SetUsers([]string{"mbland"})
392 session := CreateAuthorizedSession()
393 err := p.getEmail(context.Background(), session)
394 assert.NoError(t, err)
395 assert.Equal(t, "michael.bland@gsa.gov", session.Email)