Skip to content
This repository was archived by the owner on Dec 9, 2024. It is now read-only.

Commit 0dd9f87

Browse files
authored
Fix deleting function that is used as authorizer (#474)
1 parent 4b892e7 commit 0dd9f87

File tree

5 files changed

+54
-2
lines changed

5 files changed

+54
-2
lines changed

function/errors.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ func (e ErrFunctionValidation) Error() string {
3131
return fmt.Sprintf("Function doesn't validate. Validation error: %s", e.Message)
3232
}
3333

34+
// ErrFunctionIsAuthorizer occurs when function cannot be deleted because is used as authorizer.
35+
type ErrFunctionIsAuthorizer struct {
36+
ID ID
37+
EventType string
38+
}
39+
40+
func (e ErrFunctionIsAuthorizer) Error() string {
41+
return fmt.Sprintf("Function %s cannot be deleted because is used as an authorizer for %s event type.", e.ID, e.EventType)
42+
}
43+
3444
// ErrFunctionCallFailed occurs when function call failed.
3545
type ErrFunctionCallFailed struct {
3646
Original error

httpapi/httpapi.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ func (h HTTPAPI) deleteFunction(w http.ResponseWriter, r *http.Request, params h
328328
w.WriteHeader(http.StatusNotFound)
329329
} else if _, ok := err.(*function.ErrFunctionHasSubscriptions); ok {
330330
w.WriteHeader(http.StatusBadRequest)
331+
} else if _, ok := err.(*function.ErrFunctionIsAuthorizer); ok {
332+
w.WriteHeader(http.StatusBadRequest)
331333
} else {
332334
w.WriteHeader(http.StatusInternalServerError)
333335
}

httpapi/httpapi_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,17 @@ func TestDeleteFunction(t *testing.T) {
480480
assert.Equal(t, "Function cannot be deleted because it's subscribed to a least one event.", httpresp.Errors[0].Message)
481481
})
482482

483+
t.Run("function is authorizer", func(t *testing.T) {
484+
functions.EXPECT().DeleteFunction(gomock.Any(), gomock.Any()).Return(&function.ErrFunctionIsAuthorizer{ID: function.ID("func1"), EventType: "test.event"})
485+
486+
resp := request(router, http.MethodDelete, "/v1/spaces/default/functions/func1", nil)
487+
488+
httpresp := &httpapi.Response{}
489+
json.Unmarshal(resp.Body.Bytes(), httpresp)
490+
assert.Equal(t, http.StatusBadRequest, resp.Code)
491+
assert.Equal(t, "Function func1 cannot be deleted because is used as an authorizer for test.event event type.", httpresp.Errors[0].Message)
492+
})
493+
483494
t.Run("function not found", func(t *testing.T) {
484495
functions.EXPECT().DeleteFunction(gomock.Any(), gomock.Any()).Return(&function.ErrFunctionNotFound{ID: function.ID("testid")})
485496

libkv/function.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ func (service Service) DeleteFunction(space string, id function.ID) error {
133133
}
134134
}
135135

136+
eventTypes, err := service.ListEventTypes(space)
137+
if err != nil {
138+
return err
139+
}
140+
for _, eventType := range eventTypes {
141+
if id == *eventType.AuthorizerID {
142+
return &function.ErrFunctionIsAuthorizer{ID: id, EventType: string(eventType.Name)}
143+
}
144+
}
145+
136146
err = service.FunctionStore.Delete(FunctionKey{space, id}.String())
137147
if err != nil {
138148
return &function.ErrFunctionNotFound{ID: id}

libkv/function_test.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,11 @@ func TestDeleteFunction(t *testing.T) {
223223
kvs := []*store.KVPair{}
224224
subscriptionsDB := mock.NewMockStore(ctrl)
225225
subscriptionsDB.EXPECT().List("default/", &store.ReadOptions{Consistent: true}).Return(kvs, nil)
226+
eventTypesDB := mock.NewMockStore(ctrl)
227+
eventTypesDB.EXPECT().List("default/", &store.ReadOptions{Consistent: true}).Return(kvs, nil)
226228
functionsDB := mock.NewMockStore(ctrl)
227229
functionsDB.EXPECT().Delete("default/testid").Return(nil)
228-
service := &Service{FunctionStore: functionsDB, SubscriptionStore: subscriptionsDB, Log: zap.NewNop()}
230+
service := &Service{FunctionStore: functionsDB, SubscriptionStore: subscriptionsDB, EventTypeStore: eventTypesDB, Log: zap.NewNop()}
229231

230232
err := service.DeleteFunction("default", function.ID("testid"))
231233

@@ -236,9 +238,11 @@ func TestDeleteFunction(t *testing.T) {
236238
kvs := []*store.KVPair{}
237239
subscriptionsDB := mock.NewMockStore(ctrl)
238240
subscriptionsDB.EXPECT().List("default/", &store.ReadOptions{Consistent: true}).Return(kvs, nil)
241+
eventTypesDB := mock.NewMockStore(ctrl)
242+
eventTypesDB.EXPECT().List("default/", &store.ReadOptions{Consistent: true}).Return(kvs, nil)
239243
functionsDB := mock.NewMockStore(ctrl)
240244
functionsDB.EXPECT().Delete("default/testid").Return(errors.New("KV func not found"))
241-
service := &Service{FunctionStore: functionsDB, SubscriptionStore: subscriptionsDB, Log: zap.NewNop()}
245+
service := &Service{FunctionStore: functionsDB, SubscriptionStore: subscriptionsDB, EventTypeStore: eventTypesDB, Log: zap.NewNop()}
242246

243247
err := service.DeleteFunction("default", function.ID("testid"))
244248

@@ -257,6 +261,21 @@ func TestDeleteFunction(t *testing.T) {
257261

258262
assert.Equal(t, err, &function.ErrFunctionHasSubscriptions{})
259263
})
264+
265+
t.Run("function is authorizer", func(t *testing.T) {
266+
kvs := []*store.KVPair{
267+
{Value: []byte(`{"name":"test.event","authorizerId":"testid"}`)}}
268+
eventTypesDB := mock.NewMockStore(ctrl)
269+
eventTypesDB.EXPECT().List("default/", &store.ReadOptions{Consistent: true}).Return(kvs, nil)
270+
subscriptionsDB := mock.NewMockStore(ctrl)
271+
subscriptionsDB.EXPECT().List("default/", &store.ReadOptions{Consistent: true}).Return([]*store.KVPair{}, nil)
272+
functionsDB := mock.NewMockStore(ctrl)
273+
service := &Service{FunctionStore: functionsDB, SubscriptionStore: subscriptionsDB, EventTypeStore: eventTypesDB, Log: zap.NewNop()}
274+
275+
err := service.DeleteFunction("default", function.ID("testid"))
276+
277+
assert.Equal(t, err, &function.ErrFunctionIsAuthorizer{ID: function.ID("testid"), EventType: "test.event"})
278+
})
260279
}
261280

262281
func TestValidateFunction(t *testing.T) {

0 commit comments

Comments
 (0)