Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wallet connect for the new object requests #236

Merged
merged 7 commits into from
Aug 18, 2024
168 changes: 113 additions & 55 deletions cmd/neofs-rest-gw/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func runLocalTests(ctx context.Context, t *testing.T, key *keys.PrivateKey) {

func runTestInContainer(rootCtx context.Context, t *testing.T, key *keys.PrivateKey) {
versions := []dockerImage{
{image: "nspccdev/neofs-aio", version: "0.41.0"},
{image: "nspccdev/neofs-aio", version: "0.42.1"},
}

for _, version := range versions {
Expand Down Expand Up @@ -150,9 +150,13 @@ func runTests(ctx context.Context, t *testing.T, key *keys.PrivateKey, node stri

t.Run("rest new upload object", func(t *testing.T) { restNewObjectUpload(ctx, t, clientPool, cnrID, signer) })
t.Run("rest new upload object with bearer in cookie", func(t *testing.T) { restNewObjectUploadCookie(ctx, t, clientPool, cnrID, signer) })
t.Run("rest new head object", func(t *testing.T) { restNewObjectHead(ctx, t, clientPool, &owner, cnrID, signer) })
t.Run("rest new head by attribute", func(t *testing.T) { restNewObjectHeadByAttribute(ctx, t, clientPool, &owner, cnrID, signer) })
t.Run("rest new get by attribute", func(t *testing.T) { restNewObjectGetByAttribute(ctx, t, clientPool, &owner, cnrID, signer) })
t.Run("rest new upload object with wallet connect", func(t *testing.T) { restNewObjectUploadWC(ctx, t, clientPool, cnrID, signer) })
t.Run("rest new head object", func(t *testing.T) { restNewObjectHead(ctx, t, clientPool, &owner, cnrID, signer, false) })
t.Run("rest new head object with wallet connect", func(t *testing.T) { restNewObjectHead(ctx, t, clientPool, &owner, cnrID, signer, true) })
t.Run("rest new head by attribute", func(t *testing.T) { restNewObjectHeadByAttribute(ctx, t, clientPool, &owner, cnrID, signer, false) })
t.Run("rest new head by attribute with wallet connect", func(t *testing.T) { restNewObjectHeadByAttribute(ctx, t, clientPool, &owner, cnrID, signer, true) })
t.Run("rest new get by attribute", func(t *testing.T) { restNewObjectGetByAttribute(ctx, t, clientPool, &owner, cnrID, signer, false) })
t.Run("rest new get by attribute with wallet connect", func(t *testing.T) { restNewObjectGetByAttribute(ctx, t, clientPool, &owner, cnrID, signer, true) })
}

func createDockerContainer(ctx context.Context, t *testing.T, image, version string) testcontainers.Container {
Expand Down Expand Up @@ -1871,12 +1875,15 @@ func restObjectUploadInt(ctx context.Context, t *testing.T, clientPool *pool.Poo
}

func restNewObjectUpload(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID, signer user.Signer) {
restNewObjectUploadInt(ctx, t, clientPool, cnrID, signer, false)
restNewObjectUploadInt(ctx, t, clientPool, cnrID, signer, false, false)
}
func restNewObjectUploadCookie(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID, signer user.Signer) {
restNewObjectUploadInt(ctx, t, clientPool, cnrID, signer, true)
restNewObjectUploadInt(ctx, t, clientPool, cnrID, signer, true, false)
}
func restNewObjectUploadInt(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID, signer user.Signer, cookie bool) {
func restNewObjectUploadWC(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID, signer user.Signer) {
restNewObjectUploadInt(ctx, t, clientPool, cnrID, signer, false, true)
}
func restNewObjectUploadInt(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID, signer user.Signer, cookie bool, walletConnect bool) {
bt := apiserver.Bearer{
Object: []apiserver.Record{{
Operation: apiserver.OperationPUT,
Expand All @@ -1897,15 +1904,15 @@ func restNewObjectUploadInt(ctx context.Context, t *testing.T, clientPool *pool.
query := make(url.Values)
query.Add(walletConnectQuery, strconv.FormatBool(useWalletConnect))

// check that object bearer token is valid
request, err := http.NewRequest(http.MethodGet, testHost+"/v1/auth/bearer?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
resp := &apiserver.BinaryBearer{}
doRequest(t, httpClient, request, http.StatusOK, resp)

actualTokenRaw, err := base64.StdEncoding.DecodeString(resp.Token)
require.NoError(t, err)
if !walletConnect {
request, err := http.NewRequest(http.MethodGet, testHost+"/v1/auth/bearer?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
doRequest(t, httpClient, request, http.StatusOK, resp)
_, err = base64.StdEncoding.DecodeString(resp.Token)
require.NoError(t, err)
}

content := "content of file"
attributes := map[string]string{
Expand All @@ -1917,22 +1924,30 @@ func restNewObjectUploadInt(ctx context.Context, t *testing.T, clientPool *pool.
attributesJSON, err := json.Marshal(attributes)
require.NoError(t, err)

if !walletConnect {
// Change the query, we only need the `fullBearer` parameter here.
query = make(url.Values)
query.Add(fullBearerQuery, "true")
}
body := bytes.NewBufferString(content)
request, err = http.NewRequest(http.MethodPost, testHost+"/v1/objects/"+cnrID.String(), body)
request, err := http.NewRequest(http.MethodPost, testHost+"/v1/objects/"+cnrID.String()+"?"+query.Encode(), body)
require.NoError(t, err)

request.Header.Set("Content-Type", "text/plain")
request.Header.Set("X-Attributes", string(attributesJSON))
if cookie {
request.Header.Add("Cookie", "Bearer="+base64.StdEncoding.EncodeToString(actualTokenRaw)+";")
if !walletConnect {
request.Header.Set("Content-Type", "text/plain")
if cookie {
request.Header.Add("Cookie", "Bearer="+resp.Token+";")
} else {
request.Header.Add("Authorization", "Bearer "+resp.Token)
}
} else {
request.Header.Add("Authorization", "Bearer "+base64.StdEncoding.EncodeToString(actualTokenRaw))
prepareCommonHeaders(request.Header, bearerToken)
}

request.Header.Set("X-Attributes", string(attributesJSON))
addr := &apiserver.AddressForUpload{}
doRequest(t, httpClient, request, http.StatusOK, addr)

request.Header.Set("Content-Type", "text/plain")

var CID cid.ID
err = CID.DecodeString(addr.ContainerId)
require.NoError(t, err)
Expand All @@ -1955,7 +1970,7 @@ func restNewObjectUploadInt(ctx context.Context, t *testing.T, clientPool *pool.
}
}

func restNewObjectHead(ctx context.Context, t *testing.T, p *pool.Pool, ownerID *user.ID, cnrID cid.ID, signer user.Signer) {
func restNewObjectHead(ctx context.Context, t *testing.T, p *pool.Pool, ownerID *user.ID, cnrID cid.ID, signer user.Signer, walletConnect bool) {
bearer := apiserver.Bearer{
Object: []apiserver.Record{
{
Expand Down Expand Up @@ -1987,11 +2002,13 @@ func restNewObjectHead(ctx context.Context, t *testing.T, p *pool.Pool, ownerID
query := make(url.Values)
query.Add(walletConnectQuery, strconv.FormatBool(useWalletConnect))

request, err := http.NewRequest(http.MethodGet, testHost+"/v1/auth/bearer?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
resp := &apiserver.BinaryBearer{}
doRequest(t, httpClient, request, http.StatusOK, resp)
if !walletConnect {
request, err := http.NewRequest(http.MethodGet, testHost+"/v1/auth/bearer?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
doRequest(t, httpClient, request, http.StatusOK, resp)
}

var (
content = []byte("some content")
Expand All @@ -2006,17 +2023,27 @@ func restNewObjectHead(ctx context.Context, t *testing.T, p *pool.Pool, ownerID
}
)

if !walletConnect {
// Change the query, we only need the `fullBearer` parameter here.
query = make(url.Values)
query.Add(fullBearerQuery, "true")
}

t.Run("head", func(t *testing.T) {
objID := createObject(ctx, t, p, ownerID, cnrID, attributes, content, signer)

attrTS := getObjectCreateTimestamp(ctx, t, p, cnrID, objID, signer)
createTS, err := strconv.ParseInt(attrTS, 10, 64)
require.NoError(t, err)

request, err = http.NewRequest(http.MethodHead, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/by_id/"+objID.EncodeToString()+"?"+query.Encode(), nil)
request, err := http.NewRequest(http.MethodHead, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/by_id/"+objID.EncodeToString()+"?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
request.Header.Set("Authorization", "Bearer "+resp.Token)

if !walletConnect {
request.Header.Set("Authorization", "Bearer "+resp.Token)
} else {
prepareCommonHeaders(request.Header, bearerToken)
}

headers, _ := doRequest(t, httpClient, request, http.StatusOK, nil)
require.NotEmpty(t, headers)
Expand Down Expand Up @@ -2066,10 +2093,14 @@ func restNewObjectHead(ctx context.Context, t *testing.T, p *pool.Pool, ownerID
createTS, err := strconv.ParseInt(attrTS, 10, 64)
require.NoError(t, err)

request, err = http.NewRequest(http.MethodHead, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/by_id/"+objID.EncodeToString()+"?"+query.Encode(), nil)
request, err := http.NewRequest(http.MethodHead, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/by_id/"+objID.EncodeToString()+"?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
request.Header.Set("Authorization", "Bearer "+resp.Token)

if !walletConnect {
request.Header.Set("Authorization", "Bearer "+resp.Token)
} else {
prepareCommonHeaders(request.Header, bearerToken)
}

headers, _ := doRequest(t, httpClient, request, http.StatusOK, nil)
require.NotEmpty(t, headers)
Expand Down Expand Up @@ -2110,7 +2141,7 @@ func restNewObjectHead(ctx context.Context, t *testing.T, p *pool.Pool, ownerID
})
}

func restNewObjectHeadByAttribute(ctx context.Context, t *testing.T, p *pool.Pool, ownerID *user.ID, cnrID cid.ID, signer user.Signer) {
func restNewObjectHeadByAttribute(ctx context.Context, t *testing.T, p *pool.Pool, ownerID *user.ID, cnrID cid.ID, signer user.Signer, walletConnect bool) {
bearer := apiserver.Bearer{
Object: []apiserver.Record{
{
Expand Down Expand Up @@ -2151,15 +2182,17 @@ func restNewObjectHeadByAttribute(ctx context.Context, t *testing.T, p *pool.Poo
query := make(url.Values)
query.Add(walletConnectQuery, strconv.FormatBool(useWalletConnect))

request, err := http.NewRequest(http.MethodGet, testHost+"/v1/auth/bearer?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
resp := &apiserver.BinaryBearer{}
doRequest(t, httpClient, request, http.StatusOK, resp)
if !walletConnect {
request, err := http.NewRequest(http.MethodGet, testHost+"/v1/auth/bearer?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
doRequest(t, httpClient, request, http.StatusOK, resp)
}

var (
content = []byte("some content")
fileNameAttr = "new-head-obj-by-attr-name-echo"
fileNameAttr = "new-head-obj-by-attr-name-" + strconv.FormatBool(walletConnect)
attrKey = "soME-attribute"
attrValue = "user value"
attributes = map[string]string{
Expand All @@ -2169,17 +2202,26 @@ func restNewObjectHeadByAttribute(ctx context.Context, t *testing.T, p *pool.Poo
}
)

if !walletConnect {
query = make(url.Values)
query.Add(fullBearerQuery, "true")
}

t.Run("head", func(t *testing.T) {
objID := createObject(ctx, t, p, ownerID, cnrID, attributes, content, signer)

attrTS := getObjectCreateTimestamp(ctx, t, p, cnrID, objID, signer)
createTS, err := strconv.ParseInt(attrTS, 10, 64)
require.NoError(t, err)

request, err = http.NewRequest(http.MethodHead, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/by_attribute/"+object.AttributeFileName+"/"+fileNameAttr+"?"+query.Encode(), nil)
request, err := http.NewRequest(http.MethodHead, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/by_attribute/"+object.AttributeFileName+"/"+fileNameAttr+"?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
request.Header.Set("Authorization", "Bearer "+resp.Token)

if !walletConnect {
request.Header.Set("Authorization", "Bearer "+resp.Token)
} else {
prepareCommonHeaders(request.Header, bearerToken)
}

headers, _ := doRequest(t, httpClient, request, http.StatusOK, nil)
require.NotEmpty(t, headers)
Expand Down Expand Up @@ -2229,10 +2271,14 @@ func restNewObjectHeadByAttribute(ctx context.Context, t *testing.T, p *pool.Poo
createTS, err := strconv.ParseInt(attrTS, 10, 64)
require.NoError(t, err)

request, err = http.NewRequest(http.MethodHead, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/by_attribute/"+object.AttributeFileName+"/"+multiSegmentName+"?"+query.Encode(), nil)
request, err := http.NewRequest(http.MethodHead, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/by_attribute/"+object.AttributeFileName+"/"+multiSegmentName+"?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
request.Header.Set("Authorization", "Bearer "+resp.Token)

if !walletConnect {
request.Header.Set("Authorization", "Bearer "+resp.Token)
} else {
prepareCommonHeaders(request.Header, bearerToken)
}

headers, _ := doRequest(t, httpClient, request, http.StatusOK, nil)
require.NotEmpty(t, headers)
Expand Down Expand Up @@ -2273,7 +2319,7 @@ func restNewObjectHeadByAttribute(ctx context.Context, t *testing.T, p *pool.Poo
})
}

func restNewObjectGetByAttribute(ctx context.Context, t *testing.T, p *pool.Pool, ownerID *user.ID, cnrID cid.ID, signer user.Signer) {
func restNewObjectGetByAttribute(ctx context.Context, t *testing.T, p *pool.Pool, ownerID *user.ID, cnrID cid.ID, signer user.Signer, walletConnect bool) {
bearer := apiserver.Bearer{
Object: []apiserver.Record{
{
Expand Down Expand Up @@ -2305,15 +2351,17 @@ func restNewObjectGetByAttribute(ctx context.Context, t *testing.T, p *pool.Pool
query := make(url.Values)
query.Add(walletConnectQuery, strconv.FormatBool(useWalletConnect))

request, err := http.NewRequest(http.MethodGet, testHost+"/v1/auth/bearer?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
resp := &apiserver.BinaryBearer{}
doRequest(t, httpClient, request, http.StatusOK, resp)
if !walletConnect {
request, err := http.NewRequest(http.MethodGet, testHost+"/v1/auth/bearer?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
doRequest(t, httpClient, request, http.StatusOK, resp)
}

var (
content = []byte("some content")
fileNameAttr = "new-get-obj-by-attr-name-echo"
fileNameAttr = "new-get-obj-by-attr-name-" + strconv.FormatBool(walletConnect)
createTS = time.Now().Unix()
attrKey = "user-attribute"
attrValue = "user value"
Expand All @@ -2327,10 +2375,20 @@ func restNewObjectGetByAttribute(ctx context.Context, t *testing.T, p *pool.Pool
t.Run("get", func(t *testing.T) {
objID := createObject(ctx, t, p, ownerID, cnrID, attributes, content, signer)

request, err = http.NewRequest(http.MethodGet, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/by_attribute/"+object.AttributeFileName+"/"+fileNameAttr+"?"+query.Encode(), nil)
if !walletConnect {
// Change the query, we only need the `fullBearer` parameter here.
query = make(url.Values)
query.Add(fullBearerQuery, "true")
}

request, err := http.NewRequest(http.MethodGet, testHost+"/v1/objects/"+cnrID.EncodeToString()+"/by_attribute/"+object.AttributeFileName+"/"+fileNameAttr+"?"+query.Encode(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
request.Header.Set("Authorization", "Bearer "+resp.Token)

if !walletConnect {
request.Header.Set("Authorization", "Bearer "+resp.Token)
} else {
prepareCommonHeaders(request.Header, bearerToken)
}

headers, rawPayload := doRequest(t, httpClient, request, http.StatusOK, nil)
require.NotEmpty(t, headers)
Expand Down
Loading
Loading