From 074c3e30d1fe5144369862d0b12caf90c08fadb2 Mon Sep 17 00:00:00 2001 From: chan Date: Thu, 7 May 2026 18:05:24 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A9=80=ED=8B=B0=20=ED=85=8C=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=A9=A4=EB=B2=84=20=EC=A7=91=EA=B3=84=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/check_aaa2.go | 35 +++++++++++++ backend/go.mod | 5 +- backend/go.sum | 8 --- backend/internal/handler/user_handler.go | 65 +++++++++++++++++++++--- 4 files changed, 95 insertions(+), 18 deletions(-) create mode 100644 backend/check_aaa2.go diff --git a/backend/check_aaa2.go b/backend/check_aaa2.go new file mode 100644 index 00000000..29a5df6c --- /dev/null +++ b/backend/check_aaa2.go @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + "gorm.io/driver/postgres" + "gorm.io/gorm" + "log" +) + +type User struct { + ID string + Email string + Name string + CompanyCode string + Status string +} + +func main() { + dsn := "host=localhost user=baron password=password dbname=baron_sso port=5432 sslmode=disable TimeZone=Asia/Seoul" + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + if err != nil { + log.Fatal(err) + } + + var users []User + err = db.Raw("SELECT id, email, name, company_code, status FROM users WHERE company_code = 'aaa2' OR 'aaa2' = ANY(company_codes)").Scan(&users).Error + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Total users for aaa2: %d\n", len(users)) + for _, u := range users { + fmt.Printf("- %s (%s) | status: %s | primary: %s\n", u.Name, u.Email, u.Status, u.CompanyCode) + } +} diff --git a/backend/go.mod b/backend/go.mod index cb9b8736..e25ff780 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,6 +1,6 @@ module baron-sso-backend -go 1.26.2 +go 1.24.0 require ( github.com/ClickHouse/clickhouse-go/v2 v2.42.0 @@ -90,15 +90,12 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/richardlehane/mscfb v1.0.6 // indirect - github.com/richardlehane/msoleps v1.0.6 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/segmentio/asm v1.2.1 // indirect github.com/shirou/gopsutil/v4 v4.25.6 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/tiendc/go-deepcopy v1.7.2 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect diff --git a/backend/go.sum b/backend/go.sum index b75f78d3..5f118676 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -191,10 +191,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/richardlehane/mscfb v1.0.6 h1:eN3bvvZCp00bs7Zf52bxNwAx5lJDBK1tCuH19qq5aC8= -github.com/richardlehane/mscfb v1.0.6/go.mod h1:pe0+IUIc0AHh0+teNzBlJCtSyZdFOGgV4ZK9bsoV+Jo= -github.com/richardlehane/msoleps v1.0.6 h1:9BvkpjvD+iUBalUY4esMwv6uBkfOip/Lzvd93jvR9gg= -github.com/richardlehane/msoleps v1.0.6/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -220,8 +216,6 @@ github.com/testcontainers/testcontainers-go v0.40.0/go.mod h1:FSXV5KQtX2HAMlm7U3 github.com/testcontainers/testcontainers-go/modules/postgres v0.40.0 h1:s2bIayFXlbDFexo96y+htn7FzuhpXLYJNnIuglNKqOk= github.com/testcontainers/testcontainers-go/modules/postgres v0.40.0/go.mod h1:h+u/2KoREGTnTl9UwrQ/g+XhasAT8E6dClclAADeXoQ= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tiendc/go-deepcopy v1.7.2 h1:Ut2yYR7W9tWjTQitganoIue4UGxZwCcJy3orjrrIj44= -github.com/tiendc/go-deepcopy v1.7.2/go.mod h1:4bKjNC2r7boYOkD2IOuZpYjmlDdzjbpTRyCx+goBCJQ= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= @@ -269,8 +263,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ= -golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= diff --git a/backend/internal/handler/user_handler.go b/backend/internal/handler/user_handler.go index 587e4cf0..8e841a6d 100644 --- a/backend/internal/handler/user_handler.go +++ b/backend/internal/handler/user_handler.go @@ -276,24 +276,56 @@ func (h *UserHandler) ListUsers(c *fiber.Ctx) error { name := strings.ToLower(extractTraitString(identity.Traits, "name")) compCode := strings.ToLower(extractTraitString(identity.Traits, "companyCode")) tID := strings.ToLower(extractTraitString(identity.Traits, "tenant_id")) + secondaryCodes := extractTraitStringArray(identity.Traits, "companyCodes") // Tenant Admin & Member filtering if requesterRole == domain.RoleTenantAdmin || requesterRole == domain.RoleUser || requesterRole == domain.RoleRPAdmin { - if !manageableSlugs[compCode] && !manageableSlugs[tID] { + hasAccess := manageableSlugs[compCode] || manageableSlugs[tID] + if !hasAccess && len(secondaryCodes) > 0 { + for _, code := range secondaryCodes { + if manageableSlugs[strings.ToLower(code)] { + hasAccess = true + break + } + } + } + if !hasAccess { continue } } // Dedicated tenantSlug filter - if tenantSlug != "" && !strings.EqualFold(compCode, tenantSlug) && tID != targetTenantID { - continue + if tenantSlug != "" { + matches := strings.EqualFold(compCode, tenantSlug) || tID == targetTenantID + if !matches && len(secondaryCodes) > 0 { + for _, code := range secondaryCodes { + if strings.EqualFold(code, tenantSlug) { + matches = true + break + } + } + } + if !matches { + continue + } } // Search filtering (Keyword search in email, name, or companyCode) if search != "" { - if !strings.Contains(email, searchLower) && - !strings.Contains(name, searchLower) && - !strings.Contains(strings.ToLower(compCode), searchLower) { + matchesSearch := strings.Contains(email, searchLower) || + strings.Contains(name, searchLower) || + strings.Contains(strings.ToLower(compCode), searchLower) + + if !matchesSearch && len(secondaryCodes) > 0 { + for _, code := range secondaryCodes { + if strings.Contains(strings.ToLower(code), searchLower) { + matchesSearch = true + break + } + } + } + + if !matchesSearch { continue } } @@ -2155,6 +2187,27 @@ func extractTraitString(traits map[string]interface{}, key string) string { return "" } +func extractTraitStringArray(traits map[string]interface{}, key string) []string { + if traits == nil { + return nil + } + if raw, ok := traits[key]; ok { + if slice, ok := raw.([]interface{}); ok { + var result []string + for _, v := range slice { + if s, ok := v.(string); ok { + result = append(result, s) + } + } + return result + } + if slice, ok := raw.([]string); ok { + return slice + } + } + return nil +} + func resolvePasswordLoginID(traits map[string]interface{}) string { // First check custom_login_ids (array) if raw, ok := traits["custom_login_ids"]; ok {