From ff34e570b4e013af273c12559fb061f49d9bdecb Mon Sep 17 00:00:00 2001
From: Nandor Kracser <bonifaido@gmail.com>
Date: Fri, 26 Jul 2019 12:35:35 +0200
Subject: [PATCH] connector/gitlab: implement useLoginAsID as in GitHub
 connector

---
 Documentation/connectors/gitlab.md | 3 +++
 connector/github/github.go         | 2 +-
 connector/gitlab/gitlab.go         | 7 +++++++
 connector/gitlab/gitlab_test.go    | 6 +++---
 4 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/Documentation/connectors/gitlab.md b/Documentation/connectors/gitlab.md
index f85e24c7..74330148 100644
--- a/Documentation/connectors/gitlab.md
+++ b/Documentation/connectors/gitlab.md
@@ -33,4 +33,7 @@ connectors:
       # If `groups` is provided, this acts as a whitelist - only the user's GitLab groups that are in the configured `groups` below will go into the groups claim.  Conversely, if the user is not in any of the configured `groups`, the user will not be authenticated.
       groups:
       - my-group
+      # flag which will switch from using the internal GitLab id to the users handle (@mention) as the user id.
+      # It is possible for a user to change their own user name but it is very rare for them to do so
+      useLoginAsID: false
 ```
diff --git a/connector/github/github.go b/connector/github/github.go
index 9093c6ad..35fe6b92 100644
--- a/connector/github/github.go
+++ b/connector/github/github.go
@@ -150,7 +150,7 @@ type githubConnector struct {
 	teamNameField string
 	// if set to true and no orgs are configured then connector loads all user claims (all orgs and team)
 	loadAllGroups bool
-	// if set to true will use the users handle rather than their numeric id as the ID
+	// if set to true will use the user's handle rather than their numeric id as the ID
 	useLoginAsID bool
 }
 
diff --git a/connector/gitlab/gitlab.go b/connector/gitlab/gitlab.go
index fde519a0..fca6fbf5 100644
--- a/connector/gitlab/gitlab.go
+++ b/connector/gitlab/gitlab.go
@@ -32,6 +32,7 @@ type Config struct {
 	ClientSecret string   `json:"clientSecret"`
 	RedirectURI  string   `json:"redirectURI"`
 	Groups       []string `json:"groups"`
+	UseLoginAsID bool     `json:"useLoginAsID"`
 }
 
 type gitlabUser struct {
@@ -55,6 +56,7 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error)
 		clientSecret: c.ClientSecret,
 		logger:       logger,
 		groups:       c.Groups,
+		useLoginAsID: c.UseLoginAsID,
 	}, nil
 }
 
@@ -76,6 +78,8 @@ type gitlabConnector struct {
 	clientSecret string
 	logger       log.Logger
 	httpClient   *http.Client
+	// if set to true will use the user's handle rather than their numeric id as the ID
+	useLoginAsID bool
 }
 
 func (c *gitlabConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config {
@@ -148,6 +152,9 @@ func (c *gitlabConnector) HandleCallback(s connector.Scopes, r *http.Request) (i
 		Email:         user.Email,
 		EmailVerified: true,
 	}
+	if c.useLoginAsID {
+		identity.UserID = user.Username
+	}
 
 	if s.Groups {
 		groups, err := c.getGroups(ctx, client, s.Groups, user.Username)
diff --git a/connector/gitlab/gitlab_test.go b/connector/gitlab/gitlab_test.go
index 4be5e0f2..f56621fb 100644
--- a/connector/gitlab/gitlab_test.go
+++ b/connector/gitlab/gitlab_test.go
@@ -104,7 +104,7 @@ func TestUsernameIncludedInFederatedIdentity(t *testing.T) {
 func TestLoginUsedAsIDWhenConfigured(t *testing.T) {
 
 	s := newTestServer(map[string]interface{}{
-		"/api/v4/user": gitlabUser{Email: "some@email.com", ID: 12345678, Name: "Joe Bloggs"},
+		"/api/v4/user": gitlabUser{Email: "some@email.com", ID: 12345678, Name: "Joe Bloggs", Username: "joebloggs"},
 		"/oauth/token": map[string]interface{}{
 			"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9",
 			"expires_in":   "30",
@@ -121,11 +121,11 @@ func TestLoginUsedAsIDWhenConfigured(t *testing.T) {
 	req, err := http.NewRequest("GET", hostURL.String(), nil)
 	expectNil(t, err)
 
-	c := gitlabConnector{baseURL: s.URL, httpClient: newClient()}
+	c := gitlabConnector{baseURL: s.URL, httpClient: newClient(), useLoginAsID: true}
 	identity, err := c.HandleCallback(connector.Scopes{Groups: true}, req)
 
 	expectNil(t, err)
-	expectEquals(t, identity.UserID, "12345678")
+	expectEquals(t, identity.UserID, "joebloggs")
 	expectEquals(t, identity.Username, "Joe Bloggs")
 }
 
-- 
GitLab