From 6a2b1b4a9b5248e9c20dad41a5c1e0f6004c61d3 Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Wed, 24 Jan 2024 03:28:47 -0500 Subject: [PATCH] feat: implement provider store --- api/s5/http.go | 11 ++++++++ protocols/s5.go | 70 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/api/s5/http.go b/api/s5/http.go index 8072eaf..87bc6e3 100644 --- a/api/s5/http.go +++ b/api/s5/http.go @@ -1342,3 +1342,14 @@ func setAuthCookie(jwt string, jc jape.Context) { http.SetCookie(jc.ResponseWriter, &authCookie) } + +func GenerateDownloadUrl(hash *encoding.Multihash, portal interfaces.Portal) string { + domain := portal.Config().GetString("core.domain") + + hashStr, err := hash.ToBase64Url() + if err != nil { + portal.Logger().Error("error encoding hash", zap.Error(err)) + } + + return fmt.Sprintf("https://%s/api/s5/download/%s", domain, hashStr) +} diff --git a/protocols/s5.go b/protocols/s5.go index 68364b0..92e837b 100644 --- a/protocols/s5.go +++ b/protocols/s5.go @@ -1,19 +1,25 @@ package protocols import ( - "crypto/ed25519" - "fmt" - s5config "git.lumeweb.com/LumeWeb/libs5-go/config" - s5ed "git.lumeweb.com/LumeWeb/libs5-go/ed25519" - s5interfaces "git.lumeweb.com/LumeWeb/libs5-go/interfaces" - s5node "git.lumeweb.com/LumeWeb/libs5-go/node" - "git.lumeweb.com/LumeWeb/portal/interfaces" - bolt "go.etcd.io/bbolt" - "go.uber.org/zap" + "crypto/ed25519" + "fmt" + s5config "git.lumeweb.com/LumeWeb/libs5-go/config" + s5ed "git.lumeweb.com/LumeWeb/libs5-go/ed25519" + "git.lumeweb.com/LumeWeb/libs5-go/encoding" + s5interfaces "git.lumeweb.com/LumeWeb/libs5-go/interfaces" + s5node "git.lumeweb.com/LumeWeb/libs5-go/node" + s5storage "git.lumeweb.com/LumeWeb/libs5-go/storage" + "git.lumeweb.com/LumeWeb/libs5-go/types" + "git.lumeweb.com/LumeWeb/portal/api/s5" + "git.lumeweb.com/LumeWeb/portal/interfaces" + bolt "go.etcd.io/bbolt" + "go.uber.org/zap" + "time" ) var ( - _ interfaces.Protocol = (*S5Protocol)(nil) + _ interfaces.Protocol = (*S5Protocol)(nil) + _ s5interfaces.ProviderStore = (*S5ProviderStore)(nil) ) type S5Protocol struct { @@ -83,6 +89,8 @@ func (s *S5Protocol) Initialize(portal interfaces.Portal) error { s.node = s5node.NewNode(cfg) + s.node.SetProviderStore(&S5ProviderStore{proto: s}) + return nil } func (s *S5Protocol) Start() error { @@ -104,3 +112,45 @@ func (s *S5Protocol) Start() error { func (s *S5Protocol) Node() s5interfaces.Node { return s.node } + +type S5ProviderStore struct { + proto *S5Protocol +} + +func (s S5ProviderStore) CanProvide(hash *encoding.Multihash, kind []types.StorageLocationType) bool { + for _, t := range kind { + switch t { + case types.StorageLocationTypeArchive, types.StorageLocationTypeFile, types.StorageLocationTypeFull: + rawHash := hash.HashBytes() + if exists, _ := s.proto.portal.Storage().FileExists(rawHash); exists { + return true + } + } + } + return false +} + +func (s S5ProviderStore) Provide(hash *encoding.Multihash, kind []types.StorageLocationType) (s5interfaces.StorageLocation, error) { + for _, t := range kind { + if !s.CanProvide(hash, []types.StorageLocationType{t}) { + continue + } + + switch t { + case types.StorageLocationTypeArchive: + return s5storage.NewStorageLocation(int(types.StorageLocationTypeArchive), []string{}, calculateExpiry(24*time.Hour)), nil + case types.StorageLocationTypeFile, types.StorageLocationTypeFull: + return s5storage.NewStorageLocation(int(types.StorageLocationTypeArchive), []string{s5.GenerateDownloadUrl(hash, s.proto.portal)}, calculateExpiry(24*time.Hour)), nil + } + } + + hashStr, err := hash.ToString() + if err != nil { + return nil, err + } + + return nil, fmt.Errorf("could not provide hash %s for types %v", hashStr, kind) +} +func calculateExpiry(duration time.Duration) int64 { + return time.Now().Add(duration).Unix() +}