Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Public Shares CRUD, File Public Shares Manager #681

Merged
merged 50 commits into from
May 28, 2020
Merged

Public Shares CRUD, File Public Shares Manager #681

merged 50 commits into from
May 28, 2020

Conversation

refs
Copy link
Member

@refs refs commented Apr 23, 2020

What?

  • Manager interface accepts UpdateRequestType
    • since this is the only place where the update data exists
  • Update displayname
  • Update permissions
  • Update expiration
  • Update password
  • Delete

Other Tasks

  • Do not return expired shares to Phoenix.
  • Persistent shares manager.

Description

The file manager, as per commit 8503ee3 needs an existing file to be used as storage, as the revad process doesn't have write permissions(1).

The db file is thread safe, all operations lock a mutex, so goroutines consuming the file are sure to be using an up-to-date version.

Example file contents:

{
  "KTBfUQmYrEXy": "{\"id\":{\"opaqueId\":\"KTBfUQmYrEXy\"},\"token\":\"VjldgRWfpudX\",\"resourceId\":{\"storageId\":\"1284d238-aa92-42ce-bdc4-0b0000009162\",\"opaqueId\":\"19897125-ddd9-4939-be1d-12d86c503569\"},\"permissions\":{\"permissions\":{\"getPath\":true,\"getQuota\":true,\"initiateFileDownload\":true,\"listGrants\":true,\"listContainer\":true,\"listFileVersions\":true,\"listRecycle\":true,\"stat\":true}},\"owner\":{\"opaqueId\":\"einstein\"},\"creator\":{\"idp\":\"https://localhost:9200\",\"opaqueId\":\"einstein\"},\"ctime\":{\"seconds\":\"1587720640\",\"nanos\":939334000},\"mtime\":{\"seconds\":\"1587720755\",\"nanos\":187107000},\"expiration\":{\"seconds\":\"1587859200\"},\"displayName\":\"empty\"}",
  "jKoqDYLhZYDU": "{\"id\":{\"opaqueId\":\"jKoqDYLhZYDU\"},\"token\":\"orOSByQWpIvl\",\"resourceId\":{\"storageId\":\"1284d238-aa92-42ce-bdc4-0b0000009162\",\"opaqueId\":\"621502b8-9ed1-43c9-9a4e-b4ecf2711752\"},\"permissions\":{\"permissions\":{\"getPath\":true,\"getQuota\":true,\"initiateFileDownload\":true,\"listGrants\":true,\"listContainer\":true,\"listFileVersions\":true,\"listRecycle\":true,\"stat\":true}},\"owner\":{\"opaqueId\":\"einstein\"},\"creator\":{\"idp\":\"https://localhost:9200\",\"opaqueId\":\"einstein\"},\"ctime\":{\"seconds\":\"1587975510\",\"nanos\":771457000},\"mtime\":{\"seconds\":\"1587975510\",\"nanos\":771457000},\"displayName\":\"demo1\"}",
  "uJcxqIvypjUo": "{\"id\":{\"opaqueId\":\"uJcxqIvypjUo\"},\"token\":\"RozaxRnMYtjQ\",\"resourceId\":{\"storageId\":\"1284d238-aa92-42ce-bdc4-0b0000009162\",\"opaqueId\":\"19897125-ddd9-4939-be1d-12d86c503569\"},\"permissions\":{\"permissions\":{\"getPath\":true,\"getQuota\":true,\"initiateFileDownload\":true,\"listGrants\":true,\"listContainer\":true,\"listFileVersions\":true,\"listRecycle\":true,\"stat\":true}},\"owner\":{\"opaqueId\":\"einstein\"},\"creator\":{\"idp\":\"https://localhost:9200\",\"opaqueId\":\"einstein\"},\"ctime\":{\"seconds\":\"1587720648\",\"nanos\":135337000},\"mtime\":{\"seconds\":\"1587975296\",\"nanos\":942731000},\"expiration\":{\"seconds\":\"1588204800\"},\"displayName\":\"3\"}"
}

Share contents comparison (link.PublicShare) is achieved by string comparison, rather than reflection (no reflect.DeepEqual) or a comparison interface. This was a design choice meant to be replaced by https://pkg.go.dev/github.com/google/go-cmp/cmp for comparing protobuf struct.

Operations require a small overhead:

  1. read file contents onto a map[string]interface{}
    1.1 keys are PublicShares OpaqueID
    1.2 contents are serialized json (using jsonpb, deprecated and should use ptorojson instead)
  2. range over the shares
  3. use jsonpb Unmarshaler and unmarshal v's data onto a *link.PublicShare struct

From this point on, a PublicShare struct is available to be used.

Write / Update operations follow the same approach, only an extra step that Marshals the contents of the *link.PublicShare onto the file on a new key or overriding an existing one.

  • (1) this is an assumption by trial and error. Need solid proof.

@refs refs changed the title CRUD on Public Shares CRUD on Public Shares, File Public Shares Manager Apr 27, 2020
@refs refs changed the title CRUD on Public Shares, File Public Shares Manager Public Shares CRUD, File Public Shares Manager Apr 27, 2020
@@ -43,6 +43,61 @@ func (s *svc) CreatePublicShare(ctx context.Context, req *link.CreatePublicShare
return nil, err
}

// Grants are not accessible through a link.PublicShare, in order for a service to access a grant (link.Grant) this needs to be
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WIP. We need to persist the grant for basic authentication password checking. Still need to figure out whether to commit it to the storage or find another way

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @refs I don't think we need to commit the grant to storage for a public share, keeping it outside the storage is good enough. User accessing a public link they cannot access the storage directly anyway. What can be stored in the storage is a reference to the public link ID as metadata.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes a clean separation of concerns. Currently the password is stored on a link.Grant, that is required at the moment of a PublicShare creation, but the PublicShare itself does not include a Grant, by design. So in short, where would you think it would be a good way to store this? We were thinking on the public shares auth provider.

/cc @butonic

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bump. This is the only opinionated bit that needs to be resolved before having a functional persistent public shares storage

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the time being I'm running with an in-memory map for the lack of decision here. This should NOT be adopted in production, but as a proof of concept does the job on checking Basic credentials with the stored public share grants.

@refs refs marked this pull request as ready for review May 8, 2020 09:54
@refs refs requested a review from labkode May 8, 2020 10:03
@labkode
Copy link
Member

labkode commented May 26, 2020

@refs we need to extend the interface to add a password parameter:
https://github.com/cs3org/reva/blob/master/pkg/publicshare/publicshare.go#L36

@PVince81
Copy link
Contributor

Some test results:

  • BUG: copy link to clipboard is missing the host name

@PVince81
Copy link
Contributor

PVince81 commented May 27, 2020

@PVince81
Copy link
Contributor

fix for cross-storage propfind is here: #778

@PVince81
Copy link
Contributor

I've updated #778 but the propfind is still broken, but in another way

Use original ref for Depth 1 which works fine.
Depth infinity will have its own logic which currently only works within
a single storage.
@PVince81
Copy link
Contributor

@refs I got stuck with even more issues when resolving by resource id in the PROPFIND.

To get us unblocked, I've raised another PR #779 to restore the Depth-1 logic to what it was before the regression. The Depth-infinity logic is separate now.

@PVince81
Copy link
Contributor

@refs please merge refs#1 to receive the fix into your branch.

I could only test with curl but not with public shares as my setup is not working yet. Please verify

@refs
Copy link
Member Author

refs commented May 27, 2020

@refs please merge refs#1 to receive the fix into your branch.

I could only test with curl but not with public shares as my setup is not working yet. Please verify

@PVince81 public links behave as expected with that provisional patch 👍

@refs refs requested a review from labkode May 28, 2020 07:24
@refs
Copy link
Member Author

refs commented May 28, 2020

@labkode I think we can merge as it is so this doesn't grow larger, and I'll be addressing the remaining issues in the upcoming weeks :)

@@ -58,7 +59,10 @@ func (s *service) Close() error {
return nil
}

func (s *service) UnprotectedEndpoints() []string { return []string{} }
func (s *service) UnprotectedEndpoints() []string {
// return []string{"/cs3.sharing.link.v1beta1.LinkAPI/GetPublicShareByToken"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think needs to be unprotected

}

publicShareResponse, err := s.gateway.GetPublicShareByToken(
publicShareResponse, err := driver.GetPublicShare(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was correct, the method is GetPublicShareByToken

@labkode labkode merged commit f599518 into cs3org:master May 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants