Skip to content

Commit

Permalink
Merge pull request #164 from multiversx/merge-main-rc-v1.6.0-2023.12.21
Browse files Browse the repository at this point in the history
Merge main rc v1.6.0 2023.12.21
  • Loading branch information
iulianpascalau authored Dec 22, 2023
2 parents 4e5de92 + 44346a0 commit fe20c41
Show file tree
Hide file tree
Showing 67 changed files with 2,742 additions and 2,317 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: golangci-lint

on:
push:
branches: [ main, development, feat/* ]
branches: [ main, feat/*, rc/* ]
pull_request:
branches: [ main, development, feat/* ]
branches: [ main, feat/*, rc/* ]

permissions:
contents: read
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/pr-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ name: Tests

on:
push:
branches: [ main, feat/* ]
branches: [ main, feat/*, rc/* ]
pull_request:
branches: [ main, feat/* ]
branches: [ main, feat/*, rc/* ]

jobs:
test:
name: Unit
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
- name: Set up Go 1.17.6
uses: actions/setup-go@v3
with:
go-version: 1.20.7
id: go

- name: Check out code
uses: actions/checkout@v2
uses: actions/checkout@v3

- name: Get dependencies
run: |
Expand Down
8 changes: 5 additions & 3 deletions aggregator/fetchers/fetchers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/multiversx/mx-sdk-go/aggregator"
"github.com/multiversx/mx-sdk-go/aggregator/mock"
"github.com/multiversx/mx-sdk-go/authentication"
"github.com/multiversx/mx-sdk-go/authentication/native"
"github.com/multiversx/mx-sdk-go/blockchain"
"github.com/multiversx/mx-sdk-go/blockchain/cryptoProvider"
"github.com/multiversx/mx-sdk-go/core"
Expand Down Expand Up @@ -69,16 +70,17 @@ func createAuthClient() (authentication.AuthClient, error) {

keyGen := signing.NewKeyGenerator(ed25519.NewEd25519())
holder, _ := cryptoProvider.NewCryptoComponentsHolder(keyGen, privateKeyBytes)
args := authentication.ArgsNativeAuthClient{
args := native.ArgsNativeAuthClient{
Signer: cryptoProvider.NewSigner(),
ExtraInfo: nil,
ExtraInfo: struct{}{},
Proxy: proxy,
CryptoComponentsHolder: holder,
TokenExpiryInSeconds: 60 * 60 * 24,
Host: "oracle",
TokenHandler: native.NewAuthTokenHandler(),
}

authClient, err := authentication.NewNativeAuthClient(args)
authClient, err := native.NewNativeAuthClient(args)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion aggregator/graphqlResponseGetter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"net/url"
"testing"

"github.com/multiversx/mx-sdk-go/authentication/mock"
"github.com/multiversx/mx-sdk-go/authentication/native/mock"
"github.com/stretchr/testify/require"
)

Expand Down
4 changes: 2 additions & 2 deletions aggregator/httpResponseGetter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package aggregator
import (
"context"
"encoding/json"
"io/ioutil"
"io"
"net/http"
)

Expand Down Expand Up @@ -35,7 +35,7 @@ func (getter *httpResponseGetter) Get(ctx context.Context, url string, response
return err
}

respBytes, err := ioutil.ReadAll(resp.Body)
respBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion aggregator/notifees/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

// TxBuilder defines the component able to build & sign a transaction
type TxBuilder interface {
ApplySignature(cryptoHolder core.CryptoComponentsHolder, tx *transaction.FrontendTransaction) error
ApplyUserSignature(cryptoHolder core.CryptoComponentsHolder, tx *transaction.FrontendTransaction) error
IsInterfaceNil() bool
}

Expand Down
2 changes: 1 addition & 1 deletion aggregator/notifees/mxNotifee.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func (en *mxNotifee) PriceChanged(ctx context.Context, priceChanges []*aggregato
return err
}

err = en.txBuilder.ApplySignature(en.cryptoHolder, tx)
err = en.txBuilder.ApplyUserSignature(en.cryptoHolder, tx)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion aggregator/notifees/mxNotifee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ func TestMxNotifee_PriceChanged(t *testing.T) {
},
}
args.TxBuilder = &testsCommon.TxBuilderStub{
ApplySignatureCalled: func(cryptoHolder core.CryptoComponentsHolder, tx *transaction.FrontendTransaction) error {
ApplyUserSignatureCalled: func(cryptoHolder core.CryptoComponentsHolder, tx *transaction.FrontendTransaction) error {
return expectedErr
},
}
Expand Down
48 changes: 43 additions & 5 deletions authentication/errors.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,50 @@
package authentication

import "errors"
import (
"errors"
"fmt"
"net/http"
)

// ErrNilTxSigner signals that a nil transaction signer was provided
var ErrNilTxSigner = errors.New("nil transaction signer")
// ErrNilTokenHandler signals that a nil token handler has been provided
var ErrNilTokenHandler = errors.New("nil token handler")

// ErrNilProxy signals that a nil proxy was provided
var ErrNilProxy = errors.New("nil proxy")
// ErrNilSigner signals that a nil signer has been provided
var ErrNilSigner = errors.New("nil signer")

// ErrNilSignature signals that the token has a nil signature
var ErrNilSignature = errors.New("nil token signature")

// ErrNilAddress signals that the token has a nil address
var ErrNilAddress = errors.New("nil token address")

// ErrNilBody signals that the token has a nil body
var ErrNilBody = errors.New("nil token body")

// ErrTokenExpired signals that the provided token is expired
var ErrTokenExpired = errors.New("token expired")

// ErrNilCryptoComponentsHolder signals that a nil cryptoComponentsHolder has been provided
var ErrNilCryptoComponentsHolder = errors.New("nil cryptoComponentsHolder")

// ErrNilHttpClientWrapper signals that a nil http client wrapper was provided
var ErrNilHttpClientWrapper = errors.New("nil http client wrapper")

// ErrHTTPStatusCodeIsNotOK signals that the returned HTTP status code is not OK
var ErrHTTPStatusCodeIsNotOK = errors.New("HTTP status code is not OK")

// ErrNilCacher signals that a nil cacher has been provided
var ErrNilCacher = errors.New("nil cacher")

// ErrInvalidValue signals that an invalid value has been provided
var ErrInvalidValue = errors.New("invalid value")

// CreateHTTPStatusError creates an error with the provided http status code and error
func CreateHTTPStatusError(httpStatusCode int, err error) error {
if err == nil {
err = ErrHTTPStatusCodeIsNotOK
}

return fmt.Errorf("%w, returned http status: %d, %s",
err, httpStatusCode, http.StatusText(httpStatusCode))
}
36 changes: 36 additions & 0 deletions authentication/interface.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,43 @@
package authentication

import "context"

// AuthClient defines the behavior of an authentication client
type AuthClient interface {
GetAccessToken() (string, error)
IsInterfaceNil() bool
}

// AuthServer defines the behavior of an authentication server
type AuthServer interface {
Validate(accessToken AuthToken) error
IsInterfaceNil() bool
}

// AuthTokenHandler defines the behavior of an authentication token handler
type AuthTokenHandler interface {
Decode(accessToken string) (AuthToken, error)
Encode(authToken AuthToken) (string, error)
GetUnsignedToken(authToken AuthToken) []byte
GetSignableMessage(address, unsignedToken []byte) []byte
GetSignableMessageLegacy(address, unsignedToken []byte) []byte
IsInterfaceNil() bool
}

// AuthToken defines the behavior of an authentication token
type AuthToken interface {
GetTtl() int64
GetAddress() []byte
GetHost() []byte
GetSignature() []byte
GetBlockHash() string
GetExtraInfo() []byte
IsInterfaceNil() bool
}

// HttpClientWrapper defines the behavior of http client able to make http requests
type HttpClientWrapper interface {
GetHTTP(ctx context.Context, endpoint string) ([]byte, int, error)
PostHTTP(ctx context.Context, endpoint string, data []byte) ([]byte, int, error)
IsInterfaceNil() bool
}
70 changes: 40 additions & 30 deletions authentication/native.go → authentication/native/client.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package authentication
package native

import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"time"

"github.com/multiversx/mx-chain-core-go/core/check"
"github.com/multiversx/mx-sdk-go/authentication"
"github.com/multiversx/mx-sdk-go/builders"
"github.com/multiversx/mx-sdk-go/core"
"github.com/multiversx/mx-sdk-go/workflows"
Expand All @@ -16,60 +16,64 @@ import (
// ArgsNativeAuthClient is the DTO used in the native auth client constructor
type ArgsNativeAuthClient struct {
Signer builders.Signer
ExtraInfo interface{}
ExtraInfo struct{}
Proxy workflows.ProxyHandler
CryptoComponentsHolder core.CryptoComponentsHolder
TokenExpiryInSeconds uint64
TokenHandler authentication.AuthTokenHandler
TokenExpiryInSeconds int64
Host string
}

type nativeAuthClient struct {
type authClient struct {
signer builders.Signer
encodedExtraInfo string
extraInfo []byte
proxy workflows.ProxyHandler
tokenExpiryInSeconds uint64
cryptoComponentsHolder core.CryptoComponentsHolder
encodedHost string
tokenExpiryInSeconds int64
host []byte
token string
tokenHandler authentication.AuthTokenHandler
tokenExpire time.Time
getTimeHandler func() time.Time
}

// NewNativeAuthClient will create a new native client able to create authentication tokens
func NewNativeAuthClient(args ArgsNativeAuthClient) (*nativeAuthClient, error) {
func NewNativeAuthClient(args ArgsNativeAuthClient) (*authClient, error) {
if check.IfNil(args.Signer) {
return nil, ErrNilTxSigner
return nil, authentication.ErrNilSigner
}

extraInfoBytes, err := json.Marshal(args.ExtraInfo)
if err != nil {
return nil, fmt.Errorf("%w while marshaling args.ExtraInfo", err)
return nil, fmt.Errorf("%w while marshaling args.extraInfo", err)
}

if check.IfNil(args.Proxy) {
return nil, ErrNilProxy
return nil, workflows.ErrNilProxy
}

if check.IfNil(args.CryptoComponentsHolder) {
return nil, ErrNilCryptoComponentsHolder
if check.IfNil(args.TokenHandler) {
return nil, authentication.ErrNilTokenHandler
}

encodedHost := base64.StdEncoding.EncodeToString([]byte(args.Host))
encodedExtraInfo := base64.StdEncoding.EncodeToString(extraInfoBytes)
if check.IfNil(args.CryptoComponentsHolder) {
return nil, authentication.ErrNilCryptoComponentsHolder
}

return &nativeAuthClient{
return &authClient{
signer: args.Signer,
encodedExtraInfo: encodedExtraInfo,
extraInfo: extraInfoBytes,
proxy: args.Proxy,
cryptoComponentsHolder: args.CryptoComponentsHolder,
encodedHost: encodedHost,
host: []byte(args.Host),
tokenHandler: args.TokenHandler,
tokenExpiryInSeconds: args.TokenExpiryInSeconds,
getTimeHandler: time.Now,
}, nil
}

// GetAccessToken returns an access token used for authentication into different MultiversX services
func (nac *nativeAuthClient) GetAccessToken() (string, error) {
func (nac *authClient) GetAccessToken() (string, error) {
now := nac.getTimeHandler()
noToken := nac.tokenExpire.IsZero()
tokenExpired := now.After(nac.tokenExpire)
Expand All @@ -82,7 +86,7 @@ func (nac *nativeAuthClient) GetAccessToken() (string, error) {
return nac.token, nil
}

func (nac *nativeAuthClient) createNewToken() error {
func (nac *authClient) createNewToken() error {
nonce, err := nac.proxy.GetLatestHyperBlockNonce(context.Background())
if err != nil {
return err
Expand All @@ -93,24 +97,30 @@ func (nac *nativeAuthClient) createNewToken() error {
return err
}

token := fmt.Sprintf("%s.%s.%d.%s", nac.encodedHost, lastHyperblock.Hash, nac.tokenExpiryInSeconds, nac.encodedExtraInfo)
token := &AuthToken{
ttl: nac.tokenExpiryInSeconds,
host: nac.host,
extraInfo: nac.extraInfo,
blockHash: lastHyperblock.Hash,
address: []byte(nac.cryptoComponentsHolder.GetBech32()),
}

signature, err := nac.signer.SignMessage([]byte(token), nac.cryptoComponentsHolder.GetPrivateKey())
unsignedToken := nac.tokenHandler.GetUnsignedToken(token)
signableMessage := nac.tokenHandler.GetSignableMessage(token.GetAddress(), unsignedToken)
token.signature, err = nac.signer.SignMessage(signableMessage, nac.cryptoComponentsHolder.GetPrivateKey())
if err != nil {
return err
}

encodedToken := base64.StdEncoding.EncodeToString([]byte(token))

encodedSignature := base64.StdEncoding.EncodeToString(signature)

encodedAddress := base64.StdEncoding.EncodeToString([]byte(nac.cryptoComponentsHolder.GetBech32()))
nac.token = fmt.Sprintf("%s.%s.%s", encodedAddress, encodedToken, encodedSignature)
nac.token, err = nac.tokenHandler.Encode(token)
if err != nil {
return err
}
nac.tokenExpire = nac.getTimeHandler().Add(time.Duration(nac.tokenExpiryInSeconds))
return nil
}

// IsInterfaceNil returns true if there is no value under the interface
func (nac *nativeAuthClient) IsInterfaceNil() bool {
func (nac *authClient) IsInterfaceNil() bool {
return nac == nil
}
Loading

0 comments on commit fe20c41

Please sign in to comment.