Skip to content

Commit

Permalink
Allow to prefix retrieved by gitlab groups
Browse files Browse the repository at this point in the history
  • Loading branch information
hightoxicity committed Nov 28, 2019
1 parent c410357 commit 7f5d6d9
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
17 changes: 17 additions & 0 deletions connector/gitlab/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Config struct {
RedirectURI string `json:"redirectURI"`
Groups []string `json:"groups"`
UseLoginAsID bool `json:"useLoginAsID"`
GroupPrefix string `json:"groupPrefix"`
}

type gitlabUser struct {
Expand All @@ -57,6 +58,7 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error)
logger: logger,
groups: c.Groups,
useLoginAsID: c.UseLoginAsID,
groupPrefix: c.GroupPrefix,
}, nil
}

Expand All @@ -80,6 +82,7 @@ type gitlabConnector struct {
httpClient *http.Client
// if set to true will use the user's handle rather than their numeric id as the ID
useLoginAsID bool
groupPrefix string
}

func (c *gitlabConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config {
Expand Down Expand Up @@ -162,6 +165,13 @@ func (c *gitlabConnector) HandleCallback(s connector.Scopes, r *http.Request) (i
if err != nil {
return identity, fmt.Errorf("gitlab: get groups: %v", err)
}

if c.groupPrefix != "" {
for grpIdx := range groups {
groups[grpIdx] = c.groupPrefix + groups[grpIdx]
}
}

identity.Groups = groups
}

Expand Down Expand Up @@ -206,6 +216,13 @@ func (c *gitlabConnector) Refresh(ctx context.Context, s connector.Scopes, ident
if err != nil {
return ident, fmt.Errorf("gitlab: get groups: %v", err)
}

if c.groupPrefix != "" {
for grpIdx := range groups {
groups[grpIdx] = c.groupPrefix + groups[grpIdx]
}
}

ident.Groups = groups
}
return ident, nil
Expand Down
92 changes: 92 additions & 0 deletions connector/gitlab/gitlab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,43 @@ func TestUsernameIncludedInFederatedIdentity(t *testing.T) {
expectEquals(t, identity.Groups, []string{"team-1"})
}

func TestUsernameIncludedInFederatedIdentityGroupPrefix(t *testing.T) {

s := newTestServer(map[string]interface{}{
"/api/v4/user": gitlabUser{Email: "[email protected]", ID: 12345678},
"/oauth/token": map[string]interface{}{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9",
"expires_in": "30",
},
"/oauth/userinfo": userInfo{
Groups: []string{"team-1"},
},
})
defer s.Close()

hostURL, err := url.Parse(s.URL)
expectNil(t, err)

req, err := http.NewRequest("GET", hostURL.String(), nil)
expectNil(t, err)

c := gitlabConnector{baseURL: s.URL, httpClient: newClient(), groupPrefix: "gl_"}
identity, err := c.HandleCallback(connector.Scopes{Groups: false}, req)

expectNil(t, err)
expectEquals(t, identity.Username, "[email protected]")
expectEquals(t, identity.UserID, "12345678")
expectEquals(t, 0, len(identity.Groups))

c = gitlabConnector{baseURL: s.URL, httpClient: newClient(), groupPrefix: "gl_"}
identity, err = c.HandleCallback(connector.Scopes{Groups: true}, req)

expectNil(t, err)
expectEquals(t, identity.Username, "[email protected]")
expectEquals(t, identity.UserID, "12345678")
expectEquals(t, identity.Groups, []string{"gl_team-1"})
}

func TestLoginUsedAsIDWhenConfigured(t *testing.T) {

s := newTestServer(map[string]interface{}{
Expand Down Expand Up @@ -157,6 +194,34 @@ func TestLoginWithTeamWhitelisted(t *testing.T) {
expectEquals(t, identity.Username, "Joe Bloggs")
}

func TestLoginWithTeamWhitelistedGroupPrefix(t *testing.T) {

s := newTestServer(map[string]interface{}{
"/api/v4/user": gitlabUser{Email: "[email protected]", ID: 12345678, Name: "Joe Bloggs"},
"/oauth/token": map[string]interface{}{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9",
"expires_in": "30",
},
"/oauth/userinfo": userInfo{
Groups: []string{"team-1"},
},
})
defer s.Close()

hostURL, err := url.Parse(s.URL)
expectNil(t, err)

req, err := http.NewRequest("GET", hostURL.String(), nil)
expectNil(t, err)

c := gitlabConnector{baseURL: s.URL, httpClient: newClient(), groups: []string{"team-1"}, groupPrefix: "gl_"}
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, req)

expectNil(t, err)
expectEquals(t, identity.UserID, "12345678")
expectEquals(t, identity.Username, "Joe Bloggs")
}

func TestLoginWithTeamNonWhitelisted(t *testing.T) {

s := newTestServer(map[string]interface{}{
Expand Down Expand Up @@ -184,6 +249,33 @@ func TestLoginWithTeamNonWhitelisted(t *testing.T) {
expectEquals(t, err.Error(), "gitlab: get groups: gitlab: user \"joebloggs\" is not in any of the required groups")
}

func TestLoginWithTeamNonWhitelistedGroupPrefix(t *testing.T) {

s := newTestServer(map[string]interface{}{
"/api/v4/user": gitlabUser{Email: "[email protected]", ID: 12345678, Name: "Joe Bloggs", Username: "joebloggs"},
"/oauth/token": map[string]interface{}{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9",
"expires_in": "30",
},
"/oauth/userinfo": userInfo{
Groups: []string{"team-1"},
},
})
defer s.Close()

hostURL, err := url.Parse(s.URL)
expectNil(t, err)

req, err := http.NewRequest("GET", hostURL.String(), nil)
expectNil(t, err)

c := gitlabConnector{baseURL: s.URL, httpClient: newClient(), groups: []string{"team-2"}, groupPrefix: "gl_"}
_, err = c.HandleCallback(connector.Scopes{Groups: true}, req)

expectNotNil(t, err, "HandleCallback error")
expectEquals(t, err.Error(), "gitlab: get groups: gitlab: user \"joebloggs\" is not in any of the required groups")
}

func newTestServer(responses map[string]interface{}) *httptest.Server {
return httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
response := responses[r.RequestURI]
Expand Down

0 comments on commit 7f5d6d9

Please sign in to comment.