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: "",
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)
49
50
51 client, err := bslClient.WithBackendOrgAccessKey(ctx, testOrganization)
52 assert.NoError(err)
53 err = client.Post("access-key")
54 assert.Nil(err)
55
56
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
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
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: "",
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)
95
96
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