forked from baron/baron-sso
개발자 권한 앱 생성 오류 수정
This commit is contained in:
@@ -3295,8 +3295,8 @@ func (h *DevHandler) ensureDeveloperGrantRelation(c *fiber.Ctx, userID, tenantID
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
subject := "User:" + strings.TrimSpace(userID)
|
subject := "User:" + strings.TrimSpace(userID)
|
||||||
for _, relation := range []string{"view_dev_console", "grant_dev_permissions"} {
|
for _, relation := range []string{"developer_console_grant_manager", "view_dev_console", "grant_dev_permissions"} {
|
||||||
if !h.hasDirectTenantRelation(c, tenantID, relation, subject) {
|
if h.hasDirectTenantRelation(c, tenantID, relation, subject) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_ = h.KetoOutbox.Create(c.Context(), &domain.KetoOutbox{
|
_ = h.KetoOutbox.Create(c.Context(), &domain.KetoOutbox{
|
||||||
@@ -3304,19 +3304,14 @@ func (h *DevHandler) ensureDeveloperGrantRelation(c *fiber.Ctx, userID, tenantID
|
|||||||
Object: tenantID,
|
Object: tenantID,
|
||||||
Relation: relation,
|
Relation: relation,
|
||||||
Subject: subject,
|
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) {
|
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,
|
Subject: subject,
|
||||||
Action: domain.KetoOutboxActionDelete,
|
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)
|
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) {
|
func TestGetStats_Success(t *testing.T) {
|
||||||
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
|
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
|
||||||
if r.URL.Path == "/clients" {
|
if r.URL.Path == "/clients" {
|
||||||
|
|||||||
Reference in New Issue
Block a user