Skip to content

Commit 4daafec

Browse files
committed
feat: migrate DeletePolicy API to Connect RPC
1 parent 1fa49ac commit 4daafec

File tree

2 files changed

+161
-0
lines changed

2 files changed

+161
-0
lines changed

internal/api/v1beta1connect/policy.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"connectrpc.com/connect"
88
"github.com/raystack/frontier/core/audit"
9+
"github.com/raystack/frontier/core/namespace"
910
"github.com/raystack/frontier/core/policy"
1011
"github.com/raystack/frontier/core/role"
1112
"github.com/raystack/frontier/internal/bootstrap/schema"
@@ -91,6 +92,31 @@ func (h *ConnectHandler) UpdatePolicy(ctx context.Context, request *connect.Requ
9192
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("unsupported at the moment"))
9293
}
9394

95+
func (h *ConnectHandler) DeletePolicy(ctx context.Context, request *connect.Request[frontierv1beta1.DeletePolicyRequest]) (*connect.Response[frontierv1beta1.DeletePolicyResponse], error) {
96+
err := h.policyService.Delete(ctx, request.Msg.GetId())
97+
if err != nil {
98+
switch {
99+
case errors.Is(err, policy.ErrNotExist),
100+
errors.Is(err, policy.ErrInvalidID),
101+
errors.Is(err, policy.ErrInvalidUUID):
102+
return nil, connect.NewError(connect.CodeNotFound, ErrPolicyNotFound)
103+
case errors.Is(err, policy.ErrInvalidDetail),
104+
errors.Is(err, namespace.ErrNotExist):
105+
return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest)
106+
case errors.Is(err, policy.ErrConflict):
107+
return nil, connect.NewError(connect.CodeAlreadyExists, ErrConflictRequest)
108+
default:
109+
return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError)
110+
}
111+
}
112+
113+
audit.GetAuditor(ctx, schema.PlatformOrgID.String()).Log(audit.PolicyDeletedEvent, audit.Target{
114+
ID: request.Msg.GetId(),
115+
Type: "app/policy",
116+
})
117+
return connect.NewResponse(&frontierv1beta1.DeletePolicyResponse{}), nil
118+
}
119+
94120
func (h *ConnectHandler) ListPolicies(ctx context.Context, request *connect.Request[frontierv1beta1.ListPoliciesRequest]) (*connect.Response[frontierv1beta1.ListPoliciesResponse], error) {
95121
var policies []*frontierv1beta1.Policy
96122

internal/api/v1beta1connect/policy_test.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"time"
88

99
"connectrpc.com/connect"
10+
"github.com/raystack/frontier/core/namespace"
1011
"github.com/raystack/frontier/core/policy"
1112
"github.com/raystack/frontier/core/role"
1213
"github.com/raystack/frontier/internal/api/v1beta1connect/mocks"
@@ -625,3 +626,137 @@ func TestConnectHandler_UpdatePolicy(t *testing.T) {
625626
})
626627
}
627628
}
629+
630+
func TestConnectHandler_DeletePolicy(t *testing.T) {
631+
testPolicyID := utils.NewString()
632+
633+
tests := []struct {
634+
name string
635+
setup func(ps *mocks.PolicyService)
636+
request *connect.Request[frontierv1beta1.DeletePolicyRequest]
637+
want *connect.Response[frontierv1beta1.DeletePolicyResponse]
638+
wantErr error
639+
errCode connect.Code
640+
}{
641+
{
642+
name: "should return not found error when policy doesn't exist",
643+
setup: func(ps *mocks.PolicyService) {
644+
ps.On("Delete", mock.Anything, testPolicyID).Return(policy.ErrNotExist)
645+
},
646+
request: connect.NewRequest(&frontierv1beta1.DeletePolicyRequest{
647+
Id: testPolicyID,
648+
}),
649+
want: nil,
650+
wantErr: ErrPolicyNotFound,
651+
errCode: connect.CodeNotFound,
652+
},
653+
{
654+
name: "should return not found error when policy ID is invalid",
655+
setup: func(ps *mocks.PolicyService) {
656+
ps.On("Delete", mock.Anything, "invalid-id").Return(policy.ErrInvalidID)
657+
},
658+
request: connect.NewRequest(&frontierv1beta1.DeletePolicyRequest{
659+
Id: "invalid-id",
660+
}),
661+
want: nil,
662+
wantErr: ErrPolicyNotFound,
663+
errCode: connect.CodeNotFound,
664+
},
665+
{
666+
name: "should return not found error when policy UUID is invalid",
667+
setup: func(ps *mocks.PolicyService) {
668+
ps.On("Delete", mock.Anything, "not-a-uuid").Return(policy.ErrInvalidUUID)
669+
},
670+
request: connect.NewRequest(&frontierv1beta1.DeletePolicyRequest{
671+
Id: "not-a-uuid",
672+
}),
673+
want: nil,
674+
wantErr: ErrPolicyNotFound,
675+
errCode: connect.CodeNotFound,
676+
},
677+
{
678+
name: "should return invalid argument error when policy details are invalid",
679+
setup: func(ps *mocks.PolicyService) {
680+
ps.On("Delete", mock.Anything, testPolicyID).Return(policy.ErrInvalidDetail)
681+
},
682+
request: connect.NewRequest(&frontierv1beta1.DeletePolicyRequest{
683+
Id: testPolicyID,
684+
}),
685+
want: nil,
686+
wantErr: ErrBadRequest,
687+
errCode: connect.CodeInvalidArgument,
688+
},
689+
{
690+
name: "should return invalid argument error when namespace doesn't exist",
691+
setup: func(ps *mocks.PolicyService) {
692+
ps.On("Delete", mock.Anything, testPolicyID).Return(namespace.ErrNotExist)
693+
},
694+
request: connect.NewRequest(&frontierv1beta1.DeletePolicyRequest{
695+
Id: testPolicyID,
696+
}),
697+
want: nil,
698+
wantErr: ErrBadRequest,
699+
errCode: connect.CodeInvalidArgument,
700+
},
701+
{
702+
name: "should return already exists error when policy has conflicts",
703+
setup: func(ps *mocks.PolicyService) {
704+
ps.On("Delete", mock.Anything, testPolicyID).Return(policy.ErrConflict)
705+
},
706+
request: connect.NewRequest(&frontierv1beta1.DeletePolicyRequest{
707+
Id: testPolicyID,
708+
}),
709+
want: nil,
710+
wantErr: ErrConflictRequest,
711+
errCode: connect.CodeAlreadyExists,
712+
},
713+
{
714+
name: "should return internal server error when policy service returns unknown error",
715+
setup: func(ps *mocks.PolicyService) {
716+
ps.On("Delete", mock.Anything, testPolicyID).Return(errors.New("service error"))
717+
},
718+
request: connect.NewRequest(&frontierv1beta1.DeletePolicyRequest{
719+
Id: testPolicyID,
720+
}),
721+
want: nil,
722+
wantErr: ErrInternalServerError,
723+
errCode: connect.CodeInternal,
724+
},
725+
{
726+
name: "should successfully delete policy",
727+
setup: func(ps *mocks.PolicyService) {
728+
ps.On("Delete", mock.Anything, testPolicyID).Return(nil)
729+
},
730+
request: connect.NewRequest(&frontierv1beta1.DeletePolicyRequest{
731+
Id: testPolicyID,
732+
}),
733+
want: connect.NewResponse(&frontierv1beta1.DeletePolicyResponse{}),
734+
wantErr: nil,
735+
},
736+
}
737+
738+
for _, tt := range tests {
739+
t.Run(tt.name, func(t *testing.T) {
740+
mockPolicyService := &mocks.PolicyService{}
741+
if tt.setup != nil {
742+
tt.setup(mockPolicyService)
743+
}
744+
745+
handler := &ConnectHandler{
746+
policyService: mockPolicyService,
747+
}
748+
749+
got, err := handler.DeletePolicy(context.Background(), tt.request)
750+
if tt.wantErr != nil {
751+
assert.Error(t, err)
752+
assert.Equal(t, tt.errCode, connect.CodeOf(err))
753+
assert.Nil(t, got)
754+
} else {
755+
assert.NoError(t, err)
756+
assert.Equal(t, tt.want, got)
757+
}
758+
759+
mockPolicyService.AssertExpectations(t)
760+
})
761+
}
762+
}

0 commit comments

Comments
 (0)