forked from baron/baron-sso
개발자 권한 앱 생성 오류 수정
This commit is contained in:
@@ -3295,8 +3295,8 @@ func (h *DevHandler) ensureDeveloperGrantRelation(c *fiber.Ctx, userID, tenantID
|
||||
return
|
||||
}
|
||||
subject := "User:" + strings.TrimSpace(userID)
|
||||
for _, relation := range []string{"view_dev_console", "grant_dev_permissions"} {
|
||||
if !h.hasDirectTenantRelation(c, tenantID, relation, subject) {
|
||||
for _, relation := range []string{"developer_console_grant_manager", "view_dev_console", "grant_dev_permissions"} {
|
||||
if h.hasDirectTenantRelation(c, tenantID, relation, subject) {
|
||||
continue
|
||||
}
|
||||
_ = h.KetoOutbox.Create(c.Context(), &domain.KetoOutbox{
|
||||
@@ -3304,19 +3304,14 @@ func (h *DevHandler) ensureDeveloperGrantRelation(c *fiber.Ctx, userID, tenantID
|
||||
Object: tenantID,
|
||||
Relation: relation,
|
||||
Subject: subject,
|
||||
Action: domain.KetoOutboxActionDelete,
|
||||
Action: domain.KetoOutboxActionCreate,
|
||||
})
|
||||
if h.Keto != nil {
|
||||
if err := h.Keto.CreateRelation(c.Context(), "Tenant", tenantID, relation, subject); err != nil {
|
||||
slog.Warn("failed to grant immediate developer tenant relation", "tenantID", tenantID, "userID", userID, "relation", relation, "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if h.hasDirectTenantRelation(c, tenantID, "developer_console_grant_manager", subject) {
|
||||
return
|
||||
}
|
||||
_ = h.KetoOutbox.Create(c.Context(), &domain.KetoOutbox{
|
||||
Namespace: "Tenant",
|
||||
Object: tenantID,
|
||||
Relation: "developer_console_grant_manager",
|
||||
Subject: subject,
|
||||
Action: domain.KetoOutboxActionCreate,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *DevHandler) revokeDeveloperGrantRelation(c *fiber.Ctx, userID, tenantID string) {
|
||||
@@ -3332,6 +3327,11 @@ func (h *DevHandler) revokeDeveloperGrantRelation(c *fiber.Ctx, userID, tenantID
|
||||
Subject: subject,
|
||||
Action: domain.KetoOutboxActionDelete,
|
||||
})
|
||||
if h.Keto != nil {
|
||||
if err := h.Keto.DeleteRelation(c.Context(), "Tenant", tenantID, relation, subject); err != nil {
|
||||
slog.Warn("failed to revoke immediate developer tenant relation", "tenantID", tenantID, "userID", userID, "relation", relation, "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1102,6 +1102,103 @@ func TestCreateClient_ApprovedDeveloperCanCreatePrivateClient(t *testing.T) {
|
||||
mockOutbox.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestEnsureDeveloperGrantRelation_CreatesRequiredTenantRelations(t *testing.T) {
|
||||
mockKeto := new(devMockKetoService)
|
||||
for _, relation := range []string{"developer_console_grant_manager", "view_dev_console", "grant_dev_permissions"} {
|
||||
mockKeto.On("ListRelations", mock.Anything, "Tenant", "tenant-a", relation, "User:user-1").Return([]service.RelationTuple{}, nil).Once()
|
||||
mockKeto.On("CreateRelation", mock.Anything, "Tenant", "tenant-a", relation, "User:user-1").Return(nil).Once()
|
||||
}
|
||||
|
||||
mockOutbox := new(devMockKetoOutboxRepository)
|
||||
for _, relation := range []string{"developer_console_grant_manager", "view_dev_console", "grant_dev_permissions"} {
|
||||
expectedRelation := relation
|
||||
mockOutbox.On("Create", mock.Anything, mock.MatchedBy(func(entry *domain.KetoOutbox) bool {
|
||||
return entry.Namespace == "Tenant" &&
|
||||
entry.Object == "tenant-a" &&
|
||||
entry.Relation == expectedRelation &&
|
||||
entry.Subject == "User:user-1" &&
|
||||
entry.Action == domain.KetoOutboxActionCreate
|
||||
})).Return(nil).Once()
|
||||
}
|
||||
|
||||
h := &DevHandler{
|
||||
Keto: mockKeto,
|
||||
KetoOutbox: mockOutbox,
|
||||
}
|
||||
|
||||
app := fiber.New()
|
||||
app.Get("/test", func(c *fiber.Ctx) error {
|
||||
h.ensureDeveloperGrantRelation(c, "user-1", "tenant-a")
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/test", nil)
|
||||
resp, _ := app.Test(req, -1)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
mockKeto.AssertExpectations(t)
|
||||
mockOutbox.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestEnsureDeveloperGrantRelation_SkipsExistingTenantRelations(t *testing.T) {
|
||||
mockKeto := new(devMockKetoService)
|
||||
for _, relation := range []string{"developer_console_grant_manager", "view_dev_console", "grant_dev_permissions"} {
|
||||
mockKeto.On("ListRelations", mock.Anything, "Tenant", "tenant-a", relation, "User:user-1").
|
||||
Return([]service.RelationTuple{{Namespace: "Tenant", Object: "tenant-a", Relation: relation, SubjectID: "User:user-1"}}, nil).Once()
|
||||
}
|
||||
|
||||
h := &DevHandler{
|
||||
Keto: mockKeto,
|
||||
KetoOutbox: new(devMockKetoOutboxRepository),
|
||||
}
|
||||
|
||||
app := fiber.New()
|
||||
app.Get("/test", func(c *fiber.Ctx) error {
|
||||
h.ensureDeveloperGrantRelation(c, "user-1", "tenant-a")
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/test", nil)
|
||||
resp, _ := app.Test(req, -1)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
mockKeto.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestRevokeDeveloperGrantRelation_DeletesRequiredTenantRelations(t *testing.T) {
|
||||
mockKeto := new(devMockKetoService)
|
||||
for _, relation := range []string{"developer_console_grant_manager", "view_dev_console", "grant_dev_permissions"} {
|
||||
mockKeto.On("DeleteRelation", mock.Anything, "Tenant", "tenant-a", relation, "User:user-1").Return(nil).Once()
|
||||
}
|
||||
|
||||
mockOutbox := new(devMockKetoOutboxRepository)
|
||||
for _, relation := range []string{"developer_console_grant_manager", "view_dev_console", "grant_dev_permissions"} {
|
||||
expectedRelation := relation
|
||||
mockOutbox.On("Create", mock.Anything, mock.MatchedBy(func(entry *domain.KetoOutbox) bool {
|
||||
return entry.Namespace == "Tenant" &&
|
||||
entry.Object == "tenant-a" &&
|
||||
entry.Relation == expectedRelation &&
|
||||
entry.Subject == "User:user-1" &&
|
||||
entry.Action == domain.KetoOutboxActionDelete
|
||||
})).Return(nil).Once()
|
||||
}
|
||||
|
||||
h := &DevHandler{
|
||||
Keto: mockKeto,
|
||||
KetoOutbox: mockOutbox,
|
||||
}
|
||||
|
||||
app := fiber.New()
|
||||
app.Get("/test", func(c *fiber.Ctx) error {
|
||||
h.revokeDeveloperGrantRelation(c, "user-1", "tenant-a")
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/test", nil)
|
||||
resp, _ := app.Test(req, -1)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
mockKeto.AssertExpectations(t)
|
||||
mockOutbox.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestGetStats_Success(t *testing.T) {
|
||||
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
|
||||
if r.URL.Path == "/clients" {
|
||||
|
||||
Reference in New Issue
Block a user