From 2a0042ead5881d5a336728ba03e1bf61fee76b10 Mon Sep 17 00:00:00 2001 From: mmyj Date: Thu, 8 Oct 2020 17:31:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20TimestampChecker?= =?UTF-8?q?=20(#9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 优化 TimestampChecker * feat: 优化 TimestampChecker --- apiaccessor/accessor.go | 12 ++++++++---- apiaccessor/base_accessor.go | 16 +++++++++++----- apiaccessor/base_accessor_test.go | 17 +++++++++++++++++ apiaccessor/query_accessor.go | 8 ++++---- apiaccessor/query_accessor_test.go | 12 ++++++------ apiaccessor/setter.go | 10 +++++++++- 6 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 apiaccessor/base_accessor_test.go diff --git a/apiaccessor/accessor.go b/apiaccessor/accessor.go index 8cd4327..f65fe86 100644 --- a/apiaccessor/accessor.go +++ b/apiaccessor/accessor.go @@ -12,10 +12,14 @@ type Accessor interface { } var ( - errArgLack = errors.New("arg lack") - errSignatureUnmatched = errors.New("signature is unmatched") - errTimestampTimeout = errors.New("timestamp time out") - errNonceUsed = errors.New("nonce is used") + // ErrArgLack represent the request's arguments are lack. + ErrArgLack = errors.New("arg lack") + // ErrSignatureUnmatched represent the signature of the request's arguments is wrong. + ErrSignatureUnmatched = errors.New("signature is unmatched") + // ErrTimestampTimeout represent the timestamp argument timeout. + ErrTimestampTimeout = errors.New("timestamp time out") + // ErrNonceUsed represent the nonce argument had been used. + ErrNonceUsed = errors.New("nonce is used") ) const ( diff --git a/apiaccessor/base_accessor.go b/apiaccessor/base_accessor.go index 52523bd..18aa14d 100644 --- a/apiaccessor/base_accessor.go +++ b/apiaccessor/base_accessor.go @@ -27,15 +27,21 @@ func defEvalSignatureFunc(move uint) EvalSignature { } func defTimestampChecker(timestamp int64) error { - const sec = 5 - dt := time.Now().Unix() - timestamp + const ( + sec = 5 + timeFormat = "2006/01/02 15:04:05" + ) + now := time.Now() + dt := now.Unix() - timestamp if dt > sec || dt < -sec { - return errTimestampTimeout + nowTimeStr := now.Format(timeFormat) + timestampStr := time.Unix(timestamp, 0).In(now.Location()).Format(timeFormat) + return fmt.Errorf("%w: now %s, get %s", ErrTimestampTimeout, nowTimeStr, timestampStr) } return nil } -func defNonceChecker(nonce string) error { +func defNonceChecker(_ string) error { return nil } @@ -76,7 +82,7 @@ func (a *baseAccessor) CheckSignature() error { signature := a.evalSignatureFunc(argText) argSignature := a.args.kv[signatureTag] if signature != argSignature { - return fmt.Errorf("%w: want %s, get %s", errSignatureUnmatched, signature, argSignature) + return fmt.Errorf("%w: want %s, get %s", ErrSignatureUnmatched, signature, argSignature) } return nil } diff --git a/apiaccessor/base_accessor_test.go b/apiaccessor/base_accessor_test.go new file mode 100644 index 0000000..a3aaa3e --- /dev/null +++ b/apiaccessor/base_accessor_test.go @@ -0,0 +1,17 @@ +package apiaccessor + +import ( + "errors" + "testing" + "time" + + "github.com/go-playground/assert/v2" +) + +func TestDefTimestampChecker(t *testing.T) { + err := defTimestampChecker(1602146001) // 2020-10-08 16:33:21 + assert.Equal(t, errors.Is(err, ErrTimestampTimeout), true) + t.Log(err) + err = defTimestampChecker(time.Now().Unix()) + assert.Equal(t, err, nil) +} diff --git a/apiaccessor/query_accessor.go b/apiaccessor/query_accessor.go index a10ff0d..f74bd8b 100644 --- a/apiaccessor/query_accessor.go +++ b/apiaccessor/query_accessor.go @@ -18,19 +18,19 @@ func NewQueryAccessor(query url.Values, secretKey string, setters ...Setter) (*Q for key, vs := range query { v := vs[0] if len(v) == 0 { - return nil, fmt.Errorf("%w: %s", errArgLack, key) + return nil, fmt.Errorf("%w: %s", ErrArgLack, key) } qa.args.append(key, v) } qa.args.append(secretKeyTag, secretKey) if len(qa.args.kv[nonceTag]) == 0 { - return nil, fmt.Errorf("%w: %s", errArgLack, nonceTag) + return nil, fmt.Errorf("%w: %s", ErrArgLack, nonceTag) } if len(qa.args.kv[timestampTag]) == 0 { - return nil, fmt.Errorf("%w: %s", errArgLack, timestampTag) + return nil, fmt.Errorf("%w: %s", ErrArgLack, timestampTag) } if len(qa.args.kv[signatureTag]) == 0 { - return nil, fmt.Errorf("%w: %s", errArgLack, signatureTag) + return nil, fmt.Errorf("%w: %s", ErrArgLack, signatureTag) } for _, setter := range setters { diff --git a/apiaccessor/query_accessor_test.go b/apiaccessor/query_accessor_test.go index 958f6d1..b6cb2bd 100644 --- a/apiaccessor/query_accessor_test.go +++ b/apiaccessor/query_accessor_test.go @@ -13,13 +13,13 @@ import ( func TestNewQueryAccessor(t *testing.T) { query := url.Values{} _, err := NewQueryAccessor(query, "123") - assert.Equal(t, errors.Is(err, errArgLack), true) + assert.Equal(t, errors.Is(err, ErrArgLack), true) query = url.Values{ nonceTag: []string{"12345"}, } _, err = NewQueryAccessor(query, "123") - assert.Equal(t, errors.Is(err, errArgLack), true) + assert.Equal(t, errors.Is(err, ErrArgLack), true) query = url.Values{ nonceTag: []string{"12345"}, @@ -52,7 +52,7 @@ func TestCheckSignature(t *testing.T) { qa, err := NewQueryAccessor(query, "123") assert.Equal(t, err, nil) err = qa.CheckSignature() - assert.Equal(t, errors.Is(err, errSignatureUnmatched), true) + assert.Equal(t, errors.Is(err, ErrSignatureUnmatched), true) query = url.Values{ nonceTag: []string{"12345"}, @@ -78,7 +78,7 @@ func TestCheckTimestamp(t *testing.T) { qa, err := NewQueryAccessor(query, "123") assert.Equal(t, err, nil) err = qa.CheckTimestamp() - assert.Equal(t, errors.Is(err, errTimestampTimeout), true) + assert.Equal(t, errors.Is(err, ErrTimestampTimeout), true) query = url.Values{ nonceTag: []string{"12345"}, @@ -97,7 +97,7 @@ func TestCheckNonce(t *testing.T) { nonceMap := make(map[string]bool) mockNonceChecker := func(nonce string) error { if _, ok := nonceMap[nonce]; ok { - return errNonceUsed + return ErrNonceUsed } nonceMap[nonce] = true return nil @@ -115,5 +115,5 @@ func TestCheckNonce(t *testing.T) { err = qa.CheckNonce() assert.Equal(t, err, nil) err = qa.CheckNonce() - assert.Equal(t, errors.Is(err, errNonceUsed), true) + assert.Equal(t, errors.Is(err, ErrNonceUsed), true) } diff --git a/apiaccessor/setter.go b/apiaccessor/setter.go index 4516163..8934f77 100644 --- a/apiaccessor/setter.go +++ b/apiaccessor/setter.go @@ -46,7 +46,7 @@ func WithGeneralRedisNonceChecker(client redis.Cmdable, sec int64, keyGenFunc Ke return err } if re == 1 { - return errNonceUsed + return ErrNonceUsed } return nil } @@ -61,3 +61,11 @@ func WithNonceChecker(nc NonceChecker) Setter { return nil } } + +// WithTimestampChecker set a custom TimestampChecker for the Accessor +func WithTimestampChecker(tc TimestampChecker) Setter { + return func(b *baseAccessor) error { + b.timestampChecker = tc + return nil + } +}