@@ -29,8 +29,10 @@ func testGitHubProvider(hostname string) *GitHubProvider {
2929 return p
3030}
3131
32−func testGitHubBackend(payload []string) *httptest.Server {
32+func testGitHubBackend(payloads map[string][]string) *httptest.Server {
3333 pathToQueryMap := map[string][]string{
34+ "/repo/oauth2-proxy/oauth2-proxy": {""},
35+ "/repos/oauth2-proxy/oauth2-proxy/collaborators/mbland": {""},
3436 "/user": {""},
3537 "/user/emails": {""},
3638 "/user/orgs": {"page=1&per_page=100", "page=2&per_page=100", "page=3&per_page=100"},
@@ -47,10 +49,16 @@ func testGitHubBackend(payload []string) *httptest.Server {
4749 index = i
4850 }
4951 }
52+ payload := []string{}
53+ if ok && validQuery {
54+ payload, ok = payloads[r.URL.Path]
55+ }
5056 if !ok {
5157 w.WriteHeader(404)
5258 } else if !validQuery {
5359 w.WriteHeader(404)
60+ } else if payload[index] == "" {
61+ w.WriteHeader(204)
5462 } else {
5563 w.WriteHeader(200)
5664 w.Write([]byte(payload[index]))
@@ -99,7 +107,9 @@ func TestGitHubProviderOverrides(t *testing.T) {
99107}
100108
101109func TestGitHubProviderGetEmailAddress(t *testing.T) {
102− b := testGitHubBackend([]string{`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`})
110+ b := testGitHubBackend(map[string][]string{
111+ "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
112+ })
103113 defer b.Close()
104114
105115 bURL, _ := url.Parse(b.URL)
@@ -112,7 +122,9 @@ func TestGitHubProviderGetEmailAddress(t *testing.T) {
112122}
113123
114124func TestGitHubProviderGetEmailAddressNotVerified(t *testing.T) {
115− b := testGitHubBackend([]string{`[ {"email": "michael.bland@gsa.gov", "verified": false, "primary": true} ]`})
125+ b := testGitHubBackend(map[string][]string{
126+ "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
127+ })
116128 defer b.Close()
117129
118130 bURL, _ := url.Parse(b.URL)
@@ -125,10 +137,13 @@ func TestGitHubProviderGetEmailAddressNotVerified(t *testing.T) {
125137}
126138
127139func TestGitHubProviderGetEmailAddressWithOrg(t *testing.T) {
128− b := testGitHubBackend([]string{
129− `[ {"email": "michael.bland@gsa.gov", "primary": true, "verified": true, "login":"testorg"} ]`,
130− `[ {"email": "michael.bland1@gsa.gov", "primary": true, "verified": true, "login":"testorg1"} ]`,
131− `[ ]`,
140+ b := testGitHubBackend(map[string][]string{
141+ "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
142+ "/user/orgs": {
143+ `[ {"login":"testorg"} ]`,
144+ `[ {"login":"testorg1"} ]`,
145+ `[ ]`,
146+ },
132147 })
133148 defer b.Close()
134149
@@ -142,10 +157,93 @@ func TestGitHubProviderGetEmailAddressWithOrg(t *testing.T) {
142157 assert.Equal(t, "michael.bland@gsa.gov", email)
143158}
144159
160+func TestGitHubProviderGetEmailAddressWithWriteAccessToPublicRepo(t *testing.T) {
161+ b := testGitHubBackend(map[string][]string{
162+ "/repo/oauth2-proxy/oauth2-proxy": {`{"permissions": {"pull": true, "push": true}, "private": false}`},
163+ "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
164+ })
165+ defer b.Close()
166+
167+ bURL, _ := url.Parse(b.URL)
168+ p := testGitHubProvider(bURL.Host)
169+ p.SetRepo("oauth2-proxy/oauth2-proxy", "")
170+
171+ session := CreateAuthorizedSession()
172+ email, err := p.GetEmailAddress(context.Background(), session)
173+ assert.Equal(t, nil, err)
174+ assert.Equal(t, "michael.bland@gsa.gov", email)
175+}
176+
177+func TestGitHubProviderGetEmailAddressWithReadOnlyAccessToPrivateRepo(t *testing.T) {
178+ b := testGitHubBackend(map[string][]string{
179+ "/repo/oauth2-proxy/oauth2-proxy": {`{"permissions": {"pull": true, "push": false}, "private": true}`},
180+ "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
181+ })
182+ defer b.Close()
183+
184+ bURL, _ := url.Parse(b.URL)
185+ p := testGitHubProvider(bURL.Host)
186+ p.SetRepo("oauth2-proxy/oauth2-proxy", "")
187+
188+ session := CreateAuthorizedSession()
189+ email, err := p.GetEmailAddress(context.Background(), session)
190+ assert.Equal(t, nil, err)
191+ assert.Equal(t, "michael.bland@gsa.gov", email)
192+}
193+
194+func TestGitHubProviderGetEmailAddressWithWriteAccessToPrivateRepo(t *testing.T) {
195+ b := testGitHubBackend(map[string][]string{
196+ "/repo/oauth2-proxy/oauth2-proxy": {`{"permissions": {"pull": true, "push": true}, "private": true}`},
197+ "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
198+ })
199+ defer b.Close()
200+
201+ bURL, _ := url.Parse(b.URL)
202+ p := testGitHubProvider(bURL.Host)
203+ p.SetRepo("oauth2-proxy/oauth2-proxy", "")
204+
205+ session := CreateAuthorizedSession()
206+ email, err := p.GetEmailAddress(context.Background(), session)
207+ assert.Equal(t, nil, err)
208+ assert.Equal(t, "michael.bland@gsa.gov", email)
209+}
210+
211+func TestGitHubProviderGetEmailAddressWithNoAccessToPrivateRepo(t *testing.T) {
212+ b := testGitHubBackend(map[string][]string{
213+ "/repo/oauth2-proxy/oauth2-proxy": {},
214+ })
215+ defer b.Close()
216+
217+ bURL, _ := url.Parse(b.URL)
218+ p := testGitHubProvider(bURL.Host)
219+ p.SetRepo("oauth2-proxy/oauth2-proxy", "")
220+
221+ session := CreateAuthorizedSession()
222+ email, err := p.GetEmailAddress(context.Background(), session)
223+ assert.NotEqual(t, nil, err)
224+ assert.Equal(t, "", email)
225+}
226+
227+func TestGitHubProviderGetEmailAddressWithToken(t *testing.T) {
228+ b := testGitHubBackend(map[string][]string{
229+ "/user/emails": {`[ {"email": "michael.bland@gsa.gov", "verified": true, "primary": true} ]`},
230+ })
231+ defer b.Close()
232+
233+ bURL, _ := url.Parse(b.URL)
234+ p := testGitHubProvider(bURL.Host)
235+ p.SetRepo("oauth2-proxy/oauth2-proxy", "token")
236+
237+ session := CreateAuthorizedSession()
238+ email, err := p.GetEmailAddress(context.Background(), session)
239+ assert.Equal(t, nil, err)
240+ assert.Equal(t, "michael.bland@gsa.gov", email)
241+}
242+
145243// Note that trying to trigger the "failed building request" case is not
146244// practical, since the only way it can fail is if the URL fails to parse.
147245func TestGitHubProviderGetEmailAddressFailedRequest(t *testing.T) {
148− b := testGitHubBackend([]string{"unused payload"})
246+ b := testGitHubBackend(map[string][]string{})
149247 defer b.Close()
150248
151249 bURL, _ := url.Parse(b.URL)
@@ -161,7 +259,9 @@ func TestGitHubProviderGetEmailAddressFailedRequest(t *testing.T) {
161259}
162260
163261func TestGitHubProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) {
164− b := testGitHubBackend([]string{"{\"foo\": \"bar\"}"})
262+ b := testGitHubBackend(map[string][]string{
263+ "/user/emails": {`{"foo": "bar"}`},
264+ })
165265 defer b.Close()
166266
167267 bURL, _ := url.Parse(b.URL)
@@ -174,14 +274,47 @@ func TestGitHubProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) {
174274}
175275
176276func TestGitHubProviderGetUserName(t *testing.T) {
177− b := testGitHubBackend([]string{`{"email": "michael.bland@gsa.gov", "login": "mbland"}`})
277+ b := testGitHubBackend(map[string][]string{
278+ "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
279+ })
280+ defer b.Close()
281+
282+ bURL, _ := url.Parse(b.URL)
283+ p := testGitHubProvider(bURL.Host)
284+
285+ session := CreateAuthorizedSession()
286+ email, err := p.GetUserName(context.Background(), session)
287+ assert.Equal(t, nil, err)
288+ assert.Equal(t, "mbland", email)
289+}
290+
291+func TestGitHubProviderGetUserNameWithRepoAndToken(t *testing.T) {
292+ b := testGitHubBackend(map[string][]string{
293+ "/user": {`{"email": "michael.bland@gsa.gov", "login": "mbland"}`},
294+ "/repos/oauth2-proxy/oauth2-proxy/collaborators/mbland": {""},
295+ })
178296 defer b.Close()
179297
180298 bURL, _ := url.Parse(b.URL)
181299 p := testGitHubProvider(bURL.Host)
300+ p.SetRepo("oauth2-proxy/oauth2-proxy", "token")
182301
183302 session := CreateAuthorizedSession()
184303 email, err := p.GetUserName(context.Background(), session)
185304 assert.Equal(t, nil, err)
186305 assert.Equal(t, "mbland", email)
187306}
307+
308+func TestGitHubProviderGetUserNameWithRepoAndTokenWithoutPushAccess(t *testing.T) {
309+ b := testGitHubBackend(map[string][]string{})
310+ defer b.Close()
311+
312+ bURL, _ := url.Parse(b.URL)
313+ p := testGitHubProvider(bURL.Host)
314+ p.SetRepo("oauth2-proxy/oauth2-proxy", "token")
315+
316+ session := CreateAuthorizedSession()
317+ email, err := p.GetUserName(context.Background(), session)
318+ assert.NotEqual(t, nil, err)
319+ assert.Equal(t, "", email)
320+}