From d405c0445416a0c1cfe517a3efd8ed8c630ce7c7 Mon Sep 17 00:00:00 2001 From: zvlb Date: Thu, 11 May 2023 15:02:22 +0300 Subject: [PATCH 1/4] Aff logic for get gitlab groups permissions Signed-off-by: zvlb --- connector/gitlab/gitlab.go | 82 +++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/connector/gitlab/gitlab.go b/connector/gitlab/gitlab.go index 099cd2ef17..492c59e28e 100644 --- a/connector/gitlab/gitlab.go +++ b/connector/gitlab/gitlab.go @@ -28,12 +28,13 @@ const ( // Config holds configuration options for gitlab logins. type Config struct { - BaseURL string `json:"baseURL"` - ClientID string `json:"clientID"` - ClientSecret string `json:"clientSecret"` - RedirectURI string `json:"redirectURI"` - Groups []string `json:"groups"` - UseLoginAsID bool `json:"useLoginAsID"` + BaseURL string `json:"baseURL"` + ClientID string `json:"clientID"` + ClientSecret string `json:"clientSecret"` + RedirectURI string `json:"redirectURI"` + Groups []string `json:"groups"` + UseLoginAsID bool `json:"useLoginAsID"` + GetGroupsPermission bool `json:"getGroupsPermission"` } type gitlabUser struct { @@ -51,13 +52,14 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) c.BaseURL = "https://gitlab.com" } return &gitlabConnector{ - baseURL: c.BaseURL, - redirectURI: c.RedirectURI, - clientID: c.ClientID, - clientSecret: c.ClientSecret, - logger: logger, - groups: c.Groups, - useLoginAsID: c.UseLoginAsID, + baseURL: c.BaseURL, + redirectURI: c.RedirectURI, + clientID: c.ClientID, + clientSecret: c.ClientSecret, + logger: logger, + groups: c.Groups, + useLoginAsID: c.UseLoginAsID, + getGroupsPermission: c.GetGroupsPermission, }, nil } @@ -82,6 +84,8 @@ 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 + + getGroupsPermission bool } func (c *gitlabConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config { @@ -256,7 +260,10 @@ func (c *gitlabConnector) user(ctx context.Context, client *http.Client) (gitlab } type userInfo struct { - Groups []string + Groups []string `json:"groups"` + OwnerPermission []string `json:"https://gitlab.org/claims/groups/owner"` + MaintainerPermission []string `json:"https://gitlab.org/claims/groups/maintainer"` + DeveloperPermission []string `json:"https://gitlab.org/claims/groups/developer"` } // userGroups queries the GitLab API for group membership. @@ -287,9 +294,56 @@ func (c *gitlabConnector) userGroups(ctx context.Context, client *http.Client) ( return nil, fmt.Errorf("failed to decode response: %v", err) } + if c.getGroupsPermission { + groups := c.setGroupsPermission(u) + return groups, nil + } + return u.Groups, nil } +func (c *gitlabConnector) setGroupsPermission(u userInfo) []string { + groups := u.Groups + +L1: + for _, g := range groups { + if len(u.OwnerPermission) > 0 { + for _, op := range u.OwnerPermission { + if len(g) >= len(op) { + if g[0:len(op)] == op { + groups = append(groups, fmt.Sprintf("%s:owner", g)) + continue L1 + } + } + } + } + + if len(u.MaintainerPermission) > 0 { + for _, mp := range u.MaintainerPermission { + if len(g) >= len(mp) { + if g[0:len(mp)] == mp { + groups = append(groups, fmt.Sprintf("%s:maintainer", g)) + continue L1 + } + } + } + } + + if len(u.DeveloperPermission) > 0 { + for _, dp := range u.DeveloperPermission { + if len(g) >= len(dp) { + if g[0:len(dp)] == dp { + groups = append(groups, fmt.Sprintf("%s:developer", g)) + continue L1 + } + } + } + } + } + + return groups +} + func (c *gitlabConnector) getGroups(ctx context.Context, client *http.Client, groupScope bool, userLogin string) ([]string, error) { gitlabGroups, err := c.userGroups(ctx, client) if err != nil { From 8b9e673147b87bb61707acb6833581bd41b5f37a Mon Sep 17 00:00:00 2001 From: zvlb Date: Thu, 1 Jun 2023 17:25:32 +0300 Subject: [PATCH 2/4] Add describe to getGroupsPermission & fix setGroupsPermission loop Signed-off-by: zvlb --- connector/gitlab/gitlab.go | 49 ++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/connector/gitlab/gitlab.go b/connector/gitlab/gitlab.go index 492c59e28e..580506bb40 100644 --- a/connector/gitlab/gitlab.go +++ b/connector/gitlab/gitlab.go @@ -85,6 +85,7 @@ type gitlabConnector struct { // if set to true will use the user's handle rather than their numeric id as the ID useLoginAsID bool + // if set to true permissions will be added to list of groups getGroupsPermission bool } @@ -307,35 +308,41 @@ func (c *gitlabConnector) setGroupsPermission(u userInfo) []string { L1: for _, g := range groups { - if len(u.OwnerPermission) > 0 { - for _, op := range u.OwnerPermission { - if len(g) >= len(op) { - if g[0:len(op)] == op { - groups = append(groups, fmt.Sprintf("%s:owner", g)) - continue L1 - } + for _, op := range u.OwnerPermission { + if g == op { + groups = append(groups, fmt.Sprintf("%s:owner", g)) + continue L1 + } + if len(g) > len(op) { + if g[0:len(op)] == op && string(g[len(op)]) == "/" { + groups = append(groups, fmt.Sprintf("%s:owner", g)) + continue L1 } } } - if len(u.MaintainerPermission) > 0 { - for _, mp := range u.MaintainerPermission { - if len(g) >= len(mp) { - if g[0:len(mp)] == mp { - groups = append(groups, fmt.Sprintf("%s:maintainer", g)) - continue L1 - } + for _, mp := range u.MaintainerPermission { + if g == mp { + groups = append(groups, fmt.Sprintf("%s:maintainer", g)) + continue L1 + } + if len(g) > len(mp) { + if g[0:len(mp)] == mp && string(g[len(mp)]) == "/" { + groups = append(groups, fmt.Sprintf("%s:maintainer", g)) + continue L1 } } } - if len(u.DeveloperPermission) > 0 { - for _, dp := range u.DeveloperPermission { - if len(g) >= len(dp) { - if g[0:len(dp)] == dp { - groups = append(groups, fmt.Sprintf("%s:developer", g)) - continue L1 - } + for _, dp := range u.DeveloperPermission { + if g == dp { + groups = append(groups, fmt.Sprintf("%s:developer", g)) + continue L1 + } + if len(g) > len(dp) { + if g[0:len(dp)] == dp && string(g[len(dp)]) == "/" { + groups = append(groups, fmt.Sprintf("%s:developer", g)) + continue L1 } } } From 8c71cde1335db6c9fe980b798b4fd9759b54c02f Mon Sep 17 00:00:00 2001 From: zvlb Date: Tue, 6 Jun 2023 13:43:49 +0300 Subject: [PATCH 3/4] Add test for group with permission for gitlab connector Signed-off-by: zvlb --- connector/gitlab/gitlab_test.go | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/connector/gitlab/gitlab_test.go b/connector/gitlab/gitlab_test.go index d828b8bd16..b67b30c045 100644 --- a/connector/gitlab/gitlab_test.go +++ b/connector/gitlab/gitlab_test.go @@ -249,6 +249,47 @@ func TestRefreshWithEmptyConnectorData(t *testing.T) { expectEquals(t, emptyIdentity, identity) } +func TestGroupsWithPermission(t *testing.T) { + s := newTestServer(map[string]interface{}{ + "/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", + }, + "/oauth/userinfo": userInfo{ + Groups: []string{"ops", "dev", "ops-test", "ops/project", "dev/project1", "dev/project2"}, + OwnerPermission: []string{"ops"}, + DeveloperPermission: []string{"dev"}, + MaintainerPermission: []string{"dev/project1"}, + }, + }) + 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(), getGroupsPermission: true} + identity, err := c.HandleCallback(connector.Scopes{Groups: true}, req) + expectNil(t, err) + + expectEquals(t, identity.Groups, []string{ + "ops", + "dev", + "ops-test", + "ops/project", + "dev/project1", + "dev/project2", + "ops:owner", + "dev:developer", + "ops/project:owner", + "dev/project1:maintainer", + "dev/project2:developer", + }) +} + func newTestServer(responses map[string]interface{}) *httptest.Server { return httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { response := responses[r.RequestURI] From 3e951216537c736aaa3fb766f6bddb124f4800d7 Mon Sep 17 00:00:00 2001 From: Maksim Nabokikh Date: Thu, 24 Oct 2024 12:10:06 +0200 Subject: [PATCH 4/4] Fix formatting Signed-off-by: Maksim Nabokikh --- connector/gitlab/gitlab.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/connector/gitlab/gitlab.go b/connector/gitlab/gitlab.go index 5393b005da..7aa4439842 100644 --- a/connector/gitlab/gitlab.go +++ b/connector/gitlab/gitlab.go @@ -52,13 +52,13 @@ func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, erro c.BaseURL = "https://gitlab.com" } return &gitlabConnector{ - baseURL: c.BaseURL, - redirectURI: c.RedirectURI, - clientID: c.ClientID, - clientSecret: c.ClientSecret, - logger: logger.With(slog.Group("connector", "type", "gitlab", "id", id)), - groups: c.Groups, - useLoginAsID: c.UseLoginAsID, + baseURL: c.BaseURL, + redirectURI: c.RedirectURI, + clientID: c.ClientID, + clientSecret: c.ClientSecret, + logger: logger.With(slog.Group("connector", "type", "gitlab", "id", id)), + groups: c.Groups, + useLoginAsID: c.UseLoginAsID, getGroupsPermission: c.GetGroupsPermission, }, nil }