1
0
forked from baron/baron-sso

orgfront refresh token 관리 추가

This commit is contained in:
2026-06-18 08:00:57 +09:00
parent 5f3167a503
commit 33249eb229
32 changed files with 867 additions and 337 deletions

View File

@@ -3559,6 +3559,7 @@ func (h *UserHandler) mapIdentitySummary(ctx context.Context, identity service.K
}
summary.Tenant = tenantSummary
markBootstrapSuperAdminSummary(&summary)
return summary
}
@@ -3587,7 +3588,7 @@ func (h *UserHandler) mapLocalUserSummary(ctx context.Context, user domain.User)
Grade: tenantBoundGradeFromUser(user),
Position: user.Position,
JobTitle: user.JobTitle,
Metadata: user.Metadata,
Metadata: maps.Clone(user.Metadata),
Tenant: user.Tenant,
CreatedAt: formatTime(user.CreatedAt),
UpdatedAt: formatTime(user.UpdatedAt),
@@ -3599,9 +3600,29 @@ func (h *UserHandler) mapLocalUserSummary(ctx context.Context, user domain.User)
}
}
markBootstrapSuperAdminSummary(&summary)
return summary
}
func markBootstrapSuperAdminSummary(summary *userSummary) {
if summary == nil || !isBootstrapSuperAdminEmail(summary.Email) {
return
}
if summary.Metadata == nil {
summary.Metadata = make(domain.JSONMap)
}
summary.Metadata["bootstrapSuperAdmin"] = true
}
func isBootstrapSuperAdminEmail(email string) bool {
adminEmail := strings.ToLower(strings.TrimSpace(os.Getenv("ADMIN_EMAIL")))
if adminEmail == "" {
return false
}
return strings.ToLower(strings.TrimSpace(email)) == adminEmail
}
func (h *UserHandler) normalizePhoneNumber(phone string) string {
return normalizePhoneNumber(phone)
}

View File

@@ -1260,6 +1260,51 @@ func TestUserHandler_ListUsersUsesIdentityMirrorAndDoesNotUseUserRepo(t *testing
mockKratos.AssertNotCalled(t, "ListIdentities", mock.Anything)
}
func TestUserHandler_ListUsersMarksBootstrapSuperAdmin(t *testing.T) {
t.Setenv("ADMIN_EMAIL", "bootstrap@example.com")
app := fiber.New()
mockKratos := new(MockKratosAdmin)
createdAt := time.Date(2026, 6, 17, 12, 0, 0, 0, time.UTC)
h := &UserHandler{KratosAdmin: mockKratos}
app.Use(func(c *fiber.Ctx) error {
c.Locals("user_profile", &domain.UserProfileResponse{
Role: domain.RoleSuperAdmin,
})
return c.Next()
})
app.Get("/users", h.ListUsers)
mockKratos.On("ListIdentities", mock.Anything).Return([]service.KratosIdentity{
{
ID: "bootstrap-admin",
State: "active",
CreatedAt: createdAt,
UpdatedAt: createdAt,
Traits: map[string]any{
"email": "bootstrap@example.com",
"name": "Bootstrap Admin",
"role": domain.RoleSuperAdmin,
},
},
}, nil).Once()
req := httptest.NewRequest("GET", "/users?limit=10&offset=0", nil)
resp, err := app.Test(req)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
var res userListResponse
require.NoError(t, json.NewDecoder(resp.Body).Decode(&res))
require.Len(t, res.Items, 1)
require.Equal(t, "bootstrap-admin", res.Items[0].ID)
require.Equal(t, true, res.Items[0].Metadata["bootstrapSuperAdmin"])
mockKratos.AssertExpectations(t)
}
func TestUserHandler_ListUsersPassesQueryToIdentityMirrorPageInsteadOfLoadingFullMirror(t *testing.T) {
app := fiber.New()
createdAt := time.Date(2026, 6, 17, 8, 50, 0, 0, time.UTC)