1
0
forked from baron/baron-sso

dev API 관계 사용자 검색 및 관계 목록 사용자 정보 추가

This commit is contained in:
2026-04-15 18:23:07 +09:00
parent f494d8e50a
commit f955d23ef1
3 changed files with 282 additions and 5 deletions

View File

@@ -52,6 +52,66 @@ type devMockRedisRepo struct {
data map[string]string
}
type devMockKratosAdmin struct {
mock.Mock
}
func (m *devMockKratosAdmin) ListIdentities(ctx context.Context) ([]service.KratosIdentity, error) {
args := m.Called(ctx)
return args.Get(0).([]service.KratosIdentity), args.Error(1)
}
func (m *devMockKratosAdmin) FindIdentityIDByIdentifier(ctx context.Context, identifier string) (string, error) {
args := m.Called(ctx, identifier)
return args.String(0), args.Error(1)
}
func (m *devMockKratosAdmin) GetIdentity(ctx context.Context, identityID string) (*service.KratosIdentity, error) {
args := m.Called(ctx, identityID)
if identity, ok := args.Get(0).(*service.KratosIdentity); ok {
return identity, args.Error(1)
}
return nil, args.Error(1)
}
func (m *devMockKratosAdmin) UpdateIdentity(ctx context.Context, identityID string, traits map[string]interface{}, 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)
}
return nil, args.Error(1)
}
func (m *devMockKratosAdmin) UpdateIdentityPassword(ctx context.Context, identityID, newPassword string) error {
return m.Called(ctx, identityID, newPassword).Error(0)
}
func (m *devMockKratosAdmin) DeleteIdentity(ctx context.Context, identityID string) error {
return m.Called(ctx, identityID).Error(0)
}
func (m *devMockKratosAdmin) CreateUser(ctx context.Context, user *domain.BrokerUser, password string) (string, error) {
args := m.Called(ctx, user, password)
return args.String(0), args.Error(1)
}
func (m *devMockKratosAdmin) ListIdentitySessions(ctx context.Context, identityID string) ([]service.KratosSession, error) {
args := m.Called(ctx, identityID)
return args.Get(0).([]service.KratosSession), args.Error(1)
}
func (m *devMockKratosAdmin) GetSession(ctx context.Context, sessionID string) (*service.KratosSession, error) {
args := m.Called(ctx, sessionID)
if session, ok := args.Get(0).(*service.KratosSession); ok {
return session, args.Error(1)
}
return nil, args.Error(1)
}
func (m *devMockKratosAdmin) DeleteSession(ctx context.Context, sessionID string) error {
return m.Called(ctx, sessionID).Error(0)
}
type devMockKetoOutboxRepository struct {
mock.Mock
}
@@ -1273,13 +1333,23 @@ func TestListClientRelations_RPAdminAllowedByViewRelationshipsPermission(t *test
for _, relation := range []string{"admins", "creator", "secret_rotator", "jwks_viewer", "jwks_operator", "consent_viewer", "consent_revoker", "relationship_viewer", "status_operator"} {
mockKeto.On("ListRelations", mock.Anything, "RelyingParty", "client-1", relation, "").Return([]service.RelationTuple{}, nil)
}
mockKratos := new(devMockKratosAdmin)
mockKratos.On("GetIdentity", mock.Anything, "user-2").Return(&service.KratosIdentity{
ID: "user-2",
Traits: map[string]interface{}{
"name": "김용연",
"email": "kyy@example.com",
"id": "kyy01",
},
}, nil)
h := &DevHandler{
Hydra: &service.HydraAdminService{
AdminURL: "http://hydra.test",
HTTPClient: &http.Client{Transport: transport},
},
Keto: mockKeto,
Keto: mockKeto,
KratosAdmin: mockKratos,
}
app := fiber.New()
@@ -1304,6 +1374,9 @@ func TestListClientRelations_RPAdminAllowedByViewRelationshipsPermission(t *test
assert.Equal(t, "config_editor", result.Items[0].Relation)
assert.Equal(t, "User", result.Items[0].SubjectType)
assert.Equal(t, "user-2", result.Items[0].SubjectID)
assert.Equal(t, "김용연", result.Items[0].UserName)
assert.Equal(t, "kyy@example.com", result.Items[0].UserEmail)
assert.Equal(t, "kyy01", result.Items[0].UserLoginID)
}
func TestAddClientRelation_RPAdminAllowedByTenantGrantPermission(t *testing.T) {
@@ -1421,3 +1494,58 @@ func TestRemoveClientRelation_RPAdminAllowedByManagePermission(t *testing.T) {
assert.Equal(t, http.StatusNoContent, resp.StatusCode)
mockOutbox.AssertExpectations(t)
}
func TestSearchUsers_RPAdminSearchByNameOrEmailWithinTenantScope(t *testing.T) {
mockKratos := new(devMockKratosAdmin)
mockKratos.On("ListIdentities", mock.Anything).Return([]service.KratosIdentity{
{
ID: "user-1",
Traits: map[string]interface{}{
"name": "Alice Kim",
"email": "alice@example.com",
"id": "alice01",
"tenant_id": "tenant-1",
},
},
{
ID: "user-2",
Traits: map[string]interface{}{
"name": "Bob Lee",
"email": "bob@example.com",
"id": "bob01",
"tenant_id": "tenant-2",
},
},
}, nil)
h := &DevHandler{
KratosAdmin: mockKratos,
}
app := fiber.New()
app.Use(func(c *fiber.Ctx) error {
tenantID := "tenant-1"
c.Locals("user_profile", &domain.UserProfileResponse{
ID: "user-9",
Role: domain.RoleRPAdmin,
TenantID: &tenantID,
ManageableTenants: []domain.Tenant{
{ID: "tenant-1", Slug: "tenant-one"},
},
})
return c.Next()
})
app.Get("/api/v1/dev/users", h.SearchUsers)
req := httptest.NewRequest(http.MethodGet, "/api/v1/dev/users?search=alice", nil)
resp, _ := app.Test(req, -1)
assert.Equal(t, http.StatusOK, resp.StatusCode)
var result devUserListResponse
_ = json.NewDecoder(resp.Body).Decode(&result)
assert.Len(t, result.Items, 1)
assert.Equal(t, "user-1", result.Items[0].ID)
assert.Equal(t, "Alice Kim", result.Items[0].Name)
assert.Equal(t, "alice@example.com", result.Items[0].Email)
mockKratos.AssertExpectations(t)
}