1
0
forked from baron/baron-sso

feat(backend): auto-sync user group keto relation based on department in user update

This commit is contained in:
2026-03-31 13:50:23 +09:00
parent 5029b8049b
commit bc73b85909

View File

@@ -1042,9 +1042,11 @@ func (h *UserHandler) UpdateUser(c *fiber.Ctx) error {
// Capture current local state for transition comparison
var oldRole string
var oldTenantID string
var oldDepartment string
if h.UserRepo != nil {
if local, err := h.UserRepo.FindByID(c.Context(), userID); err == nil && local != nil {
oldRole = local.Role
oldDepartment = local.Department
if local.TenantID != nil {
oldTenantID = *local.TenantID
}
@@ -1237,8 +1239,50 @@ func (h *UserHandler) UpdateUser(c *fiber.Ctx) error {
}
// [Keto Sync] asynchronously as it's less critical for immediate UI count
go h.syncKetoRole(context.Background(), updatedLocalUser.ID,
extractTraitString(updated.Traits, "grade"), oldRole, oldTenantID, updatedLocalUser.TenantID)
go func() {
bgCtx := context.Background()
h.syncKetoRole(bgCtx, updatedLocalUser.ID,
extractTraitString(updated.Traits, "grade"), oldRole, oldTenantID, updatedLocalUser.TenantID)
// Try to automatically sync UserGroup membership based on Department
if h.UserGroupRepo != nil && h.KetoOutboxRepo != nil {
// 1. Remove from old group if department or tenant changed
if oldTenantID != "" && oldDepartment != "" && (oldTenantID != extractTraitString(updated.Traits, "tenant_id") || oldDepartment != updatedLocalUser.Department) {
if oldGroups, err := h.UserGroupRepo.ListByTenantID(bgCtx, oldTenantID); err == nil {
for _, g := range oldGroups {
if strings.EqualFold(g.Name, oldDepartment) {
_ = h.KetoOutboxRepo.Create(bgCtx, &domain.KetoOutbox{
Namespace: "Tenant",
Object: g.ID,
Relation: "members",
Subject: "User:" + updatedLocalUser.ID,
Action: domain.KetoOutboxActionDelete,
})
break
}
}
}
}
// 2. Add to new group
if updatedLocalUser.TenantID != nil && updatedLocalUser.Department != "" {
if groups, err := h.UserGroupRepo.ListByTenantID(bgCtx, *updatedLocalUser.TenantID); err == nil {
for _, g := range groups {
if strings.EqualFold(g.Name, updatedLocalUser.Department) {
_ = h.KetoOutboxRepo.Create(bgCtx, &domain.KetoOutbox{
Namespace: "Tenant",
Object: g.ID,
Relation: "members",
Subject: "User:" + updatedLocalUser.ID,
Action: domain.KetoOutboxActionCreate,
})
break
}
}
}
}
}
}()
}
if req.Password != nil && *req.Password != "" {