...

Source file src/edge-infra.dev/pkg/edge/bsl/bsl_client_test.go

Documentation: edge-infra.dev/pkg/edge/bsl

     1  package bsl
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"net/http"
     9  	"net/http/httptest"
    10  	"strings"
    11  	"testing"
    12  
    13  	bsltypes "edge-infra.dev/pkg/edge/api/bsl/types"
    14  	"edge-infra.dev/pkg/edge/api/middleware"
    15  
    16  	"github.com/NCR-Corporation/ncr-bsp-hmac/go/sign"
    17  	"github.com/stretchr/testify/assert"
    18  )
    19  
    20  const (
    21  	testUser         = "test-shared"
    22  	testPassword     = "test-shared"
    23  	testSharedKey    = "test-shared"
    24  	testSecretKey    = "test-secret"
    25  	testOrganization = "test-organization"
    26  	testToken        = "test-token"
    27  )
    28  
    29  func TestBSLClient(t *testing.T) {
    30  	assert := assert.New(t)
    31  	ctx := context.Background()
    32  
    33  	srv := buildTestServer(assert)
    34  	defer srv.Close()
    35  
    36  	config := bsltypes.BSPConfig{
    37  		Endpoint:           srv.URL,
    38  		Root:               "/example/",
    39  		OrganizationPrefix: "test-bsl",
    40  		ResetURL:           "", // not used by client
    41  	}
    42  
    43  	secret := &AccessKey{SecretKey: testSecretKey, SharedKey: testSharedKey}
    44  	bslClient := NewBSLClient(config,
    45  		func(_ context.Context, _ string) (*AccessKey, error) {
    46  			return secret, nil
    47  		})
    48  	bslClient.SetDisableWarn(true) // for testing purpose only
    49  
    50  	// Post WithBackendOrgAccessKey
    51  	client, err := bslClient.WithBackendOrgAccessKey(ctx, testOrganization)
    52  	assert.NoError(err)
    53  	err = client.Post("access-key")
    54  	assert.Nil(err)
    55  
    56  	// Post after WithAuthentication
    57  	client, securityData, err := bslClient.WithAuthentication(ctx, testOrganization, testUser, testPassword)
    58  	assert.Nil(err)
    59  	assert.NotNil(securityData)
    60  	assert.NotNil(client)
    61  
    62  	err = client.Post("auth")
    63  	assert.Nil(err)
    64  
    65  	// Post WithUserTokenCredentials
    66  	ctx = middleware.NewContext(ctx, &bsltypes.AuthUser{
    67  		Organization: testOrganization,
    68  		Token:        testToken,
    69  	})
    70  	assert.Nil(bslClient.WithUserTokenCredentials(ctx).Post("user-credentials"))
    71  
    72  	// Post WithAccessToken
    73  	assert.Nil(bslClient.WithAccessToken(ctx, testToken).SetOrg(testOrganization).Post("user-credentials"))
    74  }
    75  
    76  func TestBSLRequest(t *testing.T) {
    77  	assert := assert.New(t)
    78  	ctx := context.Background()
    79  
    80  	srv := buildTestServer(assert)
    81  	defer srv.Close()
    82  
    83  	config := bsltypes.BSPConfig{
    84  		Endpoint:           srv.URL,
    85  		Root:               "/example/",
    86  		OrganizationPrefix: "test-bsl",
    87  		ResetURL:           "", // not used by client
    88  	}
    89  	secret := &AccessKey{SecretKey: testSecretKey, SharedKey: testSharedKey}
    90  	bslClient := NewBSLClient(config,
    91  		func(_ context.Context, _ string) (*AccessKey, error) {
    92  			return secret, nil
    93  		})
    94  	bslClient.SetDisableWarn(true) // for testing purpose only
    95  
    96  	// Post WithUserTokenCredentials
    97  	ctx = middleware.NewContext(ctx, &bsltypes.AuthUser{
    98  		Organization: "old-org",
    99  		Token:        testToken,
   100  	})
   101  	client := bslClient.WithUserTokenCredentials(ctx)
   102  
   103  	var resp struct {
   104  		Name string `json:"name"`
   105  	}
   106  	err := client.SetOrg(testOrganization).
   107  		SetPayload("{\"name\": \"tester\"}").
   108  		JSON("post", "json", &resp)
   109  	assert.Nil(err)
   110  	assert.Equal("tester", resp.Name)
   111  }
   112  
   113  func buildTestServer(assert *assert.Assertions) *httptest.Server {
   114  	return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   115  		assertHeaders(assert, r)
   116  		if strings.HasSuffix(r.URL.String(), "security/authentication/login") {
   117  			sec := &bsltypes.SecurityTokenData{
   118  				Token: testToken,
   119  			}
   120  			data, err := json.Marshal(sec)
   121  			assert.NoError(err)
   122  			_, err = w.Write(data)
   123  			assert.NoError(err)
   124  			return
   125  		}
   126  		body, err := io.ReadAll(r.Body)
   127  		assert.NoError(err)
   128  		if len(body) == 0 {
   129  			body = []byte("{}")
   130  		}
   131  		_, err = w.Write(body)
   132  		assert.NoError(err)
   133  	}))
   134  }
   135  
   136  func assertHeaders(assert *assert.Assertions, r *http.Request) {
   137  	msg := fmt.Sprintf("request failed: url %s", r.URL)
   138  	assert.NotEmpty(r.Header.Get(NepCorrelationID), msg)
   139  	assert.NotEmpty(r.Header.Get(sign.DateHeader), msg)
   140  	assert.Equal("/example/test-organization/", r.Header.Get(NepOrganization), msg)
   141  	assert.Equal(jsonType, r.Header.Get("Accept"), msg)
   142  	assert.Equal(jsonType, r.Header.Get("Content-Type"), msg)
   143  	assert.Equal("true", r.Header.Get("Access-Control-Allow-Credentials"), msg)
   144  	assertAuthorization(assert, r)
   145  }
   146  
   147  func assertAuthorization(assert *assert.Assertions, r *http.Request) {
   148  	auth := r.Header.Get("Authorization")
   149  	assert.NotEmpty(auth)
   150  	authParts := strings.Split(auth, " ")
   151  	scheme := authParts[0]
   152  	if scheme == sign.AccessKeyPrefix {
   153  		keys := strings.Split(authParts[1], ":")
   154  		assert.Equal(testSharedKey, keys[0])
   155  		assert.NotEmpty(keys[1])
   156  	} else if scheme == AccessTokenPrefix {
   157  		assert.Equal(testToken, authParts[1])
   158  	} else if scheme == "Bearer" || scheme == "Basic" {
   159  		assert.NotEmpty(authParts[1])
   160  	} else {
   161  		assert.Fail("scheme not recognized", "scheme: %s for url: %s", scheme, r.URL)
   162  	}
   163  }
   164  

View as plain text