github.com/pusher/oauth2_proxy@v3.2.0+incompatible/providers/github_test.go (about) 1 package providers 2 3 import ( 4 "net/http" 5 "net/http/httptest" 6 "net/url" 7 "testing" 8 9 "github.com/stretchr/testify/assert" 10 ) 11 12 func testGitHubProvider(hostname string) *GitHubProvider { 13 p := NewGitHubProvider( 14 &ProviderData{ 15 ProviderName: "", 16 LoginURL: &url.URL{}, 17 RedeemURL: &url.URL{}, 18 ProfileURL: &url.URL{}, 19 ValidateURL: &url.URL{}, 20 Scope: ""}) 21 if hostname != "" { 22 updateURL(p.Data().LoginURL, hostname) 23 updateURL(p.Data().RedeemURL, hostname) 24 updateURL(p.Data().ProfileURL, hostname) 25 updateURL(p.Data().ValidateURL, hostname) 26 } 27 return p 28 } 29 30 func testGitHubBackend(payload []string) *httptest.Server { 31 pathToQueryMap := map[string][]string{ 32 "/user": {""}, 33 "/user/emails": {""}, 34 "/user/orgs": {"limit=200&page=1", "limit=200&page=2", "limit=200&page=3"}, 35 } 36 37 return httptest.NewServer(http.HandlerFunc( 38 func(w http.ResponseWriter, r *http.Request) { 39 query, ok := pathToQueryMap[r.URL.Path] 40 validQuery := false 41 index := 0 42 for i, q := range query { 43 if q == r.URL.RawQuery { 44 validQuery = true 45 index = i 46 } 47 } 48 if !ok { 49 w.WriteHeader(404) 50 } else if !validQuery { 51 w.WriteHeader(404) 52 } else { 53 w.WriteHeader(200) 54 w.Write([]byte(payload[index])) 55 } 56 })) 57 } 58 59 func TestGitHubProviderDefaults(t *testing.T) { 60 p := testGitHubProvider("") 61 assert.NotEqual(t, nil, p) 62 assert.Equal(t, "GitHub", p.Data().ProviderName) 63 assert.Equal(t, "https://github.com/login/oauth/authorize", 64 p.Data().LoginURL.String()) 65 assert.Equal(t, "https://github.com/login/oauth/access_token", 66 p.Data().RedeemURL.String()) 67 assert.Equal(t, "https://api.github.com/", 68 p.Data().ValidateURL.String()) 69 assert.Equal(t, "user:email", p.Data().Scope) 70 } 71 72 func TestGitHubProviderOverrides(t *testing.T) { 73 p := NewGitHubProvider( 74 &ProviderData{ 75 LoginURL: &url.URL{ 76 Scheme: "https", 77 Host: "example.com", 78 Path: "/login/oauth/authorize"}, 79 RedeemURL: &url.URL{ 80 Scheme: "https", 81 Host: "example.com", 82 Path: "/login/oauth/access_token"}, 83 ValidateURL: &url.URL{ 84 Scheme: "https", 85 Host: "api.example.com", 86 Path: "/"}, 87 Scope: "profile"}) 88 assert.NotEqual(t, nil, p) 89 assert.Equal(t, "GitHub", p.Data().ProviderName) 90 assert.Equal(t, "https://example.com/login/oauth/authorize", 91 p.Data().LoginURL.String()) 92 assert.Equal(t, "https://example.com/login/oauth/access_token", 93 p.Data().RedeemURL.String()) 94 assert.Equal(t, "https://api.example.com/", 95 p.Data().ValidateURL.String()) 96 assert.Equal(t, "profile", p.Data().Scope) 97 } 98 99 func TestGitHubProviderGetEmailAddress(t *testing.T) { 100 b := testGitHubBackend([]string{`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`}) 101 defer b.Close() 102 103 bURL, _ := url.Parse(b.URL) 104 p := testGitHubProvider(bURL.Host) 105 106 session := &SessionState{AccessToken: "imaginary_access_token"} 107 email, err := p.GetEmailAddress(session) 108 assert.Equal(t, nil, err) 109 assert.Equal(t, "michael.bland@gsa.gov", email) 110 } 111 112 func TestGitHubProviderGetEmailAddressNotVerified(t *testing.T) { 113 b := testGitHubBackend([]string{`[ {"email": "michael.bland@gsa.gov", "verified": false, "primary": true} ]`}) 114 defer b.Close() 115 116 bURL, _ := url.Parse(b.URL) 117 p := testGitHubProvider(bURL.Host) 118 119 session := &SessionState{AccessToken: "imaginary_access_token"} 120 email, err := p.GetEmailAddress(session) 121 assert.Equal(t, nil, err) 122 assert.Empty(t, "", email) 123 } 124 125 func TestGitHubProviderGetEmailAddressWithOrg(t *testing.T) { 126 b := testGitHubBackend([]string{ 127 `[ {"email": "michael.bland@gsa.gov", "primary": true, "verified": true, "login":"testorg"} ]`, 128 `[ {"email": "michael.bland1@gsa.gov", "primary": true, "verified": true, "login":"testorg1"} ]`, 129 `[ ]`, 130 }) 131 defer b.Close() 132 133 bURL, _ := url.Parse(b.URL) 134 p := testGitHubProvider(bURL.Host) 135 p.Org = "testorg1" 136 137 session := &SessionState{AccessToken: "imaginary_access_token"} 138 email, err := p.GetEmailAddress(session) 139 assert.Equal(t, nil, err) 140 assert.Equal(t, "michael.bland@gsa.gov", email) 141 } 142 143 // Note that trying to trigger the "failed building request" case is not 144 // practical, since the only way it can fail is if the URL fails to parse. 145 func TestGitHubProviderGetEmailAddressFailedRequest(t *testing.T) { 146 b := testGitHubBackend([]string{"unused payload"}) 147 defer b.Close() 148 149 bURL, _ := url.Parse(b.URL) 150 p := testGitHubProvider(bURL.Host) 151 152 // We'll trigger a request failure by using an unexpected access 153 // token. Alternatively, we could allow the parsing of the payload as 154 // JSON to fail. 155 session := &SessionState{AccessToken: "unexpected_access_token"} 156 email, err := p.GetEmailAddress(session) 157 assert.NotEqual(t, nil, err) 158 assert.Equal(t, "", email) 159 } 160 161 func TestGitHubProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) { 162 b := testGitHubBackend([]string{"{\"foo\": \"bar\"}"}) 163 defer b.Close() 164 165 bURL, _ := url.Parse(b.URL) 166 p := testGitHubProvider(bURL.Host) 167 168 session := &SessionState{AccessToken: "imaginary_access_token"} 169 email, err := p.GetEmailAddress(session) 170 assert.NotEqual(t, nil, err) 171 assert.Equal(t, "", email) 172 } 173 174 func TestGitHubProviderGetUserName(t *testing.T) { 175 b := testGitHubBackend([]string{`{"email": "michael.bland@gsa.gov", "login": "mbland"}`}) 176 defer b.Close() 177 178 bURL, _ := url.Parse(b.URL) 179 p := testGitHubProvider(bURL.Host) 180 181 session := &SessionState{AccessToken: "imaginary_access_token"} 182 email, err := p.GetUserName(session) 183 assert.Equal(t, nil, err) 184 assert.Equal(t, "mbland", email) 185 }