1
0
forked from baron/baron-sso

feat(user): support fixed UUID registration and enhance bulk import results

- Added support for fixed UUIDs during bulk registration (Search-first + ExternalID mapping)
- Implemented idempotency and visibility restoration for soft-deleted users
- Enhanced bulk upload UI to show 'New/Updated/Unchanged' status and modified fields
- Added logic to reclaim identifiers (login_id) from colliding records
- Added frontend E2E and backend unit tests for UUID integrity and conflict handling
- Fixed i18n, formatting, and mock tests to satisfy code-check
- Applied 'go fix' for 'omitzero' tags and general Go standards
This commit is contained in:
2026-06-01 15:34:08 +09:00
parent 4a1e89e421
commit 31d107ff2e
85 changed files with 2104 additions and 1149 deletions

View File

@@ -88,7 +88,7 @@ func (m *devMockKratosAdmin) GetIdentity(ctx context.Context, identityID string)
return nil, args.Error(1)
}
func (m *devMockKratosAdmin) UpdateIdentity(ctx context.Context, identityID string, traits map[string]interface{}, state string) (*service.KratosIdentity, error) {
func (m *devMockKratosAdmin) UpdateIdentity(ctx context.Context, identityID string, traits map[string]any, state string) (*service.KratosIdentity, error) {
args := m.Called(ctx, identityID, traits, state)
if identity, ok := args.Get(0).(*service.KratosIdentity); ok {
return identity, args.Error(1)
@@ -292,9 +292,9 @@ func TestGetCurrentProfile_PreservesExistingAuditUserContext(t *testing.T) {
func TestListClients_Success(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.URL.Path == "/clients" {
return httpJSONAny(r, http.StatusOK, []map[string]interface{}{
{"client_id": "client-1", "client_name": "App One", "metadata": map[string]interface{}{"status": "active"}},
{"client_id": "client-2", "client_name": "App Two", "metadata": map[string]interface{}{"status": "inactive"}},
return httpJSONAny(r, http.StatusOK, []map[string]any{
{"client_id": "client-1", "client_name": "App One", "metadata": map[string]any{"status": "active"}},
{"client_id": "client-2", "client_name": "App Two", "metadata": map[string]any{"status": "inactive"}},
}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
@@ -326,9 +326,9 @@ func TestListClients_Success(t *testing.T) {
func TestListClients_UserSeesOnlyClientsAllowedByReBAC(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.URL.Path == "/clients" {
return httpJSONAny(r, http.StatusOK, []map[string]interface{}{
{"client_id": "client-denied", "client_name": "Denied App", "metadata": map[string]interface{}{"tenant_id": "tenant-a", "status": "active"}},
{"client_id": "client-allowed", "client_name": "Allowed App", "metadata": map[string]interface{}{"tenant_id": "tenant-b", "status": "active"}},
return httpJSONAny(r, http.StatusOK, []map[string]any{
{"client_id": "client-denied", "client_name": "Denied App", "metadata": map[string]any{"tenant_id": "tenant-a", "status": "active"}},
{"client_id": "client-allowed", "client_name": "Allowed App", "metadata": map[string]any{"tenant_id": "tenant-b", "status": "active"}},
}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
@@ -796,9 +796,9 @@ func TestUpdateClient_AuditDetailsIncludeGeneralSettingChanges(t *testing.T) {
func TestListClients_ProtectedSystemClientHidden(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.URL.Path == "/clients" {
return httpJSONAny(r, http.StatusOK, []map[string]interface{}{
return httpJSONAny(r, http.StatusOK, []map[string]any{
{"client_id": "oathkeeper-introspect", "client_name": "Internal Client"},
{"client_id": "client-1", "client_name": "App One", "metadata": map[string]interface{}{"status": "active"}},
{"client_id": "client-1", "client_name": "App One", "metadata": map[string]any{"status": "active"}},
}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
@@ -834,12 +834,12 @@ func TestListClients_ProtectedSystemClientHidden(t *testing.T) {
func TestListClients_ReservedSystemNameAliasHidden(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.URL.Path == "/clients" {
return httpJSONAny(r, http.StatusOK, []map[string]interface{}{
{"client_id": "adminfront", "client_name": "AdminFront", "metadata": map[string]interface{}{"status": "active"}},
{"client_id": "4f2c9fd6-1111-2222-3333-444444444444", "client_name": "AdminFront", "metadata": map[string]interface{}{"status": "active"}},
{"client_id": "devfront", "client_name": "DevFront", "metadata": map[string]interface{}{"status": "active"}},
{"client_id": "7d2c9fd6-1111-2222-3333-444444444444", "client_name": "DevFront", "metadata": map[string]interface{}{"status": "active"}},
{"client_id": "client-1", "client_name": "App One", "metadata": map[string]interface{}{"status": "active"}},
return httpJSONAny(r, http.StatusOK, []map[string]any{
{"client_id": "adminfront", "client_name": "AdminFront", "metadata": map[string]any{"status": "active"}},
{"client_id": "4f2c9fd6-1111-2222-3333-444444444444", "client_name": "AdminFront", "metadata": map[string]any{"status": "active"}},
{"client_id": "devfront", "client_name": "DevFront", "metadata": map[string]any{"status": "active"}},
{"client_id": "7d2c9fd6-1111-2222-3333-444444444444", "client_name": "DevFront", "metadata": map[string]any{"status": "active"}},
{"client_id": "client-1", "client_name": "App One", "metadata": map[string]any{"status": "active"}},
}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
@@ -878,10 +878,10 @@ func TestListClients_ReservedSystemNameAliasHidden(t *testing.T) {
func TestGetClient_ReservedSystemNameAliasHidden(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.URL.Path == "/clients/4f2c9fd6-1111-2222-3333-444444444444" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "4f2c9fd6-1111-2222-3333-444444444444",
"client_name": "AdminFront",
"metadata": map[string]interface{}{"status": "active"},
"metadata": map[string]any{"status": "active"},
}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
@@ -910,13 +910,13 @@ func TestGetClient_ReservedSystemNameAliasHidden(t *testing.T) {
func TestUpdateClientStatus_Success(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
"client_id": "client-1", "metadata": map[string]interface{}{"status": "active"},
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "client-1", "metadata": map[string]any{"status": "active"},
}), nil
}
if r.Method == http.MethodPatch && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
"client_id": "client-1", "metadata": map[string]interface{}{"status": "inactive"},
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "client-1", "metadata": map[string]any{"status": "inactive"},
}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
@@ -936,7 +936,7 @@ func TestUpdateClientStatus_Success(t *testing.T) {
})
app.Patch("/api/v1/dev/clients/:id/status", h.UpdateClientStatus)
body, _ := json.Marshal(map[string]interface{}{"status": "inactive"})
body, _ := json.Marshal(map[string]any{"status": "inactive"})
req := httptest.NewRequest(http.MethodPatch, "/api/v1/dev/clients/client-1/status", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, _ := app.Test(req, -1)
@@ -950,20 +950,20 @@ func TestUpdateClientStatus_Success(t *testing.T) {
func TestUpdateClientStatus_UserAllowedByStatusPermission(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "client-1",
"client_name": "App One",
"metadata": map[string]interface{}{
"metadata": map[string]any{
"tenant_id": "tenant-1",
"status": "active",
},
}), nil
}
if r.Method == http.MethodPatch && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "client-1",
"client_name": "App One",
"metadata": map[string]interface{}{
"metadata": map[string]any{
"tenant_id": "tenant-1",
"status": "inactive",
},
@@ -995,7 +995,7 @@ func TestUpdateClientStatus_UserAllowedByStatusPermission(t *testing.T) {
})
app.Patch("/api/v1/dev/clients/:id/status", h.UpdateClientStatus)
body, _ := json.Marshal(map[string]interface{}{"status": "inactive"})
body, _ := json.Marshal(map[string]any{"status": "inactive"})
req := httptest.NewRequest(http.MethodPatch, "/api/v1/dev/clients/client-1/status", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, _ := app.Test(req, -1)
@@ -1010,20 +1010,20 @@ func TestUpdateClientStatus_UserAllowedByStatusPermission(t *testing.T) {
func TestUpdateClientStatus_UserAllowedByEditConfigPermission(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "client-1",
"client_name": "App One",
"metadata": map[string]interface{}{
"metadata": map[string]any{
"tenant_id": "tenant-1",
"status": "active",
},
}), nil
}
if r.Method == http.MethodPatch && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "client-1",
"client_name": "App One",
"metadata": map[string]interface{}{
"metadata": map[string]any{
"tenant_id": "tenant-1",
"status": "inactive",
},
@@ -1055,7 +1055,7 @@ func TestUpdateClientStatus_UserAllowedByEditConfigPermission(t *testing.T) {
})
app.Patch("/api/v1/dev/clients/:id/status", h.UpdateClientStatus)
body, _ := json.Marshal(map[string]interface{}{"status": "inactive"})
body, _ := json.Marshal(map[string]any{"status": "inactive"})
req := httptest.NewRequest(http.MethodPatch, "/api/v1/dev/clients/client-1/status", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, _ := app.Test(req, -1)
@@ -1070,7 +1070,7 @@ func TestUpdateClientStatus_UserAllowedByEditConfigPermission(t *testing.T) {
func TestUpdateClientStatus_ProtectedSystemClientForbidden(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/oathkeeper-introspect" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "oathkeeper-introspect",
}), nil
}
@@ -1091,7 +1091,7 @@ func TestUpdateClientStatus_ProtectedSystemClientForbidden(t *testing.T) {
})
app.Patch("/api/v1/dev/clients/:id/status", h.UpdateClientStatus)
body, _ := json.Marshal(map[string]interface{}{"status": "inactive"})
body, _ := json.Marshal(map[string]any{"status": "inactive"})
req := httptest.NewRequest(http.MethodPatch, "/api/v1/dev/clients/oathkeeper-introspect/status", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, _ := app.Test(req, -1)
@@ -1102,7 +1102,7 @@ func TestUpdateClientStatus_ProtectedSystemClientForbidden(t *testing.T) {
func TestDeleteClient_Success(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{"client_id": "client-1"}), nil
return httpJSONAny(r, http.StatusOK, map[string]any{"client_id": "client-1"}), nil
}
if r.Method == http.MethodDelete && r.URL.Path == "/clients/client-1" {
return &http.Response{StatusCode: http.StatusNoContent, Body: http.NoBody}, nil
@@ -1142,7 +1142,7 @@ func TestDeleteClient_Success(t *testing.T) {
func TestDeleteClient_ProtectedSystemClientForbidden(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/oathkeeper-introspect" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{"client_id": "oathkeeper-introspect"}), nil
return httpJSONAny(r, http.StatusOK, map[string]any{"client_id": "oathkeeper-introspect"}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
})
@@ -1172,7 +1172,7 @@ func TestDeleteClient_ProtectedSystemClientForbidden(t *testing.T) {
func TestGetClient_ProtectedSystemClientHidden(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/oathkeeper-introspect" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "oathkeeper-introspect",
"client_name": "Internal Client",
}), nil
@@ -1203,10 +1203,10 @@ func TestGetClient_ProtectedSystemClientHidden(t *testing.T) {
func TestGetClient_RPAdminAllowedByKetoViewPermission(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "client-1",
"client_name": "App One",
"metadata": map[string]interface{}{
"metadata": map[string]any{
"tenant_id": "tenant-b",
"status": "active",
},
@@ -1248,11 +1248,11 @@ func TestGetClient_RPAdminAllowedByKetoViewPermission(t *testing.T) {
func TestGetClient_RedactsSecretWithoutViewSecretPermission(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "client-1",
"client_name": "App One",
"client_secret": "stored-secret",
"metadata": map[string]interface{}{
"metadata": map[string]any{
"tenant_id": "tenant-1",
"status": "active",
},
@@ -1297,11 +1297,11 @@ func TestGetClient_RedactsSecretWithoutViewSecretPermission(t *testing.T) {
func TestGetClient_UserAllowedToViewSecretByPermission(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
return httpJSONAny(r, http.StatusOK, map[string]any{
"client_id": "client-1",
"client_name": "App One",
"client_secret": "stored-secret",
"metadata": map[string]interface{}{
"metadata": map[string]any{
"tenant_id": "tenant-1",
"status": "active",
},
@@ -1346,10 +1346,10 @@ func TestGetClient_UserAllowedToViewSecretByPermission(t *testing.T) {
func TestRotateClientSecret_Success(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodGet && r.URL.Path == "/clients/client-1" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{"client_id": "client-1"}), nil
return httpJSONAny(r, http.StatusOK, map[string]any{"client_id": "client-1"}), nil
}
if r.Method == http.MethodPut && r.URL.Path == "/clients/client-1" {
var body map[string]interface{}
var body map[string]any
json.NewDecoder(r.Body).Decode(&body)
return httpJSONAny(r, http.StatusOK, body), nil
}
@@ -1390,7 +1390,7 @@ func TestRotateClientSecret_Success(t *testing.T) {
func TestCreateClient_RPAdminAllowedByTenantGrantPermission(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodPost && r.URL.Path == "/clients" {
var body map[string]interface{}
var body map[string]any
_ = json.NewDecoder(r.Body).Decode(&body)
body["client_secret"] = "generated-secret"
return httpJSONAny(r, http.StatusCreated, body), nil
@@ -1443,7 +1443,7 @@ func TestCreateClient_RPAdminAllowedByTenantGrantPermission(t *testing.T) {
func TestCreateClient_ApprovedDeveloperCanCreatePrivateClient(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Method == http.MethodPost && r.URL.Path == "/clients" {
var body map[string]interface{}
var body map[string]any
_ = json.NewDecoder(r.Body).Decode(&body)
body["client_secret"] = "generated-secret"
return httpJSONAny(r, http.StatusCreated, body), nil
@@ -1625,11 +1625,11 @@ func TestRevokeDeveloperGrantRelation_DeletesRequiredTenantRelations(t *testing.
func TestGetStats_Success(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.URL.Path == "/clients" {
return httpJSONAny(r, http.StatusOK, []map[string]interface{}{
{"client_id": "c1", "metadata": map[string]interface{}{"tenant_id": "t1"}},
{"client_id": "c2", "metadata": map[string]interface{}{"tenant_id": "t1"}},
{"client_id": "oathkeeper-introspect", "metadata": map[string]interface{}{"tenant_id": "t1"}},
{"client_id": "c3", "metadata": map[string]interface{}{"tenant_id": "t2"}},
return httpJSONAny(r, http.StatusOK, []map[string]any{
{"client_id": "c1", "metadata": map[string]any{"tenant_id": "t1"}},
{"client_id": "c2", "metadata": map[string]any{"tenant_id": "t1"}},
{"client_id": "oathkeeper-introspect", "metadata": map[string]any{"tenant_id": "t1"}},
{"client_id": "c3", "metadata": map[string]any{"tenant_id": "t2"}},
}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
@@ -1693,9 +1693,9 @@ func TestGetStats_UserScopesAuditMetricsToVisibleClients(t *testing.T) {
now := time.Now()
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.URL.Path == "/clients" {
return httpJSONAny(r, http.StatusOK, []map[string]interface{}{
{"client_id": "client-owned", "metadata": map[string]interface{}{"tenant_id": "tenant-a"}},
{"client_id": "client-other", "metadata": map[string]interface{}{"tenant_id": "tenant-a"}},
return httpJSONAny(r, http.StatusOK, []map[string]any{
{"client_id": "client-owned", "metadata": map[string]any{"tenant_id": "tenant-a"}},
{"client_id": "client-other", "metadata": map[string]any{"tenant_id": "tenant-a"}},
}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
@@ -1785,9 +1785,9 @@ func TestGetStats_UserScopesAuditMetricsToVisibleClients(t *testing.T) {
func TestGetRPUsageDaily_UserScopesItemsToVisibleClients(t *testing.T) {
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.URL.Path == "/clients" {
return httpJSONAny(r, http.StatusOK, []map[string]interface{}{
{"client_id": "client-owned", "client_name": "Owned App", "metadata": map[string]interface{}{"tenant_id": "tenant-a"}},
{"client_id": "client-other", "client_name": "Other App", "metadata": map[string]interface{}{"tenant_id": "tenant-a"}},
return httpJSONAny(r, http.StatusOK, []map[string]any{
{"client_id": "client-owned", "client_name": "Owned App", "metadata": map[string]any{"tenant_id": "tenant-a"}},
{"client_id": "client-other", "client_name": "Other App", "metadata": map[string]any{"tenant_id": "tenant-a"}},
}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
@@ -1997,7 +1997,7 @@ func TestCreateClient_DefaultsSkipConsentToTrue(t *testing.T) {
func TestNormalizeClientAutoLoginMetadata(t *testing.T) {
t.Run("keeps supported flag and URL", func(t *testing.T) {
metadata, err := normalizeClientAutoLoginMetadata(map[string]interface{}{
metadata, err := normalizeClientAutoLoginMetadata(map[string]any{
"auto_login_supported": true,
"auto_login_url": "https://rp.example.com/login?auto=1",
})
@@ -2007,14 +2007,14 @@ func TestNormalizeClientAutoLoginMetadata(t *testing.T) {
})
t.Run("requires URL when supported", func(t *testing.T) {
_, err := normalizeClientAutoLoginMetadata(map[string]interface{}{
_, err := normalizeClientAutoLoginMetadata(map[string]any{
"auto_login_supported": true,
})
assert.Error(t, err)
})
t.Run("removes URL when unsupported", func(t *testing.T) {
metadata, err := normalizeClientAutoLoginMetadata(map[string]interface{}{
metadata, err := normalizeClientAutoLoginMetadata(map[string]any{
"auto_login_supported": false,
"auto_login_url": "https://rp.example.com/login?auto=1",
})
@@ -2293,9 +2293,9 @@ func TestCreateClient_NormalizesIDTokenClaimsMetadata(t *testing.T) {
resp, _ := app.Test(req, -1)
assert.Equal(t, http.StatusCreated, resp.StatusCode)
claims, ok := captured.Metadata[domain.MetadataIDTokenClaims].([]interface{})
claims, ok := captured.Metadata[domain.MetadataIDTokenClaims].([]any)
if assert.True(t, ok) && assert.Len(t, claims, 2) {
first, ok := claims[0].(map[string]interface{})
first, ok := claims[0].(map[string]any)
if assert.True(t, ok) {
assert.Equal(t, "top_level", first["namespace"])
assert.Equal(t, "locale", first["key"])
@@ -2305,7 +2305,7 @@ func TestCreateClient_NormalizesIDTokenClaimsMetadata(t *testing.T) {
assert.False(t, hasID)
}
second, ok := claims[1].(map[string]interface{})
second, ok := claims[1].(map[string]any)
if assert.True(t, ok) {
assert.Equal(t, "rp_claims", second["namespace"])
assert.Equal(t, "tier", second["key"])
@@ -2464,7 +2464,7 @@ func TestUpdateClient_AllowsExplicitSkipConsentFalse(t *testing.T) {
Scope: "openid profile",
TokenEndpointAuthMethod: "none",
SkipConsent: &currentSkipConsent,
Metadata: map[string]interface{}{"status": "active"},
Metadata: map[string]any{"status": "active"},
}), nil
}
if r.Method == http.MethodPut && r.URL.Path == "/clients/client-1" {
@@ -2620,7 +2620,7 @@ func TestUpdateClient_RevokesExistingConsentsWhenTenantPolicyChanges(t *testing.
ResponseTypes: []string{"code"},
Scope: "openid tenant profile email",
TokenEndpointAuthMethod: "none",
Metadata: map[string]interface{}{
Metadata: map[string]any{
"tenant_access_restricted": true,
"allowed_tenants": []string{"tenant-a"},
},
@@ -2704,7 +2704,7 @@ func TestUpdateClient_DoesNotRevokeConsentsWhenTenantPolicyUnchanged(t *testing.
ResponseTypes: []string{"code"},
Scope: "openid tenant profile email",
TokenEndpointAuthMethod: "none",
Metadata: map[string]interface{}{
Metadata: map[string]any{
"tenant_access_restricted": true,
"allowed_tenants": []string{"tenant-a"},
},
@@ -2991,9 +2991,9 @@ func TestListAuditLogs_UserAllowedByRPAuditPermission(t *testing.T) {
}
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.URL.Path == "/clients" {
return httpJSONAny(r, http.StatusOK, []map[string]interface{}{
{"client_id": "client-allowed", "client_name": "Allowed App", "metadata": map[string]interface{}{"tenant_id": "tenant-a"}},
{"client_id": "client-denied", "client_name": "Denied App", "metadata": map[string]interface{}{"tenant_id": "tenant-b"}},
return httpJSONAny(r, http.StatusOK, []map[string]any{
{"client_id": "client-allowed", "client_name": "Allowed App", "metadata": map[string]any{"tenant_id": "tenant-a"}},
{"client_id": "client-denied", "client_name": "Denied App", "metadata": map[string]any{"tenant_id": "tenant-b"}},
}), nil
}
return httpJSONAny(r, http.StatusNotFound, nil), nil
@@ -3124,7 +3124,7 @@ func TestListClientRelations_RPAdminAllowedByViewRelationshipsPermission(t *test
mockKratos := new(devMockKratosAdmin)
mockKratos.On("GetIdentity", mock.Anything, "user-2").Return(&service.KratosIdentity{
ID: "user-2",
Traits: map[string]interface{}{
Traits: map[string]any{
"name": "김용연",
"email": "kyy@example.com",
"id": "kyy01",
@@ -3195,7 +3195,7 @@ func TestListClientRelations_DedupesDuplicateRelations(t *testing.T) {
mockKratos := new(devMockKratosAdmin)
mockKratos.On("GetIdentity", mock.Anything, "user-1").Return(&service.KratosIdentity{
ID: "user-1",
Traits: map[string]interface{}{
Traits: map[string]any{
"name": "Tester",
"email": "tester@example.com",
},
@@ -3371,7 +3371,7 @@ func TestSearchUsers_RPAdminSearchByNameOrEmailWithinTenantScope(t *testing.T) {
mockKratos.On("ListIdentities", mock.Anything).Return([]service.KratosIdentity{
{
ID: "user-1",
Traits: map[string]interface{}{
Traits: map[string]any{
"name": "Alice Kim",
"email": "alice@example.com",
"id": "alice01",
@@ -3380,7 +3380,7 @@ func TestSearchUsers_RPAdminSearchByNameOrEmailWithinTenantScope(t *testing.T) {
},
{
ID: "user-2",
Traits: map[string]interface{}{
Traits: map[string]any{
"name": "Bob Lee",
"email": "bob@example.com",
"id": "bob01",
@@ -3451,7 +3451,7 @@ func TestSearchUsers_UserAllowedByRPAdminRelation(t *testing.T) {
mockKratos.On("ListIdentities", mock.Anything).Return([]service.KratosIdentity{
{
ID: "target-user",
Traits: map[string]interface{}{
Traits: map[string]any{
"name": "김용연",
"email": "kyy@example.com",
"id": "kyy01",