From 6c9f1c5a1417b9a49b21d76640e068db5857931b Mon Sep 17 00:00:00 2001 From: starsz Date: Wed, 25 Nov 2020 00:14:06 +0800 Subject: [PATCH] fix: delete POST method in /apisix/admin/consumer (#852) --- api/internal/handler/consumer/consumer.go | 40 +--- .../handler/consumer/consumer_test.go | 22 +-- api/test/e2e/consumer_test.go | 179 ++++++++++++++++++ 3 files changed, 198 insertions(+), 43 deletions(-) diff --git a/api/internal/handler/consumer/consumer.go b/api/internal/handler/consumer/consumer.go index 79d6f8be96..ab31aa35df 100644 --- a/api/internal/handler/consumer/consumer.go +++ b/api/internal/handler/consumer/consumer.go @@ -49,12 +49,10 @@ func (h *Handler) ApplyRoute(r *gin.Engine) { wrapper.InputType(reflect.TypeOf(GetInput{})))) r.GET("/apisix/admin/consumers", wgin.Wraps(h.List, wrapper.InputType(reflect.TypeOf(ListInput{})))) - r.POST("/apisix/admin/consumers", wgin.Wraps(h.Create, - wrapper.InputType(reflect.TypeOf(entity.Consumer{})))) - r.PUT("/apisix/admin/consumers/:username", wgin.Wraps(h.Update, - wrapper.InputType(reflect.TypeOf(UpdateInput{})))) - r.PUT("/apisix/admin/consumers", wgin.Wraps(h.Update, - wrapper.InputType(reflect.TypeOf(UpdateInput{})))) + r.PUT("/apisix/admin/consumers/:username", wgin.Wraps(h.Set, + wrapper.InputType(reflect.TypeOf(SetInput{})))) + r.PUT("/apisix/admin/consumers", wgin.Wraps(h.Set, + wrapper.InputType(reflect.TypeOf(SetInput{})))) r.DELETE("/apisix/admin/consumers/:usernames", wgin.Wraps(h.BatchDelete, wrapper.InputType(reflect.TypeOf(BatchDelete{})))) } @@ -98,35 +96,13 @@ func (h *Handler) List(c droplet.Context) (interface{}, error) { return ret, nil } -func (h *Handler) Create(c droplet.Context) (interface{}, error) { - input := c.Input().(*entity.Consumer) - if input.ID != nil && utils.InterfaceToString(input.ID) != input.Username { - return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, - fmt.Errorf("consumer's id and username must be a same value") - } - input.ID = input.Username - - if _, ok := input.Plugins["jwt-auth"]; ok { - jwt := input.Plugins["jwt-auth"].(map[string]interface{}) - jwt["exp"] = 86400 - - input.Plugins["jwt-auth"] = jwt - } - - if err := h.consumerStore.Create(c.Context(), input); err != nil { - return handler.SpecCodeResponse(err), err - } - - return nil, nil -} - -type UpdateInput struct { - Username string `auto_read:"username,path"` +type SetInput struct { entity.Consumer + Username string `auto_read:"username,path"` } -func (h *Handler) Update(c droplet.Context) (interface{}, error) { - input := c.Input().(*UpdateInput) +func (h *Handler) Set(c droplet.Context) (interface{}, error) { + input := c.Input().(*SetInput) if input.ID != nil && utils.InterfaceToString(input.ID) != input.Username { return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, fmt.Errorf("consumer's id and username must be a same value") diff --git a/api/internal/handler/consumer/consumer_test.go b/api/internal/handler/consumer/consumer_test.go index 1f88c52b07..e4f75c69f4 100644 --- a/api/internal/handler/consumer/consumer_test.go +++ b/api/internal/handler/consumer/consumer_test.go @@ -44,7 +44,7 @@ func TestConsumer(t *testing.T) { //create consumer ctx := droplet.NewContext() - consumer := &entity.Consumer{} + consumer := &SetInput{} reqBody := `{ "username": "jack", "plugins": { @@ -60,11 +60,11 @@ func TestConsumer(t *testing.T) { err = json.Unmarshal([]byte(reqBody), consumer) assert.Nil(t, err) ctx.SetInput(consumer) - _, err = handler.Create(ctx) + _, err = handler.Set(ctx) assert.Nil(t, err) //create consumer 2 - consumer2 := &entity.Consumer{} + consumer2 := &SetInput{} reqBody = `{ "username": "pony", "plugins": { @@ -80,7 +80,7 @@ func TestConsumer(t *testing.T) { err = json.Unmarshal([]byte(reqBody), consumer2) assert.Nil(t, err) ctx.SetInput(consumer2) - _, err = handler.Create(ctx) + _, err = handler.Set(ctx) assert.Nil(t, err) //sleep @@ -96,10 +96,10 @@ func TestConsumer(t *testing.T) { stored := ret.(*entity.Consumer) assert.Nil(t, err) assert.Equal(t, stored.ID, consumer.ID) - assert.Equal(t, stored.Username, consumer.Username) + assert.Equal(t, stored.Username, consumer.Consumer.Username) //update consumer - consumer3 := &UpdateInput{} + consumer3 := &SetInput{} consumer3.Username = "pony" reqBody = `{ "username": "pony", @@ -116,7 +116,7 @@ func TestConsumer(t *testing.T) { err = json.Unmarshal([]byte(reqBody), consumer3) assert.Nil(t, err) ctx.SetInput(consumer3) - _, err = handler.Update(ctx) + _, err = handler.Set(ctx) assert.Nil(t, err) //sleep @@ -195,7 +195,7 @@ func TestConsumer(t *testing.T) { assert.Nil(t, err) //create consumer fail - consumer_fail := &entity.Consumer{} + consumer_fail := &SetInput{} reqBody = `{ "plugins": { "limit-count": { @@ -210,11 +210,11 @@ func TestConsumer(t *testing.T) { err = json.Unmarshal([]byte(reqBody), consumer_fail) assert.Nil(t, err) ctx.SetInput(consumer_fail) - _, err = handler.Create(ctx) + _, err = handler.Set(ctx) assert.NotNil(t, err) //create consumer using Update - consumer6 := &UpdateInput{} + consumer6 := &SetInput{} reqBody = `{ "username": "nnn", "plugins": { @@ -230,7 +230,7 @@ func TestConsumer(t *testing.T) { err = json.Unmarshal([]byte(reqBody), consumer6) assert.Nil(t, err) ctx.SetInput(consumer6) - _, err = handler.Update(ctx) + _, err = handler.Set(ctx) assert.Nil(t, err) //sleep diff --git a/api/test/e2e/consumer_test.go b/api/test/e2e/consumer_test.go index e7ba2316b5..21d6f455d2 100644 --- a/api/test/e2e/consumer_test.go +++ b/api/test/e2e/consumer_test.go @@ -27,6 +27,185 @@ import ( "github.com/tidwall/gjson" ) +func TestConsumer_Create_And_Get(t *testing.T) { + tests := []HttpTestCase{ + { + caseDesc: "check consumer is not exist", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers/consumer_1", + Method: http.MethodGet, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusNotFound, + ExpectBody: "data not found", + }, + { + caseDesc: "check consumer is not exist", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers/consumer_2", + Method: http.MethodGet, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusNotFound, + ExpectBody: "data not found", + }, + { + caseDesc: "create consumer by POST", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers", + Method: http.MethodPost, + Body: `{ + "username": "consumer_1", + "plugins": { + "limit-count": { + "count": 2, + "time_window": 60, + "rejected_code": 503, + "key": "remote_addr" + } + }, + "desc": "test description" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusNotFound, + ExpectBody: "404 page not found", + }, + { + caseDesc: "create consumer by PUT", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers", + Method: http.MethodPut, + Body: `{ + "username": "consumer_2", + "plugins": { + "limit-count": { + "count": 2, + "time_window": 60, + "rejected_code": 503, + "key": "remote_addr" + } + }, + "desc": "test description" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + ExpectBody: "\"code\":0", + Sleep: sleepTime, + }, + { + caseDesc: "get consumer", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers/consumer_2", + Method: http.MethodGet, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + ExpectBody: "\"username\":\"consumer_2\"", + }, + { + caseDesc: "create consumer without username", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers", + Method: http.MethodPut, + Body: `{ + "plugins": { + "limit-count": { + "count": 2, + "time_window": 60, + "rejected_code": 503, + "key": "remote_addr" + } + }, + "desc": "test description" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusBadRequest, + ExpectBody: "\"code\":10000", + }, + { + caseDesc: "delete consumer", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers/consumer_2", + Method: http.MethodDelete, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + ExpectBody: "\"code\":0", + }, + } + + for _, tc := range tests { + testCaseCheck(tc) + } +} + +func TestConsumer_Update_And_Get(t *testing.T) { + tests := []HttpTestCase{ + { + caseDesc: "create consumer by PUT", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers", + Method: http.MethodPut, + Body: `{ + "username": "consumer_3", + "plugins": { + "limit-count": { + "count": 2, + "time_window": 60, + "rejected_code": 503, + "key": "remote_addr" + } + }, + "desc": "test description" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + ExpectBody: "\"code\":0", + Sleep: sleepTime, + }, + { + caseDesc: "update consumer by PUT", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers/consumer_3", + Method: http.MethodPut, + Body: `{ + "username": "consumer_3", + "plugins": { + "limit-count": { + "count": 2, + "time_window": 60, + "rejected_code": 504, + "key": "remote_addr" + } + }, + "desc": "test description" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + ExpectBody: "\"code\":0", + Sleep: sleepTime, + }, + { + caseDesc: "get consumer", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers/consumer_3", + Method: http.MethodGet, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + ExpectBody: "\"rejected_code\":504", + }, + { + caseDesc: "delete consumer", + Object: ManagerApiExpect(t), + Path: "/apisix/admin/consumers/consumer_3", + Method: http.MethodDelete, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + ExpectBody: "\"code\":0", + }, + } + + for _, tc := range tests { + testCaseCheck(tc) + } +} + func TestConsumer_with_key_auth(t *testing.T) { tests := []HttpTestCase{ {