package bsl import ( "context" "encoding/json" "fmt" "io" "net/http" "net/http/httptest" "strings" "testing" bsltypes "edge-infra.dev/pkg/edge/api/bsl/types" "edge-infra.dev/pkg/edge/api/middleware" "github.com/NCR-Corporation/ncr-bsp-hmac/go/sign" "github.com/stretchr/testify/assert" ) const ( testUser = "test-shared" testPassword = "test-shared" testSharedKey = "test-shared" testSecretKey = "test-secret" testOrganization = "test-organization" testToken = "test-token" ) func TestBSLClient(t *testing.T) { assert := assert.New(t) ctx := context.Background() srv := buildTestServer(assert) defer srv.Close() config := bsltypes.BSPConfig{ Endpoint: srv.URL, Root: "/example/", OrganizationPrefix: "test-bsl", ResetURL: "", // not used by client } secret := &AccessKey{SecretKey: testSecretKey, SharedKey: testSharedKey} bslClient := NewBSLClient(config, func(_ context.Context, _ string) (*AccessKey, error) { return secret, nil }) bslClient.SetDisableWarn(true) // for testing purpose only // Post WithBackendOrgAccessKey client, err := bslClient.WithBackendOrgAccessKey(ctx, testOrganization) assert.NoError(err) err = client.Post("access-key") assert.Nil(err) // Post after WithAuthentication client, securityData, err := bslClient.WithAuthentication(ctx, testOrganization, testUser, testPassword) assert.Nil(err) assert.NotNil(securityData) assert.NotNil(client) err = client.Post("auth") assert.Nil(err) // Post WithUserTokenCredentials ctx = middleware.NewContext(ctx, &bsltypes.AuthUser{ Organization: testOrganization, Token: testToken, }) assert.Nil(bslClient.WithUserTokenCredentials(ctx).Post("user-credentials")) // Post WithAccessToken assert.Nil(bslClient.WithAccessToken(ctx, testToken).SetOrg(testOrganization).Post("user-credentials")) } func TestBSLRequest(t *testing.T) { assert := assert.New(t) ctx := context.Background() srv := buildTestServer(assert) defer srv.Close() config := bsltypes.BSPConfig{ Endpoint: srv.URL, Root: "/example/", OrganizationPrefix: "test-bsl", ResetURL: "", // not used by client } secret := &AccessKey{SecretKey: testSecretKey, SharedKey: testSharedKey} bslClient := NewBSLClient(config, func(_ context.Context, _ string) (*AccessKey, error) { return secret, nil }) bslClient.SetDisableWarn(true) // for testing purpose only // Post WithUserTokenCredentials ctx = middleware.NewContext(ctx, &bsltypes.AuthUser{ Organization: "old-org", Token: testToken, }) client := bslClient.WithUserTokenCredentials(ctx) var resp struct { Name string `json:"name"` } err := client.SetOrg(testOrganization). SetPayload("{\"name\": \"tester\"}"). JSON("post", "json", &resp) assert.Nil(err) assert.Equal("tester", resp.Name) } func buildTestServer(assert *assert.Assertions) *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assertHeaders(assert, r) if strings.HasSuffix(r.URL.String(), "security/authentication/login") { sec := &bsltypes.SecurityTokenData{ Token: testToken, } data, err := json.Marshal(sec) assert.NoError(err) _, err = w.Write(data) assert.NoError(err) return } body, err := io.ReadAll(r.Body) assert.NoError(err) if len(body) == 0 { body = []byte("{}") } _, err = w.Write(body) assert.NoError(err) })) } func assertHeaders(assert *assert.Assertions, r *http.Request) { msg := fmt.Sprintf("request failed: url %s", r.URL) assert.NotEmpty(r.Header.Get(NepCorrelationID), msg) assert.NotEmpty(r.Header.Get(sign.DateHeader), msg) assert.Equal("/example/test-organization/", r.Header.Get(NepOrganization), msg) assert.Equal(jsonType, r.Header.Get("Accept"), msg) assert.Equal(jsonType, r.Header.Get("Content-Type"), msg) assert.Equal("true", r.Header.Get("Access-Control-Allow-Credentials"), msg) assertAuthorization(assert, r) } func assertAuthorization(assert *assert.Assertions, r *http.Request) { auth := r.Header.Get("Authorization") assert.NotEmpty(auth) authParts := strings.Split(auth, " ") scheme := authParts[0] if scheme == sign.AccessKeyPrefix { keys := strings.Split(authParts[1], ":") assert.Equal(testSharedKey, keys[0]) assert.NotEmpty(keys[1]) } else if scheme == AccessTokenPrefix { assert.Equal(testToken, authParts[1]) } else if scheme == "Bearer" || scheme == "Basic" { assert.NotEmpty(authParts[1]) } else { assert.Fail("scheme not recognized", "scheme: %s for url: %s", scheme, r.URL) } }