From 12c57a0e32c0d9d58706d991ffc448ac2dc44fa9 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 9 Dec 2020 12:15:48 +0100 Subject: [PATCH 1/7] publicshareManagerJson: delete public links on GET --- pkg/publicshare/manager/json/json.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/publicshare/manager/json/json.go b/pkg/publicshare/manager/json/json.go index 8c1bb63b4e..a5cd1b761a 100644 --- a/pkg/publicshare/manager/json/json.go +++ b/pkg/publicshare/manager/json/json.go @@ -292,6 +292,12 @@ func (m *manager) GetPublicShare(ctx context.Context, u *user.User, ref *link.Pu } if ref.GetId().GetOpaqueId() == ps.Id.OpaqueId { + if !notExpired(ps) { + if err := m.revokeExpiredPublicShare(ctx, ps, u); err != nil { + return nil, err + } + return nil, errors.New("no shares found by id:" + ref.GetId().String()) + } return ps, nil } @@ -452,15 +458,20 @@ func (m *manager) GetPublicShareByToken(ctx context.Context, token, password str } if local.Token == token { - // validate if it is password protected + if !notExpired(local) { + // TODO user is not needed at all in this API. + if err := m.revokeExpiredPublicShare(ctx, local, nil); err != nil { + return nil, err + } + break + } + if local.PasswordProtected { password = base64.StdEncoding.EncodeToString([]byte(password)) - // check sent password matches stored one if passDB == password { return local, nil } - // TODO(refs): custom permission denied error to catch up - // in upper layers + return nil, errors.New("json: invalid password") } return local, nil From eee556a93d5c53de108703a71772ed3e919da9e8 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 9 Dec 2020 12:18:59 +0100 Subject: [PATCH 2/7] add changelog --- changelog/unreleased/delete-public-link-on-get-operations.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/unreleased/delete-public-link-on-get-operations.md diff --git a/changelog/unreleased/delete-public-link-on-get-operations.md b/changelog/unreleased/delete-public-link-on-get-operations.md new file mode 100644 index 0000000000..0a2cdabbd8 --- /dev/null +++ b/changelog/unreleased/delete-public-link-on-get-operations.md @@ -0,0 +1,5 @@ +Enhancement: Remove expired Link on Get + +There is the scenario in which a public link has expired but ListPublicLink has not run, accessing a technically expired public share is still possible. + +https://github.com/cs3org/reva/pull/1364 \ No newline at end of file From 5c3c7beddca9c768f7bf1794661be49f2089b6b6 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 9 Dec 2020 15:04:21 +0100 Subject: [PATCH 3/7] publicshareManagerJson: introduce a janitor with a cleanup goroutine --- pkg/publicshare/manager/json/json.go | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/pkg/publicshare/manager/json/json.go b/pkg/publicshare/manager/json/json.go index a5cd1b761a..8fe0425ad3 100644 --- a/pkg/publicshare/manager/json/json.go +++ b/pkg/publicshare/manager/json/json.go @@ -28,8 +28,10 @@ import ( "io/ioutil" "math/rand" "os" + "os/signal" "path/filepath" "sync" + "syscall" "time" "github.com/rs/zerolog/log" @@ -46,6 +48,30 @@ import ( "go.opencensus.io/trace" ) +type janitor struct { + m *manager + interval time.Duration +} + +func (j *janitor) run() { + ticker := time.NewTicker(j.interval) + work := make(chan os.Signal, 1) + signal.Notify(work, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT) + + for { + select { + case <-work: + return + case _ = <-ticker.C: + j.m.cleanupExpiredShares() + } + } +} + +var j = janitor{ + interval: time.Minute, // TODO we want this interval configurable +} + func init() { registry.Register("json", New) } @@ -86,6 +112,9 @@ func New(c map[string]interface{}) (publicshare.Manager, error) { } } + j.m = &m + go j.run() + return &m, nil } @@ -359,6 +388,25 @@ func notExpired(s *link.PublicShare) bool { return false } +func (m *manager) cleanupExpiredShares() { + m.mutex.Lock() + defer m.mutex.Unlock() + + db, _ := m.readDb() + + for _, v := range db { + d := v.(map[string]interface{})["share"] + + ps := &link.PublicShare{} + r := bytes.NewBuffer([]byte(d.(string))) + _ = m.unmarshaler.Unmarshal(r, ps) + + if !notExpired(ps) { + _ = m.revokeExpiredPublicShare(context.Background(), ps, nil) + } + } +} + func (m *manager) revokeExpiredPublicShare(ctx context.Context, s *link.PublicShare, u *user.User) error { m.mutex.Unlock() defer m.mutex.Lock() @@ -520,3 +568,7 @@ type publicShare struct { link.PublicShare Password string `json:"password"` } + +func cleanupExpired() { + +} From 27ecc8c12f7f1802bb4eb9748fde954bb141486e Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 9 Dec 2020 15:53:35 +0100 Subject: [PATCH 4/7] publicshareManagerJson: code style --- pkg/publicshare/manager/json/json.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/publicshare/manager/json/json.go b/pkg/publicshare/manager/json/json.go index 8fe0425ad3..ff3325da64 100644 --- a/pkg/publicshare/manager/json/json.go +++ b/pkg/publicshare/manager/json/json.go @@ -62,7 +62,7 @@ func (j *janitor) run() { select { case <-work: return - case _ = <-ticker.C: + case <-ticker.C: j.m.cleanupExpiredShares() } } From 4e5b917c7abd58807ca22b5a9a3b88a538d095f6 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 9 Dec 2020 16:12:11 +0100 Subject: [PATCH 5/7] publicshareManagerJson: remove unused function --- pkg/publicshare/manager/json/json.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/publicshare/manager/json/json.go b/pkg/publicshare/manager/json/json.go index ff3325da64..8248a1eb77 100644 --- a/pkg/publicshare/manager/json/json.go +++ b/pkg/publicshare/manager/json/json.go @@ -568,7 +568,3 @@ type publicShare struct { link.PublicShare Password string `json:"password"` } - -func cleanupExpired() { - -} From 1d58d198a2c082c57db8b96278a1a85435ac0ad2 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Mon, 14 Dec 2020 09:47:05 +0100 Subject: [PATCH 6/7] trigger ci From f8fb629db62bdd8b2a65adb6157b962a085cf49d Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Mon, 14 Dec 2020 15:10:22 +0100 Subject: [PATCH 7/7] trigger ci, again