diff --git a/api/bolt/team/team.go b/api/bolt/team/team.go index e88e6a3f8..a503e8285 100644 --- a/api/bolt/team/team.go +++ b/api/bolt/team/team.go @@ -1,7 +1,9 @@ package team import ( - "github.com/portainer/portainer/api" + "strings" + + portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/bolt/errors" "github.com/portainer/portainer/api/bolt/internal" @@ -58,7 +60,7 @@ func (service *Service) TeamByName(name string) (*portainer.Team, error) { return err } - if t.Name == name { + if strings.EqualFold(t.Name, name) { team = &t break } diff --git a/api/bolt/user/user.go b/api/bolt/user/user.go index b74e0b524..de628e8d4 100644 --- a/api/bolt/user/user.go +++ b/api/bolt/user/user.go @@ -1,10 +1,11 @@ package user import ( - "github.com/portainer/portainer/api" + "strings" + + portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/bolt/errors" "github.com/portainer/portainer/api/bolt/internal" - "strings" "github.com/boltdb/bolt" ) @@ -61,7 +62,7 @@ func (service *Service) UserByUsername(username string) (*portainer.User, error) return err } - if strings.ToLower(u.Username) == username { + if strings.EqualFold(u.Username, username) { user = &u break } diff --git a/api/http/proxy/factory/docker/access_control.go b/api/http/proxy/factory/docker/access_control.go index 385a3c10b..7f1cb4157 100644 --- a/api/http/proxy/factory/docker/access_control.go +++ b/api/http/proxy/factory/docker/access_control.go @@ -31,6 +31,23 @@ type ( } ) +func getUniqueElements(items string) []string { + result := []string{} + seen := make(map[string]struct{}) + for _, item := range strings.Split(items, ",") { + v := strings.TrimSpace(item) + if v == "" { + continue + } + if _, ok := seen[v]; !ok { + result = append(result, v) + seen[v] = struct{}{} + } + } + + return result +} + func (transport *Transport) newResourceControlFromPortainerLabels(labelsObject map[string]interface{}, resourceID string, resourceType portainer.ResourceControlType) (*portainer.ResourceControl, error) { if labelsObject[resourceLabelForPortainerPublicResourceControl] != nil { resourceControl := authorization.NewPublicResourceControl(resourceID, resourceType) @@ -47,12 +64,12 @@ func (transport *Transport) newResourceControlFromPortainerLabels(labelsObject m userNames := make([]string, 0) if labelsObject[resourceLabelForPortainerTeamResourceControl] != nil { concatenatedTeamNames := labelsObject[resourceLabelForPortainerTeamResourceControl].(string) - teamNames = strings.Split(concatenatedTeamNames, ",") + teamNames = getUniqueElements(concatenatedTeamNames) } if labelsObject[resourceLabelForPortainerUserResourceControl] != nil { concatenatedUserNames := labelsObject[resourceLabelForPortainerUserResourceControl].(string) - userNames = strings.Split(concatenatedUserNames, ",") + userNames = getUniqueElements(concatenatedUserNames) } if len(teamNames) > 0 || len(userNames) > 0 { diff --git a/api/http/proxy/factory/docker/access_control_test.go b/api/http/proxy/factory/docker/access_control_test.go new file mode 100644 index 000000000..7fe0de46d --- /dev/null +++ b/api/http/proxy/factory/docker/access_control_test.go @@ -0,0 +1,63 @@ +package docker + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_getUniqueElements(t *testing.T) { + cases := []struct { + description string + input string + expected []string + }{ + { + description: "no items padded", + input: " ", + expected: []string{}, + }, + { + description: "single item", + input: "a", + expected: []string{"a"}, + }, + { + description: "single item padded", + input: " a ", + expected: []string{"a"}, + }, + { + description: "multiple items", + input: "a,b", + expected: []string{"a", "b"}, + }, + { + description: "multiple items padded", + input: " a , b ", + expected: []string{"a", "b"}, + }, + { + description: "multiple items with empty values", + input: " a , ,b ", + expected: []string{"a", "b"}, + }, + { + description: "duplicates", + input: " a , a ", + expected: []string{"a"}, + }, + { + description: "mix with duplicates", + input: " a ,b, a ", + expected: []string{"a", "b"}, + }, + } + + for _, tt := range cases { + t.Run(tt.description, func(t *testing.T) { + result := getUniqueElements(tt.input) + assert.ElementsMatch(t, result, tt.expected) + }) + } +}