@@ -39,6 +39,7 @@ func testGitHubBackend(payloads map[string][]string) *httptest.Server {
3939 "/repos/oauth2-proxy/oauth2-proxy/collaborators/mbland": {""},
4040 "/user": {""},
4141 "/user/emails": {""},
42+ "/user/teams": {"page=1&per_page=100", "page=2&per_page=100", "page=3&per_page=100"},
4243 "/user/orgs": {"page=1&per_page=100", "page=2&per_page=100", "page=3&per_page=100"},
4344 // GitHub Enterprise Server API
4445 "/api/v3": {""},
@@ -168,6 +169,134 @@ func TestGitHubProvider_getEmailWithOrg(t *testing.T) {
168169 assert.Equal(t, "michael.bland@gsa.gov", session.Email)
169170}
170171
172+func TestGitHubProvider_checkRestrictionsOrg(t *testing.T) {
173+ b := testGitHubBackend(map[string][]string{
174+ "/user/emails": {`[ {"email": "john.doe@example", "verified": true, "primary": true} ]`},
175+ "/user/orgs": {
176+ `[ { "login": "test-org-1" } ]`,
177+ `[ { "login": "test-org-2" } ]`,
178+ `[ ]`,
179+ },
180+ "/user/teams": {
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" } } ]`,
183+ `[ ]`,
184+ },
185+ })
186+ defer b.Close()
187+
188+ // This test should succeed, because of the valid organization.
189+ bURL, _ := url.Parse(b.URL)
190+ p := testGitHubProvider(bURL.Host,
191+ options.GitHubOptions{
192+ Org: "test-org-1",
193+ },
194+ )
195+
196+ var err error
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)
202+
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",
207+ },
208+ )
209+
210+ err = p.checkRestrictions(context.Background(), session)
211+ assert.Error(t, err)
212+}
213+
214+func TestGitHubProvider_checkRestrictionsOrgTeam(t *testing.T) {
215+ b := testGitHubBackend(map[string][]string{
216+ "/user/emails": {`[ {"email": "john.doe@example", "verified": true, "primary": true} ]`},
217+ "/user/orgs": {
218+ `[ { "login": "test-org-1" } ]`,
219+ `[ { "login": "test-org-2" } ]`,
220+ `[ ]`,
221+ },
222+ "/user/teams": {
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" } } ]`,
225+ `[ ]`,
226+ },
227+ })
228+ defer b.Close()
229+
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{
234+ Org: "test-org-1",
235+ Team: "test-team-1",
236+ },
237+ )
238+
239+ var err error
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)
245+
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",
251+ },
252+ )
253+
254+ err = p.checkRestrictions(context.Background(), session)
255+ assert.Error(t, err)
256+}
257+
258+func TestGitHubProvider_checkRestrictionsTeam(t *testing.T) {
259+ b := testGitHubBackend(map[string][]string{
260+ "/user/emails": {`[ {"email": "john.doe@example", "verified": true, "primary": true} ]`},
261+ "/user/orgs": {
262+ `[ { "login": "test-org-1" } ]`,
263+ `[ { "login": "test-org-2" } ]`,
264+ `[ ]`,
265+ },
266+ "/user/teams": {
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" } } ]`,
269+ `[ ]`,
270+ },
271+ })
272+ defer b.Close()
273+
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",
279+ },
280+ )
281+
282+ var err error
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)
288+
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",
293+ },
294+ )
295+
296+ err = p.checkRestrictions(context.Background(), session)
297+ assert.Error(t, err)
298+}
299+
171300func TestGitHubProvider_getEmailWithWriteAccessToPublicRepo(t *testing.T) {
172301 b := testGitHubBackend(map[string][]string{
173302 "/repo/oauth2-proxy/oauth2-proxy": {`{"permissions": {"pull": true, "push": true}, "private": false}`},