10 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
11 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
12 . "github.com/onsi/gomega"
13 "github.com/stretchr/testify/assert"
16func testGitHubProvider(hostname string, opts options.GitHubOptions) *GitHubProvider {
17 p := NewGitHubProvider(
21 RedeemURL: &url.URL{},
22 ProfileURL: &url.URL{},
23 ValidateURL: &url.URL{},
27 updateURL(p.Data().LoginURL, hostname)
28 updateURL(p.Data().RedeemURL, hostname)
29 updateURL(p.Data().ProfileURL, hostname)
30 updateURL(p.Data().ValidateURL, hostname)
35func testGitHubBackend(payloads map[string][]string) *httptest.Server {
36 pathToQueryMap := map[string][]string{
38 "/repos/oauth2-proxy/oauth2-proxy": {""},
39 "/repos/oauth2-proxy/oauth2-proxy/collaborators/mbland": {""},
42 "/user/teams": {"page=1&per_page=100", "page=2&per_page=100", "page=3&per_page=100"},
43 "/user/orgs": {"page=1&per_page=100", "page=2&per_page=100", "page=3&per_page=100"},
44 // GitHub Enterprise Server API
46 "/api/v3/user/emails": {""},
49 return httptest.NewServer(http.HandlerFunc(
50 func(w http.ResponseWriter, r *http.Request) {
51 query, ok := pathToQueryMap[r.URL.Path]
54 for i, q := range query {
55 if q == r.URL.RawQuery {
62 payload, ok = payloads[r.URL.Path]
66 } else if !validQuery {
68 } else if payload[index] == "" {
72 w.Write([]byte(payload[index]))
77func TestNewGitHubProvider(t *testing.T) {
80 // Test that defaults are set when calling for a new provider with nothing set
81 providerData := NewGitHubProvider(&ProviderData{}, options.GitHubOptions{}).Data()
82 g.Expect(providerData.ProviderName).To(Equal("GitHub"))
83 g.Expect(providerData.LoginURL.String()).To(Equal(githubDefaultLoginURL.String()))
84 g.Expect(providerData.RedeemURL.String()).To(Equal(githubDefaultRedeemURL.String()))
85 g.Expect(providerData.ProfileURL.String()).To(Equal(""))
86 g.Expect(providerData.ValidateURL.String()).To(Equal("https://api.github.com/"))
87 g.Expect(providerData.Scope).To(Equal("user:email read:org"))
90func TestGitHubProviderOverrides(t *testing.T) {
91 p := NewGitHubProvider(
96 Path: "/login/oauth/authorize"},
100 Path: "/login/oauth/access_token"},
101 ValidateURL: &url.URL{
103 Host: "api.example.com",
106 options.GitHubOptions{})
107 assert.NotEqual(t, nil, p)
108 assert.Equal(t, "GitHub", p.Data().ProviderName)
109 assert.Equal(t, "https://example.com/login/oauth/authorize",
110 p.Data().LoginURL.String())
111 assert.Equal(t, "https://example.com/login/oauth/access_token",
112 p.Data().RedeemURL.String())
113 assert.Equal(t, "https://api.example.com/",
114 p.Data().ValidateURL.String())
115 assert.Equal(t, "profile", p.Data().Scope)
118func TestGitHubProvider_getEmail(t *testing.T) {
119 b := testGitHubBackend(map[string][]string{
120 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
124 bURL, _ := url.Parse(b.URL)
125 p := testGitHubProvider(bURL.Host, options.GitHubOptions{})
127 session := CreateAuthorizedSession()
128 err := p.getEmail(context.Background(), session)
129 assert.NoError(t, err)
130 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
133func TestGitHubProvider_getEmailNotVerified(t *testing.T) {
134 b := testGitHubBackend(map[string][]string{
135 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": false, "primary": true} ]`},
139 bURL, _ := url.Parse(b.URL)
140 p := testGitHubProvider(bURL.Host, options.GitHubOptions{})
142 session := CreateAuthorizedSession()
143 err := p.getEmail(context.Background(), session)
144 assert.NoError(t, err)
145 assert.Empty(t, session.Email)
148func TestGitHubProvider_getEmailWithOrg(t *testing.T) {
149 b := testGitHubBackend(map[string][]string{
150 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
152 `[ {"login":"testorg"} ]`,
153 `[ {"login":"testorg1"} ]`,
159 bURL, _ := url.Parse(b.URL)
160 p := testGitHubProvider(bURL.Host,
161 options.GitHubOptions{
166 session := CreateAuthorizedSession()
167 err := p.getEmail(context.Background(), session)
168 assert.NoError(t, err)
169 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
172func TestGitHubProvider_checkRestrictionsOrg(t *testing.T) {
173 b := testGitHubBackend(map[string][]string{
174 "/user/emails": {`[ {"email": "john.doe@example", "verified": true, "primary": true} ]`},
176 `[ { "login": "test-org-1" } ]`,
177 `[ { "login": "test-org-2" } ]`,
181 `[ { "name":"test-team-1", "slug":"test-team-1", "organization": { "login": "test-org-1" } } ]`,
182 `[ { "name":"test-team-2", "slug":"test-team-2", "organization": { "login": "test-org-2" } } ]`,
188 // This test should succeed, because of the valid organization.
189 bURL, _ := url.Parse(b.URL)
190 p := testGitHubProvider(bURL.Host,
191 options.GitHubOptions{
197 session := CreateAuthorizedSession()
198 err = p.getOrgAndTeam(context.Background(), session)
199 assert.NoError(t, err)
200 err = p.checkRestrictions(context.Background(), session)
201 assert.NoError(t, err)
203 // This part should fail, because user is not part of the organization
204 p = testGitHubProvider(bURL.Host,
205 options.GitHubOptions{
206 Org: "test-org-1-fail",
210 err = p.checkRestrictions(context.Background(), session)
214func TestGitHubProvider_checkRestrictionsOrgTeam(t *testing.T) {
215 b := testGitHubBackend(map[string][]string{
216 "/user/emails": {`[ {"email": "john.doe@example", "verified": true, "primary": true} ]`},
218 `[ { "login": "test-org-1" } ]`,
219 `[ { "login": "test-org-2" } ]`,
223 `[ { "name":"test-team-1", "slug":"test-team-1", "organization": { "login": "test-org-1" } } ]`,
224 `[ { "name":"test-team-2", "slug":"test-team-2", "organization": { "login": "test-org-2" } } ]`,
230 // This test should succeed, because of the valid Org and Team combination.
231 bURL, _ := url.Parse(b.URL)
232 p := testGitHubProvider(bURL.Host,
233 options.GitHubOptions{
240 session := CreateAuthorizedSession()
241 err = p.getOrgAndTeam(context.Background(), session)
242 assert.NoError(t, err)
243 err = p.checkRestrictions(context.Background(), session)
244 assert.NoError(t, err)
246 // This part should fail, because user is not part of the organization and the team
247 p = testGitHubProvider(bURL.Host,
248 options.GitHubOptions{
249 Org: "test-org-1-fail",
250 Team: "test-team-1-fail",
254 err = p.checkRestrictions(context.Background(), session)
258func TestGitHubProvider_checkRestrictionsTeam(t *testing.T) {
259 b := testGitHubBackend(map[string][]string{
260 "/user/emails": {`[ {"email": "john.doe@example", "verified": true, "primary": true} ]`},
262 `[ { "login": "test-org-1" } ]`,
263 `[ { "login": "test-org-2" } ]`,
267 `[ { "name":"test-team-1", "slug":"test-team-1", "organization": { "login": "test-org-1" } } ]`,
268 `[ { "name":"test-team-2", "slug":"test-team-2", "organization": { "login": "test-org-2" } } ]`,
274 // This test should succeed, because of the valid org:slug combination.
275 bURL, _ := url.Parse(b.URL)
276 p := testGitHubProvider(bURL.Host,
277 options.GitHubOptions{
278 Team: "test-org-1:test-team-1, test-org-2:test-team-2-fail",
283 session := CreateAuthorizedSession()
284 err = p.getOrgAndTeam(context.Background(), session)
285 assert.NoError(t, err)
286 err = p.checkRestrictions(context.Background(), session)
287 assert.NoError(t, err)
289 // This part should fail, because user is not part of the organization:team combination
290 p = testGitHubProvider(bURL.Host,
291 options.GitHubOptions{
292 Team: "test-org-1-fail:test-team-1-fail, test-org-2-fail:test-team-2-fail",
296 err = p.checkRestrictions(context.Background(), session)
300func TestGitHubProvider_getEmailWithWriteAccessToPublicRepo(t *testing.T) {
301 b := testGitHubBackend(map[string][]string{
302 "/repo/oauth2-proxy/oauth2-proxy": {`{"permissions": {"pull": true, "push": true}, "private": false}`},
303 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
307 bURL, _ := url.Parse(b.URL)
308 p := testGitHubProvider(bURL.Host,
309 options.GitHubOptions{
310 Repo: "oauth2-proxy/oauth2-proxy",
315 session := CreateAuthorizedSession()
316 err := p.getEmail(context.Background(), session)
317 assert.NoError(t, err)
318 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
321func TestGitHubProvider_getEmailWithReadOnlyAccessToPrivateRepo(t *testing.T) {
322 b := testGitHubBackend(map[string][]string{
323 "/repo/oauth2-proxy/oauth2-proxy": {`{"permissions": {"pull": true, "push": false}, "private": true}`},
324 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
328 bURL, _ := url.Parse(b.URL)
329 p := testGitHubProvider(bURL.Host,
330 options.GitHubOptions{
331 Repo: "oauth2-proxy/oauth2-proxy",
336 session := CreateAuthorizedSession()
337 err := p.getEmail(context.Background(), session)
338 assert.NoError(t, err)
339 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
342func TestGitHubProvider_getEmailWithWriteAccessToPrivateRepo(t *testing.T) {
343 b := testGitHubBackend(map[string][]string{
344 "/repo/oauth2-proxy/oauth2-proxy": {`{"permissions": {"pull": true, "push": true}, "private": true}`},
345 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
349 bURL, _ := url.Parse(b.URL)
350 p := testGitHubProvider(bURL.Host,
351 options.GitHubOptions{
352 Repo: "oauth2-proxy/oauth2-proxy",
357 session := CreateAuthorizedSession()
358 err := p.getEmail(context.Background(), session)
359 assert.NoError(t, err)
360 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
363func TestGitHubProvider_checkRestrictionsWithNoAccessToPrivateRepo(t *testing.T) {
364 b := testGitHubBackend(map[string][]string{
365 "/repos/oauth2-proxy/oauth2-proxy": {`{}`},
369 bURL, _ := url.Parse(b.URL)
370 p := testGitHubProvider(bURL.Host,
371 options.GitHubOptions{
372 Repo: "oauth2-proxy/oauth2-proxy",
376 session := CreateAuthorizedSession()
377 err := p.checkRestrictions(context.Background(), session)
379 assert.Empty(t, session.Email)
382func TestGitHubProvider_getEmailWithToken(t *testing.T) {
383 b := testGitHubBackend(map[string][]string{
384 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
388 bURL, _ := url.Parse(b.URL)
389 p := testGitHubProvider(bURL.Host,
390 options.GitHubOptions{
391 Repo: "oauth2-proxy/oauth2-proxy",
396 session := CreateAuthorizedSession()
397 err := p.getEmail(context.Background(), session)
398 assert.NoError(t, err)
399 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
402// Note that trying to trigger the "failed building request" case is not
403// practical, since the only way it can fail is if the URL fails to parse.
404func TestGitHubProvider_getEmailFailedRequest(t *testing.T) {
405 b := testGitHubBackend(map[string][]string{})
408 bURL, _ := url.Parse(b.URL)
409 p := testGitHubProvider(bURL.Host, options.GitHubOptions{})
411 // We'll trigger a request failure by using an unexpected access
412 // token. Alternatively, we could allow the parsing of the payload as
414 session := &sessions.SessionState{AccessToken: "unexpected_access_token"}
415 err := p.getEmail(context.Background(), session)
417 assert.Empty(t, session.Email)
420func TestGitHubProvider_getEmailNotPresentInPayload(t *testing.T) {
421 b := testGitHubBackend(map[string][]string{
422 "/user/emails": {`{"foo": "bar"}`},
426 bURL, _ := url.Parse(b.URL)
427 p := testGitHubProvider(bURL.Host, options.GitHubOptions{})
429 session := CreateAuthorizedSession()
430 err := p.getEmail(context.Background(), session)
432 assert.Empty(t, session.Email)
435func TestGitHubProvider_getUser(t *testing.T) {
436 b := testGitHubBackend(map[string][]string{
437 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
441 bURL, _ := url.Parse(b.URL)
442 p := testGitHubProvider(bURL.Host, options.GitHubOptions{})
444 session := CreateAuthorizedSession()
445 err := p.getUser(context.Background(), session)
446 assert.NoError(t, err)
447 assert.Equal(t, "mbland", session.User)
450func TestGitHubProvider_getUserWithRepoAndToken(t *testing.T) {
451 b := testGitHubBackend(map[string][]string{
452 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
453 "/repos/oauth2-proxy/oauth2-proxy/collaborators/mbland": {""},
457 bURL, _ := url.Parse(b.URL)
458 p := testGitHubProvider(bURL.Host,
459 options.GitHubOptions{
460 Repo: "oauth2-proxy/oauth2-proxy",
465 session := CreateAuthorizedSession()
466 err := p.getUser(context.Background(), session)
467 assert.NoError(t, err)
468 assert.Equal(t, "mbland", session.User)
471func TestGitHubProvider_getUserWithRepoAndTokenWithoutPushAccess(t *testing.T) {
472 b := testGitHubBackend(map[string][]string{})
475 bURL, _ := url.Parse(b.URL)
476 p := testGitHubProvider(bURL.Host,
477 options.GitHubOptions{
478 Repo: "oauth2-proxy/oauth2-proxy",
483 session := CreateAuthorizedSession()
484 err := p.getUser(context.Background(), session)
486 assert.Empty(t, session.User)
489func TestGitHubProvider_getEmailWithUsername(t *testing.T) {
490 b := testGitHubBackend(map[string][]string{
491 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
492 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
496 bURL, _ := url.Parse(b.URL)
497 p := testGitHubProvider(bURL.Host,
498 options.GitHubOptions{
499 Users: []string{"mbland", "octocat"},
503 session := CreateAuthorizedSession()
504 err := p.getEmail(context.Background(), session)
505 assert.NoError(t, err)
506 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
509func TestGitHubProvider_checkRestrictionsWithNotAllowedUsername(t *testing.T) {
510 b := testGitHubBackend(map[string][]string{
511 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
512 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
516 bURL, _ := url.Parse(b.URL)
517 p := testGitHubProvider(bURL.Host,
518 options.GitHubOptions{
519 Users: []string{"octocat"},
523 session := CreateAuthorizedSession()
524 err := p.checkRestrictions(context.Background(), session)
526 assert.Empty(t, session.Email)
529func TestGitHubProvider_getEmailWithUsernameAndNotBelongToOrg(t *testing.T) {
530 b := testGitHubBackend(map[string][]string{
531 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
532 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
534 `[ {"login":"testorg"} ]`,
540 bURL, _ := url.Parse(b.URL)
541 p := testGitHubProvider(bURL.Host,
542 options.GitHubOptions{
544 Users: []string{"mbland"},
548 session := CreateAuthorizedSession()
549 err := p.getEmail(context.Background(), session)
550 assert.NoError(t, err)
551 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
554func TestGitHubProvider_getEmailWithUsernameAndNoAccessToPrivateRepo(t *testing.T) {
555 b := testGitHubBackend(map[string][]string{
556 "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
557 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
558 "/repo/oauth2-proxy/oauth2-proxy": {`{}`},
562 bURL, _ := url.Parse(b.URL)
563 p := testGitHubProvider(bURL.Host,
564 options.GitHubOptions{
565 Repo: "oauth2-proxy/oauth2-proxy",
567 Users: []string{"mbland"},
571 session := CreateAuthorizedSession()
572 err := p.getEmail(context.Background(), session)
573 assert.NoError(t, err)
574 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
577func TestGitHubProvider_ValidateSessionWithBaseUrl(t *testing.T) {
578 b := testGitHubBackend(map[string][]string{
583 bURL, _ := url.Parse(b.URL)
584 p := testGitHubProvider(bURL.Host, options.GitHubOptions{})
586 session := CreateAuthorizedSession()
588 valid := p.ValidateSession(context.Background(), session)
589 assert.True(t, valid)
592func TestGitHubProvider_ValidateSessionWithEnterpriseBaseUrl(t *testing.T) {
593 b := testGitHubBackend(map[string][]string{
598 bURL, _ := url.Parse(b.URL)
599 p := testGitHubProvider(bURL.Host, options.GitHubOptions{})
600 p.ValidateURL.Path = "/api/v3"
602 session := CreateAuthorizedSession()
604 valid := p.ValidateSession(context.Background(), session)
605 assert.True(t, valid)
608func TestGitHubProvider_ValidateSessionWithUserEmails(t *testing.T) {
609 b := testGitHubBackend(map[string][]string{
610 "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
614 bURL, _ := url.Parse(b.URL)
615 p := testGitHubProvider(bURL.Host, options.GitHubOptions{})
616 p.ValidateURL.Path = "/user/emails"
618 session := CreateAuthorizedSession()
620 valid := p.ValidateSession(context.Background(), session)
621 assert.True(t, valid)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list