You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2020/04/14 11:15:11 UTC

[servicecomb-kie] branch master updated: Add validate rule for update request, renew limitation: header: 32K, body: 2.5M, config value: 2M. (#133)

This is an automated email from the ASF dual-hosted git repository.

tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-kie.git


The following commit(s) were added to refs/heads/master by this push:
     new ac4f8ae  Add validate rule for update request, renew limitation: header: 32K, body: 2.5M, config value: 2M. (#133)
ac4f8ae is described below

commit ac4f8aed7a380b0d442a355a230e71b1170a1254
Author: humingcheng <hu...@163.com>
AuthorDate: Tue Apr 14 19:15:03 2020 +0800

    Add validate rule for update request, renew limitation: header: 32K, body: 2.5M, config value: 2M. (#133)
---
 examples/dev/conf/chassis.yaml              |  7 +++++++
 pkg/model/db_schema.go                      | 20 ++++++++++++++------
 pkg/validate/instance.go                    | 14 ++++++++++++--
 pkg/validate/instance_test.go               | 13 ++++++++-----
 server/resource/v1/common.go                |  9 ---------
 server/resource/v1/history_resource_test.go | 11 ++++++++---
 server/resource/v1/kv_resource.go           | 14 +++++++-------
 server/resource/v1/kv_resource_test.go      |  2 +-
 server/service/mongo/kv/kv_service.go       |  2 +-
 server/service/mongo/kv/kv_service_test.go  | 12 ++++--------
 server/service/service.go                   |  2 +-
 11 files changed, 63 insertions(+), 43 deletions(-)

diff --git a/examples/dev/conf/chassis.yaml b/examples/dev/conf/chassis.yaml
index e4acce0..b562acb 100755
--- a/examples/dev/conf/chassis.yaml
+++ b/examples/dev/conf/chassis.yaml
@@ -11,6 +11,13 @@ cse:
     chain:
       Provider:
         default: ratelimiter-provider,monitoring,auth-handler,track-handler
+  transport:
+    maxBodyBytes:
+      rest: 2621440 #2.5M
+    maxHeaderBytes:
+      rest: 32768 #32K
+    timeout:
+      rest: 60s
 servicecomb:
   service:
     quota:
diff --git a/pkg/model/db_schema.go b/pkg/model/db_schema.go
index f44b646..cdcf8ee 100644
--- a/pkg/model/db_schema.go
+++ b/pkg/model/db_schema.go
@@ -31,10 +31,10 @@ type LabelDoc struct {
 type KVDoc struct {
 	ID             string `json:"id,omitempty" bson:"id,omitempty" yaml:"id,omitempty" swag:"string"`
 	LabelFormat    string `json:"label_format,omitempty" bson:"label_format,omitempty" yaml:"label_format,omitempty"`
-	Key            string `json:"key" yaml:"key" validate:"commonName"`
-	Value          string `json:"value" yaml:"value" validate:"ascii,min=1,max=2097152"`
+	Key            string `json:"key" yaml:"key" validate:"key"`
+	Value          string `json:"value" yaml:"value" validate:"value"`
 	ValueType      string `json:"value_type,omitempty" bson:"value_type,omitempty" yaml:"value_type,omitempty" validate:"valueType"` //ini,json,text,yaml,properties
-	Checker        string `json:"check,omitempty" yaml:"check,omitempty"`                                                            //python script
+	Checker        string `json:"check,omitempty" yaml:"check,omitempty" validate:"check"`                                           //python script
 	CreateRevision int64  `json:"create_revision,omitempty" bson:"create_revision," yaml:"create_revision,omitempty"`
 	UpdateRevision int64  `json:"update_revision,omitempty" bson:"update_revision," yaml:"update_revision,omitempty"`
 	Project        string `json:"project,omitempty" yaml:"project,omitempty" validate:"commonName"`
@@ -42,9 +42,8 @@ type KVDoc struct {
 	CreateTime     int64  `json:"create_time,omitempty" bson:"create_time," yaml:"create_time,omitempty"`
 	UpdateTime     int64  `json:"update_time,omitempty" bson:"update_time," yaml:"update_time,omitempty"`
 
-	Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty" validate:"max=64,dive,keys,commonName,endkeys,commonName"` //redundant
-	Domain string            `json:"domain,omitempty" yaml:"domain,omitempty" validate:"commonName"`                                     //redundant
-
+	Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty" validate:"max=8,dive,keys,lableKV,endkeys,lableKV"` //redundant
+	Domain string            `json:"domain,omitempty" yaml:"domain,omitempty" validate:"commonName"`                              //redundant
 }
 
 //ViewDoc is db struct, it saves user's custom view name and criteria
@@ -69,3 +68,12 @@ type PollingDetail struct {
 	ResponseHeader map[string][]string    `json:"response_header,omitempty"  bson:"response_header,"  yaml:"response_header,omitempty"`
 	ResponseCode   int                    `json:"response_code,omitempty"  bson:"response_code,"  yaml:"response_code,omitempty"`
 }
+
+// UpdateKVRequest is db struct, it contains kv update request params
+type UpdateKVRequest struct {
+	ID      string `json:"id,omitempty" bson:"id,omitempty" yaml:"id,omitempty" swag:"string" validate:"uuid"`
+	Value   string `json:"value,omitempty" yaml:"value,omitempty" validate:"value"`
+	Project string `json:"project,omitempty" yaml:"project,omitempty" validate:"commonName"`
+	Domain  string `json:"domain,omitempty" yaml:"domain,omitempty" validate:"commonName"` //redundant
+	Status  string `json:"status,omitempty" yaml:"status,omitempty" validate:"kvStatus"`
+}
diff --git a/pkg/validate/instance.go b/pkg/validate/instance.go
index 706fb13..a71bf8b 100644
--- a/pkg/validate/instance.go
+++ b/pkg/validate/instance.go
@@ -2,17 +2,27 @@ package validate
 
 var defaultValidator = NewValidator()
 
+const (
+	key                   = "key"
+	commonNameRegexString = `^[a-zA-Z0-9]*$|^[a-zA-Z0-9][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$`
+	asciiRegexString      = `^[\x00-\x7F]*$`
+)
+
 // custom validate rules
 // please use different tag names from third party tags
 var customRules = []*RegexValidateRule{
-	NewRule("commonName", `^[a-zA-Z0-9]*$|^[a-zA-Z0-9][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$`, &Option{Min: 1, Max: 256}),
+	NewRule(key, commonNameRegexString, &Option{Min: 1, Max: 2048}), //2K
+	NewRule("commonName", commonNameRegexString, &Option{Min: 1, Max: 256}),
 	NewRule("valueType", `^(ini|json|text|yaml|properties){0,1}$`, nil),
 	NewRule("kvStatus", `^(enabled|disabled){0,1}$`, nil),
+	NewRule("value", asciiRegexString, &Option{Max: 2097152}), //ASCII, 2M
+	NewRule("lableKV", commonNameRegexString, &Option{Min: 1, Max: 32}),
+	NewRule("check", asciiRegexString, &Option{Max: 1048576}), //ASCII, 1M
 }
 
 // tags of third party validate rules we used, for error translation
 var thirdPartyTags = []string{
-	"min", "max", "length",
+	"min", "max", "length", "uuid",
 }
 
 // Init initializes validate
diff --git a/pkg/validate/instance_test.go b/pkg/validate/instance_test.go
index 5848001..0700911 100644
--- a/pkg/validate/instance_test.go
+++ b/pkg/validate/instance_test.go
@@ -10,8 +10,11 @@ import (
 )
 
 func TestValidate(t *testing.T) {
-	s := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" //64
-	testStr := s + s + s + s                                                //256
+	string32 := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" //32
+	string2k := "a"
+	for i := 0; i < 11; i++ { //2k
+		string2k = string2k + string2k
+	}
 	err := validate.Init()
 	assert.NoError(t, err)
 
@@ -34,7 +37,7 @@ func TestValidate(t *testing.T) {
 	assert.Error(t, validate.Validate(kvDoc))
 
 	kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-		Key:   testStr + "a",
+		Key:   string2k + "a",
 		Value: "a",
 	}
 	assert.Error(t, validate.Validate(kvDoc))
@@ -43,7 +46,7 @@ func TestValidate(t *testing.T) {
 		Key:   "a",
 		Value: "",
 	}
-	assert.Error(t, validate.Validate(kvDoc))
+	assert.NoError(t, validate.Validate(kvDoc))
 
 	kvDoc = &model.KVDoc{Project: "a", Domain: "a",
 		Key:       "a",
@@ -104,7 +107,7 @@ func TestValidate(t *testing.T) {
 	kvDoc = &model.KVDoc{Project: "a", Domain: "a",
 		Key:    "a",
 		Value:  "a",
-		Labels: map[string]string{testStr + "a": "a"},
+		Labels: map[string]string{string32 + "a": "a"},
 	}
 	assert.Error(t, validate.Validate(kvDoc))
 }
diff --git a/server/resource/v1/common.go b/server/resource/v1/common.go
index 19856e9..91987ea 100644
--- a/server/resource/v1/common.go
+++ b/server/resource/v1/common.go
@@ -211,15 +211,6 @@ func checkPagination(offsetStr, limitStr string) (int64, int64, error) {
 	return offset, limit, err
 }
 
-func validatePut(kv *model.KVDoc) error {
-	err := validateGet(kv.Domain, kv.Project, kv.ID)
-	if err != nil {
-		return err
-	}
-	_, err = checkStatus(kv.Status)
-	return err
-}
-
 func validateGet(domain, project, kvID string) error {
 	if kvID == "" {
 		return session.ErrIDIsNil
diff --git a/server/resource/v1/history_resource_test.go b/server/resource/v1/history_resource_test.go
index 44becb8..0f8b830 100644
--- a/server/resource/v1/history_resource_test.go
+++ b/server/resource/v1/history_resource_test.go
@@ -65,9 +65,14 @@ func TestHistoryResource_GetRevisions(t *testing.T) {
 	assert.GreaterOrEqual(t, before, 1)
 
 	t.Run("put again, should has 2 revision", func(t *testing.T) {
-		kv.Domain = "default"
-		kv.Project = "history_test"
-		kv, err = service.KVService.Update(context.Background(), kv)
+		updateKv := &model.UpdateKVRequest{
+			ID:      kv.ID,
+			Value:   kv.Value,
+			Domain:  "default",
+			Project: "history_test",
+			Status:  kv.Status,
+		}
+		kv, err = service.KVService.Update(context.Background(), updateKv)
 		assert.NoError(t, err)
 		path := fmt.Sprintf("/v1/history_test/kie/revision/%s", kv.ID)
 		r, _ := http.NewRequest("GET", path, nil)
diff --git a/server/resource/v1/kv_resource.go b/server/resource/v1/kv_resource.go
index 64cb170..6019684 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -102,21 +102,21 @@ func (r *KVResource) Put(rctx *restful.Context) {
 	var err error
 	kvID := rctx.ReadPathParameter(common.PathParamKVID)
 	project := rctx.ReadPathParameter(common.PathParameterProject)
-	kv := new(model.KVDoc)
-	if err = readRequest(rctx, kv); err != nil {
+	kvReq := new(model.UpdateKVRequest)
+	if err = readRequest(rctx, kvReq); err != nil {
 		WriteErrResponse(rctx, http.StatusBadRequest, fmt.Sprintf(FmtReadRequestError, err))
 		return
 	}
 	domain := ReadDomain(rctx)
-	kv.ID = kvID
-	kv.Domain = domain.(string)
-	kv.Project = project
-	err = validatePut(kv)
+	kvReq.ID = kvID
+	kvReq.Domain = domain.(string)
+	kvReq.Project = project
+	err = validate.Validate(kvReq)
 	if err != nil {
 		WriteErrResponse(rctx, http.StatusBadRequest, err.Error())
 		return
 	}
-	kv, err = service.KVService.Update(rctx.Ctx, kv)
+	kv, err := service.KVService.Update(rctx.Ctx, kvReq)
 	if err != nil {
 		openlogging.Error(fmt.Sprintf("put [%s] err:%s", kvID, err.Error()))
 		WriteErrResponse(rctx, http.StatusInternalServerError, "update kv failed")
diff --git a/server/resource/v1/kv_resource_test.go b/server/resource/v1/kv_resource_test.go
index 5868e6a..8d229ef 100644
--- a/server/resource/v1/kv_resource_test.go
+++ b/server/resource/v1/kv_resource_test.go
@@ -415,7 +415,7 @@ func TestKVResource_PutAndGet(t *testing.T) {
 		assert.NoError(t, err)
 		assert.Equal(t, kv.Value, result.Value)
 	})
-	kvUpdate := &model.KVDoc{
+	kvUpdate := &model.UpdateKVRequest{
 		Value: "admin",
 	}
 	t.Run("update the kv, set the value of user to admin", func(t *testing.T) {
diff --git a/server/service/mongo/kv/kv_service.go b/server/service/mongo/kv/kv_service.go
index 3d121ee..0587b03 100644
--- a/server/service/mongo/kv/kv_service.go
+++ b/server/service/mongo/kv/kv_service.go
@@ -71,7 +71,7 @@ func (s *Service) Create(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, er
 }
 
 //Update will update a key value record
-func (s *Service) Update(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error) {
+func (s *Service) Update(ctx context.Context, kv *model.UpdateKVRequest) (*model.KVDoc, error) {
 	ctx, _ = context.WithTimeout(ctx, session.Timeout)
 	oldKV, err := s.Get(ctx, kv.Domain, kv.Project, kv.ID)
 	if err != nil {
diff --git a/server/service/mongo/kv/kv_service_test.go b/server/service/mongo/kv/kv_service_test.go
index 9f8de37..0ad8fc1 100644
--- a/server/service/mongo/kv/kv_service_test.go
+++ b/server/service/mongo/kv/kv_service_test.go
@@ -95,13 +95,9 @@ func TestService_CreateOrUpdate(t *testing.T) {
 			Project: "kv-test",
 		})
 		assert.NoError(t, err)
-		afterKV, err := kvsvc.Update(context.Background(), &model.KVDoc{
-			ID:    beforeKV.ID,
-			Key:   "timeout",
-			Value: "3s",
-			Labels: map[string]string{
-				"app": "mall",
-			},
+		afterKV, err := kvsvc.Update(context.Background(), &model.UpdateKVRequest{
+			ID:      beforeKV.ID,
+			Value:   "3s",
 			Domain:  "default",
 			Project: "kv-test",
 		})
@@ -151,7 +147,7 @@ func TestService_Create(t *testing.T) {
 func TestService_Update(t *testing.T) {
 	kvsvc := &kv.Service{}
 	t.Run("update kv by kvID", func(t *testing.T) {
-		result, err := kvsvc.Update(context.TODO(), &model.KVDoc{
+		result, err := kvsvc.Update(context.TODO(), &model.UpdateKVRequest{
 			ID:      id,
 			Value:   "3s",
 			Domain:  "default",
diff --git a/server/service/service.go b/server/service/service.go
index 51552f3..be19bff 100644
--- a/server/service/service.go
+++ b/server/service/service.go
@@ -43,7 +43,7 @@ var (
 type KV interface {
 	//below 3 methods is usually for admin console
 	Create(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error)
-	Update(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error)
+	Update(ctx context.Context, kv *model.UpdateKVRequest) (*model.KVDoc, error)
 	List(ctx context.Context, domain, project string, options ...FindOption) (*model.KVResponse, error)
 	//FindOneAndDelete deletes one kv by id and return the deleted kv as these appeared before deletion
 	FindOneAndDelete(ctx context.Context, kvID string, domain, project string) (*model.KVDoc, error)