forked from baron/baron-sso
feat: allow regular users to view their own tenant's org chart
Changes the /users endpoint to allow RoleUser access and securely restricts the returned data to only users within their affiliated tenants. Removes the unnecessary back button from the Org Chart view since it's now a top-level nav item.
This commit is contained in:
@@ -100,13 +100,17 @@ func (h *UserHandler) ListUsers(c *fiber.Ctx) error {
|
||||
|
||||
// [New] Manageable Tenants Map for efficient lookup
|
||||
manageableSlugs := make(map[string]bool)
|
||||
if requesterRole == domain.RoleTenantAdmin {
|
||||
if requesterRole == domain.RoleTenantAdmin || requesterRole == domain.RoleUser || requesterRole == domain.RoleRPAdmin {
|
||||
profile, _ := c.Locals("user_profile").(*domain.UserProfileResponse)
|
||||
if profile != nil {
|
||||
for _, t := range profile.ManageableTenants {
|
||||
manageableSlugs[strings.ToLower(t.Slug)] = true
|
||||
manageableSlugs[strings.ToLower(t.ID)] = true // Add ID as well
|
||||
}
|
||||
for _, t := range profile.JoinedTenants {
|
||||
manageableSlugs[strings.ToLower(t.Slug)] = true
|
||||
manageableSlugs[strings.ToLower(t.ID)] = true
|
||||
}
|
||||
// Include primary tenant slug if not already there
|
||||
if profile.CompanyCode != "" {
|
||||
manageableSlugs[strings.ToLower(profile.CompanyCode)] = true
|
||||
@@ -137,8 +141,8 @@ func (h *UserHandler) ListUsers(c *fiber.Ctx) error {
|
||||
compCode := strings.ToLower(extractTraitString(identity.Traits, "companyCode"))
|
||||
tID := strings.ToLower(extractTraitString(identity.Traits, "tenant_id"))
|
||||
|
||||
// Tenant Admin filtering
|
||||
if requesterRole == domain.RoleTenantAdmin {
|
||||
// Tenant Admin & Member filtering
|
||||
if requesterRole == domain.RoleTenantAdmin || requesterRole == domain.RoleUser || requesterRole == domain.RoleRPAdmin {
|
||||
if !manageableSlugs[compCode] && !manageableSlugs[tID] {
|
||||
continue
|
||||
}
|
||||
@@ -194,6 +198,15 @@ func (h *UserHandler) ListUsers(c *fiber.Ctx) error {
|
||||
// 2. Fallback to Local DB if Kratos is down
|
||||
slog.Warn("Kratos unavailable, falling back to local DB for user list", "error", err)
|
||||
|
||||
// If requester is not Super Admin, we should technically filter by manageable slugs in DB too.
|
||||
// For simplicity in fallback, if tenantSlug is empty we default to their primary company code.
|
||||
if (requesterRole == domain.RoleTenantAdmin || requesterRole == domain.RoleUser || requesterRole == domain.RoleRPAdmin) && tenantSlug == "" {
|
||||
profile, _ := c.Locals("user_profile").(*domain.UserProfileResponse)
|
||||
if profile != nil && profile.CompanyCode != "" {
|
||||
tenantSlug = profile.CompanyCode
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch from UserRepo
|
||||
users, total, err := h.UserRepo.List(c.Context(), offset, limit, search, tenantSlug)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user