Structures for the one-step connection (#58)

This commit is contained in:
Pavel 2021-11-17 16:57:35 +03:00 committed by GitHub
parent 8cfe7034e6
commit cdbf1d6e33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 124 additions and 0 deletions

View File

@ -1,5 +1,11 @@
package retailcrm package retailcrm
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
)
// CustomerRequest type. // CustomerRequest type.
type CustomerRequest struct { type CustomerRequest struct {
By string `url:"by,omitempty"` By string `url:"by,omitempty"`
@ -215,3 +221,35 @@ type CustomDictionariesRequest struct {
Limit int `url:"limit,omitempty"` Limit int `url:"limit,omitempty"`
Page int `url:"page,omitempty"` Page int `url:"page,omitempty"`
} }
// ConnectRequest contains information about the system connection that is requested to be created.
type ConnectRequest struct {
// Token is used to verify the request. Do not use directly; use Verify instead.
Token string `json:"token"`
// APIKey that was generated for the module.
APIKey string `json:"apiKey"`
// URL of the system. Do not use directly; use SystemURL instead.
URL string `json:"systemUrl"`
}
// SystemURL returns system URL from the connection request without trailing slash.
func (r ConnectRequest) SystemURL() string {
if r.URL == "" {
return ""
}
if r.URL[len(r.URL)-1:] == "/" {
return r.URL[:len(r.URL)-1]
}
return r.URL
}
// Verify returns true if connection request is legitimate. Application secret should be provided to this method.
func (r ConnectRequest) Verify(secret string) bool {
mac := hmac.New(sha256.New, []byte(secret))
if _, err := mac.Write([]byte(r.APIKey)); err != nil {
panic(err)
}
return hmac.Equal([]byte(r.Token), []byte(hex.EncodeToString(mac.Sum(nil))))
}

43
request_test.go Normal file
View File

@ -0,0 +1,43 @@
package retailcrm
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"testing"
"github.com/stretchr/testify/suite"
)
type ConnectRequestTest struct {
suite.Suite
}
func TestConnectRequest(t *testing.T) {
suite.Run(t, new(ConnectRequestTest))
}
func (t *ConnectRequestTest) Test_SystemURL() {
t.Assert().Equal("", ConnectRequest{}.SystemURL())
t.Assert().Equal("https://test.retailcrm.pro", ConnectRequest{URL: "https://test.retailcrm.pro"}.SystemURL())
t.Assert().Equal("https://test.retailcrm.pro", ConnectRequest{URL: "https://test.retailcrm.pro/"}.SystemURL())
}
func (t *ConnectRequestTest) Test_Verify() {
t.Assert().True(ConnectRequest{
APIKey: "key",
Token: createConnectToken("key", "secret"),
}.Verify("secret"))
t.Assert().False(ConnectRequest{
APIKey: "key",
Token: createConnectToken("key", "secret2"),
}.Verify("secret"))
}
func createConnectToken(apiKey, secret string) string {
mac := hmac.New(sha256.New, []byte(secret))
if _, err := mac.Write([]byte(apiKey)); err != nil {
panic(err)
}
return hex.EncodeToString(mac.Sum(nil))
}

View File

@ -495,3 +495,30 @@ type UnitsResponse struct {
Success bool `json:"success"` Success bool `json:"success"`
Units *[]Unit `json:"units,omitempty"` Units *[]Unit `json:"units,omitempty"`
} }
// ErrorResponse should be returned to the one-step connection request in case of failure.
type ErrorResponse struct {
SuccessfulResponse
ErrorMessage string `json:"errorMsg"`
}
// ConnectResponse should be returned to the one-step connection request in case of successful connection.
type ConnectResponse struct {
SuccessfulResponse
AccountURL string `json:"accountUrl"`
}
// ConnectionConfigResponse contains connection configuration for one-step connection.
type ConnectionConfigResponse struct {
SuccessfulResponse
Scopes []string `json:"scopes"`
RegisterURL string `json:"registerUrl"`
}
// NewConnectResponse returns ConnectResponse with the provided account URL.
func NewConnectResponse(accountURL string) ConnectResponse {
return ConnectResponse{
SuccessfulResponse: SuccessfulResponse{Success: true},
AccountURL: accountURL,
}
}

16
response_test.go Normal file
View File

@ -0,0 +1,16 @@
package retailcrm
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestNewConnectResponse(t *testing.T) {
assert.Equal(t, ConnectResponse{
SuccessfulResponse: SuccessfulResponse{
Success: true,
},
AccountURL: "https://example.com",
}, NewConnectResponse("https://example.com"))
}