From d3760946389c389f91cb4c0a305a4d0eccb7a8e6 Mon Sep 17 00:00:00 2001 From: asabya Date: Tue, 8 Oct 2024 09:13:48 +0530 Subject: [PATCH 01/14] feat: update blockstore --- cmd/dfs/cmd/dev.go | 6 +- cmd/dfs/cmd/server_test.go | 17 +- go.mod | 13 +- go.sum | 6 +- pkg/acl/acl/controller.go | 2 +- pkg/blockstore/bee/client.go | 846 ------------------------ pkg/blockstore/bee/mock/client.go | 325 --------- pkg/blockstore/client.go | 40 -- pkg/blockstore/putergetter/bzzUpdate.go | 1 - pkg/collection/batch.go | 5 +- pkg/collection/batch_test.go | 9 +- pkg/collection/document.go | 55 +- pkg/collection/document_test.go | 9 +- pkg/collection/index.go | 39 +- pkg/collection/index_api_test.go | 46 +- pkg/collection/index_test.go | 19 +- pkg/collection/iterator_test.go | 10 +- pkg/collection/kv.go | 17 +- pkg/collection/kv_test.go | 111 ++-- pkg/dfs/api.go | 7 +- pkg/dfs/pod_api.go | 67 +- pkg/dir/chmod_test.go | 14 +- pkg/dir/dir.go | 2 +- pkg/dir/dir_present_test.go | 9 +- pkg/dir/dir_test.go | 9 +- pkg/dir/inode.go | 1 - pkg/dir/ls_test.go | 9 +- pkg/dir/mkdir_test.go | 9 +- pkg/dir/rename_test.go | 9 +- pkg/dir/rmdir_test.go | 15 +- pkg/dir/stat_test.go | 10 +- pkg/dir/sync_test.go | 9 +- pkg/feed/api.go | 6 +- pkg/feed/feed_test.go | 8 +- pkg/feed/handler.go | 14 +- pkg/feed/handler_test.go | 9 +- pkg/feed/tracker/tracker.go | 2 +- pkg/feed/tracker/tracker_test.go | 2 +- pkg/file/chmod_test.go | 8 +- pkg/file/download.go | 11 +- pkg/file/download_test.go | 8 +- pkg/file/file.go | 2 +- pkg/file/ls_test.go | 8 +- pkg/file/meta.go | 3 +- pkg/file/reader.go | 18 +- pkg/file/reader_test.go | 21 +- pkg/file/rename_test.go | 9 +- pkg/file/rm.go | 13 +- pkg/file/rm_test.go | 9 +- pkg/file/stat_test.go | 9 +- pkg/file/status_test.go | 10 +- pkg/file/upload.go | 18 +- pkg/file/upload_test.go | 9 +- pkg/file/writeAt.go | 19 +- pkg/file/writeAt_test.go | 10 +- pkg/pod/fork.go | 11 +- pkg/pod/group.go | 2 +- pkg/pod/groupMember.go | 18 +- pkg/pod/pod.go | 8 +- pkg/pod/sharing.go | 24 +- pkg/pod/subscription.go | 18 +- pkg/subscriptionManager/rpc/manager.go | 30 +- pkg/swarm-feed/swarmFeed.go | 153 ----- pkg/swarm-feed/swarm_feed_test.go | 49 -- pkg/test/close_test.go | 9 +- pkg/test/del_test.go | 9 +- pkg/test/delete_test.go | 9 +- pkg/test/fork_test.go | 9 +- pkg/test/group_new_test.go | 10 +- pkg/test/integration_test.go | 8 +- pkg/test/lite_test.go | 10 +- pkg/test/login_test.go | 9 +- pkg/test/logout_test.go | 9 +- pkg/test/ls_test.go | 9 +- pkg/test/max_file_test.go | 9 +- pkg/test/max_pod_test.go | 9 +- pkg/test/new_test.go | 9 +- pkg/test/open_test.go | 9 +- pkg/test/pod_new_test.go | 9 +- pkg/test/pod_sharing_test.go | 9 +- pkg/test/pod_stat_test.go | 9 +- pkg/test/stat_test.go | 9 +- pkg/test/subscription_test.go | 8 +- pkg/test/sync_test.go | 10 +- pkg/test/user_sharing_test.go | 7 +- pkg/user/login.go | 2 +- pkg/user/sharing.go | 35 +- pkg/user/users.go | 2 +- 88 files changed, 750 insertions(+), 1762 deletions(-) delete mode 100644 pkg/blockstore/bee/client.go delete mode 100644 pkg/blockstore/bee/mock/client.go delete mode 100644 pkg/blockstore/client.go delete mode 100644 pkg/blockstore/putergetter/bzzUpdate.go delete mode 100644 pkg/swarm-feed/swarmFeed.go delete mode 100644 pkg/swarm-feed/swarm_feed_test.go diff --git a/cmd/dfs/cmd/dev.go b/cmd/dfs/cmd/dev.go index e1c92faa..617dffa1 100644 --- a/cmd/dfs/cmd/dev.go +++ b/cmd/dfs/cmd/dev.go @@ -10,11 +10,11 @@ import ( "syscall" "testing" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/api" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/dfs" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -55,7 +55,7 @@ func startDevServer() { }) fmt.Println("Bee running at: ", beeUrl) logger := logging.New(os.Stdout, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy("0")) ens := mock2.NewMockNamespaceManager() users := user.NewUsers(mockClient, ens, -1, 0, logger) diff --git a/cmd/dfs/cmd/server_test.go b/cmd/dfs/cmd/server_test.go index f333c9ea..579b53cf 100644 --- a/cmd/dfs/cmd/server_test.go +++ b/cmd/dfs/cmd/server_test.go @@ -17,23 +17,22 @@ import ( "testing" "time" - "github.com/fairdatasociety/fairOS-dfs/pkg/pod" - - "github.com/fairdatasociety/fairOS-dfs/pkg/acl/acl" - "github.com/stretchr/testify/assert" - + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/cmd/common" + "github.com/fairdatasociety/fairOS-dfs/pkg/acl/acl" "github.com/fairdatasociety/fairOS-dfs/pkg/api" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/dfs" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" + "github.com/fairdatasociety/fairOS-dfs/pkg/pod" "github.com/fairdatasociety/fairOS-dfs/pkg/user" "github.com/gorilla/websocket" "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" ) var letterRunes = []rune("abcdefghijklmnopqrstuvwxyz") @@ -58,8 +57,8 @@ func TestApis(t *testing.T) { Post: mockpost.New(mockpost.WithAcceptAll()), }) - logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + logger := logging.New(os.Stdout, logrus.DebugLevel) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) ens := mock2.NewMockNamespaceManager() users := user.NewUsers(mockClient, ens, -1, 0, logger) diff --git a/go.mod b/go.mod index c21a152e..3f6bb7c5 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,14 @@ module github.com/fairdatasociety/fairOS-dfs -go 1.22 - -toolchain go1.22.0 +go 1.22.0 require ( + github.com/asabya/swarm-blockstore v0.0.0-20241007072942-fef6cc83ff36 github.com/btcsuite/btcd/btcec/v2 v2.3.3 github.com/c-bata/go-prompt v0.2.6 github.com/dustin/go-humanize v1.0.1 github.com/ethereum/go-ethereum v1.14.7 - github.com/ethersphere/bee/v2 v2.1.1-0.20240611213428-4b04c086d8db + github.com/ethersphere/bee/v2 v2.2.0 github.com/ethersphere/bmt v0.1.4 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb @@ -57,7 +56,7 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect github.com/ethersphere/go-price-oracle-abi v0.2.0 // indirect - github.com/ethersphere/go-storage-incentives-abi v0.8.6 // indirect + github.com/ethersphere/go-storage-incentives-abi v0.9.1 // indirect github.com/ethersphere/go-sw3-abi v0.6.5 // indirect github.com/ethersphere/langos v1.0.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect @@ -158,6 +157,8 @@ require ( rsc.io/tmplfunc v0.0.3 // indirect ) -//replace github.com/ethersphere/bee/v2 => ../../ethersphere/bee +replace github.com/ethersphere/bee/v2 => ../../ethersphere/bee + +replace github.com/asabya/swarm-blockstore => ../../asabya/swarm-blockstore replace github.com/codahale/hdrhistogram => github.com/HdrHistogram/hdrhistogram-go v0.0.0-20200919145931-8dac23c8dac1 diff --git a/go.sum b/go.sum index cfae0b2a..e49f901e 100644 --- a/go.sum +++ b/go.sum @@ -79,14 +79,12 @@ github.com/ethereum/go-ethereum v1.14.7 h1:EHpv3dE8evQmpVEQ/Ne2ahB06n2mQptdwqaMN github.com/ethereum/go-ethereum v1.14.7/go.mod h1:Mq0biU2jbdmKSZoqOj29017ygFrMnB5/Rifwp980W4o= github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 h1:KrE8I4reeVvf7C1tm8elRjj4BdscTYzz/WAbYyf/JI4= github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0/go.mod h1:D9AJLVXSyZQXJQVk8oh1EwjISE+sJTn2duYIZC0dy3w= -github.com/ethersphere/bee/v2 v2.1.1-0.20240611213428-4b04c086d8db h1:+CWPPQnOQDCUTAODgbhNT7e3UcF7ZsFBCHD3ExobeI8= -github.com/ethersphere/bee/v2 v2.1.1-0.20240611213428-4b04c086d8db/go.mod h1:2XYm5T9MbERw7caUg/iC38kwwpr8ZjMhokW0khdr3H4= github.com/ethersphere/bmt v0.1.4 h1:+rkWYNtMgDx6bkNqGdWu+U9DgGI1rRZplpSW3YhBr1Q= github.com/ethersphere/bmt v0.1.4/go.mod h1:Yd8ft1U69WDuHevZc/rwPxUv1rzPSMpMnS6xbU53aY8= github.com/ethersphere/go-price-oracle-abi v0.2.0 h1:wtIcYLgNZHY4BjYwJCnu93SvJdVAZVvBaKinspyyHvQ= github.com/ethersphere/go-price-oracle-abi v0.2.0/go.mod h1:sI/Qj4/zJ23/b1enzwMMv0/hLTpPNVNacEwCWjo6yBk= -github.com/ethersphere/go-storage-incentives-abi v0.8.6 h1:M9WwEtWoxVHKehBAoPMzQhXlzlBetuXsrGgoFvM5I8Y= -github.com/ethersphere/go-storage-incentives-abi v0.8.6/go.mod h1:SXvJVtM4sEsaSKD0jc1ClpDLw8ErPoROZDme4Wrc/Nc= +github.com/ethersphere/go-storage-incentives-abi v0.9.1 h1:/FGh5Bn78hlxMu0YjSFf1APzmmrCmmThDOZMWY+G2Cs= +github.com/ethersphere/go-storage-incentives-abi v0.9.1/go.mod h1:SXvJVtM4sEsaSKD0jc1ClpDLw8ErPoROZDme4Wrc/Nc= github.com/ethersphere/go-sw3-abi v0.6.5 h1:M5dcIe1zQYvGpY2K07UNkNU9Obc4U+A1fz68Ho/Q+XE= github.com/ethersphere/go-sw3-abi v0.6.5/go.mod h1:BmpsvJ8idQZdYEtWnvxA8POYQ8Rl/NhyCdF0zLMOOJU= github.com/ethersphere/langos v1.0.0 h1:NBtNKzXTTRSue95uOlzPN4py7Aofs0xWPzyj4AI1Vcc= diff --git a/pkg/acl/acl/controller.go b/pkg/acl/acl/controller.go index 27dedaf3..501b0920 100644 --- a/pkg/acl/acl/controller.go +++ b/pkg/acl/acl/controller.go @@ -6,7 +6,7 @@ import ( "io" "sync" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" + blockstore "github.com/asabya/swarm-blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" f "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" diff --git a/pkg/blockstore/bee/client.go b/pkg/blockstore/bee/client.go deleted file mode 100644 index 42cfd7da..00000000 --- a/pkg/blockstore/bee/client.go +++ /dev/null @@ -1,846 +0,0 @@ -/* -Copyright © 2020 FairOS Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package bee - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "hash" - "io" - "net/http" - "strconv" - "time" - - "github.com/ethersphere/bee/v2/pkg/swarm" - bmtlegacy "github.com/ethersphere/bmt/legacy" - "github.com/fairdatasociety/fairOS-dfs/pkg/logging" - lru "github.com/hashicorp/golang-lru/v2/expirable" - "github.com/sirupsen/logrus" - "golang.org/x/crypto/sha3" -) - -const ( - maxIdleConnections = 20 - maxConnectionsPerHost = 256 - requestTimeout = 6000 - chunkCacheSize = 1024 - uploadBlockCacheSize = 100 - downloadBlockCacheSize = 100 - healthUrl = "/health" - chunkUploadDownloadUrl = "/chunks" - bytesUploadDownloadUrl = "/bytes" - bzzUrl = "/bzz" - tagsUrl = "/tags" - pinsUrl = "/pins/" - feedsUrl = "/feeds/" - swarmPinHeader = "Swarm-Pin" - swarmEncryptHeader = "Swarm-Encrypt" - swarmPostageBatchId = "Swarm-Postage-Batch-Id" - swarmDeferredUploadHeader = "Swarm-Deferred-Upload" - SwarmErasureCodingHeader = "Swarm-Redundancy-Level" - swarmTagHeader = "Swarm-Tag" - contentTypeHeader = "Content-Type" -) - -// Client is a bee http client that satisfies blockstore.Client -type Client struct { - url string - client *http.Client - hasher *bmtlegacy.Hasher - chunkCache *lru.LRU[string, []byte] - uploadBlockCache *lru.LRU[string, []byte] - downloadBlockCache *lru.LRU[string, []byte] - postageBlockId string - logger logging.Logger - isProxy bool - shouldPin bool - redundancyLevel uint8 -} - -func hashFunc() hash.Hash { - return sha3.NewLegacyKeccak256() -} - -type bytesPostResponse struct { - Reference swarm.Address `json:"reference"` -} - -type tagPostRequest struct { - Address string `json:"address"` -} - -type tagPostResponse struct { - UID uint32 `json:"uid"` - StartedAt time.Time `json:"startedAt"` - Total int64 `json:"total"` - Processed int64 `json:"processed"` - Synced int64 `json:"synced"` -} - -type beeError struct { - Code int `json:"code"` - Message string `json:"message"` -} - -// NewBeeClient creates a new client which connects to the Swarm bee node to access the Swarm network. -func NewBeeClient(apiUrl, postageBlockId string, shouldPin bool, redundancyLevel uint8, logger logging.Logger) *Client { - p := bmtlegacy.NewTreePool(hashFunc, swarm.Branches, bmtlegacy.PoolSize) - cache := lru.NewLRU(chunkCacheSize, func(key string, value []byte) {}, 0) - uploadBlockCache := lru.NewLRU(uploadBlockCacheSize, func(key string, value []byte) {}, 0) - downloadBlockCache := lru.NewLRU(downloadBlockCacheSize, func(key string, value []byte) {}, 0) - return &Client{ - url: apiUrl, - client: createHTTPClient(), - hasher: bmtlegacy.New(p), - chunkCache: cache, - uploadBlockCache: uploadBlockCache, - downloadBlockCache: downloadBlockCache, - postageBlockId: postageBlockId, - logger: logger, - shouldPin: shouldPin, - redundancyLevel: redundancyLevel, - } -} - -type chunkAddressResponse struct { - Reference swarm.Address `json:"reference"` -} - -func socResource(owner, id, sig string) string { - return fmt.Sprintf("/soc/%s/%s?sig=%s", owner, id, sig) -} - -// CheckConnection is used to check if the bee client is up and running. -func (s *Client) CheckConnection() bool { - // check if node is standalone bee - matchString := "Ethereum Swarm Bee\n" - data, _ := s.checkBee(false) - if data == matchString { - return true - } - - // check if node is gateway-proxy - data, err := s.checkBee(true) - if err != nil { - return false - } - matchString = "OK" - s.isProxy = data == matchString - - return s.isProxy -} - -func (s *Client) checkBee(isProxy bool) (string, error) { - url := s.url - if isProxy { - url += healthUrl - } - req, err := http.NewRequest(http.MethodGet, url, http.NoBody) - if err != nil { - return "", err - } - req.Close = true - // skipcq: GO-S2307 - response, err := s.Do(req) - if err != nil { - return "", err - } - - defer response.Body.Close() - data, err := io.ReadAll(response.Body) - if err != nil { - return "", err - } - return string(data), nil -} - -// Do dispatches the HTTP request to the network -func (s *Client) Do(req *http.Request) (*http.Response, error) { - return s.client.Do(req) -} - -// UploadSOC is used construct and send a Single Owner Chunk to the Swarm bee client. -func (s *Client) UploadSOC(owner, id, signature string, data []byte) (address []byte, err error) { - to := time.Now() - socResStr := socResource(owner, id, signature) - fullUrl := fmt.Sprintf("%s%s", s.url, socResStr) - - req, err := http.NewRequest(http.MethodPost, fullUrl, bytes.NewBuffer(data)) - if err != nil { - return nil, err - } - req.Close = true - - // the postage block id to store the SOC chunk - req.Header.Set(swarmPostageBatchId, s.postageBlockId) - req.Header.Set(contentTypeHeader, "application/octet-stream") - req.Header.Set(swarmDeferredUploadHeader, "false") - - // TODO change this in the future when we have some alternative to pin SOC - // This is a temporary fix to force soc pinning - if s.shouldPin { - req.Header.Set(swarmPinHeader, "true") - } - - response, err := s.Do(req) - if err != nil { - return nil, err - } - - // skipcq: GO-S2307 - defer response.Body.Close() - - addrData, err := io.ReadAll(response.Body) - if err != nil { - return nil, errors.New("error uploading data") - } - - if response.StatusCode != http.StatusCreated { - var beeErr *beeError - err = json.Unmarshal(addrData, &beeErr) - if err != nil { - return nil, errors.New(string(addrData)) - } - return nil, errors.New(beeErr.Message) - } - - var addrResp *chunkAddressResponse - err = json.Unmarshal(addrData, &addrResp) - if err != nil { - return nil, err - } - - fields := logrus.Fields{ - "reference": addrResp.Reference.String(), - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "upload soc: ") - return addrResp.Reference.Bytes(), nil -} - -// UploadChunk uploads a chunk to Swarm network. -func (s *Client) UploadChunk(ch swarm.Chunk) (address []byte, err error) { - to := time.Now() - fullUrl := fmt.Sprintf("%s%s", s.url, chunkUploadDownloadUrl) - req, err := http.NewRequest(http.MethodPost, fullUrl, bytes.NewBuffer(ch.Data())) - if err != nil { - return nil, err - } - req.Close = true - - if s.shouldPin { - req.Header.Set(swarmPinHeader, "true") - } - - req.Header.Set(contentTypeHeader, "application/octet-stream") - - // the postage block id to store the chunk - req.Header.Set(swarmPostageBatchId, s.postageBlockId) - - req.Header.Set(swarmDeferredUploadHeader, "true") - - response, err := s.Do(req) - if err != nil { - return nil, err - } - // skipcq: GO-S2307 - defer response.Body.Close() - - addrData, err := io.ReadAll(response.Body) - if err != nil { - return nil, errors.New("error uploading data") - } - - if response.StatusCode != http.StatusOK { - var beeErr *beeError - err = json.Unmarshal(addrData, &beeErr) - if err != nil { - return nil, errors.New(string(addrData)) - } - return nil, errors.New(beeErr.Message) - } - - var addrResp *chunkAddressResponse - err = json.Unmarshal(addrData, &addrResp) - if err != nil { - return nil, err - } - - fields := logrus.Fields{ - "reference": ch.Address().String(), - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "upload chunk: ") - - return addrResp.Reference.Bytes(), nil -} - -// DownloadChunk downloads a chunk with given address from the Swarm network -func (s *Client) DownloadChunk(ctx context.Context, address []byte) (data []byte, err error) { - to := time.Now() - addrString := swarm.NewAddress(address).String() - - path := chunkUploadDownloadUrl + "/" + addrString - fullUrl := fmt.Sprintf("%s%s", s.url, path) - req, err := http.NewRequest(http.MethodGet, fullUrl, bytes.NewBuffer(data)) - if err != nil { - return nil, err - } - req.Close = true - - req = req.WithContext(ctx) - - response, err := s.Do(req) - if err != nil { - return nil, err - } - // skipcq: GO-S2307 - defer response.Body.Close() - - if response.StatusCode != http.StatusOK { - return nil, errors.New("error downloading data") - } - - data, err = io.ReadAll(response.Body) - if err != nil { - return nil, errors.New("error downloading data") - } - fields := logrus.Fields{ - "reference": addrString, - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "download chunk: ") - return data, nil -} - -// UploadBlob uploads a binary blob of data to Swarm network. It also optionally pins and encrypts the data. -func (s *Client) UploadBlob(data []byte, tag uint32, encrypt bool) (address []byte, err error) { - to := time.Now() - - // return the ref if this data is already in swarm - if s.inBlockCache(s.uploadBlockCache, string(data)) { - return s.getFromBlockCache(s.uploadBlockCache, string(data)), nil - } - - fullUrl := s.url + bytesUploadDownloadUrl - req, err := http.NewRequest(http.MethodPost, fullUrl, bytes.NewBuffer(data)) - if err != nil { - return nil, err - } - req.Close = true - - req.Header.Set(contentTypeHeader, "application/octet-stream") - req.Header.Set(SwarmErasureCodingHeader, strconv.Itoa(int(s.redundancyLevel))) - - if s.shouldPin { - req.Header.Set(swarmPinHeader, "true") - } - - if encrypt { - req.Header.Set(swarmEncryptHeader, "true") - } - - if tag > 0 { - req.Header.Set(swarmTagHeader, fmt.Sprintf("%d", tag)) - } - - // the postage block id to store the blob - req.Header.Set(swarmPostageBatchId, s.postageBlockId) - - req.Header.Set(swarmDeferredUploadHeader, "true") - - response, err := s.Do(req) - if err != nil { - return nil, err - } - // skipcq: GO-S2307 - defer response.Body.Close() - - respData, err := io.ReadAll(response.Body) - if err != nil { - return nil, errors.New("error uploading blob") - } - - if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated { - var beeErr *beeError - err = json.Unmarshal(respData, &beeErr) - if err != nil { - return nil, errors.New(string(respData)) - } - return nil, errors.New(beeErr.Message) - } - - var resp bytesPostResponse - err = json.Unmarshal(respData, &resp) - if err != nil { - return nil, fmt.Errorf("error unmarshalling response") - } - fields := logrus.Fields{ - "reference": resp.Reference.String(), - "size": len(data), - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "upload blob: ") - - // add the data in cache - s.addToBlockCache(s.uploadBlockCache, string(data), resp.Reference.Bytes()) - - return resp.Reference.Bytes(), nil -} - -// DownloadBlob downloads a blob of binary data from the Swarm network. -func (s *Client) DownloadBlob(address []byte) ([]byte, int, error) { - to := time.Now() - - // return the data if this address is already in cache - addrString := swarm.NewAddress(address).String() - if s.inBlockCache(s.downloadBlockCache, addrString) { - return s.getFromBlockCache(s.downloadBlockCache, addrString), 200, nil - } - - fullUrl := s.url + bytesUploadDownloadUrl + "/" + addrString - req, err := http.NewRequest(http.MethodGet, fullUrl, http.NoBody) - if err != nil { - return nil, http.StatusNotFound, err - } - req.Close = true - - response, err := s.Do(req) - if err != nil { - return nil, http.StatusNotFound, err - } - // skipcq: GO-S2307 - defer response.Body.Close() - - respData, err := io.ReadAll(response.Body) - if err != nil { - return nil, response.StatusCode, errors.New("error downloading blob") - } - - if response.StatusCode != http.StatusOK { - var beeErr *beeError - err = json.Unmarshal(respData, &beeErr) - if err != nil { - return nil, response.StatusCode, errors.New(string(respData)) - } - return nil, response.StatusCode, errors.New(beeErr.Message) - } - - fields := logrus.Fields{ - "reference": addrString, - "size": len(respData), - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "download blob: ") - - // add the data and ref if it is not in cache - if !s.inBlockCache(s.downloadBlockCache, addrString) { - s.addToBlockCache(s.downloadBlockCache, addrString, respData) - } - return respData, response.StatusCode, nil -} - -// UploadBzz uploads a file through bzz api -func (s *Client) UploadBzz(data []byte, fileName string) (address []byte, err error) { - to := time.Now() - - fullUrl := s.url + bzzUrl + "?name=" + fileName - req, err := http.NewRequest(http.MethodPost, fullUrl, bytes.NewBuffer(data)) - if err != nil { - return nil, err - } - req.Close = true - - req.Header.Set(swarmPostageBatchId, s.postageBlockId) - req.Header.Set(contentTypeHeader, "application/json") - req.Header.Set(SwarmErasureCodingHeader, strconv.Itoa(int(s.redundancyLevel))) - - response, err := s.Do(req) - if err != nil { - return nil, err - } - // skipcq: GO-S2307 - defer response.Body.Close() - - respData, err := io.ReadAll(response.Body) - if err != nil { - return nil, errors.New("error downloading bzz") - } - - if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated { - var beeErr *beeError - err = json.Unmarshal(respData, &beeErr) - if err != nil { - return nil, errors.New(string(respData)) - } - return nil, errors.New(beeErr.Message) - } - - var resp bytesPostResponse - err = json.Unmarshal(respData, &resp) - - fields := logrus.Fields{ - "reference": resp.Reference.String(), - "size": len(respData), - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "upload bzz: ") - - // add the data and ref if it is not in cache - if !s.inBlockCache(s.downloadBlockCache, resp.Reference.String()) { - s.addToBlockCache(s.downloadBlockCache, resp.Reference.String(), data) - } - return resp.Reference.Bytes(), nil -} - -// DownloadBzz downloads bzz data from the Swarm network. -func (s *Client) DownloadBzz(address []byte) ([]byte, int, error) { - to := time.Now() - - // return the data if this address is already in cache - addrString := swarm.NewAddress(address).String() - if s.inBlockCache(s.downloadBlockCache, addrString) { - return s.getFromBlockCache(s.downloadBlockCache, addrString), 200, nil - } - - fullUrl := s.url + bzzUrl + "/" + addrString - req, err := http.NewRequest(http.MethodGet, fullUrl, http.NoBody) - if err != nil { - return nil, http.StatusNotFound, err - } - req.Close = true - - response, err := s.Do(req) - if err != nil { - return nil, http.StatusNotFound, err - } - // skipcq: GO-S2307 - defer response.Body.Close() - - respData, err := io.ReadAll(response.Body) - if err != nil { - return nil, response.StatusCode, errors.New("error downloading bzz") - } - - if response.StatusCode != http.StatusOK { - var beeErr *beeError - err = json.Unmarshal(respData, &beeErr) - if err != nil { - return nil, response.StatusCode, errors.New(string(respData)) - } - return nil, response.StatusCode, errors.New(beeErr.Message) - } - - fields := logrus.Fields{ - "reference": addrString, - "size": len(respData), - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "download bzz: ") - - // add the data and ref if it is not in cache - if !s.inBlockCache(s.downloadBlockCache, addrString) { - s.addToBlockCache(s.downloadBlockCache, addrString, respData) - } - return respData, response.StatusCode, nil -} - -// DeleteReference unpins a reference so that it will be garbage collected by the Swarm network. -func (s *Client) DeleteReference(address []byte) error { - if !s.shouldPin { - return nil - } - to := time.Now() - addrString := swarm.NewAddress(address).String() - - fullUrl := s.url + pinsUrl + addrString - req, err := http.NewRequest(http.MethodDelete, fullUrl, http.NoBody) - if err != nil { - return err - } - req.Close = true - - response, err := s.Do(req) - if err != nil { - return err - } - defer response.Body.Close() - - if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusNotFound { - respData, err := io.ReadAll(response.Body) - if err != nil { - return err - } - return fmt.Errorf("failed to unpin reference : %s", respData) - } else { - _, _ = io.Copy(io.Discard, response.Body) - } - - fields := logrus.Fields{ - "reference": addrString, - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "delete chunk: ") - - return nil -} - -// CreateTag creates a tag for given address -func (s *Client) CreateTag(address []byte) (uint32, error) { - // gateway proxy does not have tags api exposed - if s.isProxy { - return 0, nil - } - to := time.Now() - - fullUrl := s.url + tagsUrl - var data []byte - var err error - if len(address) > 0 { - addrString := swarm.NewAddress(address).String() - b := &tagPostRequest{Address: addrString} - data, err = json.Marshal(b) - if err != nil { - return 0, err - } - } - req, err := http.NewRequest(http.MethodPost, fullUrl, bytes.NewBuffer(data)) - if err != nil { - return 0, err - } - req.Close = true - - response, err := s.Do(req) - if err != nil { - return 0, err - } - // skipcq: GO-S2307 - defer response.Body.Close() - - respData, err := io.ReadAll(response.Body) - if err != nil { - return 0, errors.New("error create tag") - } - - if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated { - var beeErr *beeError - err = json.Unmarshal(respData, &beeErr) - if err != nil { - return 0, errors.New(string(respData)) - } - return 0, errors.New(beeErr.Message) - } - - var resp tagPostResponse - err = json.Unmarshal(respData, &resp) - if err != nil { - return 0, fmt.Errorf("error unmarshalling response") - } - fields := logrus.Fields{ - "reference": address, - "tag": resp.UID, - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "create tag: ") - - return resp.UID, nil -} - -func (s *Client) CreateFeedManifest(owner, topic string) (swarm.Address, error) { - to := time.Now() - - fullUrl := s.url + feedsUrl + owner + "/" + topic - fmt.Println("fullUrl: ", fullUrl) - req, err := http.NewRequest(http.MethodPost, fullUrl, nil) - if err != nil { - return swarm.ZeroAddress, err - } - req.Close = true - - req.Header.Set(swarmPostageBatchId, s.postageBlockId) - - response, err := s.Do(req) - if err != nil { - return swarm.ZeroAddress, err - } - // skipcq: GO-S2307 - defer response.Body.Close() - - respData, err := io.ReadAll(response.Body) - if err != nil { - return swarm.ZeroAddress, errors.New("error create feed manifest") - } - - if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated { - var beeErr *beeError - err = json.Unmarshal(respData, &beeErr) - if err != nil { - return swarm.ZeroAddress, errors.New(string(respData)) - } - return swarm.ZeroAddress, errors.New(beeErr.Message) - } - - var resp bytesPostResponse - err = json.Unmarshal(respData, &resp) - if err != nil { - return swarm.ZeroAddress, fmt.Errorf("error unmarshalling response") - } - fields := logrus.Fields{ - "owner": owner, - "topic": topic, - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "create feed manifest: ") - return resp.Reference, nil -} - -func (s *Client) GetLatestFeedManifest(owner, topic string) ([]byte, string, string, error) { - to := time.Now() - - fullUrl := s.url + feedsUrl + owner + "/" + topic - fmt.Println("get ullUrl: ", fullUrl) - - req, err := http.NewRequest(http.MethodGet, fullUrl, nil) - if err != nil { - return nil, "", "", err - } - req.Close = true - - response, err := s.Do(req) - if err != nil { - return nil, "", "", err - } - // skipcq: GO-S2307 - defer response.Body.Close() - - respData, err := io.ReadAll(response.Body) - if err != nil { - return nil, "", "", errors.New("error getting latest feed manifest") - } - - if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated { - var beeErr *beeError - err = json.Unmarshal(respData, &beeErr) - if err != nil { - return nil, "", "", errors.New(string(respData)) - } - return nil, "", "", errors.New(beeErr.Message) - } - - var resp bytesPostResponse - err = json.Unmarshal(respData, &resp) - if err != nil { - return nil, "", "", fmt.Errorf("error unmarshalling response") - } - fields := logrus.Fields{ - "owner": owner, - "topic": topic, - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "get latest feed manifest: ") - - return resp.Reference.Bytes(), response.Header.Get("swarm-feed-index"), response.Header.Get("swarm-feed-index-next"), nil -} - -// GetTag gets sync status of a given tag -func (s *Client) GetTag(tag uint32) (int64, int64, int64, error) { - // gateway proxy does not have tags api exposed - if s.isProxy { - return 0, 0, 0, nil - } - - to := time.Now() - - fullUrl := s.url + tagsUrl + fmt.Sprintf("/%d", tag) - - req, err := http.NewRequest(http.MethodGet, fullUrl, http.NoBody) - if err != nil { - return 0, 0, 0, err - } - req.Close = true - - response, err := s.Do(req) - if err != nil { - return 0, 0, 0, err - } - // skipcq: GO-S2307 - defer response.Body.Close() - - respData, err := io.ReadAll(response.Body) - if err != nil { - return 0, 0, 0, errors.New("error getting tag") - } - - if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated { - var beeErr *beeError - err = json.Unmarshal(respData, &beeErr) - if err != nil { - return 0, 0, 0, errors.New(string(respData)) - } - return 0, 0, 0, errors.New(beeErr.Message) - } - - var resp tagPostResponse - err = json.Unmarshal(respData, &resp) - if err != nil { - return 0, 0, 0, fmt.Errorf("error unmarshalling response") - } - fields := logrus.Fields{ - "tag": resp.UID, - "duration": time.Since(to).String(), - } - s.logger.WithFields(fields).Log(logrus.DebugLevel, "get tag: ") - - return resp.Total, resp.Processed, resp.Synced, nil -} - -// createHTTPClient for connection re-use -func createHTTPClient() *http.Client { - client := &http.Client{ - Timeout: time.Second * requestTimeout, - Transport: &http.Transport{ - MaxIdleConnsPerHost: maxIdleConnections, - MaxConnsPerHost: maxConnectionsPerHost, - }, - } - return client -} - -func (*Client) addToBlockCache(cache *lru.LRU[string, []byte], key string, value []byte) { - if cache != nil { - cache.Add(key, value) - } -} - -func (*Client) inBlockCache(cache *lru.LRU[string, []byte], key string) bool { - _, in := cache.Get(key) - return in -} - -func (*Client) getFromBlockCache(cache *lru.LRU[string, []byte], key string) []byte { - if cache != nil { - value, ok := cache.Get(key) - if ok { - return value - } - return nil - } - return nil -} diff --git a/pkg/blockstore/bee/mock/client.go b/pkg/blockstore/bee/mock/client.go deleted file mode 100644 index bcd92483..00000000 --- a/pkg/blockstore/bee/mock/client.go +++ /dev/null @@ -1,325 +0,0 @@ -package mock - -import ( - "context" - "crypto/ecdsa" - "crypto/rand" - "encoding/hex" - "math/big" - "net/http" - "net/http/httptest" - "sync" - "testing" - "time" - - "github.com/ethersphere/bee/v2/pkg/storageincentives/redistribution" - - "github.com/ethereum/go-ethereum/common" - accountingmock "github.com/ethersphere/bee/v2/pkg/accounting/mock" - "github.com/ethersphere/bee/v2/pkg/api" - - "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/feeds" - "github.com/ethersphere/bee/v2/pkg/log" - p2pmock "github.com/ethersphere/bee/v2/pkg/p2p/mock" - "github.com/ethersphere/bee/v2/pkg/pingpong" - "github.com/ethersphere/bee/v2/pkg/postage" - mockbatchstore "github.com/ethersphere/bee/v2/pkg/postage/batchstore/mock" - mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" - "github.com/ethersphere/bee/v2/pkg/postage/postagecontract" - contractMock "github.com/ethersphere/bee/v2/pkg/postage/postagecontract/mock" - "github.com/ethersphere/bee/v2/pkg/pss" - "github.com/ethersphere/bee/v2/pkg/resolver" - resolverMock "github.com/ethersphere/bee/v2/pkg/resolver/mock" - "github.com/ethersphere/bee/v2/pkg/settlement/pseudosettle" - chequebookmock "github.com/ethersphere/bee/v2/pkg/settlement/swap/chequebook/mock" - "github.com/ethersphere/bee/v2/pkg/settlement/swap/erc20" - erc20mock "github.com/ethersphere/bee/v2/pkg/settlement/swap/erc20/mock" - swapmock "github.com/ethersphere/bee/v2/pkg/settlement/swap/mock" - statestore "github.com/ethersphere/bee/v2/pkg/statestore/mock" - "github.com/ethersphere/bee/v2/pkg/status" - "github.com/ethersphere/bee/v2/pkg/steward" - "github.com/ethersphere/bee/v2/pkg/storage" - "github.com/ethersphere/bee/v2/pkg/storage/inmemstore" - "github.com/ethersphere/bee/v2/pkg/storageincentives" - "github.com/ethersphere/bee/v2/pkg/storageincentives/staking" - mock2 "github.com/ethersphere/bee/v2/pkg/storageincentives/staking/mock" - mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/ethersphere/bee/v2/pkg/swarm" - "github.com/ethersphere/bee/v2/pkg/topology/lightnode" - topologymock "github.com/ethersphere/bee/v2/pkg/topology/mock" - "github.com/ethersphere/bee/v2/pkg/tracing" - "github.com/ethersphere/bee/v2/pkg/transaction" - "github.com/ethersphere/bee/v2/pkg/transaction/backendmock" - transactionmock "github.com/ethersphere/bee/v2/pkg/transaction/mock" - "github.com/ethersphere/bee/v2/pkg/util/testutil" -) - -var ( - batchOk = make([]byte, 32) - BatchOkStr string -) - -// nolint:gochecknoinits -func init() { - _, _ = rand.Read(batchOk) - - BatchOkStr = hex.EncodeToString(batchOk) -} - -type TestServerOptions struct { - Storer api.Storer - StateStorer storage.StateStorer - Resolver resolver.Interface - Pss pss.Interface - WsPath string - WsPingPeriod time.Duration - Logger log.Logger - PreventRedirect bool - Feeds feeds.Factory - CORSAllowedOrigins []string - PostageContract postagecontract.Interface - StakingContract staking.Contract - Post postage.Service - Steward steward.Interface - WsHeaders http.Header - DirectUpload bool - Probe *api.Probe - - Overlay swarm.Address - PublicKey ecdsa.PublicKey - PSSPublicKey ecdsa.PublicKey - EthereumAddress common.Address - BlockTime time.Duration - P2P *p2pmock.Service - Pingpong pingpong.Interface - TopologyOpts []topologymock.Option - AccountingOpts []accountingmock.Option - ChequebookOpts []chequebookmock.Option - SwapOpts []swapmock.Option - TransactionOpts []transactionmock.Option - - BatchStore postage.Storer - SyncStatus func() (bool, error) - - BackendOpts []backendmock.Option - Erc20Opts []erc20mock.Option - BeeMode api.BeeNodeMode - RedistributionAgent *storageincentives.Agent - NodeStatus *status.Service -} - -func NewTestBeeServer(t *testing.T, o TestServerOptions) string { - t.Helper() - pk, _ := crypto.GenerateSecp256k1Key() - signer := crypto.NewDefaultSigner(pk) - - if o.Logger == nil { - o.Logger = log.Noop - } - if o.Resolver == nil { - o.Resolver = resolverMock.NewResolver() - } - if o.WsPingPeriod == 0 { - o.WsPingPeriod = 60 * time.Second - } - if o.Post == nil { - o.Post = mockpost.New() - } - if o.BatchStore == nil { - o.BatchStore = mockbatchstore.New(mockbatchstore.WithAcceptAllExistsFunc()) // default is with accept-all Exists() func - } - if o.SyncStatus == nil { - o.SyncStatus = func() (bool, error) { return true, nil } - } - - topologyDriver := topologymock.NewTopologyDriver(o.TopologyOpts...) - acc := accountingmock.NewAccounting(o.AccountingOpts...) - settlement := swapmock.New(o.SwapOpts...) - chequebook := chequebookmock.NewChequebook(o.ChequebookOpts...) - ln := lightnode.NewContainer(o.Overlay) - - transaction := transactionmock.New(o.TransactionOpts...) - - storeRecipient := statestore.NewStateStore() - recipient := pseudosettle.New(nil, o.Logger, storeRecipient, nil, big.NewInt(10000), big.NewInt(10000), o.P2P) - - if o.StateStorer == nil { - o.StateStorer = storeRecipient - } - erc20 := erc20mock.New(o.Erc20Opts...) - backend := backendmock.New(o.BackendOpts...) - - var extraOpts = api.ExtraOptions{ - TopologyDriver: topologyDriver, - Accounting: acc, - Pseudosettle: recipient, - LightNodes: ln, - Swap: settlement, - Chequebook: chequebook, - Pingpong: o.Pingpong, - BlockTime: o.BlockTime, - Storer: o.Storer, - Resolver: o.Resolver, - Pss: o.Pss, - FeedFactory: o.Feeds, - Post: o.Post, - PostageContract: o.PostageContract, - Steward: o.Steward, - SyncStatus: o.SyncStatus, - Staking: o.StakingContract, - NodeStatus: o.NodeStatus, - } - - // By default bee mode is set to full mode. - if o.BeeMode == api.UnknownMode { - o.BeeMode = api.FullMode - } - o.CORSAllowedOrigins = append(o.CORSAllowedOrigins, "*") - s := api.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, []string{}, o.Logger, transaction, o.BatchStore, o.BeeMode, true, true, backend, o.CORSAllowedOrigins, inmemstore.New()) - testutil.CleanupCloser(t, s) - - s.SetP2P(o.P2P) - - if o.RedistributionAgent == nil { - o.RedistributionAgent, _ = createRedistributionAgentService(t, o.Overlay, o.StateStorer, erc20, transaction, backend, o.BatchStore) - s.SetRedistributionAgent(o.RedistributionAgent) - } - testutil.CleanupCloser(t, o.RedistributionAgent) - - s.SetSwarmAddress(&o.Overlay) - s.SetProbe(o.Probe) - - noOpTracer, tracerCloser, _ := tracing.NewTracer(&tracing.Options{ - Enabled: false, - }) - testutil.CleanupCloser(t, tracerCloser) - - s.Configure(signer, noOpTracer, api.Options{ - CORSAllowedOrigins: o.CORSAllowedOrigins, - WsPingPeriod: o.WsPingPeriod, - }, extraOpts, 1, erc20) - - s.MountTechnicalDebug() - s.MountDebug() - s.MountAPI() - - ts := httptest.NewServer(s) - t.Cleanup(ts.Close) - return ts.URL -} - -func createRedistributionAgentService( - t *testing.T, - addr swarm.Address, - storer storage.StateStorer, - erc20Service erc20.Service, - tranService transaction.Service, - backend storageincentives.ChainBackend, - chainStateGetter postage.ChainStateGetter, -) (*storageincentives.Agent, error) { - t.Helper() - - const blocksPerRound uint64 = 12 - const blocksPerPhase uint64 = 4 - postageContract := contractMock.New(contractMock.WithExpiresBatchesFunc(func(context.Context) error { - return nil - }), - ) - stakingContract := mock2.New(mock2.WithIsFrozen(func(context.Context, uint64) (bool, error) { - return true, nil - })) - contract := &mockContract{} - - return storageincentives.New( - addr, - common.Address{}, - backend, - contract, - postageContract, - stakingContract, - mockstorer.NewReserve(), - func() bool { return true }, - time.Millisecond*10, - blocksPerRound, - blocksPerPhase, - storer, - chainStateGetter, - erc20Service, - tranService, - &mockHealth{}, - log.Noop, - ) -} - -type contractCall int - -func (c contractCall) String() string { - switch c { - case isWinnerCall: - return "isWinnerCall" - case revealCall: - return "revealCall" - case commitCall: - return "commitCall" - case claimCall: - return "claimCall" - } - return "unknown" -} - -const ( - isWinnerCall contractCall = iota - revealCall - commitCall - claimCall -) - -type mockContract struct { - callsList []contractCall - mtx sync.Mutex -} - -func (m *mockContract) Fee(ctx context.Context, txHash common.Hash) *big.Int { - return big.NewInt(1000) -} - -func (m *mockContract) ReserveSalt(context.Context) ([]byte, error) { - return nil, nil -} - -func (m *mockContract) IsPlaying(context.Context, uint8) (bool, error) { - return true, nil -} - -func (m *mockContract) IsWinner(context.Context) (bool, error) { - m.mtx.Lock() - defer m.mtx.Unlock() - m.callsList = append(m.callsList, isWinnerCall) - return false, nil -} - -func (m *mockContract) Claim(context.Context, redistribution.ChunkInclusionProofs) (common.Hash, error) { - m.mtx.Lock() - defer m.mtx.Unlock() - m.callsList = append(m.callsList, claimCall) - return common.Hash{}, nil -} - -func (m *mockContract) Commit(context.Context, []byte, uint64) (common.Hash, error) { - m.mtx.Lock() - defer m.mtx.Unlock() - m.callsList = append(m.callsList, commitCall) - return common.Hash{}, nil -} - -func (m *mockContract) Reveal(context.Context, uint8, []byte, []byte) (common.Hash, error) { - m.mtx.Lock() - defer m.mtx.Unlock() - m.callsList = append(m.callsList, revealCall) - return common.Hash{}, nil -} - -type mockHealth struct{} - -func (m *mockHealth) IsHealthy() bool { return true } diff --git a/pkg/blockstore/client.go b/pkg/blockstore/client.go deleted file mode 100644 index a6dd3521..00000000 --- a/pkg/blockstore/client.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright © 2020 FairOS Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package blockstore - -import ( - "context" - - "github.com/ethersphere/bee/v2/pkg/swarm" -) - -// Client is the interface for block store -type Client interface { - CheckConnection() bool - UploadSOC(owner string, id string, signature string, data []byte) (address []byte, err error) - UploadChunk(ch swarm.Chunk) (address []byte, err error) - UploadBlob(data []byte, tag uint32, encrypt bool) (address []byte, err error) - UploadBzz(data []byte, fileName string) (address []byte, err error) - DownloadChunk(ctx context.Context, address []byte) (data []byte, err error) - DownloadBlob(address []byte) (data []byte, respCode int, err error) - DownloadBzz(address []byte) (data []byte, respCode int, err error) - DeleteReference(address []byte) error - CreateTag(address []byte) (uint32, error) - GetTag(tag uint32) (int64, int64, int64, error) - CreateFeedManifest(owner, topic string) (address swarm.Address, err error) - GetLatestFeedManifest(owner, topic string) (address []byte, index, nextIndex string, err error) -} diff --git a/pkg/blockstore/putergetter/bzzUpdate.go b/pkg/blockstore/putergetter/bzzUpdate.go deleted file mode 100644 index df3064a0..00000000 --- a/pkg/blockstore/putergetter/bzzUpdate.go +++ /dev/null @@ -1 +0,0 @@ -package putergetter diff --git a/pkg/collection/batch.go b/pkg/collection/batch.go index 6e632412..c7ab04a5 100644 --- a/pkg/collection/batch.go +++ b/pkg/collection/batch.go @@ -17,6 +17,7 @@ limitations under the License. package collection import ( + "bytes" "context" "errors" "fmt" @@ -76,11 +77,11 @@ func (b *Batch) Put(key string, value []byte, apnd, memory bool) error { } stringKey = fmt.Sprintf("%020d", i) } else if b.idx.indexType == BytesIndex { - ref, err := b.idx.client.UploadBlob(value, 0, true) + ref, err := b.idx.client.UploadBlob(0, "", "0", false, true, bytes.NewReader(value)) if err != nil { // skipcq: TCV-001 return err } - value = ref + value = ref.Bytes() } return b.idx.addOrUpdateStringEntry(ctx, b.memDb, stringKey, b.idx.indexType, value, memory, apnd) } diff --git a/pkg/collection/batch_test.go b/pkg/collection/batch_test.go index 54abca69..ccf47e19 100644 --- a/pkg/collection/batch_test.go +++ b/pkg/collection/batch_test.go @@ -18,19 +18,22 @@ package collection_test import ( "bytes" + "fmt" "io" "testing" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + + "github.com/asabya/swarm-blockstore/bee" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/collection" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -45,7 +48,7 @@ func TestBatchIndex(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) acc := account.New(logger) ai := acc.GetUserAccountInfo() _, _, err := acc.CreateUserAccount("") diff --git a/pkg/collection/document.go b/pkg/collection/document.go index 0bf83a00..26e1f4fb 100644 --- a/pkg/collection/document.go +++ b/pkg/collection/document.go @@ -33,10 +33,12 @@ import ( "strings" "sync" + "github.com/ethersphere/bee/v2/pkg/swarm" + + blockstore "github.com/asabya/swarm-blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/taskmanager" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -675,7 +677,7 @@ func (d *Document) Put(dbName string, doc []byte) error { } // upload the document - ref, err := d.client.UploadBlob(doc, 0, true) + ref, err := d.client.UploadBlob(0, "", "0", false, true, bytes.NewReader(doc)) if err != nil { // skipcq: TCV-001 d.logger.Errorf("inserting in to document db: ", err.Error()) return err @@ -711,7 +713,7 @@ func (d *Document) Put(dbName string, doc []byte) error { return err } embeddingHex := hex.EncodeToString(buf.Bytes()) - err := index.Put(embeddingHex, ref, StringIndex, true) + err := index.Put(embeddingHex, ref.Bytes(), StringIndex, true) if err != nil { // skipcq: TCV-001 d.logger.Errorf("inserting in to document db: ", err.Error()) return err @@ -721,7 +723,7 @@ func (d *Document) Put(dbName string, doc []byte) error { if field == DefaultIndexFieldName { apnd = false } - err := index.Put(v.(string), ref, StringIndex, apnd) + err := index.Put(v.(string), ref.Bytes(), StringIndex, apnd) if err != nil { // skipcq: TCV-001 d.logger.Errorf("inserting in to document db: ", err.Error()) return err @@ -732,7 +734,7 @@ func (d *Document) Put(dbName string, doc []byte) error { for keyField, vf := range valMap { valueField := vf.(string) mapField := keyField + valueField - err := index.Put(mapField, ref, StringIndex, true) + err := index.Put(mapField, ref.Bytes(), StringIndex, true) if err != nil { // skipcq: TCV-001 d.logger.Errorf("inserting in to document db: ", err.Error()) return err @@ -742,7 +744,7 @@ func (d *Document) Put(dbName string, doc []byte) error { case ListIndex: valList := v.([]interface{}) for _, listVal := range valList { - err := index.Put(listVal.(string), ref, StringIndex, true) + err := index.Put(listVal.(string), ref.Bytes(), StringIndex, true) if err != nil { d.logger.Errorf("inserting in to document db: ", err.Error()) return err @@ -752,7 +754,7 @@ func (d *Document) Put(dbName string, doc []byte) error { case NumberIndex: val := v.(float64) // valStr := strconv.FormatFloat(val, 'f', 6, 64) - err := index.PutNumber(val, ref, NumberIndex, true) + err := index.PutNumber(val, ref.Bytes(), NumberIndex, true) if err != nil { // skipcq: TCV-001 d.logger.Errorf("inserting in to document db: ", err.Error()) return err @@ -791,7 +793,13 @@ func (d *Document) Get(dbName, id, podPassword string) ([]byte, error) { } if idIndex.mutable { - data, _, err := d.client.DownloadBlob(reference[0]) + r, _, err := d.client.DownloadBlob(swarm.NewAddress(reference[0])) + if err != nil { // skipcq: TCV-001 + d.logger.Errorf("getting from document db: ", err.Error()) + return nil, err + } + defer r.Close() + data, err := io.ReadAll(r) if err != nil { // skipcq: TCV-001 d.logger.Errorf("getting from document db: ", err.Error()) return nil, err @@ -849,12 +857,18 @@ func (d *Document) Del(dbName, id string) error { return nil } - data, _, err := d.client.DownloadBlob(refs[0]) + r, _, err := d.client.DownloadBlob(swarm.NewAddress(refs[0])) if err != nil { // skipcq: TCV-001 d.logger.Errorf("deleting from document db: ", err.Error()) return err } + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + d.logger.Errorf("deleting from document db: ", err.Error()) + return err + } var t interface{} err = json.Unmarshal(data, &t) if err != nil { // skipcq: TCV-001 @@ -915,7 +929,7 @@ func (d *Document) Del(dbName, id string) error { } // delete the original data (unpin) - err = d.client.DeleteReference(refs[0]) + err = d.client.DeleteReference(swarm.NewAddress(refs[0])) if err != nil { // skipcq: TCV-001 d.logger.Errorf("deleting from document db: ", err.Error()) return err @@ -1504,12 +1518,18 @@ func (d *Document) DocBatchPut(docBatch *DocBatch, doc []byte, index int64) erro if err == nil { // skipcq: TCV-001 // found a doc with the same id, so remove it and all the indexes if len(refs) > 0 { - data, _, err := d.client.DownloadBlob(refs[0]) + r, _, err := d.client.DownloadBlob(swarm.NewAddress(refs[0])) if err != nil { d.logger.Errorf("inserting in batch: ", err.Error()) return err } + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { + d.logger.Errorf("inserting in batch: ", err.Error()) + return err + } var t interface{} err = json.Unmarshal(data, &t) if err != nil { @@ -1564,7 +1584,7 @@ func (d *Document) DocBatchPut(docBatch *DocBatch, doc []byte, index int64) erro } } - err = d.client.DeleteReference(refs[0]) + err = d.client.DeleteReference(swarm.NewAddress(refs[0])) if err != nil { d.logger.Errorf("inserting in batch: ", err.Error()) return err @@ -1575,11 +1595,12 @@ func (d *Document) DocBatchPut(docBatch *DocBatch, doc []byte, index int64) erro } // upload the document - ref, err = d.client.UploadBlob(doc, 0, true) + addr, err := d.client.UploadBlob(0, "", "0", false, true, bytes.NewReader(doc)) if err != nil { // skipcq: TCV-001 d.logger.Errorf("inserting in batch: ", err.Error()) return err } + ref = addr.Bytes() } else { // skipcq: TCV-001 // store the seek index of the document instead of its reference b := make([]byte, binary.MaxVarintLen64) @@ -1785,7 +1806,13 @@ func newEntryTask(c blockstore.Client, allData *[][]byte, ref []byte, mtx sync.L // Execute func (et *entryTask) Execute(context.Context) error { - data, _, err := et.c.DownloadBlob(et.ref) + r, _, err := et.c.DownloadBlob(swarm.NewAddress(et.ref)) + if err != nil { + return err + } + defer r.Close() + + data, err := io.ReadAll(r) if err != nil { return err } diff --git a/pkg/collection/document_test.go b/pkg/collection/document_test.go index 7ae768c9..6e092b68 100644 --- a/pkg/collection/document_test.go +++ b/pkg/collection/document_test.go @@ -20,17 +20,20 @@ import ( "context" "encoding/json" "errors" + "fmt" "io" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + + "github.com/asabya/swarm-blockstore/bee" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/collection" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" f "github.com/fairdatasociety/fairOS-dfs/pkg/file" @@ -61,7 +64,7 @@ func TestDocumentStore(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) acc := account.New(logger) ai := acc.GetUserAccountInfo() _, _, err := acc.CreateUserAccount("") diff --git a/pkg/collection/index.go b/pkg/collection/index.go index cef4a848..ecc8ac6b 100644 --- a/pkg/collection/index.go +++ b/pkg/collection/index.go @@ -17,17 +17,21 @@ limitations under the License. package collection import ( + "bytes" "context" "encoding/json" "errors" "fmt" + "io" "net/http" "runtime" "sync/atomic" "time" + "github.com/ethersphere/bee/v2/pkg/swarm" + + blockstore "github.com/asabya/swarm-blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -134,19 +138,19 @@ func CreateIndex(podName, collectionName, indexName, encryptionPassword string, return ErrManifestUnmarshall } - ref, err := client.UploadBlob(data, 0, true) + ref, err := client.UploadBlob(0, "", "0", false, true, bytes.NewReader(data)) if err != nil { // skipcq: TCV-001 return ErrManifestUnmarshall } if string(oldData) == utils.DeletedFeedMagicWord { // skipcq: TCV-001 - err = fd.UpdateFeed(user, topic, ref, []byte(encryptionPassword), false) + err = fd.UpdateFeed(user, topic, ref.Bytes(), []byte(encryptionPassword), false) if err != nil { return ErrManifestCreate } return nil } - err = fd.CreateFeed(user, topic, ref, []byte(encryptionPassword)) + err = fd.CreateFeed(user, topic, ref.Bytes(), []byte(encryptionPassword)) if err != nil { // skipcq: TCV-001 return ErrManifestCreate } @@ -275,7 +279,7 @@ func (idx *Index) loadManifest(manifestPath, encryptionPassword string) (*Manife if err != nil { // skipcq: TCV-001 return nil, ErrNoManifestFound } - data, respCode, err := idx.client.DownloadBlob(refData) + r, respCode, err := idx.client.DownloadBlob(swarm.NewAddress(refData)) if err != nil { // skipcq: TCV-001 return nil, ErrNoManifestFound } @@ -283,6 +287,13 @@ func (idx *Index) loadManifest(manifestPath, encryptionPassword string) (*Manife return nil, ErrNoManifestFound } + defer r.Close() + + data, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return nil, ErrManifestUnmarshall + } + var manifest Manifest err = json.Unmarshal(data, &manifest) if err != nil { // skipcq: TCV-001 @@ -300,13 +311,13 @@ func (idx *Index) updateManifest(manifest *Manifest, encryptionPassword string) return ErrManifestUnmarshall } - ref, err := idx.client.UploadBlob(data, 0, true) + ref, err := idx.client.UploadBlob(0, "", "0", false, true, bytes.NewReader(data)) if err != nil { // skipcq: TCV-001 return ErrManifestUnmarshall } topic := utils.HashString(manifest.Name) - err = idx.feed.UpdateFeed(idx.user, topic, ref, []byte(encryptionPassword), false) + err = idx.feed.UpdateFeed(idx.user, topic, ref.Bytes(), []byte(encryptionPassword), false) if err != nil { // skipcq: TCV-001 return ErrManifestCreate } @@ -322,7 +333,7 @@ func (idx *Index) storeManifest(manifest *Manifest, encryptionPassword string) e logStr := fmt.Sprintf("storing Manifest: %s, data len = %d", manifest.Name, len(data)) idx.logger.Debug(logStr) - ref, err := idx.client.UploadBlob(data, 0, true) + ref, err := idx.client.UploadBlob(0, "", "0", false, true, bytes.NewReader(data)) // TODO: once the tags issue is fixed i bytes. // remove the error string check if err != nil { // skipcq: TCV-001 @@ -332,14 +343,14 @@ func (idx *Index) storeManifest(manifest *Manifest, encryptionPassword string) e topic := utils.HashString(manifest.Name) _, _, err = idx.feed.GetFeedData(topic, idx.user, []byte(encryptionPassword), false) if err == nil || errors.Is(err, file.ErrDeletedFeed) { - err = idx.feed.UpdateFeed(idx.user, topic, ref, []byte(encryptionPassword), false) + err = idx.feed.UpdateFeed(idx.user, topic, ref.Bytes(), []byte(encryptionPassword), false) if err != nil { // skipcq: TCV-001 idx.logger.Errorf("updateFeed failed in storeManifest : %s", err.Error()) return ErrManifestCreate } return nil } - err = idx.feed.CreateFeed(idx.user, topic, ref, []byte(encryptionPassword)) + err = idx.feed.CreateFeed(idx.user, topic, ref.Bytes(), []byte(encryptionPassword)) if err != nil { // skipcq: TCV-001 idx.logger.Errorf("createFeed failed in storeManifest : %s", err.Error()) return ErrManifestCreate @@ -380,7 +391,13 @@ func getRootManifestOfIndex(actualIndexName, encryptionPassword string, fd *feed if err != nil { return nil } - data, _, err := client.DownloadBlob(addr) + r, _, err := client.DownloadBlob(swarm.NewAddress(addr)) + if err != nil { + return nil + } + defer r.Close() + + data, err := io.ReadAll(r) if err != nil { return nil } diff --git a/pkg/collection/index_api_test.go b/pkg/collection/index_api_test.go index c0671851..45faff42 100644 --- a/pkg/collection/index_api_test.go +++ b/pkg/collection/index_api_test.go @@ -19,20 +19,24 @@ package collection_test import ( "bytes" "errors" + "fmt" "io" "net/http" "testing" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + "github.com/ethersphere/bee/v2/pkg/swarm" + + "github.com/asabya/swarm-blockstore/bee" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/collection" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -47,7 +51,7 @@ func TestIndexAPI(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) acc := account.New(logger) ai := acc.GetUserAccountInfo() _, _, err := acc.CreateUserAccount("") @@ -153,11 +157,11 @@ func TestIndexAPI(t *testing.T) { } func addDoc(t *testing.T, key string, value []byte, index *collection.Index, client *bee.Client, apnd bool) { - ref, err := client.UploadBlob(value, 0, false) + ref, err := client.UploadBlob(0, "", "0", false, false, bytes.NewReader(value)) if err != nil { t.Fatalf("could not add doc %s:%s, %v", key, value, err) } - err = index.Put(key, ref, collection.StringIndex, apnd) + err = index.Put(key, ref.Bytes(), collection.StringIndex, apnd) if err != nil { t.Fatalf("could not add doc in index: %s:%s, %v", key, ref, err) } @@ -171,13 +175,18 @@ func getDoc(t *testing.T, key string, index *collection.Index, client *bee.Clien } t.Fatal(err) } - data, respCode, err := client.DownloadBlob(ref[0]) + r, respCode, err := client.DownloadBlob(swarm.NewAddress(ref[0])) if err != nil { t.Fatal(err) } if respCode != http.StatusOK { t.Fatalf("invalid response code") } + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { + t.Fatal(err) + } return data } func getAllDocs(t *testing.T, key string, index *collection.Index, client *bee.Client) [][]byte { @@ -191,26 +200,36 @@ func getAllDocs(t *testing.T, key string, index *collection.Index, client *bee.C var data [][]byte for _, ref := range refs { - buf, respCode, err := client.DownloadBlob(ref) + r, respCode, err := client.DownloadBlob(swarm.NewAddress(ref)) if err != nil { t.Fatal(err) } if respCode != http.StatusOK { t.Fatalf("invalid response code") } + buf, err := io.ReadAll(r) + if err != nil { + t.Fatal(err) + } + r.Close() data = append(data, buf) } return data } func getValue(t *testing.T, ref []byte, client *bee.Client) []byte { - data, respCode, err := client.DownloadBlob(ref) + r, respCode, err := client.DownloadBlob(swarm.NewAddress(ref)) if err != nil { t.Fatal(err) } if respCode != http.StatusOK { t.Fatalf("invalid response code") } + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { + t.Fatal(err) + } return data } @@ -219,13 +238,18 @@ func delDoc(t *testing.T, key string, index *collection.Index, client *bee.Clien if err != nil { t.Fatal(err) } - data, respCode, err := client.DownloadBlob(ref[0]) + r, respCode, err := client.DownloadBlob(swarm.NewAddress(ref[0])) if err != nil { t.Fatal(err) } if respCode != http.StatusOK { t.Fatalf("invalid response code") } + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { + t.Fatal(err) + } return data } @@ -289,11 +313,11 @@ func addBatchDocs(t *testing.T, batch *collection.Batch, client *bee.Client) map // add the documents for k, v := range kvMap { - ref, err := client.UploadBlob(v, 0, false) + ref, err := client.UploadBlob(0, "", "0", false, false, bytes.NewReader(v)) if err != nil { t.Fatalf("could not add doc %s:%s, %v", k, ref, err) } - err = batch.Put(k, ref, false, false) + err = batch.Put(k, ref.Bytes(), false, false) if err != nil { t.Fatal(err) } diff --git a/pkg/collection/index_test.go b/pkg/collection/index_test.go index 74949334..577a436e 100644 --- a/pkg/collection/index_test.go +++ b/pkg/collection/index_test.go @@ -20,20 +20,24 @@ import ( "bytes" "encoding/json" "errors" + "fmt" "io" "strconv" "testing" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + "github.com/ethersphere/bee/v2/pkg/swarm" + + blockstore "github.com/asabya/swarm-blockstore" + "github.com/asabya/swarm-blockstore/bee" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/collection" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -49,7 +53,7 @@ func TestIndex(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) acc := account.New(logger) ai := acc.GetUserAccountInfo() _, _, err := acc.CreateUserAccount("") @@ -212,10 +216,15 @@ func isIndexPresent(t *testing.T, podName, collectionName, indexName, encryption topic := utils.HashString(actualIndexName) _, addr, err := fd.GetFeedData(topic, user, []byte(encryptionPassword), false) if err == nil && len(addr) != 0 { - data, _, err := client.DownloadBlob(addr) + r, _, err := client.DownloadBlob(swarm.NewAddress(addr)) if err != nil { return false } + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { + t.Fatal(err) + } var manifest collection.Manifest err = json.Unmarshal(data, &manifest) if err != nil { diff --git a/pkg/collection/iterator_test.go b/pkg/collection/iterator_test.go index 31791ebe..502d03db 100644 --- a/pkg/collection/iterator_test.go +++ b/pkg/collection/iterator_test.go @@ -25,16 +25,18 @@ import ( "strconv" "testing" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + + blockstore "github.com/asabya/swarm-blockstore" + "github.com/asabya/swarm-blockstore/bee" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/collection" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -50,7 +52,7 @@ func TestIndexIterator(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) acc := account.New(logger) ai := acc.GetUserAccountInfo() _, _, err := acc.CreateUserAccount("") diff --git a/pkg/collection/kv.go b/pkg/collection/kv.go index 5fc92ea1..908a0130 100644 --- a/pkg/collection/kv.go +++ b/pkg/collection/kv.go @@ -25,8 +25,10 @@ import ( "strings" "sync" + "github.com/ethersphere/bee/v2/pkg/swarm" + + blockstore "github.com/asabya/swarm-blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" @@ -265,11 +267,11 @@ func (kv *KeyValue) KVPut(name, key string, value []byte) error { } return table.index.PutNumber(fkey, value, NumberIndex, false) case BytesIndex: - ref, err := kv.client.UploadBlob(value, 0, true) + ref, err := kv.client.UploadBlob(0, "", "0", false, true, bytes.NewReader(value)) if err != nil { // skipcq: TCV-001 return err } - return table.index.Put(key, ref, StringIndex, false) + return table.index.Put(key, ref.Bytes(), StringIndex, false) default: // skipcq: TCV-001 return ErrKVInvalidIndexType } @@ -288,10 +290,17 @@ func (kv *KeyValue) KVGet(name, key string) ([]string, []byte, error) { return nil, nil, err } if table.indexType == BytesIndex { - data, _, err := kv.client.DownloadBlob(value[0]) + r, _, err := kv.client.DownloadBlob(swarm.NewAddress(value[0])) + if err != nil { // skipcq: TCV-001 + return nil, nil, err + } + + defer r.Close() + data, err := io.ReadAll(r) if err != nil { // skipcq: TCV-001 return nil, nil, err } + value[0] = data } return table.columns, value[0], nil diff --git a/pkg/collection/kv_test.go b/pkg/collection/kv_test.go index 2ca823dc..a785b0b3 100644 --- a/pkg/collection/kv_test.go +++ b/pkg/collection/kv_test.go @@ -29,13 +29,15 @@ import ( "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + + "github.com/asabya/swarm-blockstore/bee" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/collection" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -65,7 +67,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -103,7 +106,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -137,7 +141,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -176,7 +181,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -215,7 +221,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -249,7 +256,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -341,7 +349,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -373,7 +382,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -393,7 +403,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -422,7 +433,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -441,7 +453,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -488,7 +501,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -539,7 +553,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -578,7 +593,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -605,7 +621,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -670,7 +687,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -693,7 +711,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -726,7 +745,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -750,7 +770,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -816,7 +837,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) defer fd.CommitFeeds() user := acc.GetAddress(account.UserAccountIndex) @@ -878,7 +900,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -911,7 +934,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, 500, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -964,7 +988,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1028,7 +1053,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1109,7 +1135,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1206,7 +1233,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1250,7 +1278,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1295,7 +1324,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1359,7 +1389,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1417,7 +1448,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1458,7 +1490,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1489,7 +1522,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1516,7 +1550,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1543,7 +1578,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) @@ -1570,7 +1606,8 @@ func TestKeyValueStore(t *testing.T) { PreventRedirect: true, Post: mockpost.New(mockpost.WithAcceptAll()), }) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) user := acc.GetAddress(account.UserAccountIndex) kvStore := collection.NewKeyValueStore("pod1", fd, ai, user, mockClient, logger) diff --git a/pkg/dfs/api.go b/pkg/dfs/api.go index b84fae3d..c3ff06a7 100644 --- a/pkg/dfs/api.go +++ b/pkg/dfs/api.go @@ -19,11 +19,12 @@ package dfs import ( "context" "errors" + "fmt" "io" "time" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" + blockstore "github.com/asabya/swarm-blockstore" + "github.com/asabya/swarm-blockstore/bee" "github.com/fairdatasociety/fairOS-dfs/pkg/contracts" ethClient "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -73,7 +74,7 @@ func NewDfsAPI(ctx context.Context, opts *Options) (*API, error) { } return nil, errEthClient } - c := bee.NewBeeClient(opts.BeeApiEndpoint, opts.Stamp, true, opts.RedundancyLevel, logger) + c := bee.NewBeeClient(opts.BeeApiEndpoint, bee.WithStamp(opts.Stamp), bee.WithRedundancy(fmt.Sprintf("%d", opts.RedundancyLevel))) if !c.CheckConnection() { logger.Errorf("dfs: bee client initialisation failed") return nil, errBeeClient diff --git a/pkg/dfs/pod_api.go b/pkg/dfs/pod_api.go index 57fce41f..972b7c03 100644 --- a/pkg/dfs/pod_api.go +++ b/pkg/dfs/pod_api.go @@ -30,6 +30,8 @@ import ( "sync" "time" + "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/fairdatasociety/fairOS-dfs/pkg/account" c "github.com/fairdatasociety/fairOS-dfs/pkg/collection" "github.com/fairdatasociety/fairOS-dfs/pkg/contracts/datahub" @@ -249,7 +251,7 @@ func (a *API) PodReceiveInfo(sessionId string, ref utils.Reference) (*pod.ShareI // PublicPodReceiveInfo receives the pod information for a public pod func (a *API) PublicPodReceiveInfo(ref utils.Reference) (*pod.ShareInfo, error) { - data, resp, err := a.client.DownloadBlob(ref.Bytes()) + r, resp, err := a.client.DownloadBlob(swarm.NewAddress(ref.Bytes())) if err != nil { // skipcq: TCV-001 return nil, err } @@ -257,7 +259,12 @@ func (a *API) PublicPodReceiveInfo(ref utils.Reference) (*pod.ShareInfo, error) if resp != http.StatusOK { // skipcq: TCV-001 return nil, fmt.Errorf("ReceivePodInfo: could not download blob") } + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return nil, err + } var shareInfo *pod.ShareInfo err = json.Unmarshal(data, &shareInfo) if err != nil { @@ -292,11 +299,17 @@ func (a *API) PublicPodFileDownload(pod *pod.ShareInfo, filePath string) (io.Rea return nil, 0, err } - fileInodeBytes, _, err := a.client.DownloadBlob(meta.InodeAddress) + r, _, err := a.client.DownloadBlob(swarm.NewAddress(meta.InodeAddress)) if err != nil { // skipcq: TCV-001 return nil, 0, err } + defer r.Close() + + fileInodeBytes, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return nil, 0, err + } var fileInode file.INode err = json.Unmarshal(fileInodeBytes, &fileInode) if err != nil { // skipcq: TCV-001 @@ -310,11 +323,17 @@ func (a *API) PublicPodFileDownload(pod *pod.ShareInfo, filePath string) (io.Rea // PublicPodFileDownloadFromMetadata downloads a file from a public pod func (a *API) PublicPodFileDownloadFromMetadata(meta *file.MetaData) (io.ReadCloser, uint64, error) { - fileInodeBytes, _, err := a.client.DownloadBlob(meta.InodeAddress) + r, _, err := a.client.DownloadBlob(swarm.NewAddress(meta.InodeAddress)) if err != nil { // skipcq: TCV-001 return nil, 0, err } + defer r.Close() + + fileInodeBytes, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return nil, 0, err + } var fileInode file.INode err = json.Unmarshal(fileInodeBytes, &fileInode) if err != nil { // skipcq: TCV-001 @@ -390,17 +409,23 @@ func (a *API) PublicPodDisLs(pod *pod.ShareInfo, dirPathToLs string) ([]dir.Entr if err != nil { // skipcq: TCV-001 return nil, nil, err } - fileInodeBytes, _, err := a.client.DownloadBlob(meta.InodeAddress) + r, _, err := a.client.DownloadBlob(swarm.NewAddress(meta.InodeAddress)) if err != nil { // skipcq: TCV-001 return nil, nil, err } + defer r.Close() + + fileInodeBytes, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return nil, nil, err + } var fileInode file.INode err = json.Unmarshal(fileInodeBytes, &fileInode) if err != nil { // skipcq: TCV-001 return nil, nil, err } - r := file.NewReader(fileInode, a.client, meta.Size, meta.BlockSize, meta.Compression, false) + r = file.NewReader(fileInode, a.client, meta.Size, meta.BlockSize, meta.Compression, false) data, err = io.ReadAll(r) if err != nil { // skipcq: TCV-001 return nil, nil, err @@ -460,20 +485,26 @@ func (a *API) PublicPodDisLs(pod *pod.ShareInfo, dirPathToLs string) ([]dir.Entr errChan <- err return } - fileInodeBytes, _, err := a.client.DownloadBlob(meta.InodeAddress) + rOne, _, err := a.client.DownloadBlob(swarm.NewAddress(meta.InodeAddress)) + if err != nil { + errChan <- err + return + } + defer rOne.Close() + fileInodeBytes, err := io.ReadAll(rOne) if err != nil { errChan <- err return } - var fileInode file.INode err = json.Unmarshal(fileInodeBytes, &fileInode) if err != nil { errChan <- err return } - r := file.NewReader(fileInode, a.client, meta.Size, meta.BlockSize, meta.Compression, false) - data, err = io.ReadAll(r) + rTwo := file.NewReader(fileInode, a.client, meta.Size, meta.BlockSize, meta.Compression, false) + defer rTwo.Close() + data, err = io.ReadAll(rTwo) if err != nil { errChan <- err return @@ -607,7 +638,14 @@ func (a *API) PublicPodSnapshot(p *pod.ShareInfo, dirPathToLs string) (*pod.DirS if err != nil { // skipcq: TCV-001 return nil, err } - fileInodeBytes, _, err := a.client.DownloadBlob(meta.InodeAddress) + blobReader, _, err := a.client.DownloadBlob(swarm.NewAddress(meta.InodeAddress)) + if err != nil { // skipcq: TCV-001 + return nil, err + } + + defer blobReader.Close() + + fileInodeBytes, err := io.ReadAll(blobReader) if err != nil { // skipcq: TCV-001 return nil, err } @@ -689,12 +727,19 @@ func (a *API) getSnapShotForDir(dirL *pod.DirSnapShot, fd *feed.API, accountInfo errChan <- err return } - fileInodeBytes, _, err := a.client.DownloadBlob(meta.InodeAddress) + blobReader, _, err := a.client.DownloadBlob(swarm.NewAddress(meta.InodeAddress)) if err != nil { errChan <- err return } + defer blobReader.Close() + + fileInodeBytes, err := io.ReadAll(blobReader) + if err != nil { + errChan <- err + return + } var fileInode file.INode err = json.Unmarshal(fileInodeBytes, &fileInode) if err != nil { diff --git a/pkg/dir/chmod_test.go b/pkg/dir/chmod_test.go index 619ab507..bd5d87e5 100644 --- a/pkg/dir/chmod_test.go +++ b/pkg/dir/chmod_test.go @@ -7,14 +7,16 @@ import ( "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + "github.com/fairdatasociety/fairOS-dfs/pkg/file" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/asabya/swarm-blockstore/bee" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/fairdatasociety/fairOS-dfs/pkg/dir" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -33,7 +35,8 @@ func TestChmod(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { @@ -54,7 +57,6 @@ func TestChmod(t *testing.T) { t.Run("chmod-dir", func(t *testing.T) { podPassword, _ := utils.GetRandString(pod.PasswordLength) dirObject := dir.NewDirectory("pod1", mockClient, fd, user, mockFile, tm, logger) - // make root dir so that other directories can be added err = dirObject.MkRootDir("pod1", podPassword, user, fd) if err != nil { @@ -83,6 +85,7 @@ func TestChmod(t *testing.T) { if err != nil { t.Fatal(err) } + fmt.Println(3) // stat the directory dirStats, err := dirObject.DirStat("pod1", podPassword, "/dirToChmod") @@ -93,16 +96,19 @@ func TestChmod(t *testing.T) { if fmt.Sprintf("%o", dir.S_IFDIR|0700) != fmt.Sprintf("%o", dirStats.Mode) { t.Fatal("default mode mismatch") } + fmt.Println(4) err = dirObject.Chmod("/dirToChmod", podPassword, 0664) if err != nil { t.Fatal(err) } + fmt.Println(5) dirStats, err = dirObject.DirStat("pod1", podPassword, "/dirToChmod") if err != nil { t.Fatal(err) } + fmt.Println(6) if fmt.Sprintf("%o", dir.S_IFDIR|0664) != fmt.Sprintf("%o", dirStats.Mode) { t.Fatal("updated mode mismatch") diff --git a/pkg/dir/dir.go b/pkg/dir/dir.go index 2bae9937..c265649b 100644 --- a/pkg/dir/dir.go +++ b/pkg/dir/dir.go @@ -22,9 +22,9 @@ import ( "strconv" "sync" + blockstore "github.com/asabya/swarm-blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/taskmanager" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" f "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" diff --git a/pkg/dir/dir_present_test.go b/pkg/dir/dir_present_test.go index 4b17b68e..b6413406 100644 --- a/pkg/dir/dir_present_test.go +++ b/pkg/dir/dir_present_test.go @@ -18,18 +18,20 @@ package dir_test import ( "context" + "fmt" "io" "testing" "time" "github.com/fairdatasociety/fairOS-dfs/pkg/file" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/asabya/swarm-blockstore/bee" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/fairdatasociety/fairOS-dfs/pkg/dir" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -48,7 +50,8 @@ func TestDirPresent(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/dir/dir_test.go b/pkg/dir/dir_test.go index 5f6c0bae..8883bde7 100644 --- a/pkg/dir/dir_test.go +++ b/pkg/dir/dir_test.go @@ -2,17 +2,19 @@ package dir_test import ( "context" + "fmt" "io" "testing" "time" "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/dir" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -31,7 +33,8 @@ func TestDirRmAllFromMap(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/dir/inode.go b/pkg/dir/inode.go index 215a622a..2707e9d8 100644 --- a/pkg/dir/inode.go +++ b/pkg/dir/inode.go @@ -112,7 +112,6 @@ func (d *Directory) SetInode(podPassword string, iNode *Inode) error { if err != nil { // skipcq: TCV-001 return err } - err = d.file.Upload(bufio.NewReader(bytes.NewBuffer(data)), IndexFileName, int64(len(data)), file.MinBlockSize, 0, totalPath, "gzip", podPassword) if err != nil { return err diff --git a/pkg/dir/ls_test.go b/pkg/dir/ls_test.go index 398f94ef..3ff4cdcc 100644 --- a/pkg/dir/ls_test.go +++ b/pkg/dir/ls_test.go @@ -19,6 +19,7 @@ package dir_test import ( "context" "errors" + "fmt" "io" "sort" "testing" @@ -26,10 +27,11 @@ import ( "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" "github.com/sirupsen/logrus" @@ -52,7 +54,8 @@ func TestListDirectory(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/dir/mkdir_test.go b/pkg/dir/mkdir_test.go index 60fb8159..5cfaf509 100644 --- a/pkg/dir/mkdir_test.go +++ b/pkg/dir/mkdir_test.go @@ -18,16 +18,18 @@ package dir_test import ( "context" + "fmt" "io" "testing" "time" "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" "github.com/sirupsen/logrus" @@ -49,7 +51,8 @@ func TestMkdir(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/dir/rename_test.go b/pkg/dir/rename_test.go index 81015f96..fa6f2014 100644 --- a/pkg/dir/rename_test.go +++ b/pkg/dir/rename_test.go @@ -4,16 +4,18 @@ import ( "bytes" "context" "errors" + "fmt" "io" "sort" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/dir" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" @@ -33,7 +35,8 @@ func TestRenameDirectory(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/dir/rmdir_test.go b/pkg/dir/rmdir_test.go index a110cbe0..68d87950 100644 --- a/pkg/dir/rmdir_test.go +++ b/pkg/dir/rmdir_test.go @@ -19,16 +19,18 @@ package dir_test import ( "context" "errors" + "fmt" "io" "testing" "time" "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" "github.com/sirupsen/logrus" @@ -50,7 +52,8 @@ func TestRmdir(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { @@ -187,7 +190,8 @@ func TestRmRootDirByPath(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { @@ -280,7 +284,8 @@ func TestRmRootDir(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/dir/stat_test.go b/pkg/dir/stat_test.go index 20e0619e..9e739fd1 100644 --- a/pkg/dir/stat_test.go +++ b/pkg/dir/stat_test.go @@ -19,17 +19,20 @@ package dir_test import ( "context" "errors" + "fmt" "io" "strconv" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" "github.com/sirupsen/logrus" @@ -51,7 +54,8 @@ func TestStat(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/dir/sync_test.go b/pkg/dir/sync_test.go index 17f7d052..b7327588 100644 --- a/pkg/dir/sync_test.go +++ b/pkg/dir/sync_test.go @@ -18,6 +18,7 @@ package dir_test import ( "context" + "fmt" "io" "sync" "testing" @@ -25,11 +26,12 @@ import ( "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/dir" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -53,7 +55,8 @@ func TestSync(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/feed/api.go b/pkg/feed/api.go index 0f033aa0..615aab11 100644 --- a/pkg/feed/api.go +++ b/pkg/feed/api.go @@ -21,11 +21,11 @@ import ( "fmt" "time" + blockstore "github.com/asabya/swarm-blockstore" "github.com/ethersphere/bee/v2/pkg/crypto" "github.com/ethersphere/bee/v2/pkg/swarm" bmtlegacy "github.com/ethersphere/bmt/legacy" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/feed/lookup" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" @@ -174,11 +174,11 @@ func (a *API) CreateFeedFromTopic(topic []byte, user utils.Address, data []byte) func (a *API) GetSOCFromAddress(address []byte) ([]byte, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() - data, err := a.handler.client.DownloadChunk(ctx, address) + ch, err := a.handler.client.DownloadChunk(ctx, swarm.NewAddress(address)) if err != nil { return nil, err } - ch := swarm.NewChunk(swarm.NewAddress(address), data) + return a.handler.rawSignedChunkData(ch) } diff --git a/pkg/feed/feed_test.go b/pkg/feed/feed_test.go index 5287b5b6..b0ddb52a 100644 --- a/pkg/feed/feed_test.go +++ b/pkg/feed/feed_test.go @@ -20,17 +20,19 @@ import ( "bytes" "crypto/rand" "errors" + "fmt" "io" "testing" "time" "github.com/stretchr/testify/require" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" @@ -49,7 +51,7 @@ func TestFeed(t *testing.T) { Storer: storer, Post: mockpost.New(mockpost.WithAcceptAll()), }) - client := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + client := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) t.Run("create-feed", func(t *testing.T) { acc := account.New(logger) diff --git a/pkg/feed/handler.go b/pkg/feed/handler.go index 7a22c7f1..3479bdab 100644 --- a/pkg/feed/handler.go +++ b/pkg/feed/handler.go @@ -30,12 +30,12 @@ import ( "sync/atomic" "time" + blockstore "github.com/asabya/swarm-blockstore" bCrypto "github.com/ethersphere/bee/v2/pkg/crypto" "github.com/ethersphere/bee/v2/pkg/soc" "github.com/ethersphere/bee/v2/pkg/swarm" bmtlegacy "github.com/ethersphere/bmt/legacy" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/feed/lookup" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" @@ -303,15 +303,15 @@ retry: func (h *Handler) update(id, owner, signature, data []byte) ([]byte, error) { // send the SOC chunk - addr, err := h.client.UploadSOC(utils.Encode(owner), utils.Encode(id), utils.Encode(signature), data) + addr, err := h.client.UploadSOC(utils.Encode(owner), utils.Encode(id), utils.Encode(signature), "", "0", false, data) if err != nil { return nil, err } - return addr, nil + return addr.Bytes(), nil } func (h *Handler) deleteChunk(ref []byte) error { - return h.client.DeleteReference(ref) + return h.client.DeleteReference(swarm.NewAddress(ref)) } // GetContent retrieves the data payload of the last synced update of the feed @@ -372,14 +372,13 @@ func (h *Handler) Lookup(ctx context.Context, query *Query) (*CacheEntry, error) if err != nil { // skipcq: TCV-001 return nil, err } - data, err := h.client.DownloadChunk(ctx, addr.Bytes()) + ch, err := h.client.DownloadChunk(ctx, addr) if err != nil { if errors.Is(err, context.DeadlineExceeded) || err.Error() == "error downloading data" { // chunk not found return nil, nil } return nil, err } - ch := swarm.NewChunk(addr, data) var request request if err := h.fromChunk(ch, &request, query, &id); err != nil { @@ -422,11 +421,10 @@ func (h *Handler) LookupEpoch(ctx context.Context, query *Query) (*CacheEntry, e if err != nil { // skipcq: TCV-001 return nil, err } - data, err := h.client.DownloadChunk(ctx, addr.Bytes()) + ch, err := h.client.DownloadChunk(ctx, addr) if err != nil { return nil, err } - ch := swarm.NewChunk(addr, data) var request request if err := h.fromChunk(ch, &request, query, &id); err != nil { return nil, err diff --git a/pkg/feed/handler_test.go b/pkg/feed/handler_test.go index 73847a63..88e08c1e 100644 --- a/pkg/feed/handler_test.go +++ b/pkg/feed/handler_test.go @@ -1,16 +1,19 @@ package feed import ( + "fmt" "io" "testing" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/ethersphere/bee/v2/pkg/swarm" bmtlegacy "github.com/ethersphere/bmt/legacy" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" ) @@ -22,7 +25,7 @@ func TestHandler(t *testing.T) { Storer: storer, Post: mockpost.New(mockpost.WithAcceptAll()), }) - client := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + client := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) t.Run("new-handler", func(t *testing.T) { acc := account.New(logger) diff --git a/pkg/feed/tracker/tracker.go b/pkg/feed/tracker/tracker.go index e17c4d18..641d089b 100644 --- a/pkg/feed/tracker/tracker.go +++ b/pkg/feed/tracker/tracker.go @@ -10,7 +10,7 @@ package tracker // "strings" // "sync" // -// "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" +// "github.com/asabya/swarm-blockstore" // "github.com/fairdatasociety/fairOS-dfs/pkg/feed" // "github.com/fairdatasociety/fairOS-dfs/pkg/logging" // "github.com/fairdatasociety/fairOS-dfs/pkg/utils" diff --git a/pkg/feed/tracker/tracker_test.go b/pkg/feed/tracker/tracker_test.go index 68acfec3..523c21f8 100644 --- a/pkg/feed/tracker/tracker_test.go +++ b/pkg/feed/tracker/tracker_test.go @@ -10,7 +10,7 @@ package tracker // "github.com/stretchr/testify/require" // // "github.com/fairdatasociety/fairOS-dfs/pkg/account" -// "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" +// "github.com/asabya/swarm-blockstore/bee/mock" // "github.com/fairdatasociety/fairOS-dfs/pkg/feed" // "github.com/fairdatasociety/fairOS-dfs/pkg/feed/lookup" // "github.com/fairdatasociety/fairOS-dfs/pkg/logging" diff --git a/pkg/file/chmod_test.go b/pkg/file/chmod_test.go index 8e92b0cf..12f6760e 100644 --- a/pkg/file/chmod_test.go +++ b/pkg/file/chmod_test.go @@ -7,11 +7,12 @@ import ( "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -32,7 +33,8 @@ func TestChmod(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/file/download.go b/pkg/file/download.go index dd644ec8..b4419419 100644 --- a/pkg/file/download.go +++ b/pkg/file/download.go @@ -21,6 +21,8 @@ import ( "errors" "io" + "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" ) @@ -55,7 +57,14 @@ func (f *File) ReadSeeker(podFileWithPath, podPassword string) (io.ReadSeekClose if meta == nil { // skipcq: TCV-001 return nil, 0, ErrFileNotFound } - fileInodeBytes, _, err := f.getClient().DownloadBlob(meta.InodeAddress) + r, _, err := f.getClient().DownloadBlob(swarm.NewAddress(meta.InodeAddress)) + if err != nil { // skipcq: TCV-001 + return nil, 0, err + } + + defer r.Close() + + fileInodeBytes, err := io.ReadAll(r) if err != nil { // skipcq: TCV-001 return nil, 0, err } diff --git a/pkg/file/download_test.go b/pkg/file/download_test.go index 9c193efc..5abef00e 100644 --- a/pkg/file/download_test.go +++ b/pkg/file/download_test.go @@ -24,11 +24,12 @@ import ( "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -49,7 +50,8 @@ func TestDownload(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") require.NoError(t, err) diff --git a/pkg/file/file.go b/pkg/file/file.go index 254a511b..fa8a2741 100644 --- a/pkg/file/file.go +++ b/pkg/file/file.go @@ -25,7 +25,7 @@ import ( "github.com/fairdatasociety/fairOS-dfs/pkg/taskmanager" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" + blockstore "github.com/asabya/swarm-blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" diff --git a/pkg/file/ls_test.go b/pkg/file/ls_test.go index 659437ba..9bf35cde 100644 --- a/pkg/file/ls_test.go +++ b/pkg/file/ls_test.go @@ -24,11 +24,12 @@ import ( "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -47,7 +48,8 @@ func TestListFiles(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/file/meta.go b/pkg/file/meta.go index 6dd8569e..2c14d858 100644 --- a/pkg/file/meta.go +++ b/pkg/file/meta.go @@ -73,7 +73,8 @@ func (f *File) handleMeta(meta *MetaData, podPassword string) error { if err == nil || errors.Is(err, ErrDeletedFeed) { return f.updateMeta(meta, podPassword) } - return f.uploadMeta(meta, podPassword) + err = f.uploadMeta(meta, podPassword) + return err } func (f *File) uploadMeta(meta *MetaData, podPassword string) error { diff --git a/pkg/file/reader.go b/pkg/file/reader.go index a0a1214a..edc7686d 100644 --- a/pkg/file/reader.go +++ b/pkg/file/reader.go @@ -20,9 +20,10 @@ import ( "bytes" "encoding/json" "errors" + "github.com/ethersphere/bee/v2/pkg/swarm" "io" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" + blockstore "github.com/asabya/swarm-blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" "github.com/golang/snappy" lru "github.com/hashicorp/golang-lru/v2/expirable" @@ -66,11 +67,17 @@ func (f *File) OpenFileForIndex(podFile, podPassword string) (*Reader, error) { return nil, ErrFileNotFound } - encryptedFileInodeBytes, _, err := f.getClient().DownloadBlob(meta.InodeAddress) + r, _, err := f.getClient().DownloadBlob(swarm.NewAddress(meta.InodeAddress)) if err != nil { return nil, err } + defer r.Close() + + encryptedFileInodeBytes, err := io.ReadAll(r) + if err != nil { + return nil, err + } temp := make([]byte, len(encryptedFileInodeBytes)) copy(temp, encryptedFileInodeBytes) fileInodeBytes, err := utils.DecryptBytes([]byte(podPassword), temp) @@ -313,11 +320,16 @@ func (r *Reader) getBlock(ref []byte, compression string, blockSize uint32) ([]b return data, nil } } - stdoutBytes, _, err := r.client.DownloadBlob(ref) + rd, _, err := r.client.DownloadBlob(swarm.NewAddress(ref)) if err != nil { // skipcq: TCV-001 return nil, err } + defer rd.Close() + stdoutBytes, err := io.ReadAll(rd) + if err != nil { // skipcq: TCV-001 + return nil, err + } decompressedData, err := Decompress(stdoutBytes, compression, blockSize) if err != nil { // skipcq: TCV-001 return nil, err diff --git a/pkg/file/reader_test.go b/pkg/file/reader_test.go index 250d385a..54a38047 100644 --- a/pkg/file/reader_test.go +++ b/pkg/file/reader_test.go @@ -17,19 +17,19 @@ limitations under the License. package file_test import ( + "bytes" "crypto/rand" "errors" + "fmt" "io" "math/big" "testing" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/logging" - "github.com/sirupsen/logrus" - - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" "github.com/stretchr/testify/assert" @@ -44,8 +44,7 @@ func TestFileReader(t *testing.T) { Post: mockpost.New(mockpost.WithAcceptAll()), }) - logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) t.Run("read-entire-file-shorter-than-block", func(t *testing.T) { fileSize := uint64(15) @@ -343,14 +342,14 @@ func createFile(t *testing.T, fileSize uint64, blockSize uint32, compression str buf = compressedData } - addr, err := mockClient.UploadBlob(buf, 0, true) + addr, err := mockClient.UploadBlob(0, "", "0", false, true, bytes.NewReader(buf)) if err != nil { t.Fatal(err) } fileBlock := &file.BlockInfo{ Size: bytesToWrite, CompressedSize: uint32(len(buf)), - Reference: utils.NewReference(addr), + Reference: utils.NewReference(addr.Bytes()), } fileBlocks = append(fileBlocks, fileBlock) bytesRemaining -= uint64(bytesToWrite) @@ -467,14 +466,14 @@ func createFileWithNewlines(t *testing.T, fileSize uint64, blockSize uint32, com buf = compressedData } - addr, err := mockClient.UploadBlob(buf, 0, true) + addr, err := mockClient.UploadBlob(0, "", "0", false, true, bytes.NewReader(buf)) if err != nil { t.Fatal(err) } fileBlock := &file.BlockInfo{ Size: bytesToWrite, CompressedSize: uint32(len(buf)), - Reference: utils.NewReference(addr), + Reference: utils.NewReference(addr.Bytes()), } fileBlocks = append(fileBlocks, fileBlock) bytesRemaining -= uint64(bytesToWrite) diff --git a/pkg/file/rename_test.go b/pkg/file/rename_test.go index 61491c4c..5ce0b817 100644 --- a/pkg/file/rename_test.go +++ b/pkg/file/rename_test.go @@ -3,15 +3,17 @@ package file_test import ( "bytes" "context" + "fmt" "io" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/dir" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" @@ -31,7 +33,8 @@ func TestRename(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/file/rm.go b/pkg/file/rm.go index aa530433..31c479ff 100644 --- a/pkg/file/rm.go +++ b/pkg/file/rm.go @@ -19,6 +19,7 @@ package file import ( "encoding/json" "fmt" + "io" "net/http" "github.com/ethersphere/bee/v2/pkg/swarm" @@ -32,7 +33,7 @@ func (f *File) RmFile(podFileWithPath, podPassword string) error { if meta == nil { return ErrFileNotFound } - fileInodeBytes, respCode, err := f.client.DownloadBlob(meta.InodeAddress) + r, respCode, err := f.client.DownloadBlob(swarm.NewAddress(meta.InodeAddress)) if err != nil { // skipcq: TCV-001 return err } @@ -40,7 +41,13 @@ func (f *File) RmFile(podFileWithPath, podPassword string) error { f.logger.Warningf("could not remove blocks in %s", swarm.NewAddress(meta.InodeAddress).String()) return fmt.Errorf("could not remove blocks in %v", swarm.NewAddress(meta.InodeAddress).String()) } + defer r.Close() + fileInodeBytes, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + f.logger.Warningf("could not read data in address %s", swarm.NewAddress(meta.InodeAddress).String()) + return fmt.Errorf("could not read data in address %v", swarm.NewAddress(meta.InodeAddress).String()) + } // find the inode and remove the blocks present in the inode one by one var fInode *INode err = json.Unmarshal(fileInodeBytes, &fInode) @@ -49,13 +56,13 @@ func (f *File) RmFile(podFileWithPath, podPassword string) error { return fmt.Errorf("could not unmarshall data in address %v", swarm.NewAddress(meta.InodeAddress).String()) } - err = f.client.DeleteReference(meta.InodeAddress) + err = f.client.DeleteReference(swarm.NewAddress(meta.InodeAddress)) if err != nil { f.logger.Errorf("could not delete file inode %s", swarm.NewAddress(meta.InodeAddress).String()) return fmt.Errorf("could not delete file inode %s: %s", swarm.NewAddress(meta.InodeAddress).String(), err.Error()) } for _, fblocks := range fInode.Blocks { - err = f.client.DeleteReference(fblocks.Reference.Bytes()) + err = f.client.DeleteReference(swarm.NewAddress(fblocks.Reference.Bytes())) if err != nil { // skipcq: TCV-001 f.logger.Errorf("could not delete file block %s", swarm.NewAddress(fblocks.Reference.Bytes()).String()) return fmt.Errorf("could not delete file inode %v", swarm.NewAddress(fblocks.Reference.Bytes()).String()) diff --git a/pkg/file/rm_test.go b/pkg/file/rm_test.go index e43f6348..0e49fa12 100644 --- a/pkg/file/rm_test.go +++ b/pkg/file/rm_test.go @@ -18,15 +18,17 @@ package file_test import ( "context" + "fmt" "io" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -46,7 +48,8 @@ func TestRemoveFile(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") require.NoError(t, err) diff --git a/pkg/file/stat_test.go b/pkg/file/stat_test.go index 1a83df20..b4bfe616 100644 --- a/pkg/file/stat_test.go +++ b/pkg/file/stat_test.go @@ -24,11 +24,13 @@ import ( "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -47,7 +49,8 @@ func TestStat(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/file/status_test.go b/pkg/file/status_test.go index 9ec5fd16..da27ce5d 100644 --- a/pkg/file/status_test.go +++ b/pkg/file/status_test.go @@ -2,17 +2,20 @@ package file_test import ( "context" + "fmt" "io" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + "github.com/stretchr/testify/require" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -31,7 +34,8 @@ func TestStatus(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/file/upload.go b/pkg/file/upload.go index 5c07ebdc..cbf49648 100644 --- a/pkg/file/upload.go +++ b/pkg/file/upload.go @@ -28,6 +28,8 @@ import ( "sync" "time" + "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" "github.com/golang/snappy" "github.com/klauspost/pgzip" @@ -58,8 +60,7 @@ func (f *File) Upload(fd io.Reader, podFileName string, fileSize int64, blockSiz } reader := bufio.NewReader(fd) now := time.Now().Unix() - - tag, err := f.client.CreateTag(nil) + tag, err := f.client.CreateTag(swarm.ZeroAddress) if err != nil { // skipcq: TCV-001 return err } @@ -146,8 +147,7 @@ func (f *File) Upload(fd io.Reader, podFileName string, fileSize int64, blockSiz return } } - - addr, uploadErr := f.client.UploadBlob(uploadData, tag, true) + addr, uploadErr := f.client.UploadBlob(tag, "", "0", false, true, bytes.NewReader(uploadData)) if uploadErr != nil { mainErr = uploadErr return @@ -156,7 +156,7 @@ func (f *File) Upload(fd io.Reader, podFileName string, fileSize int64, blockSiz fileBlock := &BlockInfo{ Size: uint32(size), CompressedSize: uint32(len(uploadData)), - Reference: utils.NewReference(addr), + Reference: utils.NewReference(addr.Bytes()), } refMapMu.Lock() @@ -186,23 +186,19 @@ func (f *File) Upload(fd io.Reader, podFileName string, fileSize int64, blockSiz for i := 0; i < len(refMap); i++ { fileINode.Blocks = append(fileINode.Blocks, refMap[i]) } - fileInodeData, err := json.Marshal(fileINode) if err != nil { // skipcq: TCV-001 return err } - - addr, err := f.client.UploadBlob(fileInodeData, 0, true) + addr, err := f.client.UploadBlob(tag, "", "0", false, true, bytes.NewReader(fileInodeData)) if err != nil { // skipcq: TCV-001 return err } - - meta.InodeAddress = addr + meta.InodeAddress = addr.Bytes() err = f.handleMeta(&meta, podPassword) if err != nil { // skipcq: TCV-001 return err } - totalPath := utils.CombinePathAndFile(meta.Path, meta.Name) f.AddToFileMap(totalPath, &meta) if tag > 0 { diff --git a/pkg/file/upload_test.go b/pkg/file/upload_test.go index fd02dfd0..9aaea8bc 100644 --- a/pkg/file/upload_test.go +++ b/pkg/file/upload_test.go @@ -21,17 +21,19 @@ import ( "context" "crypto/rand" "errors" + "fmt" "io" "os" "path/filepath" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -50,7 +52,8 @@ func TestUpload(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/file/writeAt.go b/pkg/file/writeAt.go index 00350d24..09ea3f99 100644 --- a/pkg/file/writeAt.go +++ b/pkg/file/writeAt.go @@ -8,6 +8,8 @@ import ( "io" "sync" + "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" ) @@ -26,7 +28,14 @@ func (f *File) WriteAt(podFileWithPath, podPassword string, update io.Reader, of } // download file inode (blocks info) - fileInodeBytes, _, err := f.getClient().DownloadBlob(meta.InodeAddress) + r, _, err := f.getClient().DownloadBlob(swarm.NewAddress(meta.InodeAddress)) + if err != nil { // skipcq: TCV-001 + return 0, err + } + + defer r.Close() + + fileInodeBytes, err := io.ReadAll(r) if err != nil { // skipcq: TCV-001 return 0, err } @@ -204,7 +213,7 @@ func (f *File) WriteAt(podFileWithPath, podPassword string, update io.Reader, of } } - addr, uploadErr := f.client.UploadBlob(uploadData, tag, true) + addr, uploadErr := f.client.UploadBlob(tag, "", "0", false, true, bytes.NewReader(uploadData)) if uploadErr != nil { mainErr = uploadErr return @@ -213,7 +222,7 @@ func (f *File) WriteAt(podFileWithPath, podPassword string, update io.Reader, of fileBlock := &BlockInfo{ Size: uint32(size), CompressedSize: uint32(len(uploadData)), - Reference: utils.NewReference(addr), + Reference: utils.NewReference(addr.Bytes()), } refMapMu.Lock() @@ -249,11 +258,11 @@ func (f *File) WriteAt(podFileWithPath, podPassword string, update io.Reader, of return 0, err } - addr, err := f.client.UploadBlob(fileInodeData, 0, true) + addr, err := f.client.UploadBlob(tag, "", "0", false, true, bytes.NewReader(fileInodeData)) if err != nil { // skipcq: TCV-001 return 0, err } - meta.InodeAddress = addr + meta.InodeAddress = addr.Bytes() meta.Size = newDataSize err = f.handleMeta(meta, podPassword) diff --git a/pkg/file/writeAt_test.go b/pkg/file/writeAt_test.go index 787073de..8ea52e05 100644 --- a/pkg/file/writeAt_test.go +++ b/pkg/file/writeAt_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "errors" + "fmt" "io" "math/rand" "os" @@ -11,11 +12,13 @@ import ( "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -40,7 +43,8 @@ func TestWriteAt(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/pod/fork.go b/pkg/pod/fork.go index 9348f12d..acaca56a 100644 --- a/pkg/pod/fork.go +++ b/pkg/pod/fork.go @@ -3,9 +3,12 @@ package pod import ( "encoding/json" "fmt" + "io" "net/http" "strings" + "github.com/ethersphere/bee/v2/pkg/swarm" + d "github.com/fairdatasociety/fairOS-dfs/pkg/dir" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" f "github.com/fairdatasociety/fairOS-dfs/pkg/file" @@ -48,13 +51,19 @@ func (p *Pod) PodForkFromRef(forkName, refString string) error { if err != nil { return nil } - data, resp, err := p.client.DownloadBlob(ref.Bytes()) + r, resp, err := p.client.DownloadBlob(swarm.NewAddress(ref.Bytes())) if err != nil { // skipcq: TCV-001 return err } if resp != http.StatusOK { // skipcq: TCV-001 return fmt.Errorf("ReceivePod: could not download blob") } + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return err + } + var shareInfo ShareInfo err = json.Unmarshal(data, &shareInfo) if err != nil { // skipcq: TCV-001 diff --git a/pkg/pod/group.go b/pkg/pod/group.go index cc51780d..4e51044d 100644 --- a/pkg/pod/group.go +++ b/pkg/pod/group.go @@ -11,12 +11,12 @@ import ( "strings" "sync" + blockstore "github.com/asabya/swarm-blockstore" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/fairdatasociety/fairOS-dfs/pkg/account" "github.com/fairdatasociety/fairOS-dfs/pkg/acl" aclController "github.com/fairdatasociety/fairOS-dfs/pkg/acl/acl" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" c "github.com/fairdatasociety/fairOS-dfs/pkg/collection" d "github.com/fairdatasociety/fairOS-dfs/pkg/dir" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" diff --git a/pkg/pod/groupMember.go b/pkg/pod/groupMember.go index b3924ca2..f41a80e7 100644 --- a/pkg/pod/groupMember.go +++ b/pkg/pod/groupMember.go @@ -1,12 +1,16 @@ package pod import ( + "bytes" "crypto/ecdsa" "crypto/sha256" "encoding/json" "errors" + "io" "strings" + "github.com/ethersphere/bee/v2/pkg/swarm" + aclController "github.com/fairdatasociety/fairOS-dfs/pkg/acl/acl" "github.com/ethereum/go-ethereum/crypto" @@ -71,7 +75,7 @@ func (g *Group) AddMember(groupName string, memberAddress common.Address, member return nil, err } - ref, err := g.client.UploadBlob(data, 0, false) + ref, err := g.client.UploadBlob(0, "", "0", false, false, bytes.NewReader(data)) if err != nil { return nil, err } @@ -81,7 +85,7 @@ func (g *Group) AddMember(groupName string, memberAddress common.Address, member return nil, err } - return ref, nil + return ref.Bytes(), nil } func (g *Group) AcceptGroupInvite(ref []byte) error { @@ -91,10 +95,18 @@ func (g *Group) AcceptGroupInvite(ref []byte) error { } // download blob - data, _, err := g.client.DownloadBlob(ref) + r, _, err := g.client.DownloadBlob(swarm.NewAddress(ref)) if err != nil { return err } + + defer r.Close() + + data, err := io.ReadAll(r) + if err != nil { + return err + } + // unmarshall into GroupItem group := &GroupItem{} err = json.Unmarshal(data, group) diff --git a/pkg/pod/pod.go b/pkg/pod/pod.go index 2cede24f..abd83614 100644 --- a/pkg/pod/pod.go +++ b/pkg/pod/pod.go @@ -21,14 +21,12 @@ import ( "sync" "time" - "github.com/fairdatasociety/fairOS-dfs/pkg/file" - - "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager" - + blockstore "github.com/asabya/swarm-blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" + "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" + "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager" "github.com/fairdatasociety/fairOS-dfs/pkg/taskmanager" ) diff --git a/pkg/pod/sharing.go b/pkg/pod/sharing.go index ca8bc40a..658bd39c 100644 --- a/pkg/pod/sharing.go +++ b/pkg/pod/sharing.go @@ -17,10 +17,14 @@ limitations under the License. package pod import ( + "bytes" "encoding/json" "fmt" + "io" "net/http" + "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" ) @@ -72,13 +76,12 @@ func (p *Pod) PodShare(podName, sharedPodName string) (string, error) { if err != nil { // skipcq: TCV-001 return "", err } - ref, err := p.client.UploadBlob(data, 0, false) + ref, err := p.client.UploadBlob(0, "", "0", false, false, bytes.NewReader(data)) if err != nil { // skipcq: TCV-001 return "", err } - shareInfoRef := utils.NewReference(ref) - return shareInfoRef.String(), nil + return ref.String(), nil } // GetPodSharingInfo returns the raw shareInfo @@ -116,7 +119,7 @@ func (p *Pod) GetPodSharingInfo(podName string) (*ShareInfo, error) { // ReceivePodInfo returns the shareInfo from the reference func (p *Pod) ReceivePodInfo(ref utils.Reference) (*ShareInfo, error) { - data, resp, err := p.client.DownloadBlob(ref.Bytes()) + r, resp, err := p.client.DownloadBlob(swarm.NewAddress(ref.Bytes())) if err != nil { // skipcq: TCV-001 return nil, err } @@ -124,7 +127,12 @@ func (p *Pod) ReceivePodInfo(ref utils.Reference) (*ShareInfo, error) { if resp != http.StatusOK { // skipcq: TCV-001 return nil, fmt.Errorf("ReceivePodInfo: could not download blob") } + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return nil, err + } var shareInfo ShareInfo err = json.Unmarshal(data, &shareInfo) if err != nil { @@ -136,13 +144,19 @@ func (p *Pod) ReceivePodInfo(ref utils.Reference) (*ShareInfo, error) { // ReceivePod imports a pod by creating a new pod with the same name and password func (p *Pod) ReceivePod(sharedPodName string, ref utils.Reference) (*Info, error) { - data, resp, err := p.client.DownloadBlob(ref.Bytes()) + r, resp, err := p.client.DownloadBlob(swarm.NewAddress(ref.Bytes())) if err != nil { // skipcq: TCV-001 return nil, err } if resp != http.StatusOK { // skipcq: TCV-001 return nil, fmt.Errorf("receivePod: could not download blob") } + defer r.Close() + + data, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return nil, err + } var shareInfo ShareInfo err = json.Unmarshal(data, &shareInfo) if err != nil { // skipcq: TCV-001 diff --git a/pkg/pod/subscription.go b/pkg/pod/subscription.go index 013ed418..f719b5b6 100644 --- a/pkg/pod/subscription.go +++ b/pkg/pod/subscription.go @@ -1,13 +1,16 @@ package pod import ( + "bytes" "crypto/ecdsa" "crypto/sha256" - "encoding/hex" "encoding/json" "fmt" + "io" "net/http" + "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/ethereum/go-ethereum/common" "github.com/fairdatasociety/fairOS-dfs/pkg/contracts/datahub" "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager/rpc" @@ -91,12 +94,12 @@ func (p *Pod) EncryptUploadSubscriptionInfo(podName string, subscriberPublicKey return "", err } - ref, err := p.client.UploadBlob(encData, 0, false) + ref, err := p.client.UploadBlob(0, "", "0", false, false, bytes.NewReader(encData)) if err != nil { return "", err } - return hex.EncodeToString(ref), nil + return ref.String(), nil } // RequestSubscription will send a subscriptionManager request to the owner of the pod @@ -145,11 +148,11 @@ func (p *Pod) OpenSubscribedPodFromReference(reference string, ownerPublicKey *e a, _ := ownerPublicKey.Curve.ScalarMult(ownerPublicKey.X, ownerPublicKey.Y, p.acc.GetUserAccountInfo().GetPrivateKey().D.Bytes()) secret := sha256.Sum256(a.Bytes()) - ref, err := hex.DecodeString(reference) + ref, err := swarm.ParseHexAddress(reference) if err != nil { // skipcq: TCV-001 return nil, err } - encData, resp, err := p.client.DownloadBlob(ref) + r, resp, err := p.client.DownloadBlob(ref) if err != nil { // skipcq: TCV-001 return nil, err } @@ -157,7 +160,12 @@ func (p *Pod) OpenSubscribedPodFromReference(reference string, ownerPublicKey *e if resp != http.StatusOK { // skipcq: TCV-001 return nil, fmt.Errorf("OpenSubscribedPodFromReference: could not get subscription info") } + defer r.Close() + encData, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return nil, err + } data, err := utils.DecryptBytes(secret[:], encData) if err != nil { return nil, err diff --git a/pkg/subscriptionManager/rpc/manager.go b/pkg/subscriptionManager/rpc/manager.go index dff4e548..63dbcbe7 100644 --- a/pkg/subscriptionManager/rpc/manager.go +++ b/pkg/subscriptionManager/rpc/manager.go @@ -1,15 +1,19 @@ package rpc import ( + "bytes" "context" "crypto/ecdsa" "encoding/json" "errors" "fmt" + "io" "math/big" "net/http" "time" + "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -30,13 +34,13 @@ const ( ) type SubscriptionInfoPutter interface { - UploadBlob(data []byte, tag uint32, encrypt bool) (address []byte, err error) - UploadBzz(data []byte, fileName string) (address []byte, err error) + UploadBlob(tag uint32, stamp, redundancyLevel string, pin, encrypt bool, data io.Reader) (address swarm.Address, err error) + UploadFileBzz(data []byte, fileName, stamp, redundancyLevel string, pin bool) (address swarm.Address, err error) } type SubscriptionInfoGetter interface { - DownloadBlob(address []byte) (data []byte, respCode int, err error) - DownloadBzz(address []byte) (data []byte, respCode int, err error) + DownloadBlob(address swarm.Address) (reader io.ReadCloser, respCode int, err error) + DownloadBzz(address swarm.Address) (data []byte, respCode int, err error) } type SubscriptionItemInfo struct { @@ -87,12 +91,12 @@ func (c *Client) AddPodToMarketplace(podAddress, owner common.Address, pod, titl if err != nil { // skipcq: TCV-001 return err } - ref, err := c.putter.UploadBzz(data, fmt.Sprintf("%d.sub.json", time.Now().Unix())) + ref, err := c.putter.UploadFileBzz(data, fmt.Sprintf("%d.sub.json", time.Now().Unix()), "", "0", false) if err != nil { // skipcq: TCV-001 return err } var a [32]byte - copy(a[:], ref) + copy(a[:], ref.Bytes()) tx, err := c.datahub.ListSub(opts, nameHash, a, new(big.Int).SetUint64(price), category, podAddress, new(big.Int).SetUint64(uint64(daysValid))) if err != nil { @@ -166,13 +170,13 @@ func (c *Client) AllowAccess(owner common.Address, shareInfo *ShareInfo, request return err } - ref, err := c.putter.UploadBlob(encData, 0, false) + ref, err := c.putter.UploadBlob(0, "", "0", false, false, bytes.NewReader(encData)) if err != nil { return err } var fixedRef [32]byte - copy(fixedRef[:], ref) + copy(fixedRef[:], ref.Bytes()) tx, err := c.datahub.SellSub(opts, requestHash, fixedRef) if err != nil { @@ -188,13 +192,19 @@ func (c *Client) AllowAccess(owner common.Address, shareInfo *ShareInfo, request } func (c *Client) GetSubscription(infoLocation []byte, secret [32]byte) (*ShareInfo, error) { - encData, respCode, err := c.getter.DownloadBlob(infoLocation) + r, respCode, err := c.getter.DownloadBlob(swarm.NewAddress(infoLocation)) if err != nil { // skipcq: TCV-001 return nil, err } if respCode != http.StatusOK { // skipcq: TCV-001 return nil, fmt.Errorf("ReceivePodInfo: could not download blob") } + defer r.Close() + + encData, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return nil, err + } data, err := utils.DecryptBytes(secret[:], encData) if err != nil { @@ -215,7 +225,7 @@ func (c *Client) GetSubscribablePodInfo(subHash [32]byte) (*SubscriptionItemInfo if err != nil { return nil, err } - data, respCode, err := c.getter.DownloadBzz(item.SwarmLocation[:]) + data, respCode, err := c.getter.DownloadBzz(swarm.NewAddress(item.SwarmLocation[:])) if err != nil { // skipcq: TCV-001 return nil, err } diff --git a/pkg/swarm-feed/swarmFeed.go b/pkg/swarm-feed/swarmFeed.go deleted file mode 100644 index 3b80568c..00000000 --- a/pkg/swarm-feed/swarmFeed.go +++ /dev/null @@ -1,153 +0,0 @@ -package swarm_feed - -import ( - "bytes" - "encoding/binary" - "encoding/hex" - "errors" - "fmt" - "reflect" - "strings" - "time" - - "github.com/ethersphere/bee/v2/pkg/cac" - "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/soc" - "github.com/ethersphere/bee/v2/pkg/swarm" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" - "github.com/fairdatasociety/fairOS-dfs/pkg/utils" - "golang.org/x/crypto/sha3" -) - -const ( - FEED_INDEX_HEX_LENGTH = 16 - TOPIC_HEX_LENGTH = 64 -) - -type Topic string - -type Index interface{} -type Identifier []byte -type IndexBytes []byte - -type Feed struct { - bClient blockstore.Client -} - -func NewFeed(bClient blockstore.Client) *Feed { - return &Feed{bClient: bClient} -} - -func (f *Feed) Upload(owner, topic string, signer crypto.Signer, payload swarm.Address) (swarm.Address, error) { - topicHash := keccak256Hash([]byte(topic)) - _, _, nextIndex, _ := f.bClient.GetLatestFeedManifest(owner, utils.Encode(topicHash)) - if nextIndex == "" { - nextIndex = strings.Repeat("0", FEED_INDEX_HEX_LENGTH) - } - id, err := makeFeedIdentifier(topicHash, nextIndex) - if err != nil { - return swarm.ZeroAddress, err - } - timestamp := numberToUint64BE(time.Now().Unix()) - payloadBytes := concatBytes(timestamp, payload.Bytes()) - - ch, err := cac.New(payloadBytes) - if err != nil { - return swarm.ZeroAddress, err - } - s := soc.New(soc.ID(id), ch) - _, err = s.Sign(signer) - if err != nil { - return swarm.ZeroAddress, err - } - _, err = f.bClient.UploadSOC(owner, utils.Encode(id), utils.Encode(s.Signature()), ch.Data()) - if err != nil { - return swarm.ZeroAddress, err - } - return f.bClient.CreateFeedManifest(owner, utils.Encode(topicHash)) -} - -func concatBytes(byteSlices ...[]byte) []byte { - var buffer bytes.Buffer - for _, b := range byteSlices { - buffer.Write(b) - } - return buffer.Bytes() -} - -func isEpoch(epoch interface{}) bool { - v := reflect.ValueOf(epoch) - if v.Kind() != reflect.Struct { - return false - } - - if v.FieldByName("time").IsValid() && v.FieldByName("level").IsValid() { - return true - } - - return false -} - -func keccak256Hash(data ...[]byte) Identifier { - hash := sha3.NewLegacyKeccak256() - for _, d := range data { - hash.Write(d) - } - return hash.Sum(nil) -} - -func hexToBytes(hexStr string) ([]byte, error) { - return hex.DecodeString(hexStr) -} - -func hashFeedIdentifier(topic []byte, index IndexBytes) (Identifier, error) { - return keccak256Hash(topic, index), nil -} - -func numberToUint64BE(num int64) IndexBytes { - indexBytes := make([]byte, 8) - binary.BigEndian.PutUint64(indexBytes, uint64(num)) - return indexBytes -} - -func makeSequentialFeedIdentifier(topic []byte, index int64) (Identifier, error) { - indexBytes := numberToUint64BE(index) - return hashFeedIdentifier(topic, indexBytes) -} - -func makeFeedIndexBytes(s string) (IndexBytes, error) { - hex, err := makeHexString(s, FEED_INDEX_HEX_LENGTH) - if err != nil { - return nil, err - } - return hexToBytes(hex) -} - -func makeHexString(s string, length int) (string, error) { - if len(s) > length { - return "", errors.New("string length exceeds the required length") - } - return fmt.Sprintf("%0*s", length, s), nil -} - -func makeFeedIdentifier(topic []byte, index Index) (Identifier, error) { - switch idx := index.(type) { - case int: - return makeSequentialFeedIdentifier(topic, int64(idx)) - case string: - indexBytes, err := makeFeedIndexBytes(idx) - if err != nil { - return nil, err - } - return hashFeedIdentifier(topic, indexBytes) - default: - if isEpoch(index) { - return nil, errors.New("epoch is not yet implemented") - } - indexBytes, ok := index.(IndexBytes) - if !ok { - return nil, errors.New("invalid index type") - } - return hashFeedIdentifier(topic, indexBytes) - } -} diff --git a/pkg/swarm-feed/swarm_feed_test.go b/pkg/swarm-feed/swarm_feed_test.go deleted file mode 100644 index 6858996b..00000000 --- a/pkg/swarm-feed/swarm_feed_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package swarm_feed - -import ( - "crypto/ecdsa" - "fmt" - "io" - "testing" - - "github.com/ethersphere/bee/v2/pkg/swarm" - - "github.com/fairdatasociety/fairOS-dfs/pkg/logging" - "github.com/sirupsen/logrus" - - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - - eCrypto "github.com/ethereum/go-ethereum/crypto" - "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/fairdatasociety/fairOS-dfs/pkg/utils" -) - -func TestFeed(t *testing.T) { - t.Skip() - logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient("http://localhost:1633", "1ba87c174b66150dacde56df0b914661cff548afcd96957d46f8201694f4a983", true, 0, logger) - bzzAddr := "ea615d35603a3606426f97822b03020761b2e496568424c0b309103a7f66fb9f" - bzzRef, err := swarm.ParseHexAddress(bzzAddr) - pk, err := eCrypto.HexToECDSA("31b0713ac15ac3082180963d288975131a1f63658400fa88f00cf00adedf2609") - if err != nil { - t.Fatal(err) - - } - - // get Address from private key - publicKey := pk.Public().(*ecdsa.PublicKey) - addr, err := crypto.NewEthereumAddress(*publicKey) - if err != nil { - t.Fatal(err) - } - topic := "bzzUpdate js 105" - signer := crypto.NewDefaultSigner(pk) - - f := NewFeed(mockClient) - - manifest, err := f.Upload(utils.Encode(addr), topic, signer, bzzRef) - if err != nil { - t.Fatal(err) - } - fmt.Println("manifest: ", manifest) -} diff --git a/pkg/test/close_test.go b/pkg/test/close_test.go index eb060bab..3534e294 100644 --- a/pkg/test/close_test.go +++ b/pkg/test/close_test.go @@ -18,15 +18,17 @@ package test_test import ( "context" + "fmt" "io" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" @@ -45,7 +47,8 @@ func TestClose(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/test/del_test.go b/pkg/test/del_test.go index 96e8d3b3..5a3e9fc2 100644 --- a/pkg/test/del_test.go +++ b/pkg/test/del_test.go @@ -18,17 +18,19 @@ package test_test import ( "context" + "fmt" "io" "sort" "strings" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/collection" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -48,7 +50,8 @@ func TestPodDelete(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") diff --git a/pkg/test/delete_test.go b/pkg/test/delete_test.go index 7fa43356..a02f0cdf 100644 --- a/pkg/test/delete_test.go +++ b/pkg/test/delete_test.go @@ -19,14 +19,16 @@ package test_test import ( "context" "errors" + "fmt" "io" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" mock3 "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager/rpc/mock" @@ -44,7 +46,8 @@ func TestDelete(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + tm := taskmanager.New(1, 10, time.Second*15, logger) defer func() { _ = tm.Stop(context.Background()) diff --git a/pkg/test/fork_test.go b/pkg/test/fork_test.go index dc710a23..13506905 100644 --- a/pkg/test/fork_test.go +++ b/pkg/test/fork_test.go @@ -18,15 +18,17 @@ package test_test import ( "context" + "fmt" "io" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -46,7 +48,8 @@ func TestFork(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/test/group_new_test.go b/pkg/test/group_new_test.go index b28f4fc8..376af62d 100644 --- a/pkg/test/group_new_test.go +++ b/pkg/test/group_new_test.go @@ -18,16 +18,19 @@ package test_test import ( "errors" + "fmt" "io" "testing" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/ethereum/go-ethereum/common" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" "github.com/fairdatasociety/fairOS-dfs/pkg/acl/acl" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -45,7 +48,8 @@ func TestGroupNew(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/test/integration_test.go b/pkg/test/integration_test.go index 10b8d98a..fdf4af98 100644 --- a/pkg/test/integration_test.go +++ b/pkg/test/integration_test.go @@ -2,20 +2,22 @@ package test_test import ( "crypto/rand" + "fmt" "io" "math/big" "path/filepath" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/cmd/common" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/dfs" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -47,7 +49,7 @@ func TestLiteUser(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) users := user.NewUsers(mockClient, ens, -1, 0, logger) dfsApi := dfs.NewMockDfsAPI(mockClient, users, logger) diff --git a/pkg/test/lite_test.go b/pkg/test/lite_test.go index 17fe2958..a5b656a3 100644 --- a/pkg/test/lite_test.go +++ b/pkg/test/lite_test.go @@ -3,14 +3,17 @@ package test_test import ( "context" "errors" + "fmt" "io" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" mock3 "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager/rpc/mock" @@ -28,7 +31,8 @@ func TestLite(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + tm := taskmanager.New(1, 10, time.Second*15, logger) defer func() { _ = tm.Stop(context.Background()) diff --git a/pkg/test/login_test.go b/pkg/test/login_test.go index 84a7476b..d23e8080 100644 --- a/pkg/test/login_test.go +++ b/pkg/test/login_test.go @@ -19,19 +19,21 @@ package test_test import ( "context" "errors" + "fmt" "io" "sort" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" mock3 "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager/rpc/mock" "github.com/sirupsen/logrus" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" @@ -49,7 +51,8 @@ func TestLogin(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + tm := taskmanager.New(1, 10, time.Second*15, logger) defer func() { _ = tm.Stop(context.Background()) diff --git a/pkg/test/logout_test.go b/pkg/test/logout_test.go index 7964b49c..63732962 100644 --- a/pkg/test/logout_test.go +++ b/pkg/test/logout_test.go @@ -19,10 +19,12 @@ package test_test import ( "context" "errors" + "fmt" "io" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" @@ -31,8 +33,8 @@ import ( "github.com/plexsysio/taskmanager" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/user" @@ -47,7 +49,8 @@ func TestLogout(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + tm := taskmanager.New(1, 10, time.Second*15, logger) defer func() { _ = tm.Stop(context.Background()) diff --git a/pkg/test/ls_test.go b/pkg/test/ls_test.go index 92788aae..3dae128c 100644 --- a/pkg/test/ls_test.go +++ b/pkg/test/ls_test.go @@ -18,13 +18,15 @@ package test_test import ( "context" + "fmt" "io" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager/rpc/mock" @@ -35,8 +37,8 @@ import ( "github.com/plexsysio/taskmanager" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" ) @@ -50,7 +52,8 @@ func TestPod_ListPods(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) accountInfo := acc.GetUserAccountInfo() fd := feed.New(accountInfo, mockClient, -1, 0, logger) diff --git a/pkg/test/max_file_test.go b/pkg/test/max_file_test.go index 8431dbc5..c03f3ca7 100644 --- a/pkg/test/max_file_test.go +++ b/pkg/test/max_file_test.go @@ -2,12 +2,14 @@ package test_test import ( "context" + "fmt" "io" "testing" "time" "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" @@ -16,9 +18,9 @@ import ( "github.com/plexsysio/taskmanager" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" @@ -34,7 +36,8 @@ func TestMaxFiles(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/test/max_pod_test.go b/pkg/test/max_pod_test.go index 8c6387cd..a436348b 100644 --- a/pkg/test/max_pod_test.go +++ b/pkg/test/max_pod_test.go @@ -2,12 +2,14 @@ package test_test import ( "context" + "fmt" "io" "testing" "time" "github.com/stretchr/testify/require" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" @@ -16,9 +18,9 @@ import ( "github.com/plexsysio/taskmanager" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" @@ -34,7 +36,8 @@ func TestMaxPods(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/test/new_test.go b/pkg/test/new_test.go index 936e2469..8b7150bc 100644 --- a/pkg/test/new_test.go +++ b/pkg/test/new_test.go @@ -19,10 +19,12 @@ package test_test import ( "context" "errors" + "fmt" "io" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" @@ -31,8 +33,8 @@ import ( "github.com/plexsysio/taskmanager" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/user" @@ -47,7 +49,8 @@ func TestNew(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + tm := taskmanager.New(1, 10, time.Second*15, logger) defer func() { _ = tm.Stop(context.Background()) diff --git a/pkg/test/open_test.go b/pkg/test/open_test.go index 2943198c..e6a84124 100644 --- a/pkg/test/open_test.go +++ b/pkg/test/open_test.go @@ -20,14 +20,16 @@ import ( "context" "crypto/rand" "errors" + "fmt" "io" "os" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager/rpc/mock" @@ -36,8 +38,8 @@ import ( "github.com/plexsysio/taskmanager" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" @@ -53,7 +55,8 @@ func TestOpen(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/test/pod_new_test.go b/pkg/test/pod_new_test.go index 52e0543f..9fa270ec 100644 --- a/pkg/test/pod_new_test.go +++ b/pkg/test/pod_new_test.go @@ -19,14 +19,16 @@ package test_test import ( "context" "errors" + "fmt" "io" "strings" "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager/rpc/mock" @@ -35,8 +37,8 @@ import ( "github.com/fairdatasociety/fairOS-dfs/pkg/utils" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" @@ -51,7 +53,8 @@ func TestPodNew(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/test/pod_sharing_test.go b/pkg/test/pod_sharing_test.go index 3db7e1c8..546464e5 100644 --- a/pkg/test/pod_sharing_test.go +++ b/pkg/test/pod_sharing_test.go @@ -19,10 +19,12 @@ package test_test import ( "context" "errors" + "fmt" "io" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" @@ -33,9 +35,9 @@ import ( "github.com/plexsysio/taskmanager" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" @@ -51,7 +53,8 @@ func TestShare(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/test/pod_stat_test.go b/pkg/test/pod_stat_test.go index a87e60fa..2aa1358b 100644 --- a/pkg/test/pod_stat_test.go +++ b/pkg/test/pod_stat_test.go @@ -18,11 +18,13 @@ package test_test import ( "context" + "fmt" "io" "strings" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" @@ -33,9 +35,9 @@ import ( "github.com/plexsysio/taskmanager" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" @@ -50,7 +52,8 @@ func TestStat(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/test/stat_test.go b/pkg/test/stat_test.go index 60a0b691..48eb5e18 100644 --- a/pkg/test/stat_test.go +++ b/pkg/test/stat_test.go @@ -19,10 +19,12 @@ package test_test import ( "context" "errors" + "fmt" "io" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" @@ -33,8 +35,8 @@ import ( "github.com/plexsysio/taskmanager" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" ) @@ -48,7 +50,8 @@ func TestUserStat(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + tm := taskmanager.New(1, 10, time.Second*15, logger) defer func() { _ = tm.Stop(context.Background()) diff --git a/pkg/test/subscription_test.go b/pkg/test/subscription_test.go index c150f9c1..86d82e28 100644 --- a/pkg/test/subscription_test.go +++ b/pkg/test/subscription_test.go @@ -11,16 +11,17 @@ import ( "github.com/ethereum/go-ethereum/crypto" + "github.com/asabya/swarm-blockstore/bee" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/ethereum/go-ethereum/common" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" @@ -40,7 +41,8 @@ func TestSubscription(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc1 := account.New(logger) _, _, err := acc1.CreateUserAccount("") if err != nil { diff --git a/pkg/test/sync_test.go b/pkg/test/sync_test.go index f7f74ffd..ea5563a5 100644 --- a/pkg/test/sync_test.go +++ b/pkg/test/sync_test.go @@ -18,10 +18,13 @@ package test_test import ( "context" + "fmt" "io" "testing" "time" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" @@ -30,9 +33,9 @@ import ( mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager/rpc/mock" + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" @@ -49,7 +52,8 @@ func TestSync(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + acc := account.New(logger) _, _, err := acc.CreateUserAccount("") if err != nil { diff --git a/pkg/test/user_sharing_test.go b/pkg/test/user_sharing_test.go index d6729dca..0e8790e4 100644 --- a/pkg/test/user_sharing_test.go +++ b/pkg/test/user_sharing_test.go @@ -25,15 +25,16 @@ import ( "testing" "time" + "github.com/asabya/swarm-blockstore/bee" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee" "github.com/sirupsen/logrus" mock3 "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager/rpc/mock" + "github.com/asabya/swarm-blockstore/bee/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/account" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore/bee/mock" mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/ensm/eth/mock" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" "github.com/fairdatasociety/fairOS-dfs/pkg/file" @@ -53,7 +54,7 @@ func TestSharing(t *testing.T) { }) logger := logging.New(io.Discard, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, mock.BatchOkStr, true, 0, logger) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) acc1 := account.New(logger) _, _, err := acc1.CreateUserAccount("") diff --git a/pkg/user/login.go b/pkg/user/login.go index ea9772a1..061af83e 100644 --- a/pkg/user/login.go +++ b/pkg/user/login.go @@ -20,6 +20,7 @@ import ( "fmt" "sync" + blockstore "github.com/asabya/swarm-blockstore" acl2 "github.com/fairdatasociety/fairOS-dfs/pkg/acl/acl" "github.com/ethereum/go-ethereum/common" @@ -27,7 +28,6 @@ import ( "github.com/fairdatasociety/fairOS-dfs/pkg/account" "github.com/fairdatasociety/fairOS-dfs/pkg/auth" "github.com/fairdatasociety/fairOS-dfs/pkg/auth/jwt" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" d "github.com/fairdatasociety/fairOS-dfs/pkg/dir" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" f "github.com/fairdatasociety/fairOS-dfs/pkg/file" diff --git a/pkg/user/sharing.go b/pkg/user/sharing.go index 13b45b26..dd5f79fc 100644 --- a/pkg/user/sharing.go +++ b/pkg/user/sharing.go @@ -17,12 +17,15 @@ limitations under the License. package user import ( - "encoding/hex" + "bytes" "encoding/json" + "io" "net/http" "strconv" "time" + "github.com/ethersphere/bee/v2/pkg/swarm" + f "github.com/fairdatasociety/fairOS-dfs/pkg/file" "github.com/fairdatasociety/fairOS-dfs/pkg/pod" "github.com/fairdatasociety/fairOS-dfs/pkg/utils" @@ -89,26 +92,31 @@ func (u *Users) ShareFileWithUser(podName, podPassword, podFileWithPath, destina } // upload the encrypted data and get the reference - ref, err := u.client.UploadBlob(data, 0, true) + ref, err := u.client.UploadBlob(0, "", "0", false, true, bytes.NewReader(data)) if err != nil { // skipcq: TCV-001 return "", err } - return hex.EncodeToString(ref), nil + return ref.String(), nil } // ReceiveFileFromUser imports an exported file in to the current user and pod by reading the sharing file entry. func (u *Users) ReceiveFileFromUser(_ *Info, pd *pod.Pod, podName, ref, podDir string) (string, error) { - refBytes, err := hex.DecodeString(ref) + refBytes, err := swarm.ParseHexAddress(ref) if err != nil { return "", err } // get the encrypted meta - data, respCode, err := u.client.DownloadBlob(refBytes) + r, respCode, err := u.client.DownloadBlob(refBytes) if err != nil || respCode != http.StatusOK { return "", err } // skipcq: TCV-001 + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { + return "", err + } // unmarshall the entry sharingEntry := SharingEntry{} err = json.Unmarshal(data, &sharingEntry) @@ -163,28 +171,39 @@ func (u *Users) ReceiveFileFromUser(_ *Info, pd *pod.Pod, podName, ref, podDir s // ReceiveFileInfo displays the information of the exported file. This is used to decide whether // to import the file or not. func (u *Users) ReceiveFileInfo(ref string) (*ReceiveFileInfo, error) { - refBytes, err := hex.DecodeString(ref) + refBytes, err := swarm.ParseHexAddress(ref) if err != nil { return nil, err } // get the encrypted meta - data, respCode, err := u.client.DownloadBlob(refBytes) + r, respCode, err := u.client.DownloadBlob(refBytes) if err != nil || respCode != http.StatusOK { // skipcq: TCV-001 return nil, err } + defer r.Close() + data, err := io.ReadAll(r) + if err != nil { + return nil, err + } // unmarshall the entry sharingEntry := SharingEntry{} err = json.Unmarshal(data, &sharingEntry) if err != nil { // skipcq: TCV-001 return nil, err } - fileInodeBytes, respCode, err := u.client.DownloadBlob(sharingEntry.Meta.InodeAddress) + inodeReader, respCode, err := u.client.DownloadBlob(swarm.NewAddress(sharingEntry.Meta.InodeAddress)) if err != nil || respCode != http.StatusOK { // skipcq: TCV-001 return nil, err } + defer inodeReader.Close() + + fileInodeBytes, err := io.ReadAll(inodeReader) + if err != nil { + return nil, err + } var fileInode f.INode err = json.Unmarshal(fileInodeBytes, &fileInode) if err != nil { // skipcq: TCV-001 diff --git a/pkg/user/users.go b/pkg/user/users.go index 98b4d1f0..9ea36beb 100644 --- a/pkg/user/users.go +++ b/pkg/user/users.go @@ -20,7 +20,7 @@ import ( "sync" "time" - "github.com/fairdatasociety/fairOS-dfs/pkg/blockstore" + blockstore "github.com/asabya/swarm-blockstore" "github.com/fairdatasociety/fairOS-dfs/pkg/ensm" "github.com/fairdatasociety/fairOS-dfs/pkg/logging" ) From 8dd0f0f25588cfde9a923363bb2a28f1ff821520 Mon Sep 17 00:00:00 2001 From: asabya Date: Tue, 22 Oct 2024 14:48:16 +0530 Subject: [PATCH 02/14] act working --- cmd/dfs/cmd/server.go | 15 + go.mod | 20 +- go.sum | 34 +- pkg/account/account.go | 1 - pkg/act/act.go | 95 +++++ pkg/act/act_test.go | 838 +++++++++++++++++++++++++++++++++++++++++ pkg/act/grant.go | 199 ++++++++++ pkg/act/new.go | 152 ++++++++ pkg/api/act.go | 263 +++++++++++++ pkg/dfs/act_api.go | 168 +++++++++ pkg/user/info.go | 7 + pkg/user/login.go | 24 +- 12 files changed, 1784 insertions(+), 32 deletions(-) create mode 100644 pkg/act/act.go create mode 100644 pkg/act/act_test.go create mode 100644 pkg/act/grant.go create mode 100644 pkg/act/new.go create mode 100644 pkg/api/act.go create mode 100644 pkg/dfs/act_api.go diff --git a/cmd/dfs/cmd/server.go b/cmd/dfs/cmd/server.go index 7e6c02a9..9c5275c3 100644 --- a/cmd/dfs/cmd/server.go +++ b/cmd/dfs/cmd/server.go @@ -456,6 +456,21 @@ func startHttpService(logger logging.Logger) *http.Server { gitRouter.HandleFunc("/{user}/{repo}.git/git-upload-pack", handler.GitUploadPack).Methods("POST") gitRouter.HandleFunc("/{user}/{repo}.git/git-receive-pack", handler.GitReceivePack).Methods("POST") + actRouter := baseRouter.PathPrefix("/act/").Subrouter() + actRouter.Use(handler.GitAuthMiddleware) + + // list acts + // owner + actRouter.HandleFunc("/grantee/{actName}", handler.CreateGranteeHandler).Methods("POST") + actRouter.HandleFunc("/grantee/{actName}", handler.GrantRevokeHandler).Methods("PATCH") + actRouter.HandleFunc("/grantee/{actName}", handler.ListGranteesHandler).Methods("GET") + actRouter.HandleFunc("/share-pod", handler.ACTPodShareHandler).Methods("PATCH") + actRouter.HandleFunc("/list", handler.ACTListHandler).Methods("GET") + actRouter.HandleFunc("/act-shared-pods", handler.ACTSharedPods).Methods("GET") + // grantee + actRouter.HandleFunc("/save-act-pod", handler.ACTSavePod).Methods("POST") + actRouter.HandleFunc("/open-act-pod", handler.ACTOpenPod).Methods("POST") + var origins []string for _, c := range corsOrigins { c = strings.TrimSpace(c) diff --git a/go.mod b/go.mod index 3f6bb7c5..42ddc994 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,9 @@ module github.com/fairdatasociety/fairOS-dfs go 1.22.0 require ( - github.com/asabya/swarm-blockstore v0.0.0-20241007072942-fef6cc83ff36 - github.com/btcsuite/btcd/btcec/v2 v2.3.3 + github.com/asabya/swarm-act v0.0.0-20241022090815-9b494c0051de + github.com/asabya/swarm-blockstore v0.0.0-20241022084926-8d6753f32697 + github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/c-bata/go-prompt v0.2.6 github.com/dustin/go-humanize v1.0.1 github.com/ethereum/go-ethereum v1.14.7 @@ -43,7 +44,7 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/btcsuite/btcd v0.22.3 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect @@ -55,6 +56,7 @@ require ( github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/ethersphere/go-price-oracle-abi v0.2.0 // indirect github.com/ethersphere/go-storage-incentives-abi v0.9.1 // indirect github.com/ethersphere/go-sw3-abi v0.6.5 // indirect @@ -75,7 +77,7 @@ require ( github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/uint256 v1.3.0 // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -127,7 +129,7 @@ require ( github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/supranational/blst v0.3.11 // indirect + github.com/supranational/blst v0.3.13 // indirect github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect @@ -137,7 +139,7 @@ require ( github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/wealdtech/go-multicodec v1.4.0 // indirect - github.com/yusufpapurcu/wmi v1.2.2 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect @@ -147,7 +149,7 @@ require ( golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect @@ -157,8 +159,4 @@ require ( rsc.io/tmplfunc v0.0.3 // indirect ) -replace github.com/ethersphere/bee/v2 => ../../ethersphere/bee - -replace github.com/asabya/swarm-blockstore => ../../asabya/swarm-blockstore - replace github.com/codahale/hdrhistogram => github.com/HdrHistogram/hdrhistogram-go v0.0.0-20200919145931-8dac23c8dac1 diff --git a/go.sum b/go.sum index e49f901e..5560e5bf 100644 --- a/go.sum +++ b/go.sum @@ -11,15 +11,19 @@ github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkT github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asabya/swarm-act v0.0.0-20241022090815-9b494c0051de h1:d5PDY+pU7QCIu3VNSftUq6rc4hNC6GfxH8vI1JItWNU= +github.com/asabya/swarm-act v0.0.0-20241022090815-9b494c0051de/go.mod h1:JKFHSirdVKLWOdJpk7cl8732JiI+a9G64dzB58CEO8w= +github.com/asabya/swarm-blockstore v0.0.0-20241022084926-8d6753f32697 h1:MhH/TMo8jvCafB/WcI8MKajuWuodymKHiLZLGAQ35nE= +github.com/asabya/swarm-blockstore v0.0.0-20241022084926-8d6753f32697/go.mod h1:Tc8wjIjbbV0Ofrr3JPmxDcbmg571M6yFEdKOqWelWgo= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= -github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.3 h1:kYNaWFvOw6xvqP0vR20RP1Zq1DVMBxEO8QN5d1/EfNg= github.com/btcsuite/btcd v0.22.3/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.3.3 h1:6+iXlDKE8RMtKsvK0gshlXIuPbyWM/h84Ensb7o3sC0= -github.com/btcsuite/btcd/btcec/v2 v2.3.3/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= @@ -77,8 +81,10 @@ github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHE github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.14.7 h1:EHpv3dE8evQmpVEQ/Ne2ahB06n2mQptdwqaMNhAT29g= github.com/ethereum/go-ethereum v1.14.7/go.mod h1:Mq0biU2jbdmKSZoqOj29017ygFrMnB5/Rifwp980W4o= -github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 h1:KrE8I4reeVvf7C1tm8elRjj4BdscTYzz/WAbYyf/JI4= -github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0/go.mod h1:D9AJLVXSyZQXJQVk8oh1EwjISE+sJTn2duYIZC0dy3w= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= +github.com/ethersphere/bee/v2 v2.2.0 h1:UOrnGuacIlRD9RHSux9W13eI0ppsJvz6Xa0MTn6UuJ4= +github.com/ethersphere/bee/v2 v2.2.0/go.mod h1:9mrRirUnAJwSmnB9kJBx6Bo94LCgFrj2jYDJA20SIe0= github.com/ethersphere/bmt v0.1.4 h1:+rkWYNtMgDx6bkNqGdWu+U9DgGI1rRZplpSW3YhBr1Q= github.com/ethersphere/bmt v0.1.4/go.mod h1:Yd8ft1U69WDuHevZc/rwPxUv1rzPSMpMnS6xbU53aY8= github.com/ethersphere/go-price-oracle-abi v0.2.0 h1:wtIcYLgNZHY4BjYwJCnu93SvJdVAZVvBaKinspyyHvQ= @@ -179,8 +185,8 @@ github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6w github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.3.0 h1:4wdcm/tnd0xXdu7iS3ruNvxkWwrb4aeBQv19ayYn8F4= -github.com/holiman/uint256 v1.3.0/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= @@ -377,8 +383,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= -github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a h1:kAe4YSu0O0UFn1DowNo2MY5p6xzqtJ/wQ7LZynSvGaY= github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= github.com/swaggo/http-swagger v1.3.4 h1:q7t/XLx0n15H1Q9/tk3Y9L4n210XzJF5WtnDX64a5ww= @@ -415,8 +421,8 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRT github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= gitlab.com/nolash/go-mockbytes v0.0.7 h1:9XVFpEfY67kGBVJve3uV19kzqORdlo7V+q09OE6Yo54= gitlab.com/nolash/go-mockbytes v0.0.7/go.mod h1:KKOpNTT39j2Eo+P6uUTOncntfeKY6AFh/2CxuD5MpgE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -522,8 +528,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/account/account.go b/pkg/account/account.go index e6db5857..6e2e9841 100644 --- a/pkg/account/account.go +++ b/pkg/account/account.go @@ -88,7 +88,6 @@ func (a *Account) CreateUserAccount(mnemonic string) (string, []byte, error) { if err != nil { return "", nil, err } - hdw, err := hdwallet.NewFromMnemonic(mnemonic) if err != nil { // skipcq: TCV-001 return "", nil, err diff --git a/pkg/act/act.go b/pkg/act/act.go new file mode 100644 index 00000000..8793b843 --- /dev/null +++ b/pkg/act/act.go @@ -0,0 +1,95 @@ +package act + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "io" + "sync" + + "github.com/btcsuite/btcd/btcec/v2" + + swarm_act "github.com/asabya/swarm-act" + + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" + + blockstore "github.com/asabya/swarm-blockstore" + "github.com/ethereum/go-ethereum/crypto" + "github.com/fairdatasociety/fairOS-dfs/pkg/account" + "github.com/fairdatasociety/fairOS-dfs/pkg/feed" + f "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/fairdatasociety/fairOS-dfs/pkg/logging" + "github.com/fairdatasociety/fairOS-dfs/pkg/taskmanager" +) + +var ( + ErrACTAlreadyExists = errors.New("ACT already exists") + ErrACTDoesNowExist = errors.New("ACT does not exist") +) + +type ACT struct { + fd *feed.API + acc *account.Account + client blockstore.Client + logger logging.Logger + tm taskmanager.TaskManagerGO + act *swarm_act.ACT + mu *sync.RWMutex +} + +func NewACT(client blockstore.Client, feed *feed.API, account *account.Account, m taskmanager.TaskManagerGO, logger logging.Logger) *ACT { + accountInfo := account.GetUserAccountInfo() + accPrivKey, _ := btcec.PrivKeyFromBytes(accountInfo.GetPrivateKey().D.Bytes()) + act := swarm_act.New(client, accPrivKey.ToECDSA(), "") + return &ACT{ + fd: feed, + acc: account, + client: client, + logger: logger, + tm: m, + act: act, + mu: &sync.RWMutex{}, + } +} + +func (t *ACT) storeUserACTs(actList List) error { + data, err := json.Marshal(actList) + if err != nil { + return err + } + + // store data as file and get metadata + // This is a very hacky way to store pod data, but it works for now + // We create a new file object with the user account address and upload the data + // We use the user private key to encrypt data. + f2 := f.NewFile("", t.client, t.fd, t.acc.GetAddress(account.UserAccountIndex), t.tm, t.logger) + privKeyBytes := crypto.FromECDSA(t.acc.GetUserAccountInfo().GetPrivateKey()) + return f2.Upload(bytes.NewReader(data), actFile, int64(len(data)), f.MinBlockSize, 0, "/", "gzip", hex.EncodeToString(privKeyBytes)) +} + +func (t *ACT) loadUserACTs() (List, error) { + actList := List{} + f2 := f.NewFile("", t.client, t.fd, t.acc.GetAddress(account.UserAccountIndex), t.tm, t.logger) + topicString := utils.CombinePathAndFile("", actFile) + privKeyBytes := crypto.FromECDSA(t.acc.GetUserAccountInfo().GetPrivateKey()) + r, _, err := f2.Download(topicString, hex.EncodeToString(privKeyBytes)) + if err != nil { // skipcq: TCV-001 + return actList, nil + } + data, err := io.ReadAll(r) + if err != nil { // skipcq: TCV-001 + return nil, err + } + + if len(data) == 0 { + return actList, nil + } + + err = json.Unmarshal(data, &actList) + if err != nil { // skipcq: TCV-001 + return nil, err + } + + return actList, nil +} diff --git a/pkg/act/act_test.go b/pkg/act/act_test.go new file mode 100644 index 00000000..b1dc9803 --- /dev/null +++ b/pkg/act/act_test.go @@ -0,0 +1,838 @@ +package act + +import ( + "context" + "crypto/ecdsa" + "crypto/rand" + "encoding/hex" + "fmt" + "io" + "os" + "testing" + "time" + + "github.com/asabya/swarm-blockstore/bee" + "github.com/asabya/swarm-blockstore/bee/mock" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/ethersphere/bee/v2/pkg/crypto" + "github.com/ethersphere/bee/v2/pkg/file/redundancy" + mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock" + mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" + "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/fairdatasociety/fairOS-dfs/pkg/account" + "github.com/fairdatasociety/fairOS-dfs/pkg/feed" + "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/fairdatasociety/fairOS-dfs/pkg/logging" + "github.com/fairdatasociety/fairOS-dfs/pkg/pod" + mock2 "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager/rpc/mock" + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" + "github.com/plexsysio/taskmanager" + "github.com/sirupsen/logrus" +) + +func TestACT(t *testing.T) { + storer := mockstorer.New() + beeUrl := mock.NewTestBeeServer(t, mock.TestServerOptions{ + Storer: storer, + PreventRedirect: true, + Post: mockpost.New(mockpost.WithAcceptAll()), + }) + + logger := logging.New(io.Discard, logrus.DebugLevel) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) + + accounts := []*account.Account{} + for i := 0; i < 10; i++ { + acc := account.New(logger) + _, _, err := acc.CreateUserAccount("") + if err != nil { + t.Fatal(err) + } + accounts = append(accounts, acc) + } + + tm := taskmanager.New(1, 10, time.Second*15, logger) + defer func() { + _ = tm.Stop(context.Background()) + }() + sm := mock2.NewMockSubscriptionManager() + pods := []string{"test1", "test2"} + acts := []string{"testact1", "testact2"} + _ = sm + _ = pods + t.Run("create-first-act", func(t *testing.T) { + acc := accounts[0] + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) + + ownerACT := NewACT(mockClient, fd, acc, tm, logger) + actName := acts[0] + for i := 1; i < 10; i++ { + acc := accounts[i] + _, err := ownerACT.CreateUpdateACT(actName, acc.GetUserAccountInfo().GetPublicKey(), nil) + if err != nil { + t.Fatal(err) + } + <-time.After(1 * time.Second) + } + a, err := ownerACT.GetACT(actName) + if err != nil { + t.Fatal(err) + } + pubKeys, err := ownerACT.act.GetGrantees(context.Background(), a.GranteesRef) + if err != nil { + t.Fatal(err) + } + if len(pubKeys) != 9 { + t.Fatal("pubkeys not matching") + } + }) + t.Run("create-first-then-revoke-act", func(t *testing.T) { + acc := accounts[0] + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) + + ownerACT := NewACT(mockClient, fd, acc, tm, logger) + actName := acts[1] + for i := 1; i < 2; i++ { + acc := accounts[i] + accPrivKey, _ := btcec.PrivKeyFromBytes(acc.GetUserAccountInfo().GetPrivateKey().D.Bytes()) + _, err := ownerACT.CreateUpdateACT(actName, accPrivKey.PubKey().ToECDSA(), nil) + if err != nil { + t.Fatal(err) + } + <-time.After(1 * time.Second) + + } + a, err := ownerACT.GetACT(actName) + if err != nil { + t.Fatal(err) + } + pubKeys, err := ownerACT.act.GetGrantees(context.Background(), a.GranteesRef) + if err != nil { + t.Fatal(err) + } + if len(pubKeys) != 1 { + t.Fatal("pubkeys not matching") + } + + for i := 1; i < 2; i++ { + acc := accounts[i] + _, err := ownerACT.CreateUpdateACT(actName, nil, acc.GetUserAccountInfo().GetPublicKey()) + if err != nil { + t.Fatal(err) + } + <-time.After(1 * time.Second) + } + a, err = ownerACT.GetACT(actName) + if err != nil { + t.Fatal(err) + } + + pubKeys, err = ownerACT.act.GetGrantees(context.Background(), a.GranteesRef) + if err != nil { + t.Fatal(err) + } + if len(pubKeys) != 0 { + t.Fatal("pubkeys not matching") + } + }) + t.Run("create-second-act", func(t *testing.T) { + acc := accounts[0] + fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) + + ownerACT := NewACT(mockClient, fd, acc, tm, logger) + for _, actName := range acts { + for i := 1; i < 10; i++ { + acc := accounts[i] + _, err := ownerACT.CreateUpdateACT(actName, acc.GetUserAccountInfo().GetPublicKey(), nil) + if err != nil { + t.Fatal(err) + } + } + } + list, err := ownerACT.GetList() + if err != nil { + t.Fatal(err) + } + if len(list) != 2 { + t.Fatal("acts not matching") + } + }) + + t.Run("act-file-upload", func(t *testing.T) { + ownerAcc := accounts[0] + fd := feed.New(ownerAcc.GetUserAccountInfo(), mockClient, -1, 0, logger) + pod1 := pod.NewPod(mockClient, fd, ownerAcc, tm, sm, -1, 0, logger) + podPassword, _ := utils.GetRandString(pod.PasswordLength) + _, err := pod1.CreatePod(pods[0], "", podPassword) + if err != nil { + t.Fatalf("error creating pod %s: %s", pods[0], err.Error()) + } + + p, err := pod1.OpenPod(pods[0]) + if err != nil { + t.Fatalf("error opening pod %s: %s", pods[0], err.Error()) + } + + maxfiles := 1 + filePath := "/" + for i := 1; i <= maxfiles; i++ { + fileName, _ := utils.GetRandString(100) + compression := "" + fileSize := int64(1000) + blockSize := file.MinBlockSize + _, err = uploadFile(t, p.GetFile(), filePath, fileName, compression, p.GetPodPassword(), fileSize, blockSize) + if err != nil { + t.Fatal(err) + } + err = p.GetDirectory().AddEntryToDir("/", p.GetPodPassword(), fileName, true) + if err != nil { + t.Fatal(i, err) + } + } + + ref, err := pod1.PodShare(pods[0], "") + if err != nil { + t.Fatal(err) + } + reference, err := swarm.ParseHexAddress(ref) + if err != nil { + t.Fatal(err) + } + + ownerACT := NewACT(mockClient, fd, ownerAcc, tm, logger) + granteeAcc := accounts[1] + _, err = ownerACT.CreateUpdateACT(acts[0], granteeAcc.GetUserAccountInfo().GetPublicKey(), nil) + if err != nil { + t.Fatal(err) + } + <-time.After(1 * time.Second) + + respOne, err := ownerACT.GrantAccess(acts[0], reference) + if err != nil { + t.Fatal(err) + } + <-time.After(1 * time.Second) + + granteeFeed := feed.New(granteeAcc.GetUserAccountInfo(), mockClient, -1, 0, logger) + granteeACT := NewACT(mockClient, granteeFeed, granteeAcc, tm, logger) + err = granteeACT.SaveGrantedPod(acts[0], respOne) + if err != nil { + t.Fatal(err) + } + addr, err := granteeACT.GetPodAccess(acts[0]) + if err != nil { + t.Fatal(err) + } + + granteePod := pod.NewPod(mockClient, granteeFeed, granteeAcc, tm, sm, -1, 0, logger) + _, err = granteePod.ReceivePodInfo(utils.NewReference(addr.Bytes())) + if err != nil { + t.Fatal(err) + } + <-time.After(1 * time.Second) + + actAfterRevoke, err := ownerACT.CreateUpdateACT(acts[0], nil, granteeAcc.GetUserAccountInfo().GetPublicKey()) + if err != nil { + t.Fatal(err) + } + <-time.After(time.Second) + + _, err = ownerACT.act.GetGrantees(context.Background(), actAfterRevoke.GranteesRef) + if err != nil { + t.Fatal(err) + } + _, err = granteeACT.GetPodAccess(acts[0]) + if err == nil { + t.Fatal("grantee should not have access") + } + }) + + t.Run("act-content-list", func(t *testing.T) { + ownerAcc := accounts[0] + fd := feed.New(ownerAcc.GetUserAccountInfo(), mockClient, -1, 0, logger) + pod1 := pod.NewPod(mockClient, fd, ownerAcc, tm, sm, -1, 0, logger) + ownerACT := NewACT(mockClient, fd, ownerAcc, tm, logger) + granteeAcc := accounts[1] + _, err := ownerACT.CreateUpdateACT(acts[0], granteeAcc.GetUserAccountInfo().GetPublicKey(), nil) + if err != nil { + t.Fatal(err) + } + <-time.After(1 * time.Second) + for i := 1; i < 10; i++ { + podPassword, _ := utils.GetRandString(pod.PasswordLength) + podname, _ := utils.GetRandString(pod.PasswordLength) + _, err := pod1.CreatePod(podname, "", podPassword) + if err != nil { + t.Fatalf("error creating pod %s: %s", podname, err.Error()) + } + ref, err := pod1.PodShare(podname, "") + if err != nil { + t.Fatal(err) + } + reference, err := swarm.ParseHexAddress(ref) + if err != nil { + t.Fatal(err) + } + _, err = ownerACT.GrantAccess(acts[0], reference) + if err != nil { + t.Fatal(err) + } + <-time.After(1 * time.Second) + } + contents, err := ownerACT.GetContentList(acts[0]) + if err != nil { + t.Fatal(err) + } + if len(contents) != 9 { + t.Fatal("contents not matching") + } + + }) + // + //t.Run("group-member-add", func(t *testing.T) { + // t.Skip() + // fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) + // mockAcl := acl.NewACL(mockClient, fd, logger) + // group := pod.NewGroup(mockClient, fd, acc, mockAcl, logger) + // groupName1, _ := utils.GetRandString(10) + // _, err = group.CreateGroup(groupName1) + // if err != nil { + // t.Fatalf("error creating group %s: %s", groupName1, err.Error()) + // } + // + // _, err = group.ListGroup() + // if err != nil { + // t.Fatalf("error getting groups") + // } + // + // g, err := group.OpenGroup(groupName1) + // if err != nil { + // t.Fatalf("error opening group %s: %s", groupName1, err.Error()) + // } + // maxfiles := 10 + // filePath := "/" + // for i := 1; i <= maxfiles; i++ { + // fileName, _ := utils.GetRandString(100) + // compression := "" + // fileSize := int64(1000) + // blockSize := file.MinBlockSize + // _, err = uploadFile(t, g.GetFile(), filePath, fileName, compression, g.GetPodPassword(), fileSize, blockSize) + // if err != nil { + // t.Fatal(err) + // } + // err = g.GetDirectory().AddEntryToDir("/", g.GetPodPassword(), fileName, true) + // if err != nil { + // t.Fatal(i, err) + // } + // } + // + // acc2 := account.New(logger) + // _, _, err = acc2.CreateUserAccount("") + // if err != nil { + // t.Fatal(err) + // } + // addr := acc2.GetUserAccountInfo().GetAddress() + // addrStr := addr.Hex() + // ref, err := group.AddMember(groupName1, common.HexToAddress(addrStr), acc2.GetUserAccountInfo().GetPublicKey(), acl.PermissionWrite) + // if err != nil { + // t.Fatal(err) + // } + // fd2 := feed.New(acc2.GetUserAccountInfo(), mockClient, -1, 0, logger) + // + // group2 := pod.NewGroup(mockClient, fd2, acc2, mockAcl, logger) + // err = group2.AcceptGroupInvite(ref) + // if err != nil { + // t.Fatal(err) + // } + // + // gi, err := group2.OpenGroup(groupName1) + // if err != nil { + // t.Fatal(err) + // } + // dirInode, err := gi.GetDirectory().GetInode(gi.GetPodPassword(), filePath) + // if err != nil { + // t.Fatal(err) + // } + // if len(dirInode.FileOrDirNames) != maxfiles { + // t.Fatal("files not present") + // } + //}) + // + //t.Run("group-member-check-no-permission", func(t *testing.T) { + // t.Skip() + // fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) + // mockAcl := acl.NewACL(mockClient, fd, logger) + // group := pod.NewGroup(mockClient, fd, acc, mockAcl, logger) + // groupName1, _ := utils.GetRandString(10) + // _, err = group.CreateGroup(groupName1) + // if err != nil { + // t.Fatalf("error creating group %s: %s", groupName1, err.Error()) + // } + // + // _, err = group.ListGroup() + // if err != nil { + // t.Fatalf("error getting groups") + // } + // + // _, err = group.OpenGroup(groupName1) + // if err != nil { + // t.Fatalf("error opening group %s: %s", groupName1, err.Error()) + // } + // + // acc2 := account.New(logger) + // _, _, err = acc2.CreateUserAccount("") + // if err != nil { + // t.Fatal(err) + // } + // + // fd2 := feed.New(acc2.GetUserAccountInfo(), mockClient, -1, 0, logger) + // mockAcl2 := acl.NewACL(mockClient, fd2, logger) + // + // group2 := pod.NewGroup(mockClient, fd2, acc2, mockAcl2, logger) + // groupName2, _ := utils.GetRandString(10) + // _, err = group2.CreateGroup(groupName2) + // if err != nil { + // t.Fatalf("error creating group %s: %s", groupName1, err.Error()) + // } + // + // _, err = group2.OpenGroup(groupName2) + // if err != nil { + // t.Fatal(err) + // } + // perm, err := group2.GetPermission(groupName2) + // if err != nil { + // t.Fatal(err) + // } + // if perm != acl.PermissionWrite { + // t.Fatal("permission does not match") + // } + // + // perm1, err := group.GetPermission(groupName1) + // if err != nil { + // t.Fatal(err) + // } + // if perm1 != acl.PermissionWrite { + // t.Fatal("permission does not match") + // } + //}) + // + //t.Run("group-member-check-permission", func(t *testing.T) { + // t.Skip() + // fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) + // mockAcl := acl.NewACL(mockClient, fd, logger) + // group := pod.NewGroup(mockClient, fd, acc, mockAcl, logger) + // groupName1, _ := utils.GetRandString(10) + // _, err = group.CreateGroup(groupName1) + // if err != nil { + // t.Fatalf("error creating group %s: %s", groupName1, err.Error()) + // } + // + // _, err = group.ListGroup() + // if err != nil { + // t.Fatalf("error getting groups") + // } + // + // _, err = group.OpenGroup(groupName1) + // if err != nil { + // t.Fatalf("error opening group %s: %s", groupName1, err.Error()) + // } + // + // acc2 := account.New(logger) + // _, _, err = acc2.CreateUserAccount("") + // if err != nil { + // t.Fatal(err) + // } + // addr := acc2.GetUserAccountInfo().GetAddress() + // addrStr := addr.Hex() + // ref, err := group.AddMember(groupName1, common.HexToAddress(addrStr), acc2.GetUserAccountInfo().GetPublicKey(), acl.PermissionRead) + // if err != nil { + // t.Fatal(err) + // } + // fd2 := feed.New(acc2.GetUserAccountInfo(), mockClient, -1, 0, logger) + // + // group2 := pod.NewGroup(mockClient, fd2, acc2, mockAcl, logger) + // err = group2.AcceptGroupInvite(ref) + // if err != nil { + // t.Fatal(err) + // } + // + // _, err = group2.OpenGroup(groupName1) + // if err != nil { + // t.Fatal(err) + // } + // + // perm, err := group2.GetPermission(groupName1) + // if err != nil { + // t.Fatal(err) + // } + // if perm != acl.PermissionRead { + // t.Fatal("permission not read") + // } + // + // err = group.UpdatePermission(groupName1, common.HexToAddress(addrStr), acl.PermissionWrite) + // if err != nil { + // t.Fatal(err) + // } + // perm, err = group2.GetPermission(groupName1) + // if err != nil { + // t.Fatal(err) + // } + // if perm != acl.PermissionWrite { + // t.Fatal("permission not write") + // } + //}) + // + //t.Run("group-member-upload-files", func(t *testing.T) { + // t.Skip() + // fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) + // mockAcl := acl.NewACL(mockClient, fd, logger) + // group := pod.NewGroup(mockClient, fd, acc, mockAcl, logger) + // groupName1, _ := utils.GetRandString(10) + // _, err = group.CreateGroup(groupName1) + // if err != nil { + // t.Fatalf("error creating group %s: %s", groupName1, err.Error()) + // } + // + // _, err = group.ListGroup() + // if err != nil { + // t.Fatalf("error getting groups") + // } + // + // _, err = group.OpenGroup(groupName1) + // if err != nil { + // t.Fatalf("error opening group %s: %s", groupName1, err.Error()) + // } + // + // acc2 := account.New(logger) + // _, _, err = acc2.CreateUserAccount("") + // if err != nil { + // t.Fatal(err) + // } + // addr := acc2.GetUserAccountInfo().GetAddress() + // addrStr := addr.Hex() + // ref, err := group.AddMember(groupName1, common.HexToAddress(addrStr), acc2.GetUserAccountInfo().GetPublicKey(), acl.PermissionRead) + // if err != nil { + // t.Fatal(err) + // } + // fd2 := feed.New(acc2.GetUserAccountInfo(), mockClient, -1, 0, logger) + // + // group2 := pod.NewGroup(mockClient, fd2, acc2, mockAcl, logger) + // err = group2.AcceptGroupInvite(ref) + // if err != nil { + // t.Fatal(err) + // } + // + // g, err := group2.OpenGroup(groupName1) + // if err != nil { + // t.Fatal(err) + // } + // + // fileName, _ := utils.GetRandString(100) + // compression := "" + // fileSize := int64(1000) + // blockSize := file.MinBlockSize + // _, err = uploadFile(t, g.GetFile(), "/", fileName, compression, g.GetPodPassword(), fileSize, blockSize) + // if !errors.Is(err, feed.ErrReadOnlyFeed) { + // t.Fatal(err) + // } + // + // err = group.UpdatePermission(groupName1, common.HexToAddress(addrStr), acl.PermissionWrite) + // if err != nil { + // t.Fatal(err) + // } + // + // // reopen the group to reload feed with new permission + // err = group2.CloseGroup(groupName1) + // if err != nil { + // t.Fatal(err) + // } + // g, err = group2.OpenGroup(groupName1) + // if err != nil { + // t.Fatal(err) + // } + // + // _, err = uploadFile(t, g.GetFile(), "/", fileName, compression, g.GetPodPassword(), fileSize, blockSize) + // if err != nil { + // t.Fatal(err) + // } + // err = g.GetDirectory().AddEntryToDir("/", g.GetPodPassword(), fileName, true) + // if err != nil { + // t.Fatal(err) + // } + // + // dirInode, err := g.GetDirectory().GetInode(g.GetPodPassword(), "/") + // if err != nil { + // t.Fatal(err) + // } + // if len(dirInode.FileOrDirNames) != 1 { + // t.Fatal("files not present") + // } + // if dirInode.FileOrDirNames[0] != "_F_"+fileName { + // t.Fatal("file name not correct") + // } + //}) + // + //t.Run("group-member-remove", func(t *testing.T) { + // t.Skip() + // fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) + // mockAcl := acl.NewACL(mockClient, fd, logger) + // group := pod.NewGroup(mockClient, fd, acc, mockAcl, logger) + // groupName1, _ := utils.GetRandString(10) + // _, err = group.CreateGroup(groupName1) + // if err != nil { + // t.Fatalf("error creating group %s: %s", groupName1, err.Error()) + // } + // + // _, err = group.ListGroup() + // if err != nil { + // t.Fatalf("error getting groups") + // } + // + // _, err = group.OpenGroup(groupName1) + // if err != nil { + // t.Fatalf("error opening group %s: %s", groupName1, err.Error()) + // } + // + // acc2 := account.New(logger) + // _, _, err = acc2.CreateUserAccount("") + // if err != nil { + // t.Fatal(err) + // } + // addr := acc2.GetUserAccountInfo().GetAddress() + // addrStr := addr.Hex() + // ref, err := group.AddMember(groupName1, common.HexToAddress(addrStr), acc2.GetUserAccountInfo().GetPublicKey(), acl.PermissionRead) + // if err != nil { + // t.Fatal(err) + // } + // fd2 := feed.New(acc2.GetUserAccountInfo(), mockClient, -1, 0, logger) + // + // group2 := pod.NewGroup(mockClient, fd2, acc2, mockAcl, logger) + // err = group2.AcceptGroupInvite(ref) + // if err != nil { + // t.Fatal(err) + // } + // + // err = group.RemoveMember(groupName1, common.HexToAddress(addrStr)) + // if err != nil { + // t.Fatal(err) + // } + // _, err = group2.OpenGroup(groupName1) + // if !errors.Is(err, pod.ErrPermissionDenied) { + // t.Fatal(err) + // } + //}) + // + //t.Run("group-remove", func(t *testing.T) { + // t.Skip() + // fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) + // mockAcl := acl.NewACL(mockClient, fd, logger) + // group := pod.NewGroup(mockClient, fd, acc, mockAcl, logger) + // groupName1, _ := utils.GetRandString(10) + // _, err = group.CreateGroup(groupName1) + // if err != nil { + // t.Fatalf("error creating group %s: %s", groupName1, err.Error()) + // } + // + // _, err = group.ListGroup() + // if err != nil { + // t.Fatalf("error getting groups") + // } + // + // _, err = group.OpenGroup(groupName1) + // if err != nil { + // t.Fatalf("error opening group %s: %s", groupName1, err.Error()) + // } + // + // acc2 := account.New(logger) + // _, _, err = acc2.CreateUserAccount("") + // if err != nil { + // t.Fatal(err) + // } + // addr := acc2.GetUserAccountInfo().GetAddress() + // addrStr := addr.Hex() + // ref, err := group.AddMember(groupName1, common.HexToAddress(addrStr), acc2.GetUserAccountInfo().GetPublicKey(), acl.PermissionRead) + // if err != nil { + // t.Fatal(err) + // } + // fd2 := feed.New(acc2.GetUserAccountInfo(), mockClient, -1, 0, logger) + // + // group2 := pod.NewGroup(mockClient, fd2, acc2, mockAcl, logger) + // err = group2.AcceptGroupInvite(ref) + // if err != nil { + // t.Fatal(err) + // } + // + // err = group.RemoveGroup(groupName1) + // if err != nil { + // t.Fatal(err) + // } + // _, err = group2.OpenGroup(groupName1) + // if !errors.Is(err, pod.ErrPermissionDenied) { + // t.Fatal(err) + // } + // _, err = group2.OpenGroup(groupName1) + // if !errors.Is(err, pod.ErrGroupDoesNotExist) { + // t.Fatal(err) + // } + //}) + // + //t.Run("group-add-multiple-member", func(t *testing.T) { + // t.Skip() + // fd := feed.New(acc.GetUserAccountInfo(), mockClient, -1, 0, logger) + // mockAcl := acl.NewACL(mockClient, fd, logger) + // group := pod.NewGroup(mockClient, fd, acc, mockAcl, logger) + // groupName1, _ := utils.GetRandString(10) + // _, err = group.CreateGroup(groupName1) + // if err != nil { + // t.Fatalf("error creating group %s: %s", groupName1, err.Error()) + // } + // + // _, err = group.ListGroup() + // if err != nil { + // t.Fatalf("error getting groups") + // } + // _, err = group.OpenGroup(groupName1) + // if err != nil { + // t.Fatalf("error opening group %s: %s", groupName1, err.Error()) + // } + // userCount := 10 + // for i := 0; i < userCount; i++ { + // acc2 := account.New(logger) + // _, _, err = acc2.CreateUserAccount("") + // if err != nil { + // t.Fatal(err) + // } + // addr := acc2.GetUserAccountInfo().GetAddress() + // addrStr := addr.Hex() + // _, err = group.AddMember(groupName1, common.HexToAddress(addrStr), acc2.GetUserAccountInfo().GetPublicKey(), acl.PermissionWrite) + // if err != nil { + // t.Fatal(err) + // } + // } + // users, err := group.GetGroupMembers(groupName1) + // if err != nil { + // t.Fatal(err) + // } + // if len(users) != userCount+1 { + // t.Fatal("users not added") + // } + //}) + +} +func uploadFile(t *testing.T, fileObject *file.File, filePath, fileName, compression, podPassword string, fileSize int64, blockSize uint32) ([]byte, error) { + // create a temp file + fd, err := os.CreateTemp("", fileName) + if err != nil { + t.Fatal(err) + } + defer os.Remove(fd.Name()) + + // write contents to file + content := make([]byte, fileSize) + _, err = rand.Read(content) + if err != nil { + t.Fatal(err) + } + if _, err = fd.Write(content); err != nil { + t.Fatal(err) + } + + // close file + uploadFileName := fd.Name() + err = fd.Close() + if err != nil { + t.Fatal(err) + } + + // open file to upload + f1, err := os.Open(uploadFileName) + if err != nil { + t.Fatal(err) + } + + // upload the temp file + return content, fileObject.Upload(f1, fileName, fileSize, blockSize, 0, filePath, compression, podPassword) +} + +func addFilesAndDirectories(t *testing.T, info *pod.Info, pod1 *pod.Pod, podName1, podPassword string) { + t.Helper() + dirObject := info.GetDirectory() + err := dirObject.MkDir("/parentDir", podPassword, 0) + if err != nil { + t.Fatal(err) + } + + node := dirObject.GetDirFromDirectoryMap("/parentDir") + if pod1.GetName(node) != "parentDir" { + t.Fatal("dir name mismatch in pod") + } + if pod1.GetPath(node) != "/" { + t.Fatal("dir path mismatch in pod") + } + + // populate the directory with few directory and files + err = dirObject.MkDir("/parentDir/subDir1", podPassword, 0) + if err != nil { + t.Fatal(err) + } + err = dirObject.MkDir("/parentDir/subDir2", podPassword, 0) + if err != nil { + t.Fatal(err) + } + fileObject := info.GetFile() + _, err = uploadFile(t, fileObject, "/parentDir", "file1", "", podPassword, 100, file.MinBlockSize) + if err != nil { + t.Fatal(err) + } + err = dirObject.AddEntryToDir("/parentDir", podPassword, "file1", true) + if err != nil { + t.Fatal(err) + } + _, err = uploadFile(t, fileObject, "/parentDir", "file2", "", podPassword, 200, file.MinBlockSize) + if err != nil { + t.Fatal(err) + } + err = dirObject.AddEntryToDir("/parentDir", podPassword, "file2", true) + if err != nil { + t.Fatal(err) + } + + // close the pod + err = pod1.ClosePod(podName1) + if err != nil { + t.Fatal(err) + } + + // close the pod + err = pod1.ClosePod(podName1) + if err == nil { + t.Fatal("pod should not be open") + } +} + +func getPrivKey(keyNumber int) *ecdsa.PrivateKey { + var keyHex string + + switch keyNumber { + case 0: + keyHex = "a786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfa" + case 1: + keyHex = "b786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfb" + case 2: + keyHex = "c786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfc" + default: + panic("Invalid key number") + } + + data, err := hex.DecodeString(keyHex) + if err != nil { + panic(err) + } + + privKey, err := crypto.DecodeSecp256k1PrivateKey(data) + if err != nil { + panic(err) + } + + return privKey +} diff --git a/pkg/act/grant.go b/pkg/act/grant.go new file mode 100644 index 00000000..75bd9495 --- /dev/null +++ b/pkg/act/grant.go @@ -0,0 +1,199 @@ +package act + +import ( + "context" + "crypto/ecdsa" + "encoding/hex" + "fmt" + "time" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/ethersphere/bee/v2/pkg/crypto" + "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" +) + +func (t *ACT) GrantAccess(actName string, address swarm.Address) (*Content, error) { + t.mu.Lock() + defer t.mu.Unlock() + + list, err := t.loadUserACTs() + if err != nil { + return nil, err + } + // check if act with name already exists + act, ok := list[actName] + if !ok { + return nil, ErrACTDoesNowExist + } + owner := t.acc.GetUserAccountInfo().GetAddress() + + uploadResp, err := t.act.HandleUpload(context.Background(), address, act.HistoryRef) + if err != nil { + return nil, err + } + + topic := fmt.Sprintf("%s-%s", actName, owner.String()) + topicBytes := utils.HashString(topic) + err = t.fd.UpdateFeed(owner, topicBytes, uploadResp.HistoryReference.Bytes(), nil, false) + if err != nil { + return nil, err + } + opk, err := encodeKey(t.acc.GetUserAccountInfo().GetPublicKey()) + if err != nil { + return nil, err + } + content := &Content{ + Reference: uploadResp.Reference.String(), + Topic: topicBytes, + Owner: owner, + OwnerPublicKey: opk, + AddedAt: time.Now(), + } + act.Content = append(act.Content, content) + list[actName] = act + err = t.storeUserACTs(list) + if err != nil { + return nil, err + } + return content, nil +} + +func (t *ACT) GetPodAccess(actName string) (swarm.Address, error) { + t.mu.Lock() + defer t.mu.Unlock() + + list, err := t.loadUserACTs() + if err != nil { + return swarm.ZeroAddress, err + } + // check if act with name already exists + act, ok := list[actName] + if !ok { + return swarm.ZeroAddress, ErrACTDoesNowExist + } + if len(act.Content) == 0 { + return swarm.ZeroAddress, ErrACTDoesNowExist + } + + _, href, err := t.fd.GetFeedData(act.Content[0].Topic, act.Content[0].Owner, nil, false) + if err != nil { + return swarm.ZeroAddress, err + } + + ownerPubKey, err := parseKey(act.Content[0].OwnerPublicKey) + if err != nil { + return swarm.ZeroAddress, err + } + reference, err := swarm.ParseHexAddress(act.Content[0].Reference) + if err != nil { + return swarm.ZeroAddress, err + } + return t.act.HandleDownload(context.Background(), reference, swarm.NewAddress(href), ownerPubKey, time.Now().Unix()) +} + +func (t *ACT) SaveGrantedPod(actName string, c *Content) error { + t.mu.Lock() + defer t.mu.Unlock() + + list, err := t.loadUserACTs() + if err != nil { + return err + } + // check if act with name already exists + act, ok := list[actName] + if ok { + return ErrACTAlreadyExists + } + reference, err := swarm.ParseHexAddress(c.Reference) + if err != nil { + return err + } + act = &Act{ + Name: actName, + CreatedAt: c.AddedAt, + HistoryRef: swarm.ZeroAddress, + GranteesRef: reference, + Content: []*Content{c}, + } + list[actName] = act + return t.storeUserACTs(list) +} + +func (t *ACT) GetGrantees(actName string) ([]string, error) { + t.mu.Lock() + defer t.mu.Unlock() + + list, err := t.loadUserACTs() + if err != nil { + return nil, err + } + act, ok := list[actName] + if !ok { + return nil, ErrACTDoesNowExist + } + grantees, err := t.act.GetGrantees(context.Background(), act.GranteesRef) + if err != nil { + return nil, err + } + return encodeKeys(grantees) +} + +func (t *ACT) GetContentList(actName string) ([]*Content, error) { + t.mu.Lock() + defer t.mu.Unlock() + + list, err := t.loadUserACTs() + if err != nil { + return nil, err + } + act, ok := list[actName] + if !ok { + return nil, ErrACTDoesNowExist + } + return act.Content, nil +} + +func encodeKeys(keys []*ecdsa.PublicKey) ([]string, error) { + encodedList := make([]string, 0, len(keys)) + for _, key := range keys { + encoded, err := encodeKey(key) + if err != nil { + return nil, err + } + encodedList = append(encodedList, encoded) + } + return encodedList, nil +} + +func encodeKey(key *ecdsa.PublicKey) (string, error) { + if key == nil { + return "", fmt.Errorf("nil key found") + } + return hex.EncodeToString(crypto.EncodeSecp256k1PublicKey(key)), nil +} + +func parseKeys(list []string) ([]*ecdsa.PublicKey, error) { + parsedList := make([]*ecdsa.PublicKey, 0, len(list)) + for _, g := range list { + h, err := parseKey(g) + if err != nil { + return []*ecdsa.PublicKey{}, err + } + parsedList = append(parsedList, h) + } + + return parsedList, nil +} + +func parseKey(g string) (*ecdsa.PublicKey, error) { + h, err := hex.DecodeString(g) + if err != nil { + return nil, fmt.Errorf("failed to decode grantee: %w", err) + } + k, err := btcec.ParsePubKey(h) + if err != nil { + return nil, fmt.Errorf("failed to parse grantee public key: %w", err) + } + return k.ToECDSA(), nil +} diff --git a/pkg/act/new.go b/pkg/act/new.go new file mode 100644 index 00000000..634fce0a --- /dev/null +++ b/pkg/act/new.go @@ -0,0 +1,152 @@ +package act + +import ( + "context" + "crypto/ecdsa" + "fmt" + "time" + + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/ethersphere/bee/v2/pkg/crypto" + + "github.com/ethersphere/bee/v2/pkg/api" + + "github.com/ethersphere/bee/v2/pkg/swarm" +) + +const ( + actFile = "ACTs" +) + +type List map[string]*Act + +// Act represents an Access Control Trie (ACT) with its metadata, grantees, and associated content. +type Act struct { + Name string `json:"name"` + HistoryRef swarm.Address `json:"historyRef"` + GranteesRef swarm.Address `json:"granteesRef"` + CreatedAt time.Time `json:"createdAt"` + Content []*Content `json:"content"` +} + +// Content represents a pod or data reference associated with the ACT. +type Content struct { + Reference string `json:"reference"` + Topic []byte `json:"topic"` + Owner utils.Address `json:"owner"` + OwnerPublicKey string `json:"ownerPublicKey"` + AddedAt time.Time `json:"addedAt"` +} + +func (t *ACT) CreateUpdateACT(actName string, publicKeyGrant, publicKeyRevoke *ecdsa.PublicKey) (*Act, error) { + t.mu.Lock() + defer t.mu.Unlock() + + list, err := t.loadUserACTs() + if err != nil { + return nil, err + } + if publicKeyGrant != nil { + gkBytes := crypto.EncodeSecp256k1PublicKey(publicKeyGrant) + gkParsedPublicKey, err := btcec.ParsePubKey(gkBytes) + if err != nil { + return nil, err + } + publicKeyGrant = gkParsedPublicKey.ToECDSA() + } + if publicKeyRevoke != nil { + rkBytes := crypto.EncodeSecp256k1PublicKey(publicKeyRevoke) + rkParsedPublicKey, err := btcec.ParsePubKey(rkBytes) + if err != nil { + return nil, err + } + publicKeyRevoke = rkParsedPublicKey.ToECDSA() + } + + var ( + resp = &api.GranteesPostResponse{} + grantList = []*ecdsa.PublicKey{} + revokeList = []*ecdsa.PublicKey{} + owner = t.acc.GetUserAccountInfo().GetAddress() + topic = fmt.Sprintf("%s-%s", actName, owner.String()) + topicBytes = utils.HashString(topic) + ) + // check if act with name already exists + act, ok := list[actName] + if !ok { + act = &Act{ + Name: actName, + CreatedAt: time.Now(), + HistoryRef: swarm.ZeroAddress, + GranteesRef: swarm.ZeroAddress, + Content: []*Content{}, + } + grantList = []*ecdsa.PublicKey{publicKeyGrant} + resp, err = t.act.CreateGrantee(context.Background(), act.HistoryRef, grantList) + if err != nil { + return nil, err + } + + err = t.fd.CreateFeed(owner, topicBytes, resp.HistoryReference.Bytes(), nil) + if err != nil { + return nil, err + } + } else { + if publicKeyGrant == nil && publicKeyRevoke == nil { + return nil, fmt.Errorf("grant or revoke key is required") + } + if publicKeyGrant != nil { + grantList = []*ecdsa.PublicKey{publicKeyGrant} + } else { + grantList = nil + } + if publicKeyRevoke != nil { + revokeList = []*ecdsa.PublicKey{publicKeyRevoke} + } else { + revokeList = nil + } + resp, err = t.act.RevokeGrant(context.Background(), act.GranteesRef, act.HistoryRef, grantList, revokeList) + if err != nil { + return nil, err + } + err = t.fd.UpdateFeed(owner, topicBytes, resp.HistoryReference.Bytes(), nil, false) + if err != nil { + return nil, err + } + } + + act.GranteesRef = resp.Reference + act.HistoryRef = resp.HistoryReference + + list[actName] = act + err = t.storeUserACTs(list) + if err != nil { + return nil, err + } + return act, nil +} + +func (t *ACT) GetACT(actName string) (*Act, error) { + t.mu.Lock() + defer t.mu.Unlock() + + list, err := t.loadUserACTs() + if err != nil { + return nil, err + } + act, ok := list[actName] + if !ok { + return nil, ErrACTDoesNowExist + } + + return act, nil +} + +func (t *ACT) GetList() (List, error) { + t.mu.Lock() + defer t.mu.Unlock() + + return t.loadUserACTs() +} diff --git a/pkg/api/act.go b/pkg/api/act.go new file mode 100644 index 00000000..f971f400 --- /dev/null +++ b/pkg/api/act.go @@ -0,0 +1,263 @@ +package api + +import ( + "crypto/ecdsa" + "encoding/hex" + "encoding/json" + "net/http" + + "github.com/fairdatasociety/fairOS-dfs/pkg/act" + + "github.com/btcsuite/btcd/btcec/v2" + + "github.com/fairdatasociety/fairOS-dfs/pkg/auth" + "github.com/gorilla/mux" + "resenje.org/jsonhttp" +) + +func (h *Handler) ACTListHandler(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + + list, err := h.dfsAPI.GetACTs(sessionId) + if err != nil { + h.logger.Error("list acts failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + + jsonhttp.OK(w, list) +} + +func (h *Handler) ListGranteesHandler(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + + vars := mux.Vars(r) + actName := vars["actName"] + + grantees, err := h.dfsAPI.ListGrantees(sessionId, actName) + if err != nil { + h.logger.Error("list grantees failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + + jsonhttp.OK(w, grantees) +} +func (h *Handler) ACTOpenPod(w http.ResponseWriter, r *http.Request) {} +func (h *Handler) ACTSavePod(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + vars := mux.Vars(r) + actName := vars["actName"] + + contentType := r.Header.Get("Content-Type") + if contentType != jsonContentType { + h.logger.Errorf("save act pod: invalid request body type") + jsonhttp.BadRequest(w, &response{Message: "save act pod: invalid request body type"}) + return + } + + decoder := json.NewDecoder(r.Body) + var saveReq act.Content + err = decoder.Decode(&saveReq) + if err != nil { + h.logger.Errorf("save act pod: could not decode arguments") + jsonhttp.BadRequest(w, &response{Message: "save act pod: could not decode arguments"}) + return + } + + err = h.dfsAPI.SaveACTPod(sessionId, actName, &saveReq) + if err != nil { + h.logger.Error("save act pod failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + w.WriteHeader(http.StatusOK) +} +func (h *Handler) ACTSharedPods(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + vars := mux.Vars(r) + actName := vars["actName"] + + list, err := h.dfsAPI.GetACTContents(sessionId, actName) + if err != nil { + h.logger.Error("list contents failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + + jsonhttp.OK(w, list) +} + +func (h *Handler) GrantRevokeHandler(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + + vars := mux.Vars(r) + actName := vars["actName"] + + grantUser := r.URL.Query().Get("grant") + revokeUser := r.URL.Query().Get("revoke") + if grantUser == "" && revokeUser == "" { + h.logger.Error("grant revoke failed: ", err) + jsonhttp.BadRequest(w, &response{Message: "grant and revoke user public key required"}) + return + } + if grantUser == revokeUser { + h.logger.Error("grant revoke failed: ", err) + jsonhttp.BadRequest(w, &response{Message: "grant and revoke user public key cannot be the same"}) + } + var ( + granteePubKey *ecdsa.PublicKey + removePubKey *ecdsa.PublicKey + ) + if grantUser != "" { + pubkg, err := hex.DecodeString(grantUser) + if err != nil { + h.logger.Error("grant revoke failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + pubg, err := btcec.ParsePubKey(pubkg) + if err != nil { + h.logger.Error("grant revoke failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + granteePubKey = pubg.ToECDSA() + } + if revokeUser != "" { + pubkr, err := hex.DecodeString(revokeUser) + if err != nil { + h.logger.Error("grant revoke failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + pubr, err := btcec.ParsePubKey(pubkr) + if err != nil { + h.logger.Error("grant revoke failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + removePubKey = pubr.ToECDSA() + } + + err = h.dfsAPI.GrantRevokeGranteePublicKey(sessionId, actName, granteePubKey, removePubKey) + if err != nil { + h.logger.Error("grant revoke failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + w.WriteHeader(http.StatusOK) +} +func (h *Handler) ACTPodShareHandler(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + + vars := mux.Vars(r) + actName := vars["actName"] + podName := vars["podName"] + + err = h.dfsAPI.ACTPodShare(sessionId, podName, actName) + if err != nil { + h.logger.Error("create grantee failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + w.WriteHeader(http.StatusOK) +} + +func (h *Handler) CreateGranteeHandler(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + + vars := mux.Vars(r) + actName := vars["actName"] + + userPublicKeyString := r.URL.Query().Get("grantee") + pubk, err := hex.DecodeString(userPublicKeyString) + if err != nil { + h.logger.Error("create grantee failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + pub, err := btcec.ParsePubKey(pubk) + if err != nil { + h.logger.Error("create grantee failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + err = h.dfsAPI.CreateGranteePublicKey(sessionId, actName, pub.ToECDSA()) + if err != nil { + h.logger.Error("create grantee failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + w.WriteHeader(http.StatusOK) +} diff --git a/pkg/dfs/act_api.go b/pkg/dfs/act_api.go new file mode 100644 index 00000000..8c2a0bd8 --- /dev/null +++ b/pkg/dfs/act_api.go @@ -0,0 +1,168 @@ +package dfs + +import ( + "crypto/ecdsa" + + "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/fairdatasociety/fairOS-dfs/pkg/act" +) + +func (a *API) CreateGranteePublicKey(sessionId, actName string, publicKey *ecdsa.PublicKey) error { + // get the loggedin user information + ui := a.users.GetLoggedInUserInfo(sessionId) + if ui == nil { + return ErrUserNotLoggedIn + } + actList := ui.GetACTList() + _, err := actList.CreateUpdateACT(actName, publicKey, nil) + return err +} + +func (a *API) GrantRevokeGranteePublicKey(sessionId, actName string, publicKeyGrant, publicKeyRevoke *ecdsa.PublicKey) error { + // get the loggedin user information + ui := a.users.GetLoggedInUserInfo(sessionId) + if ui == nil { + return ErrUserNotLoggedIn + } + + actList := ui.GetACTList() + _, err := actList.CreateUpdateACT(actName, publicKeyGrant, publicKeyRevoke) + return err +} + +func (a *API) ListGrantees(sessionId, actName string) ([]string, error) { + // get the loggedin user information + ui := a.users.GetLoggedInUserInfo(sessionId) + if ui == nil { + return nil, ErrUserNotLoggedIn + } + + actList := ui.GetACTList() + return actList.GetGrantees(actName) +} + +func (a *API) ACTPodShare(sessionId, podName, actName string) error { + ui := a.users.GetLoggedInUserInfo(sessionId) + if ui == nil { + return ErrUserNotLoggedIn + } + + actList := ui.GetACTList() + address, err := ui.GetPod().PodShare(podName, "") + if err != nil { + return err + } + + addr, err := swarm.ParseHexAddress(address) + if err != nil { + return err + } + + _, err = actList.GrantAccess(actName, addr) + return err +} + +func (a *API) GetACTs(sessionId string) (act.List, error) { + // get the loggedin user information + ui := a.users.GetLoggedInUserInfo(sessionId) + if ui == nil { + return nil, ErrUserNotLoggedIn + } + + actList := ui.GetACTList() + return actList.GetList() +} +func (a *API) SaveACTPod(sessionId, actName string, c *act.Content) error { + // get the loggedin user information + ui := a.users.GetLoggedInUserInfo(sessionId) + if ui == nil { + return ErrUserNotLoggedIn + } + + actList := ui.GetACTList() + return actList.SaveGrantedPod(actName, c) +} + +func (a *API) GetACTContents(sessionId, actName string) ([]*act.Content, error) { + // get the loggedin user information + ui := a.users.GetLoggedInUserInfo(sessionId) + if ui == nil { + return nil, ErrUserNotLoggedIn + } + + actList := ui.GetACTList() + + return actList.GetContentList(actName) +} + +//func (a *API) GrantRevokeGrantee(sessionId, grantUser, revokeUser, actName string) error { +// // get the loggedin user information +// ui := a.users.GetLoggedInUserInfo(sessionId) +// if ui == nil { +// return ErrUserNotLoggedIn +// } +// grantList := make([]*ecdsa.PublicKey, 1) +// revokeList := make([]*ecdsa.PublicKey, 1) +// +// actList := ui.GetACTList() +// act, err := actList.GetACT(actName) +// if err != nil { // skipcq: TCV-001 +// return err +// } +// historyRef, granteeListRef := act.HistoryRef, act.GranteesRef +// if grantUser == "" && revokeUser == "" { +// return fmt.Errorf("grant or revoke user required") +// } +// if grantUser != "" { +// publicKeyGrant, _, err := a.users.GetUserInfo(grantUser) +// if err != nil { // skipcq: TCV-001 +// return err +// } +// if publicKeyGrant == nil { +// return fmt.Errorf("public key not found") +// } +// grantList[0] = publicKeyGrant +// } +// if revokeUser != "" { +// publicKeyRevoke, _, err := a.users.GetUserInfo(revokeUser) +// if err != nil { // skipcq: TCV-001 +// return err +// } +// if publicKeyRevoke == nil { +// return fmt.Errorf("public key not found") +// } +// revokeList[0] = publicKeyRevoke +// } +// +// swarmAct := ui.GetACT() +// createResp, err := swarmAct.RevokeGrant(a.context, granteeListRef, historyRef, grantList, revokeList) +// if err != nil { // skipcq: TCV-001 +// return err +// } +// _, err = actList.CreateUpdateACT(actName, createResp.HistoryReference, createResp.Reference) +// return err +//} + +//func (a *API) CreateGrantee(sessionId, user, actName string) error { +// // get the loggedin user information +// ui := a.users.GetLoggedInUserInfo(sessionId) +// if ui == nil { +// return ErrUserNotLoggedIn +// } +// +// publicKey, _, err := a.users.GetUserInfo(user) +// if err != nil { // skipcq: TCV-001 +// return err +// } +// if publicKey == nil { +// return fmt.Errorf("public key not found") +// } +// +// act := ui.GetACT() +// addList := []*ecdsa.PublicKey{publicKey} +// createResp, err := act.CreateGrantee(a.context, swarm.ZeroAddress, addList) +// +// // TODO save in ACT LIST +// _ = createResp +// return err +//} diff --git a/pkg/user/info.go b/pkg/user/info.go index e2db8b35..ffa14663 100644 --- a/pkg/user/info.go +++ b/pkg/user/info.go @@ -19,6 +19,8 @@ package user import ( "sync" + "github.com/fairdatasociety/fairOS-dfs/pkg/act" + "github.com/fairdatasociety/fairOS-dfs/pkg/account" d "github.com/fairdatasociety/fairOS-dfs/pkg/dir" "github.com/fairdatasociety/fairOS-dfs/pkg/feed" @@ -38,6 +40,7 @@ type Info struct { group *pod.Group openPods map[string]*pod.Info openPodsMu *sync.RWMutex + actList *act.ACT } // GetUserName return username @@ -55,6 +58,10 @@ func (i *Info) GetPod() *pod.Pod { return i.pod } +func (i *Info) GetACTList() *act.ACT { + return i.actList +} + // GetGroup returns user group handler func (i *Info) GetGroup() *pod.Group { return i.group diff --git a/pkg/user/login.go b/pkg/user/login.go index 061af83e..a0ab0e36 100644 --- a/pkg/user/login.go +++ b/pkg/user/login.go @@ -17,9 +17,12 @@ limitations under the License. package user import ( + "crypto/ecdsa" "fmt" "sync" + "github.com/fairdatasociety/fairOS-dfs/pkg/act" + blockstore "github.com/asabya/swarm-blockstore" acl2 "github.com/fairdatasociety/fairOS-dfs/pkg/acl/acl" @@ -75,7 +78,7 @@ func (u *Users) LoginUserV2(userName, passPhrase string, client blockstore.Clien } // load public key from public resolver - publicKey, nameHash, err := u.ens.GetInfo(userName) + publicKey, nameHash, err := u.GetUserInfo(userName) if err != nil { // skipcq: TCV-001 return nil, err } @@ -95,11 +98,15 @@ func (u *Users) LoginUserV2(userName, passPhrase string, client blockstore.Clien } // Instantiate pod, dir & file objects - file := f.NewFile(userName, client, fd, accountInfo.GetAddress(), tm, u.logger) - pod := p.NewPod(u.client, fd, acc, tm, sm, u.feedCacheSize, u.feedCacheTTL, u.logger) - acl := acl2.NewACL(u.client, fd, u.logger) - group := p.NewGroup(u.client, fd, acc, acl, u.logger) - dir := d.NewDirectory(userName, client, fd, accountInfo.GetAddress(), file, tm, u.logger) + var ( + file = f.NewFile(userName, client, fd, accountInfo.GetAddress(), tm, u.logger) + pod = p.NewPod(u.client, fd, acc, tm, sm, u.feedCacheSize, u.feedCacheTTL, u.logger) + acl = acl2.NewACL(u.client, fd, u.logger) + group = p.NewGroup(u.client, fd, acc, acl, u.logger) + dir = d.NewDirectory(userName, client, fd, accountInfo.GetAddress(), file, tm, u.logger) + actList = act.NewACT(client, fd, acc, tm, u.logger) + ) + if sessionId == "" { sessionId = auth.GetUniqueSessionId() } @@ -115,6 +122,7 @@ func (u *Users) LoginUserV2(userName, passPhrase string, client blockstore.Clien group: group, openPods: make(map[string]*p.Info), openPodsMu: &sync.RWMutex{}, + actList: actList, } // set cookie and add user to map if err = u.addUserAndSessionToMap(ui); err != nil { // skipcq: TCV-001 @@ -338,3 +346,7 @@ func (u *Users) LoginWithWallet(addressHex, signature string, client blockstore. // set cookie and add user to map return ui, utils.Encode(nameHash[:]), u.addUserAndSessionToMap(ui) } + +func (u *Users) GetUserInfo(userName string) (*ecdsa.PublicKey, string, error) { + return u.ens.GetInfo(userName) +} From c74d0a696c102cb013e43d9e7bf2e08f28110a6a Mon Sep 17 00:00:00 2001 From: asabya Date: Wed, 23 Oct 2024 11:23:39 +0530 Subject: [PATCH 03/14] fix: lint --- pkg/act/act_test.go | 9 +++++---- pkg/act/grant.go | 19 +++---------------- pkg/act/new.go | 6 +++--- 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/pkg/act/act_test.go b/pkg/act/act_test.go index b1dc9803..5b571283 100644 --- a/pkg/act/act_test.go +++ b/pkg/act/act_test.go @@ -147,6 +147,7 @@ func TestACT(t *testing.T) { if err != nil { t.Fatal(err) } + <-time.After(1 * time.Second) } } list, err := ownerACT.GetList() @@ -253,7 +254,7 @@ func TestACT(t *testing.T) { pod1 := pod.NewPod(mockClient, fd, ownerAcc, tm, sm, -1, 0, logger) ownerACT := NewACT(mockClient, fd, ownerAcc, tm, logger) granteeAcc := accounts[1] - _, err := ownerACT.CreateUpdateACT(acts[0], granteeAcc.GetUserAccountInfo().GetPublicKey(), nil) + _, err := ownerACT.CreateUpdateACT(acts[1], granteeAcc.GetUserAccountInfo().GetPublicKey(), nil) if err != nil { t.Fatal(err) } @@ -273,18 +274,18 @@ func TestACT(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = ownerACT.GrantAccess(acts[0], reference) + _, err = ownerACT.GrantAccess(acts[1], reference) if err != nil { t.Fatal(err) } <-time.After(1 * time.Second) } - contents, err := ownerACT.GetContentList(acts[0]) + contents, err := ownerACT.GetContentList(acts[1]) if err != nil { t.Fatal(err) } if len(contents) != 9 { - t.Fatal("contents not matching") + t.Fatal("contents not matching", len(contents)) } }) diff --git a/pkg/act/grant.go b/pkg/act/grant.go index 75bd9495..b7922dd0 100644 --- a/pkg/act/grant.go +++ b/pkg/act/grant.go @@ -101,7 +101,7 @@ func (t *ACT) SaveGrantedPod(actName string, c *Content) error { return err } // check if act with name already exists - act, ok := list[actName] + _, ok := list[actName] if ok { return ErrACTAlreadyExists } @@ -109,14 +109,14 @@ func (t *ACT) SaveGrantedPod(actName string, c *Content) error { if err != nil { return err } - act = &Act{ + a := &Act{ Name: actName, CreatedAt: c.AddedAt, HistoryRef: swarm.ZeroAddress, GranteesRef: reference, Content: []*Content{c}, } - list[actName] = act + list[actName] = a return t.storeUserACTs(list) } @@ -173,19 +173,6 @@ func encodeKey(key *ecdsa.PublicKey) (string, error) { return hex.EncodeToString(crypto.EncodeSecp256k1PublicKey(key)), nil } -func parseKeys(list []string) ([]*ecdsa.PublicKey, error) { - parsedList := make([]*ecdsa.PublicKey, 0, len(list)) - for _, g := range list { - h, err := parseKey(g) - if err != nil { - return []*ecdsa.PublicKey{}, err - } - parsedList = append(parsedList, h) - } - - return parsedList, nil -} - func parseKey(g string) (*ecdsa.PublicKey, error) { h, err := hex.DecodeString(g) if err != nil { diff --git a/pkg/act/new.go b/pkg/act/new.go index 634fce0a..8e356704 100644 --- a/pkg/act/new.go +++ b/pkg/act/new.go @@ -67,8 +67,8 @@ func (t *ACT) CreateUpdateACT(actName string, publicKeyGrant, publicKeyRevoke *e var ( resp = &api.GranteesPostResponse{} - grantList = []*ecdsa.PublicKey{} - revokeList = []*ecdsa.PublicKey{} + grantList []*ecdsa.PublicKey + revokeList []*ecdsa.PublicKey owner = t.acc.GetUserAccountInfo().GetAddress() topic = fmt.Sprintf("%s-%s", actName, owner.String()) topicBytes = utils.HashString(topic) @@ -88,7 +88,6 @@ func (t *ACT) CreateUpdateACT(actName string, publicKeyGrant, publicKeyRevoke *e if err != nil { return nil, err } - err = t.fd.CreateFeed(owner, topicBytes, resp.HistoryReference.Bytes(), nil) if err != nil { return nil, err @@ -107,6 +106,7 @@ func (t *ACT) CreateUpdateACT(actName string, publicKeyGrant, publicKeyRevoke *e } else { revokeList = nil } + resp, err = t.act.RevokeGrant(context.Background(), act.GranteesRef, act.HistoryRef, grantList, revokeList) if err != nil { return nil, err From 78c4430f16a0594aba5fd8f4fc4f7c1642ac578b Mon Sep 17 00:00:00 2001 From: asabya Date: Wed, 23 Oct 2024 12:35:51 +0530 Subject: [PATCH 04/14] fix: change log level in test --- cmd/dfs/cmd/server_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/dfs/cmd/server_test.go b/cmd/dfs/cmd/server_test.go index 579b53cf..80202c07 100644 --- a/cmd/dfs/cmd/server_test.go +++ b/cmd/dfs/cmd/server_test.go @@ -57,7 +57,7 @@ func TestApis(t *testing.T) { Post: mockpost.New(mockpost.WithAcceptAll()), }) - logger := logging.New(os.Stdout, logrus.DebugLevel) + logger := logging.New(os.Stdout, logrus.PanicLevel) mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) ens := mock2.NewMockNamespaceManager() From c55c30535c02afb552ad029ca57e1c6e246fa9b7 Mon Sep 17 00:00:00 2001 From: asabya Date: Wed, 23 Oct 2024 14:42:38 +0530 Subject: [PATCH 05/14] fix: tests --- Makefile | 2 +- cmd/dfs/cmd/server.go | 6 +- pkg/act/act_test.go | 8 +- pkg/act/grant.go | 8 +- pkg/act/new.go | 29 +-- pkg/api/act.go | 321 ++++++++++++++++------- pkg/dfs/act_api.go | 27 ++ pkg/pod/open.go | 6 - pkg/test/subscription_test.go | 12 +- swagger/docs.go | 476 ++++++++++++++++++++++++++++++++++ swagger/swagger.json | 476 ++++++++++++++++++++++++++++++++++ swagger/swagger.yaml | 323 +++++++++++++++++++++++ 12 files changed, 1562 insertions(+), 132 deletions(-) diff --git a/Makefile b/Makefile index 581558fe..6b7a9803 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ linter: .PHONY: swagger swagger: which swag || ( echo "install swag for your system from https://github.com/swaggo/swag" && exit 1) - swag init -g ./cmd/server.go -d cmd/dfs,pkg/api,cmd/common,pkg/dir,pkg/file,pkg/pod,pkg/user,pkg/collection -o ./swagger + swag init -g ./cmd/server.go -d cmd/dfs,pkg/api,cmd/common,pkg/dir,pkg/file,pkg/pod,pkg/user,pkg/collection,pkg/act,pkg/utils -o ./swagger .PHONY: vet vet: diff --git a/cmd/dfs/cmd/server.go b/cmd/dfs/cmd/server.go index 9c5275c3..c305c878 100644 --- a/cmd/dfs/cmd/server.go +++ b/cmd/dfs/cmd/server.go @@ -464,12 +464,12 @@ func startHttpService(logger logging.Logger) *http.Server { actRouter.HandleFunc("/grantee/{actName}", handler.CreateGranteeHandler).Methods("POST") actRouter.HandleFunc("/grantee/{actName}", handler.GrantRevokeHandler).Methods("PATCH") actRouter.HandleFunc("/grantee/{actName}", handler.ListGranteesHandler).Methods("GET") - actRouter.HandleFunc("/share-pod", handler.ACTPodShareHandler).Methods("PATCH") + actRouter.HandleFunc("/share-pod/{actName}/{podname}", handler.ACTPodShareHandler).Methods("POST") actRouter.HandleFunc("/list", handler.ACTListHandler).Methods("GET") actRouter.HandleFunc("/act-shared-pods", handler.ACTSharedPods).Methods("GET") // grantee - actRouter.HandleFunc("/save-act-pod", handler.ACTSavePod).Methods("POST") - actRouter.HandleFunc("/open-act-pod", handler.ACTOpenPod).Methods("POST") + actRouter.HandleFunc("/save-act-pod/{actName}", handler.ACTSavePod).Methods("POST") + actRouter.HandleFunc("/open-act-pod/{actName}", handler.ACTOpenPod).Methods("POST") var origins []string for _, c := range corsOrigins { diff --git a/pkg/act/act_test.go b/pkg/act/act_test.go index 5b571283..73122fab 100644 --- a/pkg/act/act_test.go +++ b/pkg/act/act_test.go @@ -78,7 +78,7 @@ func TestACT(t *testing.T) { if err != nil { t.Fatal(err) } - pubKeys, err := ownerACT.act.GetGrantees(context.Background(), a.GranteesRef) + pubKeys, err := ownerACT.act.GetGrantees(context.Background(), swarm.NewAddress(a.GranteesRef)) if err != nil { t.Fatal(err) } @@ -106,7 +106,7 @@ func TestACT(t *testing.T) { if err != nil { t.Fatal(err) } - pubKeys, err := ownerACT.act.GetGrantees(context.Background(), a.GranteesRef) + pubKeys, err := ownerACT.act.GetGrantees(context.Background(), swarm.NewAddress(a.GranteesRef)) if err != nil { t.Fatal(err) } @@ -127,7 +127,7 @@ func TestACT(t *testing.T) { t.Fatal(err) } - pubKeys, err = ownerACT.act.GetGrantees(context.Background(), a.GranteesRef) + pubKeys, err = ownerACT.act.GetGrantees(context.Background(), swarm.NewAddress(a.GranteesRef)) if err != nil { t.Fatal(err) } @@ -238,7 +238,7 @@ func TestACT(t *testing.T) { } <-time.After(time.Second) - _, err = ownerACT.act.GetGrantees(context.Background(), actAfterRevoke.GranteesRef) + _, err = ownerACT.act.GetGrantees(context.Background(), swarm.NewAddress(actAfterRevoke.GranteesRef)) if err != nil { t.Fatal(err) } diff --git a/pkg/act/grant.go b/pkg/act/grant.go index b7922dd0..9856db32 100644 --- a/pkg/act/grant.go +++ b/pkg/act/grant.go @@ -28,7 +28,7 @@ func (t *ACT) GrantAccess(actName string, address swarm.Address) (*Content, erro } owner := t.acc.GetUserAccountInfo().GetAddress() - uploadResp, err := t.act.HandleUpload(context.Background(), address, act.HistoryRef) + uploadResp, err := t.act.HandleUpload(context.Background(), address, swarm.NewAddress(act.HistoryRef)) if err != nil { return nil, err } @@ -112,8 +112,8 @@ func (t *ACT) SaveGrantedPod(actName string, c *Content) error { a := &Act{ Name: actName, CreatedAt: c.AddedAt, - HistoryRef: swarm.ZeroAddress, - GranteesRef: reference, + HistoryRef: swarm.ZeroAddress.Bytes(), + GranteesRef: reference.Bytes(), Content: []*Content{c}, } list[actName] = a @@ -132,7 +132,7 @@ func (t *ACT) GetGrantees(actName string) ([]string, error) { if !ok { return nil, ErrACTDoesNowExist } - grantees, err := t.act.GetGrantees(context.Background(), act.GranteesRef) + grantees, err := t.act.GetGrantees(context.Background(), swarm.NewAddress(act.GranteesRef)) if err != nil { return nil, err } diff --git a/pkg/act/new.go b/pkg/act/new.go index 8e356704..dc040652 100644 --- a/pkg/act/new.go +++ b/pkg/act/new.go @@ -6,14 +6,11 @@ import ( "fmt" "time" - "github.com/fairdatasociety/fairOS-dfs/pkg/utils" - "github.com/btcsuite/btcd/btcec/v2" - "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/api" - + "github.com/ethersphere/bee/v2/pkg/crypto" "github.com/ethersphere/bee/v2/pkg/swarm" + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" ) const ( @@ -24,11 +21,11 @@ type List map[string]*Act // Act represents an Access Control Trie (ACT) with its metadata, grantees, and associated content. type Act struct { - Name string `json:"name"` - HistoryRef swarm.Address `json:"historyRef"` - GranteesRef swarm.Address `json:"granteesRef"` - CreatedAt time.Time `json:"createdAt"` - Content []*Content `json:"content"` + Name string `json:"name"` + HistoryRef []byte `json:"historyRef"` + GranteesRef []byte `json:"granteesRef"` + CreatedAt time.Time `json:"createdAt"` + Content []*Content `json:"content"` } // Content represents a pod or data reference associated with the ACT. @@ -79,12 +76,12 @@ func (t *ACT) CreateUpdateACT(actName string, publicKeyGrant, publicKeyRevoke *e act = &Act{ Name: actName, CreatedAt: time.Now(), - HistoryRef: swarm.ZeroAddress, - GranteesRef: swarm.ZeroAddress, + HistoryRef: swarm.ZeroAddress.Bytes(), + GranteesRef: swarm.ZeroAddress.Bytes(), Content: []*Content{}, } grantList = []*ecdsa.PublicKey{publicKeyGrant} - resp, err = t.act.CreateGrantee(context.Background(), act.HistoryRef, grantList) + resp, err = t.act.CreateGrantee(context.Background(), swarm.NewAddress(act.HistoryRef), grantList) if err != nil { return nil, err } @@ -107,7 +104,7 @@ func (t *ACT) CreateUpdateACT(actName string, publicKeyGrant, publicKeyRevoke *e revokeList = nil } - resp, err = t.act.RevokeGrant(context.Background(), act.GranteesRef, act.HistoryRef, grantList, revokeList) + resp, err = t.act.RevokeGrant(context.Background(), swarm.NewAddress(act.GranteesRef), swarm.NewAddress(act.HistoryRef), grantList, revokeList) if err != nil { return nil, err } @@ -117,8 +114,8 @@ func (t *ACT) CreateUpdateACT(actName string, publicKeyGrant, publicKeyRevoke *e } } - act.GranteesRef = resp.Reference - act.HistoryRef = resp.HistoryReference + act.GranteesRef = resp.Reference.Bytes() + act.HistoryRef = resp.HistoryReference.Bytes() list[actName] = act err = t.storeUserACTs(list) diff --git a/pkg/api/act.go b/pkg/api/act.go index f971f400..391fa15c 100644 --- a/pkg/api/act.go +++ b/pkg/api/act.go @@ -15,30 +15,20 @@ import ( "resenje.org/jsonhttp" ) -func (h *Handler) ACTListHandler(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) - if err != nil { - h.logger.Errorf("sessionId parse failed: ", err) - jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) - return - } - if sessionId == "" { - h.logger.Error("sessionId not set: ", err) - jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) - return - } - - list, err := h.dfsAPI.GetACTs(sessionId) - if err != nil { - h.logger.Error("list acts failed: ", err) - jsonhttp.BadRequest(w, &response{Message: err.Error()}) - return - } - - jsonhttp.OK(w, list) -} - -func (h *Handler) ListGranteesHandler(w http.ResponseWriter, r *http.Request) { +// CreateGranteeHandler godoc +// +// @Summary Create ACT with grantee public key +// @Description CreateGranteeHandler is the api handler for creating act with grantee public key. +// @ID create-act +// @Tags act +// @Produce json +// @Param actName path string true "unique act identifier" +// @Param grantee query string true "grantee public key" +// @Success 201 {object} response +// @Failure 400 {object} response +// @Failure 500 {object} response +// @Router /v1/act/grantee/{actName} [post] +func (h *Handler) CreateGranteeHandler(w http.ResponseWriter, r *http.Request) { sessionId, err := auth.GetSessionIdFromGitRequest(r) if err != nil { h.logger.Errorf("sessionId parse failed: ", err) @@ -54,80 +44,43 @@ func (h *Handler) ListGranteesHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) actName := vars["actName"] - grantees, err := h.dfsAPI.ListGrantees(sessionId, actName) + userPublicKeyString := r.URL.Query().Get("grantee") + pubk, err := hex.DecodeString(userPublicKeyString) if err != nil { - h.logger.Error("list grantees failed: ", err) + h.logger.Error("create grantee failed: ", err) jsonhttp.BadRequest(w, &response{Message: err.Error()}) return } - - jsonhttp.OK(w, grantees) -} -func (h *Handler) ACTOpenPod(w http.ResponseWriter, r *http.Request) {} -func (h *Handler) ACTSavePod(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) - if err != nil { - h.logger.Errorf("sessionId parse failed: ", err) - jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) - return - } - if sessionId == "" { - h.logger.Error("sessionId not set: ", err) - jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) - return - } - vars := mux.Vars(r) - actName := vars["actName"] - - contentType := r.Header.Get("Content-Type") - if contentType != jsonContentType { - h.logger.Errorf("save act pod: invalid request body type") - jsonhttp.BadRequest(w, &response{Message: "save act pod: invalid request body type"}) - return - } - - decoder := json.NewDecoder(r.Body) - var saveReq act.Content - err = decoder.Decode(&saveReq) - if err != nil { - h.logger.Errorf("save act pod: could not decode arguments") - jsonhttp.BadRequest(w, &response{Message: "save act pod: could not decode arguments"}) - return - } - - err = h.dfsAPI.SaveACTPod(sessionId, actName, &saveReq) + pub, err := btcec.ParsePubKey(pubk) if err != nil { - h.logger.Error("save act pod failed: ", err) + h.logger.Error("create grantee failed: ", err) jsonhttp.BadRequest(w, &response{Message: err.Error()}) return } - w.WriteHeader(http.StatusOK) -} -func (h *Handler) ACTSharedPods(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) - if err != nil { - h.logger.Errorf("sessionId parse failed: ", err) - jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) - return - } - if sessionId == "" { - h.logger.Error("sessionId not set: ", err) - jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) - return - } - vars := mux.Vars(r) - actName := vars["actName"] - - list, err := h.dfsAPI.GetACTContents(sessionId, actName) + err = h.dfsAPI.CreateGranteePublicKey(sessionId, actName, pub.ToECDSA()) if err != nil { - h.logger.Error("list contents failed: ", err) + h.logger.Error("create grantee failed: ", err) jsonhttp.BadRequest(w, &response{Message: err.Error()}) return } - - jsonhttp.OK(w, list) + jsonhttp.Created(w, &response{Message: "act created"}) } +// GrantRevokeHandler godoc +// +// @Summary Grant ACT with grantee public key +// @Description GrantRevokeHandler is the api handler for granting and revoking access in an existing act. +// @ID grant-revoke-act +// @Tags act +// @Produce json +// @Param actName path string true "unique act identifier" +// @Param grant query string false "grantee public key" +// @Param revoke query string false "revoke public key" +// @Param Cookie header string true "cookie parameter" +// @Success 200 {object} response +// @Failure 400 {object} response +// @Failure 500 {object} response +// @Router /v1/act/grantee/{actName} [patch] func (h *Handler) GrantRevokeHandler(w http.ResponseWriter, r *http.Request) { sessionId, err := auth.GetSessionIdFromGitRequest(r) if err != nil { @@ -198,6 +151,60 @@ func (h *Handler) GrantRevokeHandler(w http.ResponseWriter, r *http.Request) { } w.WriteHeader(http.StatusOK) } + +// ListGranteesHandler godoc +// +// @Summary List grantees in ACT +// @Description ListGranteesHandler is the api handler for listing grantees in an existing act. +// @ID list-grantee-act +// @Tags act +// @Produce json +// @Param actName path string true "unique act identifier" +// @Param Cookie header string true "cookie parameter" +// @Success 200 {object} []string +// @Failure 400 {object} response +// @Failure 500 {object} response +// @Router /v1/act/grantee/{actName} [get] +func (h *Handler) ListGranteesHandler(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + + vars := mux.Vars(r) + actName := vars["actName"] + + grantees, err := h.dfsAPI.ListGrantees(sessionId, actName) + if err != nil { + h.logger.Error("list grantees failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + + jsonhttp.OK(w, grantees) +} + +// ACTPodShareHandler godoc +// +// @Summary share a pod in act +// @Description ACTPodShareHandler is the api handler for adding a pod in act. +// @ID share-pod-act +// @Tags act +// @Produce json +// @Param actName path string true "unique act identifier" +// @Param podname path string true "pod to share in act" +// @Param Cookie header string true "cookie parameter" +// @Success 200 {object} response +// @Failure 400 {object} response +// @Failure 500 {object} response +// @Router /v1/act/share-pod/{actName}/{podname} [post] func (h *Handler) ACTPodShareHandler(w http.ResponseWriter, r *http.Request) { sessionId, err := auth.GetSessionIdFromGitRequest(r) if err != nil { @@ -221,10 +228,22 @@ func (h *Handler) ACTPodShareHandler(w http.ResponseWriter, r *http.Request) { jsonhttp.BadRequest(w, &response{Message: err.Error()}) return } - w.WriteHeader(http.StatusOK) + jsonhttp.OK(w, &response{Message: "pod shared"}) } -func (h *Handler) CreateGranteeHandler(w http.ResponseWriter, r *http.Request) { +// ACTListHandler godoc +// +// @Summary List acts +// @Description ACTListHandler is the api handler for listing acts. +// @ID list-act +// @Tags act +// @Produce json +// @Param Cookie header string true "cookie parameter" +// @Success 200 {object} act.List +// @Failure 400 {object} response +// @Failure 500 {object} response +// @Router /v1/act/list [get] +func (h *Handler) ACTListHandler(w http.ResponseWriter, r *http.Request) { sessionId, err := auth.GetSessionIdFromGitRequest(r) if err != nil { h.logger.Errorf("sessionId parse failed: ", err) @@ -237,27 +256,141 @@ func (h *Handler) CreateGranteeHandler(w http.ResponseWriter, r *http.Request) { return } + list, err := h.dfsAPI.GetACTs(sessionId) + if err != nil { + h.logger.Error("list acts failed: ", err) + jsonhttp.BadRequest(w, &response{Message: err.Error()}) + return + } + + jsonhttp.OK(w, list) +} + +// ACTSharedPods godoc +// +// @Summary List pods in act +// @Description ACTSharedPods is the api handler for listing pods shared in act. +// @ID list-shared-pod-act +// @Tags act +// @Produce json +// @Param actName path string true "unique act identifier" +// @Param Cookie header string true "cookie parameter" +// @Success 200 {object} []act.Content +// @Failure 400 {object} response +// @Failure 500 {object} response +// @Router /v1/act/act-shared-pods [get] +func (h *Handler) ACTSharedPods(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } vars := mux.Vars(r) actName := vars["actName"] - userPublicKeyString := r.URL.Query().Get("grantee") - pubk, err := hex.DecodeString(userPublicKeyString) + list, err := h.dfsAPI.GetACTContents(sessionId, actName) if err != nil { - h.logger.Error("create grantee failed: ", err) + h.logger.Error("list contents failed: ", err) jsonhttp.BadRequest(w, &response{Message: err.Error()}) return } - pub, err := btcec.ParsePubKey(pubk) + + jsonhttp.OK(w, list) +} + +// ACTOpenPod godoc +// +// @Summary Open Act pod +// @Description ACTOpenPod is the api handler for opening pod in act. +// @ID open-pod-act +// @Tags act +// @Produce json +// @Param actName path string true "unique act identifier" +// @Param Cookie header string true "cookie parameter" +// @Success 200 {object} response +// @Failure 400 {object} response +// @Failure 500 {object} response +// @Router /v1/act/open-act-pod/{actName} [post] +func (h *Handler) ACTOpenPod(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) if err != nil { - h.logger.Error("create grantee failed: ", err) + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + vars := mux.Vars(r) + actName := vars["actName"] + + err = h.dfsAPI.OpenACTPod(sessionId, actName) + if err != nil { + h.logger.Error("open act pod failed: ", err) jsonhttp.BadRequest(w, &response{Message: err.Error()}) return } - err = h.dfsAPI.CreateGranteePublicKey(sessionId, actName, pub.ToECDSA()) + jsonhttp.OK(w, &response{Message: "pod opened"}) +} + +// ACTSavePod godoc +// +// @Summary Save shared acted pod in act list +// @Description ACTSavePod is the api handler for saving shared act pod. +// @ID save-pod-act +// @Tags act +// @Produce json +// @Param actName path string true "unique act identifier" +// @Param content body act.Content true "acted pod info" +// @Param Cookie header string true "cookie parameter" +// @Success 200 {object} response +// @Failure 400 {object} response +// @Failure 500 {object} response +// @Router /v1/act/save-act-pod/{actName} [post] +func (h *Handler) ACTSavePod(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) if err != nil { - h.logger.Error("create grantee failed: ", err) + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + vars := mux.Vars(r) + actName := vars["actName"] + + contentType := r.Header.Get("Content-Type") + if contentType != jsonContentType { + h.logger.Errorf("save act pod: invalid request body type") + jsonhttp.BadRequest(w, &response{Message: "save act pod: invalid request body type"}) + return + } + + decoder := json.NewDecoder(r.Body) + var saveReq act.Content + err = decoder.Decode(&saveReq) + if err != nil { + h.logger.Errorf("save act pod: could not decode arguments") + jsonhttp.BadRequest(w, &response{Message: "save act pod: could not decode arguments"}) + return + } + + err = h.dfsAPI.SaveACTPod(sessionId, actName, &saveReq) + if err != nil { + h.logger.Error("save act pod failed: ", err) jsonhttp.BadRequest(w, &response{Message: err.Error()}) return } - w.WriteHeader(http.StatusOK) + jsonhttp.OK(w, &response{Message: "pod saved"}) } diff --git a/pkg/dfs/act_api.go b/pkg/dfs/act_api.go index 8c2a0bd8..b9a3541c 100644 --- a/pkg/dfs/act_api.go +++ b/pkg/dfs/act_api.go @@ -3,6 +3,8 @@ package dfs import ( "crypto/ecdsa" + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" + "github.com/ethersphere/bee/v2/pkg/swarm" "github.com/fairdatasociety/fairOS-dfs/pkg/act" ) @@ -62,6 +64,31 @@ func (a *API) ACTPodShare(sessionId, podName, actName string) error { return err } +func (a *API) OpenACTPod(sessionId, actName string) error { + ui := a.users.GetLoggedInUserInfo(sessionId) + if ui == nil { + return ErrUserNotLoggedIn + } + + actList := ui.GetACTList() + addr, err := actList.GetPodAccess(actName) + if err != nil { + return err + } + + info, err := ui.GetPod().ReceivePodInfo(utils.NewReference(addr.Bytes())) + if err != nil { + return err + } + + _, err = ui.GetPod().OpenFromShareInfo(info) + if err != nil { + return err + } + + return err +} + func (a *API) GetACTs(sessionId string) (act.List, error) { // get the loggedin user information ui := a.users.GetLoggedInUserInfo(sessionId) diff --git a/pkg/pod/open.go b/pkg/pod/open.go index c83cee87..e04346c3 100644 --- a/pkg/pod/open.go +++ b/pkg/pod/open.go @@ -147,12 +147,6 @@ func (p *Pod) OpenFromShareInfo(si *ShareInfo) (*Info, error) { } p.addPodToPodMap(si.PodName, podInfo) - // sync the pod's files and directories - err := p.SyncPod(si.PodName) - if err != nil && err != d.ErrResourceDeleted { // skipcq: TCV-001 - return nil, err - } - return podInfo, nil } diff --git a/pkg/test/subscription_test.go b/pkg/test/subscription_test.go index 86d82e28..195d7a32 100644 --- a/pkg/test/subscription_test.go +++ b/pkg/test/subscription_test.go @@ -150,7 +150,10 @@ func TestSubscription(t *testing.T) { dirObject := pi.GetDirectory() - dirInode1 := dirObject.GetDirFromDirectoryMap("/parentDir/subDir1") + dirInode1, err := dirObject.GetInode(pi.GetPodPassword(), "/parentDir/subDir1") + if err != nil { + t.Fatal(err) + } if dirInode1 == nil { t.Fatalf("invalid dir entry") } @@ -161,10 +164,11 @@ func TestSubscription(t *testing.T) { if dirInode1.Meta.Name != "subDir1" { t.Fatalf("invalid dir entry") } - dirInode2 := dirObject.GetDirFromDirectoryMap("/parentDir/subDir2") - if dirInode2 == nil { - t.Fatalf("invalid dir entry") + dirInode2, err := dirObject.GetInode(pi.GetPodPassword(), "/parentDir/subDir2") + if err != nil { + t.Fatal(err) } + if dirInode2.Meta.Path != "/parentDir" { t.Fatalf("invalid path entry") } diff --git a/swagger/docs.go b/swagger/docs.go index f038ac2e..50392bd6 100644 --- a/swagger/docs.go +++ b/swagger/docs.go @@ -289,6 +289,421 @@ const docTemplate = `{ } } }, + "/v1/act/act-shared-pods": { + "get": { + "description": "ACTSharedPods is the api handler for listing pods shared in act.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "List pods in act", + "operationId": "list-shared-pod-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/act.Content" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, + "/v1/act/grantee/{actName}": { + "get": { + "description": "ListGranteesHandler is the api handler for listing grantees in an existing act.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "List grantees in ACT", + "operationId": "list-grantee-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + }, + "post": { + "description": "CreateGranteeHandler is the api handler for creating act with grantee public key.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "Create ACT with grantee public key", + "operationId": "create-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "grantee public key", + "name": "grantee", + "in": "query", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + }, + "patch": { + "description": "GrantRevokeHandler is the api handler for granting and revoking access in an existing act.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "Grant ACT with grantee public key", + "operationId": "grant-revoke-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "grantee public key", + "name": "grant", + "in": "query" + }, + { + "type": "string", + "description": "revoke public key", + "name": "revoke", + "in": "query" + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, + "/v1/act/list": { + "get": { + "description": "ACTListHandler is the api handler for listing acts.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "List acts", + "operationId": "list-act", + "parameters": [ + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/act.List" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, + "/v1/act/open-act-pod/{actName}": { + "post": { + "description": "ACTOpenPod is the api handler for opening pod in act.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "Open Act pod", + "operationId": "open-pod-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, + "/v1/act/save-act-pod/{actName}": { + "post": { + "description": "ACTSavePod is the api handler for saving shared act pod.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "Save shared acted pod in act list", + "operationId": "save-pod-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "description": "acted pod info", + "name": "content", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/act.Content" + } + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, + "/v1/act/share-pod/{actName}/{podname}": { + "post": { + "description": "ACTPodShareHandler is the api handler for adding a pod in act.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "share a pod in act", + "operationId": "share-pod-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "pod to share in act", + "name": "podname", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, "/v1/dir/chmod": { "post": { "description": "DirectoryModeHandler is the api handler to change mode of a directory", @@ -4770,6 +5185,67 @@ const docTemplate = `{ } }, "definitions": { + "act.Act": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/act.Content" + } + }, + "createdAt": { + "type": "string" + }, + "granteesRef": { + "type": "array", + "items": { + "type": "integer" + } + }, + "historyRef": { + "type": "array", + "items": { + "type": "integer" + } + }, + "name": { + "type": "string" + } + } + }, + "act.Content": { + "type": "object", + "properties": { + "addedAt": { + "type": "string" + }, + "owner": { + "type": "array", + "items": { + "type": "integer" + } + }, + "ownerPublicKey": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "topic": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, + "act.List": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/act.Act" + } + }, "api.Collection": { "type": "object", "properties": { diff --git a/swagger/swagger.json b/swagger/swagger.json index 928f9ecf..75b1c10e 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -280,6 +280,421 @@ } } }, + "/v1/act/act-shared-pods": { + "get": { + "description": "ACTSharedPods is the api handler for listing pods shared in act.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "List pods in act", + "operationId": "list-shared-pod-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/act.Content" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, + "/v1/act/grantee/{actName}": { + "get": { + "description": "ListGranteesHandler is the api handler for listing grantees in an existing act.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "List grantees in ACT", + "operationId": "list-grantee-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + }, + "post": { + "description": "CreateGranteeHandler is the api handler for creating act with grantee public key.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "Create ACT with grantee public key", + "operationId": "create-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "grantee public key", + "name": "grantee", + "in": "query", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + }, + "patch": { + "description": "GrantRevokeHandler is the api handler for granting and revoking access in an existing act.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "Grant ACT with grantee public key", + "operationId": "grant-revoke-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "grantee public key", + "name": "grant", + "in": "query" + }, + { + "type": "string", + "description": "revoke public key", + "name": "revoke", + "in": "query" + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, + "/v1/act/list": { + "get": { + "description": "ACTListHandler is the api handler for listing acts.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "List acts", + "operationId": "list-act", + "parameters": [ + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/act.List" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, + "/v1/act/open-act-pod/{actName}": { + "post": { + "description": "ACTOpenPod is the api handler for opening pod in act.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "Open Act pod", + "operationId": "open-pod-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, + "/v1/act/save-act-pod/{actName}": { + "post": { + "description": "ACTSavePod is the api handler for saving shared act pod.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "Save shared acted pod in act list", + "operationId": "save-pod-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "description": "acted pod info", + "name": "content", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/act.Content" + } + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, + "/v1/act/share-pod/{actName}/{podname}": { + "post": { + "description": "ACTPodShareHandler is the api handler for adding a pod in act.", + "produces": [ + "application/json" + ], + "tags": [ + "act" + ], + "summary": "share a pod in act", + "operationId": "share-pod-act", + "parameters": [ + { + "type": "string", + "description": "unique act identifier", + "name": "actName", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "pod to share in act", + "name": "podname", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "cookie parameter", + "name": "Cookie", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/api.response" + } + } + } + } + }, "/v1/dir/chmod": { "post": { "description": "DirectoryModeHandler is the api handler to change mode of a directory", @@ -4761,6 +5176,67 @@ } }, "definitions": { + "act.Act": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/definitions/act.Content" + } + }, + "createdAt": { + "type": "string" + }, + "granteesRef": { + "type": "array", + "items": { + "type": "integer" + } + }, + "historyRef": { + "type": "array", + "items": { + "type": "integer" + } + }, + "name": { + "type": "string" + } + } + }, + "act.Content": { + "type": "object", + "properties": { + "addedAt": { + "type": "string" + }, + "owner": { + "type": "array", + "items": { + "type": "integer" + } + }, + "ownerPublicKey": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "topic": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, + "act.List": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/act.Act" + } + }, "api.Collection": { "type": "object", "properties": { diff --git a/swagger/swagger.yaml b/swagger/swagger.yaml index 1b65a89e..754b71c3 100644 --- a/swagger/swagger.yaml +++ b/swagger/swagger.yaml @@ -1,4 +1,44 @@ definitions: + act.Act: + properties: + content: + items: + $ref: '#/definitions/act.Content' + type: array + createdAt: + type: string + granteesRef: + items: + type: integer + type: array + historyRef: + items: + type: integer + type: array + name: + type: string + type: object + act.Content: + properties: + addedAt: + type: string + owner: + items: + type: integer + type: array + ownerPublicKey: + type: string + reference: + type: string + topic: + items: + type: integer + type: array + type: object + act.List: + additionalProperties: + $ref: '#/definitions/act.Act' + type: object api.Collection: properties: indexes: @@ -821,6 +861,289 @@ paths: summary: download file from a shared pod tags: - public + /v1/act/act-shared-pods: + get: + description: ACTSharedPods is the api handler for listing pods shared in act. + operationId: list-shared-pod-act + parameters: + - description: unique act identifier + in: path + name: actName + required: true + type: string + - description: cookie parameter + in: header + name: Cookie + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/act.Content' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/api.response' + summary: List pods in act + tags: + - act + /v1/act/grantee/{actName}: + get: + description: ListGranteesHandler is the api handler for listing grantees in + an existing act. + operationId: list-grantee-act + parameters: + - description: unique act identifier + in: path + name: actName + required: true + type: string + - description: cookie parameter + in: header + name: Cookie + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + type: string + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/api.response' + summary: List grantees in ACT + tags: + - act + patch: + description: GrantRevokeHandler is the api handler for granting and revoking + access in an existing act. + operationId: grant-revoke-act + parameters: + - description: unique act identifier + in: path + name: actName + required: true + type: string + - description: grantee public key + in: query + name: grant + type: string + - description: revoke public key + in: query + name: revoke + type: string + - description: cookie parameter + in: header + name: Cookie + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/api.response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/api.response' + summary: Grant ACT with grantee public key + tags: + - act + post: + description: CreateGranteeHandler is the api handler for creating act with grantee + public key. + operationId: create-act + parameters: + - description: unique act identifier + in: path + name: actName + required: true + type: string + - description: grantee public key + in: query + name: grantee + required: true + type: string + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/api.response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/api.response' + summary: Create ACT with grantee public key + tags: + - act + /v1/act/list: + get: + description: ACTListHandler is the api handler for listing acts. + operationId: list-act + parameters: + - description: cookie parameter + in: header + name: Cookie + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/act.List' + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/api.response' + summary: List acts + tags: + - act + /v1/act/open-act-pod/{actName}: + post: + description: ACTOpenPod is the api handler for opening pod in act. + operationId: open-pod-act + parameters: + - description: unique act identifier + in: path + name: actName + required: true + type: string + - description: cookie parameter + in: header + name: Cookie + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/api.response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/api.response' + summary: Open Act pod + tags: + - act + /v1/act/save-act-pod/{actName}: + post: + description: ACTSavePod is the api handler for saving shared act pod. + operationId: save-pod-act + parameters: + - description: unique act identifier + in: path + name: actName + required: true + type: string + - description: acted pod info + in: body + name: content + required: true + schema: + $ref: '#/definitions/act.Content' + - description: cookie parameter + in: header + name: Cookie + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/api.response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/api.response' + summary: Save shared acted pod in act list + tags: + - act + /v1/act/share-pod/{actName}/{podname}: + post: + description: ACTPodShareHandler is the api handler for adding a pod in act. + operationId: share-pod-act + parameters: + - description: unique act identifier + in: path + name: actName + required: true + type: string + - description: pod to share in act + in: path + name: podname + required: true + type: string + - description: cookie parameter + in: header + name: Cookie + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/api.response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/api.response' + summary: share a pod in act + tags: + - act /v1/dir/chmod: post: consumes: From a8f42ab671ca96b477d989903c707864f5d8da8a Mon Sep 17 00:00:00 2001 From: asabya Date: Wed, 23 Oct 2024 16:07:38 +0530 Subject: [PATCH 06/14] fix: windows port issue --- .github/workflows/go.yml | 8 ++++++++ pkg/dir/chmod_test.go | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 15baaa60..56e84d6c 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -41,6 +41,14 @@ jobs: - name: Lint if: matrix.os == 'ubuntu-latest' run: make lint + - name: Set up port range and TIME_WAIT + if: matrix.os == 'windows-latest' + run: | + # Increase the dynamic port range + New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name MaxUserPort -Value 65534 -PropertyType DWord -Force + # Decrease the TIME_WAIT duration + New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name TcpTimedWaitDelay -Value 30 -PropertyType DWord -Force + shell: pwsh - name: Vet if: matrix.os == 'ubuntu-latest' run: make vet diff --git a/pkg/dir/chmod_test.go b/pkg/dir/chmod_test.go index bd5d87e5..1c2925da 100644 --- a/pkg/dir/chmod_test.go +++ b/pkg/dir/chmod_test.go @@ -85,7 +85,6 @@ func TestChmod(t *testing.T) { if err != nil { t.Fatal(err) } - fmt.Println(3) // stat the directory dirStats, err := dirObject.DirStat("pod1", podPassword, "/dirToChmod") @@ -96,19 +95,16 @@ func TestChmod(t *testing.T) { if fmt.Sprintf("%o", dir.S_IFDIR|0700) != fmt.Sprintf("%o", dirStats.Mode) { t.Fatal("default mode mismatch") } - fmt.Println(4) err = dirObject.Chmod("/dirToChmod", podPassword, 0664) if err != nil { t.Fatal(err) } - fmt.Println(5) dirStats, err = dirObject.DirStat("pod1", podPassword, "/dirToChmod") if err != nil { t.Fatal(err) } - fmt.Println(6) if fmt.Sprintf("%o", dir.S_IFDIR|0664) != fmt.Sprintf("%o", dirStats.Mode) { t.Fatal("updated mode mismatch") From dcec20e64b615ed01557d5997961dc55c5fd5faa Mon Sep 17 00:00:00 2001 From: asabya Date: Wed, 23 Oct 2024 17:39:04 +0530 Subject: [PATCH 07/14] fix: windows port issue --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 56e84d6c..2610e07b 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -47,7 +47,7 @@ jobs: # Increase the dynamic port range New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name MaxUserPort -Value 65534 -PropertyType DWord -Force # Decrease the TIME_WAIT duration - New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name TcpTimedWaitDelay -Value 30 -PropertyType DWord -Force + New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name TcpTimedWaitDelay -Value 3 -PropertyType DWord -Force shell: pwsh - name: Vet if: matrix.os == 'ubuntu-latest' From 6141ee809e030694b6606caec0e8c655e8503cd5 Mon Sep 17 00:00:00 2001 From: asabya Date: Thu, 24 Oct 2024 13:24:10 +0530 Subject: [PATCH 08/14] minor checks --- pkg/act/grant.go | 20 ++++++++++++++++++++ pkg/act/new.go | 8 ++++++++ 2 files changed, 28 insertions(+) diff --git a/pkg/act/grant.go b/pkg/act/grant.go index 9856db32..5310492a 100644 --- a/pkg/act/grant.go +++ b/pkg/act/grant.go @@ -14,6 +14,10 @@ import ( ) func (t *ACT) GrantAccess(actName string, address swarm.Address) (*Content, error) { + if actName == "" { + return nil, fmt.Errorf("act name is required") + } + t.mu.Lock() defer t.mu.Unlock() @@ -60,6 +64,10 @@ func (t *ACT) GrantAccess(actName string, address swarm.Address) (*Content, erro } func (t *ACT) GetPodAccess(actName string) (swarm.Address, error) { + if actName == "" { + return swarm.ZeroAddress, fmt.Errorf("act name is required") + } + t.mu.Lock() defer t.mu.Unlock() @@ -93,6 +101,10 @@ func (t *ACT) GetPodAccess(actName string) (swarm.Address, error) { } func (t *ACT) SaveGrantedPod(actName string, c *Content) error { + if actName == "" { + return fmt.Errorf("act name is required") + } + t.mu.Lock() defer t.mu.Unlock() @@ -121,6 +133,10 @@ func (t *ACT) SaveGrantedPod(actName string, c *Content) error { } func (t *ACT) GetGrantees(actName string) ([]string, error) { + if actName == "" { + return nil, fmt.Errorf("act name is required") + } + t.mu.Lock() defer t.mu.Unlock() @@ -140,6 +156,10 @@ func (t *ACT) GetGrantees(actName string) ([]string, error) { } func (t *ACT) GetContentList(actName string) ([]*Content, error) { + if actName == "" { + return nil, fmt.Errorf("act name is required") + } + t.mu.Lock() defer t.mu.Unlock() diff --git a/pkg/act/new.go b/pkg/act/new.go index dc040652..2e615c8b 100644 --- a/pkg/act/new.go +++ b/pkg/act/new.go @@ -38,6 +38,10 @@ type Content struct { } func (t *ACT) CreateUpdateACT(actName string, publicKeyGrant, publicKeyRevoke *ecdsa.PublicKey) (*Act, error) { + if actName == "" { + return nil, fmt.Errorf("act name is required") + } + t.mu.Lock() defer t.mu.Unlock() @@ -126,6 +130,10 @@ func (t *ACT) CreateUpdateACT(actName string, publicKeyGrant, publicKeyRevoke *e } func (t *ACT) GetACT(actName string) (*Act, error) { + if actName == "" { + return nil, fmt.Errorf("act name is required") + } + t.mu.Lock() defer t.mu.Unlock() From e29c12234680d4bb5e0550fa709ea43f006691f5 Mon Sep 17 00:00:00 2001 From: asabya Date: Fri, 25 Oct 2024 16:21:49 +0530 Subject: [PATCH 09/14] feat: act --- cmd/dfs-cli/cmd/act.go | 126 +++++++++++++++++ cmd/dfs-cli/cmd/fdfs-api.go | 1 - cmd/dfs-cli/cmd/filesystem.go | 5 +- cmd/dfs-cli/cmd/prompt.go | 124 +++++++++++++++++ cmd/dfs-cli/cmd/user.go | 11 +- cmd/dfs/cmd/dev.go | 2 +- cmd/dfs/cmd/server.go | 6 +- cmd/dfs/cmd/server_test.go | 254 +++++++++++++++++++++++++++++++++- pkg/api/act.go | 50 ++++--- pkg/dfs/act_api.go | 13 +- pkg/pod/open.go | 28 ++++ pkg/user/login.go | 5 +- pkg/user/new.go | 4 +- swagger/docs.go | 24 +++- swagger/swagger.json | 24 +++- swagger/swagger.yaml | 17 ++- 16 files changed, 649 insertions(+), 45 deletions(-) create mode 100644 cmd/dfs-cli/cmd/act.go diff --git a/cmd/dfs-cli/cmd/act.go b/cmd/dfs-cli/cmd/act.go new file mode 100644 index 00000000..27ff4d08 --- /dev/null +++ b/cmd/dfs-cli/cmd/act.go @@ -0,0 +1,126 @@ +package cmd + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" + + "github.com/fairdatasociety/fairOS-dfs/pkg/api" +) + +func actNew(actName, publicKey string) { + url := fmt.Sprintf("%s/%s?grantee=%s", actGrantee, actName, publicKey) + data, err := fdfsAPI.postReq(http.MethodPost, url, nil) + if err != nil { + fmt.Println("could not create act: ", err) + return + } + message := strings.ReplaceAll(string(data), "\n", "") + fmt.Println(message) +} + +func actGrantRevoke(actName, key, action string) { + url := fmt.Sprintf("%s/%s", actGrantee, actName) + switch action { + case "grant": + url = fmt.Sprintf("%s?grant=%s", url, key) + case "revoke": + url = fmt.Sprintf("%s?revoke=%s", url, key) + default: + fmt.Println("invalid action") + } + data, err := fdfsAPI.postReq(http.MethodPatch, url, nil) + if err != nil { + fmt.Println("could not create act: ", err) + return + } + message := strings.ReplaceAll(string(data), "\n", "") + fmt.Println(message) +} + +func actListGrantees(actName string) { + url := fmt.Sprintf("%s/%s", actGrantee, actName) + data, err := fdfsAPI.postReq(http.MethodGet, url, nil) + if err != nil { + fmt.Println("could not create act: ", err) + return + } + message := strings.ReplaceAll(string(data), "\n", "") + fmt.Println(message) +} + +func actPodShare(actName, podName string) { + url := fmt.Sprintf("%s/%s/%s", actSharePod, actName, podName) + data, err := fdfsAPI.postReq(http.MethodPost, url, nil) + if err != nil { + fmt.Println("could not create act: ", err) + return + } + message := strings.ReplaceAll(string(data), "\n", "") + fmt.Println(message) +} + +func actListAll() { + data, err := fdfsAPI.postReq(http.MethodGet, actList, nil) + if err != nil { + fmt.Println("could not create act: ", err) + return + } + message := strings.ReplaceAll(string(data), "\n", "") + fmt.Println(message) +} + +func actPodsShared(actName string) { + url := fmt.Sprintf("%s/%s", actSharedPods, actName) + data, err := fdfsAPI.postReq(http.MethodGet, url, nil) + if err != nil { + fmt.Println("could not create act: ", err) + return + } + message := strings.ReplaceAll(string(data), "\n", "") + fmt.Println(message) +} + +func actSaveSharedPod(actName, reference, topic, owner, ownerPublicKey string) { + url := fmt.Sprintf("%s/%s", actSavePod, actName) + topicBytes, err := base64.StdEncoding.DecodeString(topic) + if err != nil { + fmt.Println("could not save act: ", err) + return + } + content := &api.Content{ + Reference: reference, + Topic: topicBytes, + Owner: owner, + OwnerPublicKey: ownerPublicKey, + } + data, err := json.Marshal(content) + if err != nil { + fmt.Println("could not save act: ", err) + return + } + resp, err := fdfsAPI.postReq(http.MethodPost, url, data) + if err != nil { + fmt.Println("could not create act: ", err) + return + } + message := strings.ReplaceAll(string(resp), "\n", "") + fmt.Println(message) +} + +func actOpenSharedPod(actName string) { + url := fmt.Sprintf("%s/%s", actOpenPod, actName) + data, err := fdfsAPI.postReq(http.MethodPost, url, nil) + if err != nil { + fmt.Println("could not open act: ", err) + return + } + currentPod = "podone" + currentDirectory = utils.PathSeparator + message := strings.ReplaceAll(string(data), "\n", "") + fmt.Println(message) +} diff --git a/cmd/dfs-cli/cmd/fdfs-api.go b/cmd/dfs-cli/cmd/fdfs-api.go index 5467c882..1ee16aa2 100644 --- a/cmd/dfs-cli/cmd/fdfs-api.go +++ b/cmd/dfs-cli/cmd/fdfs-api.go @@ -125,7 +125,6 @@ func (s *fdfsClient) postReq(method, urlPath string, jsonBytes []byte) ([]byte, return nil, err } } - if s.getAccessToken() != "" { req.Header.Add("Authorization", "Bearer "+s.getAccessToken()) } diff --git a/cmd/dfs-cli/cmd/filesystem.go b/cmd/dfs-cli/cmd/filesystem.go index 28f5816f..5fa12bfc 100644 --- a/cmd/dfs-cli/cmd/filesystem.go +++ b/cmd/dfs-cli/cmd/filesystem.go @@ -236,10 +236,7 @@ func downloadFile(podName, localFileName, podFileName string) { fmt.Println("download failed: ", err) return } - if err = out.Close(); err != nil { - fmt.Println("download failed: ", err) - return - } + defer out.Close() args := make(map[string]string) args["podName"] = podName diff --git a/cmd/dfs-cli/cmd/prompt.go b/cmd/dfs-cli/cmd/prompt.go index c7c5f258..7c4da7b0 100644 --- a/cmd/dfs-cli/cmd/prompt.go +++ b/cmd/dfs-cli/cmd/prompt.go @@ -101,6 +101,12 @@ const ( apiUserSignatureLogin = apiVersionV2 + "/user/login-with-signature" apiUserPresentV2 = apiVersionV2 + "/user/present" apiUserDeleteV2 = apiVersionV2 + "/user/delete" + actGrantee = apiVersion + "/act/grantee" + actSharePod = apiVersion + "/act/share-pod" + actList = apiVersion + "/act/list" + actSharedPods = apiVersion + "/act/act-shared-pods" + actSavePod = apiVersion + "/act/save-act-pod" + actOpenPod = apiVersion + "/act/open-act-pod" ) func newPrompt() { @@ -187,6 +193,17 @@ var docSuggestions = []prompt.Suggest{ {Text: "loadjson", Description: "load the json file in to the newly created document db"}, } +var actSuggestions = []prompt.Suggest{ + {Text: "new", Description: "creates a new act"}, + {Text: "grantRevoke", Description: "grant nad revoke users in act"}, + {Text: "lsGrantees", Description: "list all grantees in act"}, + {Text: "share", Description: "share a pod in act"}, + {Text: "ls", Description: "list all acts"}, + {Text: "lsContent", Description: "list all pods shared in act"}, + {Text: "save", Description: "save shared act"}, + {Text: "open", Description: "open act pod"}, +} + var suggestions = []prompt.Suggest{ {Text: "user new", Description: "create a new user"}, {Text: "user del", Description: "delete a existing user"}, @@ -238,6 +255,14 @@ var suggestions = []prompt.Suggest{ {Text: "rmdir", Description: "remove a existing directory"}, {Text: "pwd", Description: "show the current working directory"}, {Text: "rm", Description: "remove a file"}, + {Text: "act new", Description: "creates a new act"}, + {Text: "act grantRevoke", Description: "grant nad revoke users in act"}, + {Text: "act lsGrantees", Description: "list all grantees in act"}, + {Text: "act share", Description: "share a pod in act"}, + {Text: "act ls", Description: "list all acts"}, + {Text: "act lsContent", Description: "list all pods shared in act"}, + {Text: "act save", Description: "save shared act"}, + {Text: "act open", Description: "open act pod"}, } func completer(in prompt.Document) []prompt.Suggest { @@ -254,6 +279,8 @@ func completer(in prompt.Document) []prompt.Suggest { return prompt.FilterHasPrefix(kvSuggestions, in.GetWordBeforeCursor(), true) } else if strings.HasPrefix(in.TextBeforeCursor(), "doc") { return prompt.FilterHasPrefix(docSuggestions, in.GetWordBeforeCursor(), true) + } else if strings.HasPrefix(in.TextBeforeCursor(), "act") { + return prompt.FilterHasPrefix(actSuggestions, in.GetWordBeforeCursor(), true) } return prompt.FilterHasPrefix(suggestions, w, true) } @@ -282,6 +309,7 @@ func executor(in string) { case "new": if len(blocks) < 3 { fmt.Println("invalid command. Missing \"userName\" argument") + fmt.Println("\nuser new ") return } userName := blocks[2] @@ -303,6 +331,7 @@ func executor(in string) { case "login": if len(blocks) < 3 { fmt.Println("invalid command. Missing \"userName\" argument") + fmt.Println("\nuser login ") return } userName := blocks[2] @@ -313,6 +342,7 @@ func executor(in string) { case "signatureLogin": if len(blocks) < 3 { fmt.Println("invalid command. Missing \"signature\" argument") + fmt.Println("\nuser signatureLogin ") return } signature := blocks[2] @@ -324,6 +354,7 @@ func executor(in string) { case "present": if len(blocks) < 3 { fmt.Println("invalid command. Missing \"userName\" argument") + fmt.Println("\nuser present ") return } userName := blocks[2] @@ -332,6 +363,7 @@ func executor(in string) { case "del": if currentUser == "" { fmt.Println("please login as user to do the operation") + fmt.Println("\nuser del") return } deleteUser(apiUserDeleteV2) @@ -342,6 +374,7 @@ func executor(in string) { case "logout": if currentUser == "" { fmt.Println("please login as user to do the operation") + fmt.Println("\nuser logout") return } logoutUser() @@ -352,6 +385,7 @@ func executor(in string) { case "loggedin": if len(blocks) < 3 { fmt.Println("invalid command. Missing \"userName\" argument") + fmt.Println("\nuser loggedin ") return } userName := blocks[2] @@ -360,6 +394,7 @@ func executor(in string) { case "stat": if currentUser == "" { fmt.Println("please login as user to do the operation") + fmt.Println("\nuser stat") return } statUser() @@ -381,6 +416,7 @@ func executor(in string) { case "new": if len(blocks) < 3 { fmt.Println("invalid command. Missing \"podName\" argument") + fmt.Println("\npod new ") return } podName := blocks[2] @@ -389,6 +425,7 @@ func executor(in string) { case "del": if len(blocks) < 3 { fmt.Println("invalid command. Missing \"podName\" argument") + fmt.Println("\npod del ") return } podName := blocks[2] @@ -399,6 +436,7 @@ func executor(in string) { case "open": if len(blocks) < 3 { fmt.Println("invalid command. Missing \"podName\" argument") + fmt.Println("\npod open ") return } podName := blocks[2] @@ -418,6 +456,7 @@ func executor(in string) { } if len(blocks) < 3 { fmt.Println("invalid command. Missing \"podName\" argument") + fmt.Println("\npod stat ") return } podName := blocks[2] @@ -891,6 +930,7 @@ func executor(in string) { } if len(blocks) < 4 { fmt.Println("invalid command. Missing one or more arguments") + fmt.Println("\nupload ") return } fileName := filepath.Base(blocks[1]) @@ -915,6 +955,7 @@ func executor(in string) { } if len(blocks) < 3 { fmt.Println("invalid command. Missing one or more arguments") + fmt.Println("\ndownload ") return } localDir := blocks[1] @@ -1025,6 +1066,80 @@ func executor(in string) { sharingRefString := blocks[1] fileReceiveInfo(currentPod, sharingRefString) currentPrompt = getCurrentPrompt() + case "act": + if currentUser == "" { + fmt.Println("login as a user to execute these commands") + return + } + if len(blocks) < 2 { + log.Println("invalid command.") + help() + return + } + switch blocks[1] { + case "new": + if len(blocks) < 4 { + fmt.Println("invalid command. Missing \"actName\" argument") + return + } + actName := blocks[2] + grantee := blocks[3] + actNew(actName, grantee) + + case "grantRevoke": + if len(blocks) < 5 { + fmt.Println("invalid command. Missing \"actName\", \"public-key\", \"action\" argument") + return + } + actName := blocks[2] + key := blocks[3] + action := blocks[4] + actGrantRevoke(actName, key, action) + case "lsGrantees": + if len(blocks) < 3 { + fmt.Println("invalid command. Missing \"actName\" argument") + return + } + actName := blocks[2] + actListGrantees(actName) + case "share": + if len(blocks) < 4 { + fmt.Println("invalid command. Missing \"actName\" argument") + return + } + actName := blocks[2] + podName := blocks[3] + actPodShare(actName, podName) + case "ls": + actListAll() + case "lsContent": + if len(blocks) < 3 { + fmt.Println("invalid command. Missing \"actName\" argument") + return + } + actName := blocks[2] + actPodsShared(actName) + case "save": + if len(blocks) < 7 { + fmt.Println("invalid command. Missing arguments") + fmt.Println("act (act-name) (reference) (topic) (owner-address) (owner-public-key)") + return + } + actName := blocks[2] + reference := blocks[3] + topic := blocks[4] + ownerAddress := blocks[5] + ownerPublicKey := blocks[6] + actSaveSharedPod(actName, reference, topic, ownerAddress, ownerPublicKey) + case "open": + if len(blocks) < 3 { + fmt.Println("invalid command. Missing \"actName\" argument") + return + } + actName := blocks[2] + actOpenSharedPod(actName) + currentPrompt = getCurrentPrompt() + } default: fmt.Println("invalid command") } @@ -1093,6 +1208,15 @@ func help() { fmt.Println(" - help - display this help") fmt.Println(" - exit - exits from the prompt") + fmt.Println(" - act (act-name) (grantee-public-key) - creates a new act") + fmt.Println(" - act (act-name) (public-key) (action) - grant or revoke user in act") + fmt.Println(" - act - list all grantees") + fmt.Println(" - act (act-name) (pod-name)- share a pod in act") + fmt.Println(" - act - list all acts") + fmt.Println(" - act (act-name) - list all pods shared in act") + fmt.Println(" - act (act-name) (reference) (topic) (owner-address) (owner-public-key) - save shared act") + fmt.Println(" - act (act-name) - open act pod") + } func getCurrentPrompt() string { diff --git a/cmd/dfs-cli/cmd/user.go b/cmd/dfs-cli/cmd/user.go index 66f3e81e..2fbec04b 100644 --- a/cmd/dfs-cli/cmd/user.go +++ b/cmd/dfs-cli/cmd/user.go @@ -66,7 +66,12 @@ func userNew(userName, mnemonic string) { fmt.Println("Please store the 12 words mnemonic safely") fmt.Println("if you loose that, you cannot recover the data in-case of an emergency.") fmt.Println("you can also use that mnemonic to access the data in-case this device is lost") - + fmt.Println("=============== Mnemonic Start ==========================") + fmt.Println(resp.Mnemonic) + fmt.Println("=============== Mnemonic End ==========================") + fmt.Println("=============== PublicKey Start ==========================") + fmt.Println(resp.PublicKey) + fmt.Println("=============== PublicKey End ==========================") fdfsAPI.setAccessToken(resp.AccessToken) currentUser = userName @@ -94,7 +99,9 @@ func userLogin(userName, apiEndpoint string) { fmt.Println("create user: ", err) return } - + fmt.Println("=============== PublicKey Start ==========================") + fmt.Println(resp.PublicKey) + fmt.Println("=============== PublicKey End ==========================") currentUser = userName message := strings.ReplaceAll(string(data), "\n", "") fdfsAPI.setAccessToken(resp.AccessToken) diff --git a/cmd/dfs/cmd/dev.go b/cmd/dfs/cmd/dev.go index 617dffa1..842f36ce 100644 --- a/cmd/dfs/cmd/dev.go +++ b/cmd/dfs/cmd/dev.go @@ -55,7 +55,7 @@ func startDevServer() { }) fmt.Println("Bee running at: ", beeUrl) logger := logging.New(os.Stdout, logrus.DebugLevel) - mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy("0")) + mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy("0"), bee.WithPinning(true)) ens := mock2.NewMockNamespaceManager() users := user.NewUsers(mockClient, ens, -1, 0, logger) diff --git a/cmd/dfs/cmd/server.go b/cmd/dfs/cmd/server.go index c305c878..e0653240 100644 --- a/cmd/dfs/cmd/server.go +++ b/cmd/dfs/cmd/server.go @@ -457,16 +457,16 @@ func startHttpService(logger logging.Logger) *http.Server { gitRouter.HandleFunc("/{user}/{repo}.git/git-receive-pack", handler.GitReceivePack).Methods("POST") actRouter := baseRouter.PathPrefix("/act/").Subrouter() - actRouter.Use(handler.GitAuthMiddleware) + actRouter.Use(handler.LoginMiddleware) // list acts // owner actRouter.HandleFunc("/grantee/{actName}", handler.CreateGranteeHandler).Methods("POST") actRouter.HandleFunc("/grantee/{actName}", handler.GrantRevokeHandler).Methods("PATCH") actRouter.HandleFunc("/grantee/{actName}", handler.ListGranteesHandler).Methods("GET") - actRouter.HandleFunc("/share-pod/{actName}/{podname}", handler.ACTPodShareHandler).Methods("POST") + actRouter.HandleFunc("/share-pod/{actName}/{podName}", handler.ACTPodShareHandler).Methods("POST") actRouter.HandleFunc("/list", handler.ACTListHandler).Methods("GET") - actRouter.HandleFunc("/act-shared-pods", handler.ACTSharedPods).Methods("GET") + actRouter.HandleFunc("/act-shared-pods/{actName}", handler.ACTSharedPods).Methods("GET") // grantee actRouter.HandleFunc("/save-act-pod/{actName}", handler.ACTSavePod).Methods("POST") actRouter.HandleFunc("/open-act-pod/{actName}", handler.ACTOpenPod).Methods("POST") diff --git a/cmd/dfs/cmd/server_test.go b/cmd/dfs/cmd/server_test.go index 80202c07..4d5d8ed1 100644 --- a/cmd/dfs/cmd/server_test.go +++ b/cmd/dfs/cmd/server_test.go @@ -57,7 +57,7 @@ func TestApis(t *testing.T) { Post: mockpost.New(mockpost.WithAcceptAll()), }) - logger := logging.New(os.Stdout, logrus.PanicLevel) + logger := logging.New(os.Stdout, logrus.DebugLevel) mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) ens := mock2.NewMockNamespaceManager() @@ -1649,6 +1649,258 @@ func TestApis(t *testing.T) { } }) + t.Run("act-publisher", func(t *testing.T) { + c := http.Client{Timeout: time.Duration(1) * time.Minute} + userRequest := &common.UserSignupRequest{ + UserName: randStringRunes(16), + Password: randStringRunes(12), + } + + userTwoRequest := &common.UserSignupRequest{ + UserName: randStringRunes(16), + Password: randStringRunes(12), + } + + userBytes, err := json.Marshal(userRequest) + if err != nil { + t.Fatal(err) + } + + userTwoBytes, err := json.Marshal(userTwoRequest) + if err != nil { + t.Fatal(err) + } + userResps := []*api.UserSignupResponse{} + cookies := [][]string{} + + for _, user := range [][]byte{userBytes, userTwoBytes} { + signupRequestDataHttpReq, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", basev2, string(common.UserSignup)), bytes.NewBuffer(user)) + if err != nil { + t.Fatal(err) + } + signupRequestDataHttpReq.Header.Add("Content-Type", "application/json") + signupRequestDataHttpReq.Header.Add("Content-Length", strconv.Itoa(len(user))) + signupRequestResp, err := c.Do(signupRequestDataHttpReq) + if err != nil { + t.Fatal(err) + } + + err = signupRequestResp.Body.Close() + if err != nil { + t.Fatal(err) + } + if signupRequestResp.StatusCode != http.StatusCreated { + t.Fatal("Signup failed", signupRequestResp.StatusCode) + } + + userLoginHttpReq, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", basev2, string(common.UserLogin)), bytes.NewBuffer(user)) + if err != nil { + t.Fatal(err) + + } + userLoginHttpReq.Header.Add("Content-Type", "application/json") + userLoginHttpReq.Header.Add("Content-Length", strconv.Itoa(len(user))) + userLoginResp, err := c.Do(userLoginHttpReq) + if err != nil { + t.Fatal(err) + } + var resp api.UserSignupResponse + data, err := io.ReadAll(userLoginResp.Body) + if err != nil { + t.Fatal(err) + } + err = json.Unmarshal(data, &resp) + if err != nil { + t.Fatal(err) + } + userResps = append(userResps, &resp) + err = userLoginResp.Body.Close() + if err != nil { + t.Fatal(err) + } + if userLoginResp.StatusCode != http.StatusOK { + t.Fatal("user should be able to login") + } + cookie := userLoginResp.Header["Set-Cookie"] + cookies = append(cookies, cookie) + } + + // pod new + podRequest := &common.PodRequest{ + PodName: randStringRunes(16), + } + podBytes, err := json.Marshal(podRequest) + if err != nil { + t.Fatal(err) + } + podNewHttpReq, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", basev1, string(common.PodNew)), bytes.NewBuffer(podBytes)) + if err != nil { + t.Fatal(err) + } + podNewHttpReq.Header.Set("Cookie", cookies[0][0]) + podNewHttpReq.Header.Add("Content-Type", "application/json") + podNewHttpReq.Header.Add("Content-Length", strconv.Itoa(len(podBytes))) + podNewResp, err := c.Do(podNewHttpReq) + if err != nil { + t.Fatal(err) + } + + err = podNewResp.Body.Close() + if err != nil { + t.Fatal(err) + } + if podNewResp.StatusCode != 201 { + t.Fatal("pod creation failed") + } + + entries := []struct { + path string + isDir bool + size int64 + content []byte + }{ + { + path: "/file1", + size: 1024 * 1024, + }, + } + + for _, v := range entries { + + body := new(bytes.Buffer) + writer := multipart.NewWriter(body) + contentLength := fmt.Sprintf("%d", v.size) + + err = writer.WriteField("podName", podRequest.PodName) + if err != nil { + t.Fatal(err) + } + err = writer.WriteField("contentLength", contentLength) + if err != nil { + t.Fatal(err) + } + err = writer.WriteField("dirPath", filepath.Dir(v.path)) + if err != nil { + t.Fatal(err) + } + err = writer.WriteField("blockSize", "1Mb") + if err != nil { + t.Fatal(err) + } + part, err := writer.CreateFormFile("files", filepath.Base(v.path)) + if err != nil { + t.Fatal(err) + } + reader := &io.LimitedReader{R: rand.Reader, N: v.size} + _, err = io.Copy(part, reader) + if err != nil { + t.Fatal(err) + } + + err = writer.Close() + if err != nil { + t.Fatal(err) + } + + uploadReq, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", basev1, string(common.FileUpload)), body) + if err != nil { + t.Fatal(err) + + } + uploadReq.Header.Set("Cookie", cookies[0][0]) + contentType := fmt.Sprintf("multipart/form-data;boundary=%v", writer.Boundary()) + uploadReq.Header.Add("Content-Type", contentType) + uploadResp, err := c.Do(uploadReq) + if err != nil { + t.Fatal(err) + } + err = uploadResp.Body.Close() + if err != nil { + t.Fatal(err) + } + if uploadResp.StatusCode != 200 { + t.Fatal("upload failed") + } + } + <-time.After(time.Second * 2) + url := fmt.Sprintf("%s%s/%s?grantee=%s", basev1, "/act/grantee", "actone", userResps[1].PublicKey) + actCreateHttpReq, err := http.NewRequest(http.MethodPost, url, http.NoBody) + if err != nil { + t.Fatal(err) + } + actCreateHttpReq.Header.Set("Cookie", cookies[0][0]) + actCreateResp, err := c.Do(actCreateHttpReq) + if err != nil { + t.Fatal(err) + } + + _, err = io.ReadAll(actCreateResp.Body) + if err != nil { + t.Fatal(err) + } + + url = fmt.Sprintf("%s%s/%s/%s", basev1, "/act/share-pod", "actone", podRequest.PodName) + actSharePodHttpReq, err := http.NewRequest(http.MethodPost, url, http.NoBody) + if err != nil { + t.Fatal(err) + } + actSharePodHttpReq.Header.Set("Cookie", cookies[0][0]) + actSharePodResp, err := c.Do(actSharePodHttpReq) + if err != nil { + t.Fatal(err) + } + + actSharePodRespBytes, err := io.ReadAll(actSharePodResp.Body) + if err != nil { + t.Fatal(err) + } + content := &api.Content{} + + err = json.Unmarshal(actSharePodRespBytes, content) + if err != nil { + t.Fatal(err) + } + fmt.Println(content) + + url = fmt.Sprintf("%s%s/%s", basev1, "/act/save-act-pod", "actone") + actSavePodHttpReq, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(actSharePodRespBytes)) + if err != nil { + t.Fatal(err) + } + actSavePodHttpReq.Header.Set("Cookie", cookies[1][0]) + actSavePodHttpReq.Header.Add("Content-Type", "application/json") + actSavePodHttpReq.Header.Add("Content-Length", strconv.Itoa(len(actSharePodRespBytes))) + + actSavePodResp, err := c.Do(actSavePodHttpReq) + if err != nil { + t.Fatal(err) + } + + actSavePodRespBytes, err := io.ReadAll(actSavePodResp.Body) + if err != nil { + t.Fatal(err) + } + fmt.Println(string(actSavePodRespBytes)) + + url = fmt.Sprintf("%s%s/%s", basev1, "/act/open-act-pod", "actone") + actOpenPodHttpReq, err := http.NewRequest(http.MethodPost, url, http.NoBody) + if err != nil { + t.Fatal(err) + } + actOpenPodHttpReq.Header.Set("Cookie", cookies[1][0]) + + actOpenPodResp, err := c.Do(actOpenPodHttpReq) + if err != nil { + t.Fatal(err) + } + + actOpenPodRespBytes, err := io.ReadAll(actOpenPodResp.Body) + if err != nil { + t.Fatal(err) + } + fmt.Println(string(actOpenPodRespBytes)) + }) + t.Run("ws test", func(t *testing.T) { u := url.URL{Scheme: "ws", Host: base, Path: "/ws/v1/"} header := http.Header{} diff --git a/pkg/api/act.go b/pkg/api/act.go index 391fa15c..77cc779c 100644 --- a/pkg/api/act.go +++ b/pkg/api/act.go @@ -6,15 +6,22 @@ import ( "encoding/json" "net/http" - "github.com/fairdatasociety/fairOS-dfs/pkg/act" - "github.com/btcsuite/btcd/btcec/v2" + "github.com/fairdatasociety/fairOS-dfs/pkg/act" + "github.com/fairdatasociety/fairOS-dfs/pkg/utils" "github.com/fairdatasociety/fairOS-dfs/pkg/auth" "github.com/gorilla/mux" "resenje.org/jsonhttp" ) +type Content struct { + Reference string `json:"reference"` + Topic []byte `json:"topic"` + Owner string `json:"owner"` + OwnerPublicKey string `json:"ownerPublicKey"` +} + // CreateGranteeHandler godoc // // @Summary Create ACT with grantee public key @@ -29,7 +36,7 @@ import ( // @Failure 500 {object} response // @Router /v1/act/grantee/{actName} [post] func (h *Handler) CreateGranteeHandler(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) + sessionId, err := auth.GetSessionIdFromRequest(r) if err != nil { h.logger.Errorf("sessionId parse failed: ", err) jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) @@ -82,7 +89,7 @@ func (h *Handler) CreateGranteeHandler(w http.ResponseWriter, r *http.Request) { // @Failure 500 {object} response // @Router /v1/act/grantee/{actName} [patch] func (h *Handler) GrantRevokeHandler(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) + sessionId, err := auth.GetSessionIdFromRequest(r) if err != nil { h.logger.Errorf("sessionId parse failed: ", err) jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) @@ -166,7 +173,7 @@ func (h *Handler) GrantRevokeHandler(w http.ResponseWriter, r *http.Request) { // @Failure 500 {object} response // @Router /v1/act/grantee/{actName} [get] func (h *Handler) ListGranteesHandler(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) + sessionId, err := auth.GetSessionIdFromRequest(r) if err != nil { h.logger.Errorf("sessionId parse failed: ", err) jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) @@ -201,12 +208,12 @@ func (h *Handler) ListGranteesHandler(w http.ResponseWriter, r *http.Request) { // @Param actName path string true "unique act identifier" // @Param podname path string true "pod to share in act" // @Param Cookie header string true "cookie parameter" -// @Success 200 {object} response +// @Success 200 {object} Content // @Failure 400 {object} response // @Failure 500 {object} response // @Router /v1/act/share-pod/{actName}/{podname} [post] func (h *Handler) ACTPodShareHandler(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) + sessionId, err := auth.GetSessionIdFromRequest(r) if err != nil { h.logger.Errorf("sessionId parse failed: ", err) jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) @@ -222,13 +229,18 @@ func (h *Handler) ACTPodShareHandler(w http.ResponseWriter, r *http.Request) { actName := vars["actName"] podName := vars["podName"] - err = h.dfsAPI.ACTPodShare(sessionId, podName, actName) + content, err := h.dfsAPI.ACTPodShare(sessionId, podName, actName) if err != nil { h.logger.Error("create grantee failed: ", err) jsonhttp.BadRequest(w, &response{Message: err.Error()}) return } - jsonhttp.OK(w, &response{Message: "pod shared"}) + jsonhttp.OK(w, &Content{ + Reference: content.Reference, + Topic: content.Topic, + Owner: content.Owner.String(), + OwnerPublicKey: content.OwnerPublicKey, + }) } // ACTListHandler godoc @@ -244,7 +256,7 @@ func (h *Handler) ACTPodShareHandler(w http.ResponseWriter, r *http.Request) { // @Failure 500 {object} response // @Router /v1/act/list [get] func (h *Handler) ACTListHandler(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) + sessionId, err := auth.GetSessionIdFromRequest(r) if err != nil { h.logger.Errorf("sessionId parse failed: ", err) jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) @@ -278,9 +290,9 @@ func (h *Handler) ACTListHandler(w http.ResponseWriter, r *http.Request) { // @Success 200 {object} []act.Content // @Failure 400 {object} response // @Failure 500 {object} response -// @Router /v1/act/act-shared-pods [get] +// @Router /v1/act/act-shared-pods/{actName} [get] func (h *Handler) ACTSharedPods(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) + sessionId, err := auth.GetSessionIdFromRequest(r) if err != nil { h.logger.Errorf("sessionId parse failed: ", err) jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) @@ -318,7 +330,7 @@ func (h *Handler) ACTSharedPods(w http.ResponseWriter, r *http.Request) { // @Failure 500 {object} response // @Router /v1/act/open-act-pod/{actName} [post] func (h *Handler) ACTOpenPod(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) + sessionId, err := auth.GetSessionIdFromRequest(r) if err != nil { h.logger.Errorf("sessionId parse failed: ", err) jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) @@ -356,7 +368,7 @@ func (h *Handler) ACTOpenPod(w http.ResponseWriter, r *http.Request) { // @Failure 500 {object} response // @Router /v1/act/save-act-pod/{actName} [post] func (h *Handler) ACTSavePod(w http.ResponseWriter, r *http.Request) { - sessionId, err := auth.GetSessionIdFromGitRequest(r) + sessionId, err := auth.GetSessionIdFromRequest(r) if err != nil { h.logger.Errorf("sessionId parse failed: ", err) jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) @@ -378,15 +390,21 @@ func (h *Handler) ACTSavePod(w http.ResponseWriter, r *http.Request) { } decoder := json.NewDecoder(r.Body) - var saveReq act.Content + var saveReq Content err = decoder.Decode(&saveReq) if err != nil { h.logger.Errorf("save act pod: could not decode arguments") jsonhttp.BadRequest(w, &response{Message: "save act pod: could not decode arguments"}) return } + contentReq := act.Content{ + Reference: saveReq.Reference, + Topic: saveReq.Topic, + Owner: utils.HexToAddress(saveReq.Owner), + OwnerPublicKey: saveReq.OwnerPublicKey, + } - err = h.dfsAPI.SaveACTPod(sessionId, actName, &saveReq) + err = h.dfsAPI.SaveACTPod(sessionId, actName, &contentReq) if err != nil { h.logger.Error("save act pod failed: ", err) jsonhttp.BadRequest(w, &response{Message: err.Error()}) diff --git a/pkg/dfs/act_api.go b/pkg/dfs/act_api.go index b9a3541c..a23965c4 100644 --- a/pkg/dfs/act_api.go +++ b/pkg/dfs/act_api.go @@ -43,25 +43,24 @@ func (a *API) ListGrantees(sessionId, actName string) ([]string, error) { return actList.GetGrantees(actName) } -func (a *API) ACTPodShare(sessionId, podName, actName string) error { +func (a *API) ACTPodShare(sessionId, podName, actName string) (*act.Content, error) { ui := a.users.GetLoggedInUserInfo(sessionId) if ui == nil { - return ErrUserNotLoggedIn + return nil, ErrUserNotLoggedIn } actList := ui.GetACTList() address, err := ui.GetPod().PodShare(podName, "") if err != nil { - return err + return nil, err } addr, err := swarm.ParseHexAddress(address) if err != nil { - return err + return nil, err } - _, err = actList.GrantAccess(actName, addr) - return err + return actList.GrantAccess(actName, addr) } func (a *API) OpenACTPod(sessionId, actName string) error { @@ -81,7 +80,7 @@ func (a *API) OpenACTPod(sessionId, actName string) error { return err } - _, err = ui.GetPod().OpenFromShareInfo(info) + _, err = ui.GetPod().OpenActPod(info, actName) if err != nil { return err } diff --git a/pkg/pod/open.go b/pkg/pod/open.go index e04346c3..f59fe000 100644 --- a/pkg/pod/open.go +++ b/pkg/pod/open.go @@ -122,6 +122,34 @@ func (p *Pod) OpenPod(podName string) (*Info, error) { return podInfo, nil } +func (p *Pod) OpenActPod(si *ShareInfo, actName string) (*Info, error) { + accountInfo := p.acc.GetEmptyAccountInfo() + address := utils.HexToAddress(si.Address) + accountInfo.SetAddress(address) + + fd := feed.New(accountInfo, p.client, p.feedCacheSize, p.feedCacheTTL, p.logger) + file := f.NewFile(si.PodName, p.client, fd, accountInfo.GetAddress(), p.tm, p.logger) + dir := d.NewDirectory(si.PodName, p.client, fd, accountInfo.GetAddress(), file, p.tm, p.logger) + + kvStore := c.NewKeyValueStore(si.PodName, fd, accountInfo, address, p.client, p.logger) + docStore := c.NewDocumentStore(si.PodName, fd, accountInfo, address, file, p.tm, p.client, p.logger) + + podInfo := &Info{ + podName: si.PodName, + podPassword: si.Password, + userAddress: address, + accountInfo: accountInfo, + feed: fd, + dir: dir, + file: file, + kvStore: kvStore, + docStore: docStore, + } + p.addPodToPodMap(actName, podInfo) + + return podInfo, nil +} + func (p *Pod) OpenFromShareInfo(si *ShareInfo) (*Info, error) { accountInfo := p.acc.GetEmptyAccountInfo() address := utils.HexToAddress(si.Address) diff --git a/pkg/user/login.go b/pkg/user/login.go index a0ab0e36..7d3dbe24 100644 --- a/pkg/user/login.go +++ b/pkg/user/login.go @@ -18,6 +18,7 @@ package user import ( "crypto/ecdsa" + "encoding/hex" "fmt" "sync" @@ -137,7 +138,7 @@ func (u *Users) LoginUserV2(userName, passPhrase string, client blockstore.Clien return &LoginResponse{ Address: address.Hex(), NameHash: nameHash, - PublicKey: utils.Encode(crypto.FromECDSAPub(publicKey)), + PublicKey: hex.EncodeToString(crypto.FromECDSAPub(publicKey)), UserInfo: ui, AccessToken: token, }, nil @@ -197,7 +198,7 @@ func (u *Users) LoginUserWithSignature(signature, password string, client blocks return &LoginResponse{ Address: addr.Hex(), - PublicKey: utils.Encode(crypto.FromECDSAPub(accountInfo.GetPublicKey())), + PublicKey: hex.EncodeToString(crypto.FromECDSAPub(accountInfo.GetPublicKey())), UserInfo: ui, AccessToken: token, }, nil diff --git a/pkg/user/new.go b/pkg/user/new.go index 9da77f2d..7a79c747 100644 --- a/pkg/user/new.go +++ b/pkg/user/new.go @@ -17,6 +17,7 @@ limitations under the License. package user import ( + "encoding/hex" "errors" "regexp" "sync" @@ -34,7 +35,6 @@ import ( p "github.com/fairdatasociety/fairOS-dfs/pkg/pod" "github.com/fairdatasociety/fairOS-dfs/pkg/subscriptionManager" "github.com/fairdatasociety/fairOS-dfs/pkg/taskmanager" - "github.com/fairdatasociety/fairOS-dfs/pkg/utils" ) const ( @@ -152,7 +152,7 @@ func (u *Users) CreateNewUserV2(userName, passPhrase, mnemonic, sessionId string return nil, err } signUp.UserInfo = ui - signUp.PublicKey = utils.Encode(crypto.FromECDSAPub(accountInfo.GetPublicKey())) + signUp.PublicKey = hex.EncodeToString(crypto.FromECDSAPub(accountInfo.GetPublicKey())) return signUp, nil } diff --git a/swagger/docs.go b/swagger/docs.go index 50392bd6..1ecd8198 100644 --- a/swagger/docs.go +++ b/swagger/docs.go @@ -289,7 +289,7 @@ const docTemplate = `{ } } }, - "/v1/act/act-shared-pods": { + "/v1/act/act-shared-pods/{actName}": { "get": { "description": "ACTSharedPods is the api handler for listing pods shared in act.", "produces": [ @@ -686,7 +686,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.response" + "$ref": "#/definitions/api.Content" } }, "400": { @@ -5274,6 +5274,26 @@ const docTemplate = `{ } } }, + "api.Content": { + "type": "object", + "properties": { + "owner": { + "type": "string" + }, + "ownerPublicKey": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "topic": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, "api.DirModeRequest": { "type": "object", "properties": { diff --git a/swagger/swagger.json b/swagger/swagger.json index 75b1c10e..65fccb40 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -280,7 +280,7 @@ } } }, - "/v1/act/act-shared-pods": { + "/v1/act/act-shared-pods/{actName}": { "get": { "description": "ACTSharedPods is the api handler for listing pods shared in act.", "produces": [ @@ -677,7 +677,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.response" + "$ref": "#/definitions/api.Content" } }, "400": { @@ -5265,6 +5265,26 @@ } } }, + "api.Content": { + "type": "object", + "properties": { + "owner": { + "type": "string" + }, + "ownerPublicKey": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "topic": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, "api.DirModeRequest": { "type": "object", "properties": { diff --git a/swagger/swagger.yaml b/swagger/swagger.yaml index 754b71c3..f17e96b3 100644 --- a/swagger/swagger.yaml +++ b/swagger/swagger.yaml @@ -57,6 +57,19 @@ definitions: $ref: '#/definitions/api.Collection' type: array type: object + api.Content: + properties: + owner: + type: string + ownerPublicKey: + type: string + reference: + type: string + topic: + items: + type: integer + type: array + type: object api.DirModeRequest: properties: dirPath: @@ -861,7 +874,7 @@ paths: summary: download file from a shared pod tags: - public - /v1/act/act-shared-pods: + /v1/act/act-shared-pods/{actName}: get: description: ACTSharedPods is the api handler for listing pods shared in act. operationId: list-shared-pod-act @@ -1132,7 +1145,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/api.response' + $ref: '#/definitions/api.Content' "400": description: Bad Request schema: From 0e74c372678f27ba667c78de568e3619508237a9 Mon Sep 17 00:00:00 2001 From: asabya Date: Fri, 25 Oct 2024 17:39:36 +0530 Subject: [PATCH 10/14] fix: signup returns accesstoken --- cmd/dfs-cli/cmd/act.go | 2 +- cmd/dfs-cli/cmd/user.go | 3 +++ pkg/api/user_signup.go | 16 +++++++++------- pkg/user/login.go | 4 ++++ pkg/user/new.go | 24 +++++++++++++++++++----- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/cmd/dfs-cli/cmd/act.go b/cmd/dfs-cli/cmd/act.go index 27ff4d08..120dd0f1 100644 --- a/cmd/dfs-cli/cmd/act.go +++ b/cmd/dfs-cli/cmd/act.go @@ -119,7 +119,7 @@ func actOpenSharedPod(actName string) { fmt.Println("could not open act: ", err) return } - currentPod = "podone" + currentPod = actName currentDirectory = utils.PathSeparator message := strings.ReplaceAll(string(data), "\n", "") fmt.Println(message) diff --git a/cmd/dfs-cli/cmd/user.go b/cmd/dfs-cli/cmd/user.go index 2fbec04b..1135ba6b 100644 --- a/cmd/dfs-cli/cmd/user.go +++ b/cmd/dfs-cli/cmd/user.go @@ -75,6 +75,9 @@ func userNew(userName, mnemonic string) { fdfsAPI.setAccessToken(resp.AccessToken) currentUser = userName + message := strings.ReplaceAll(string(data), "\n", "") + fmt.Println(message) + } func userLogin(userName, apiEndpoint string) { diff --git a/pkg/api/user_signup.go b/pkg/api/user_signup.go index f262bd82..e7280ecc 100644 --- a/pkg/api/user_signup.go +++ b/pkg/api/user_signup.go @@ -18,6 +18,7 @@ package api import ( "encoding/json" + "errors" "net/http" "github.com/fairdatasociety/fairOS-dfs/cmd/common" @@ -90,12 +91,12 @@ func (h *Handler) UserSignupV2Handler(w http.ResponseWriter, r *http.Request) { // create user signUp, err := h.dfsAPI.CreateUserV2(user, password, mnemonic, "") if err != nil { - if err == u.ErrUserAlreadyPresent { + if errors.Is(err, u.ErrUserAlreadyPresent) { h.logger.Errorf("user signup: %v", err) jsonhttp.BadRequest(w, &response{Message: "user signup: " + err.Error()}) return } - if err == eth.ErrInsufficientBalance { + if errors.Is(err, eth.ErrInsufficientBalance) { h.logger.Errorf("user signup: %v", err) if signUp != nil { jsonhttp.PaymentRequired(w, &UserSignupResponse{ @@ -130,10 +131,11 @@ func (h *Handler) UserSignupV2Handler(w http.ResponseWriter, r *http.Request) { // send the response w.Header().Set("Content-Type", " application/json") jsonhttp.Created(w, &UserSignupResponse{ - Address: signUp.Address, - Mnemonic: mnemonic, - NameHash: "0x" + signUp.NameHash, - PublicKey: signUp.PublicKey, - Message: "user signed-up successfully", + Address: signUp.Address, + Mnemonic: mnemonic, + NameHash: "0x" + signUp.NameHash, + PublicKey: signUp.PublicKey, + Message: "user signed-up successfully", + AccessToken: signUp.AccessToken, }) } diff --git a/pkg/user/login.go b/pkg/user/login.go index 7d3dbe24..c444eb33 100644 --- a/pkg/user/login.go +++ b/pkg/user/login.go @@ -168,6 +168,7 @@ func (u *Users) LoginUserWithSignature(signature, password string, client blocks pod := p.NewPod(u.client, fd, acc, tm, sm, u.feedCacheSize, u.feedCacheTTL, u.logger) acl := acl2.NewACL(u.client, fd, u.logger) group := p.NewGroup(u.client, fd, acc, acl, u.logger) + actList := act.NewACT(client, fd, acc, tm, u.logger) if sessionId == "" { sessionId = auth.GetUniqueSessionId() } @@ -183,6 +184,7 @@ func (u *Users) LoginUserWithSignature(signature, password string, client blocks group: group, openPods: make(map[string]*p.Info), openPodsMu: &sync.RWMutex{}, + actList: actList, } // set cookie and add user to map @@ -329,6 +331,7 @@ func (u *Users) LoginWithWallet(addressHex, signature string, client blockstore. acl := acl2.NewACL(u.client, fd, u.logger) group := p.NewGroup(u.client, fd, acc, acl, u.logger) dir := d.NewDirectory(addressHex, client, fd, accountInfo.GetAddress(), file, tm, u.logger) + actList := act.NewACT(client, fd, acc, tm, u.logger) if sessionId == "" { sessionId = auth.GetUniqueSessionId() } @@ -343,6 +346,7 @@ func (u *Users) LoginWithWallet(addressHex, signature string, client blockstore. group: group, openPods: make(map[string]*p.Info), openPodsMu: &sync.RWMutex{}, + actList: actList, } // set cookie and add user to map return ui, utils.Encode(nameHash[:]), u.addUserAndSessionToMap(ui) diff --git a/pkg/user/new.go b/pkg/user/new.go index 7a79c747..eeb600b9 100644 --- a/pkg/user/new.go +++ b/pkg/user/new.go @@ -22,6 +22,10 @@ import ( "regexp" "sync" + "github.com/fairdatasociety/fairOS-dfs/pkg/act" + + "github.com/fairdatasociety/fairOS-dfs/pkg/auth/jwt" + acl2 "github.com/fairdatasociety/fairOS-dfs/pkg/acl/acl" "github.com/ethereum/go-ethereum/common" @@ -44,11 +48,12 @@ const ( // SignupResponse is the response of a successful signup type SignupResponse struct { - Address string `json:"address"` - Mnemonic string `json:"mnemonic"` - NameHash string `json:"nameHash"` - PublicKey string `json:"publicKey"` - UserInfo *Info `json:"userInfo"` + Address string `json:"address"` + Mnemonic string `json:"mnemonic"` + NameHash string `json:"nameHash"` + PublicKey string `json:"publicKey"` + UserInfo *Info `json:"userInfo"` + AccessToken string `json:"accessToken"` } // CreateNewUserV2 creates a new user with the given username and password. if a mnemonic is passed @@ -130,6 +135,7 @@ func (u *Users) CreateNewUserV2(userName, passPhrase, mnemonic, sessionId string pod := p.NewPod(u.client, fd, acc, tm, sm, u.feedCacheSize, u.feedCacheTTL, u.logger) acl := acl2.NewACL(u.client, fd, u.logger) group := p.NewGroup(u.client, fd, acc, acl, u.logger) + actList := act.NewACT(u.client, fd, acc, tm, u.logger) if sessionId == "" { sessionId = auth.GetUniqueSessionId() } @@ -145,14 +151,22 @@ func (u *Users) CreateNewUserV2(userName, passPhrase, mnemonic, sessionId string group: group, openPods: make(map[string]*p.Info), openPodsMu: &sync.RWMutex{}, + actList: actList, } // set cookie and add user to map if err = u.addUserAndSessionToMap(ui); err != nil { // skipcq: TCV-001 return nil, err } + + token, err := jwt.GenerateToken(sessionId) + if err != nil { + u.logger.Errorf("error generating token: %v\n", err) + } + signUp.UserInfo = ui signUp.PublicKey = hex.EncodeToString(crypto.FromECDSAPub(accountInfo.GetPublicKey())) + signUp.AccessToken = token return signUp, nil } From 80f4fb56de561b49ce1f7901dc948a21bda1f66c Mon Sep 17 00:00:00 2001 From: asabya Date: Mon, 28 Oct 2024 10:52:48 +0530 Subject: [PATCH 11/14] chore: update readme --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index ff764348..e1d1bb5f 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,20 @@ The user can share files in his pod with any other user just like in other centr Pod creation is cheap. A user can create multiple pods and use it to organise his data. for ex: Personal-Pod, Applications-Pod etc. +## (NEW) Access Control Trie (ACT) Integration +### Overview +We have introduced a new feature that integrates Swarm's Access Control Trie (ACT) into fairOS-dfs to enable user-based access control. This enhancement allows for more granular permissions and secure data sharing among users. + +### What is ACT? +The Access Control Trie (ACT) is a mechanism provided by Swarm for managing access permissions to resources stored on the Swarm network. It allows publishers to grant or revoke access to specific grantees. + +### How is ACT Integrated into fairOS-dfs? +In the native Swarm implementation, ACT is node-based and lacks the concept of users, which is not suitable for user-centric applications like fairOS-dfs. We have integrated ACT in such a way that: + +- User-Based Initialization: Access control is initialized with a user's key, tying permissions directly to user identities. +- Grantee Management: Users can be added as grantees by their public keys, allowing specific users to access shared resources. +- Secure Sharing: Instead of sharing the pod sharing reference directly, we wrap that reference using ACT and share the wrapped actRef. This ensures that only authorized users can access the shared content, even if the actRef is obtained by others. + ## (NEW) What is a group? A group is a shared drive created by a user. It is basically a pod, but on steroids. Group Owner can add members and update permissions. Members with "write" permission can create and store any number of files or directories in a group. From 7728f693f5be1411d8992df27ee936cc2507171a Mon Sep 17 00:00:00 2001 From: asabya Date: Mon, 28 Oct 2024 22:56:57 +0530 Subject: [PATCH 12/14] change log level --- cmd/dfs/cmd/server_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/dfs/cmd/server_test.go b/cmd/dfs/cmd/server_test.go index 4d5d8ed1..82cadbbc 100644 --- a/cmd/dfs/cmd/server_test.go +++ b/cmd/dfs/cmd/server_test.go @@ -57,7 +57,7 @@ func TestApis(t *testing.T) { Post: mockpost.New(mockpost.WithAcceptAll()), }) - logger := logging.New(os.Stdout, logrus.DebugLevel) + logger := logging.New(os.Stdout, logrus.PanicLevel) mockClient := bee.NewBeeClient(beeUrl, bee.WithStamp(mock.BatchOkStr), bee.WithRedundancy(fmt.Sprintf("%d", redundancy.NONE)), bee.WithPinning(true)) ens := mock2.NewMockNamespaceManager() From bceeb50a528054ef32cf827535463dd7dbef1307 Mon Sep 17 00:00:00 2001 From: asabya Date: Mon, 28 Oct 2024 23:22:27 +0530 Subject: [PATCH 13/14] update go version in actions --- .github/workflows/coverge.yml | 2 +- .github/workflows/go.yml | 4 ++-- .github/workflows/release.yaml | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/coverge.yml b/.github/workflows/coverge.yml index f5780cda..7295b7f5 100644 --- a/.github/workflows/coverge.yml +++ b/.github/workflows/coverge.yml @@ -15,7 +15,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: '1.21.4' + go-version: '1.22.0' - name: Checkout uses: actions/checkout@v3 with: diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 2610e07b..be2382c6 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -14,7 +14,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - go: ['1.21.4'] + go: ['1.22.0'] os: [ubuntu-latest, macos-latest, windows-latest] steps: - name: Setup Go @@ -47,7 +47,7 @@ jobs: # Increase the dynamic port range New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name MaxUserPort -Value 65534 -PropertyType DWord -Force # Decrease the TIME_WAIT duration - New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name TcpTimedWaitDelay -Value 3 -PropertyType DWord -Force + New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name TcpTimedWaitDelay -Value 1 -PropertyType DWord -Force shell: pwsh - name: Vet if: matrix.os == 'ubuntu-latest' diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 615666a6..66fd6340 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -18,7 +18,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: '1.21.4' + go-version: '1.22.0' - name: Checkout uses: actions/checkout@v3 with: @@ -45,7 +45,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: '1.21.4' + go-version: '1.22.0' - name: Checkout uses: actions/checkout@v3 with: @@ -88,7 +88,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: '1.21.4' + go-version: '1.22.0' - name: Checkout uses: actions/checkout@v3 with: From 0544028cf49969dcd752133adb2ff038a9a5320d Mon Sep 17 00:00:00 2001 From: asabya Date: Tue, 29 Oct 2024 08:05:29 +0530 Subject: [PATCH 14/14] port fix on windows --- .github/workflows/go.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index be2382c6..648f7484 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -44,10 +44,9 @@ jobs: - name: Set up port range and TIME_WAIT if: matrix.os == 'windows-latest' run: | - # Increase the dynamic port range - New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name MaxUserPort -Value 65534 -PropertyType DWord -Force - # Decrease the TIME_WAIT duration - New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name TcpTimedWaitDelay -Value 1 -PropertyType DWord -Force + Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters' -Name 'TcpTimedWaitDelay' -Type DWord -Value 3 -Force + Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters' -Name 'MaxUserPort' -Type DWord -Value 65534 -Force + Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters' -Name 'MaxFreeTcbs' -Type DWord -Value 65536 -Force shell: pwsh - name: Vet if: matrix.os == 'ubuntu-latest'