From 81b9c3e9d310be477ea2604e393086ba8cf8da3b Mon Sep 17 00:00:00 2001 From: David Christofas Date: Wed, 8 Feb 2023 16:49:45 +0100 Subject: [PATCH] handle expiration for space memberships (#3628) --- .../unreleased/space-member-expiration.md | 5 +++++ .../handlers/apps/sharing/shares/spaces.go | 22 ++++++++++++++++++- pkg/storage/utils/decomposedfs/spaces.go | 13 +++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 changelog/unreleased/space-member-expiration.md diff --git a/changelog/unreleased/space-member-expiration.md b/changelog/unreleased/space-member-expiration.md new file mode 100644 index 0000000000..2edbe964e1 --- /dev/null +++ b/changelog/unreleased/space-member-expiration.md @@ -0,0 +1,5 @@ +Enhancement: Add expiration date to space memberships + +Added an optional expiration date to space memberships to restrict the access in time. + +https://github.com/cs3org/reva/pull/3628 diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go index cc73c2f7f7..790ab188a5 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go @@ -22,6 +22,7 @@ import ( "context" "fmt" "net/http" + "time" groupv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" @@ -100,13 +101,32 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p // The viewer role doesn't have the ListGrants permission so we set it here. permissions.ListGrants = true + expireDate := r.PostFormValue("expireDate") + var expirationTs *types.Timestamp + if expireDate != "" { + expiration, err := time.Parse(_iso8601, expireDate) + if err != nil { + // Web sends different formats when adding and when editing a space membership... + // We need to fix this in a separate PR. + expiration, err = time.Parse(time.RFC3339, expireDate) + if err != nil { + response.WriteOCSError(w, r, response.MetaBadRequest.StatusCode, "could not parse expireDate", err) + return + } + } + expirationTs = &types.Timestamp{ + Seconds: uint64(expiration.UnixNano() / int64(time.Second)), + Nanos: uint32(expiration.UnixNano() % int64(time.Second)), + } + } createShareRes, err := client.CreateShare(ctx, &collaborationv1beta1.CreateShareRequest{ ResourceInfo: info, Grant: &collaborationv1beta1.ShareGrant{ Permissions: &collaborationv1beta1.SharePermissions{ Permissions: permissions, }, - Grantee: &grantee, + Grantee: &grantee, + Expiration: expirationTs, }, }) if err != nil || createShareRes.Status.Code != rpc.Code_CODE_OK { diff --git a/pkg/storage/utils/decomposedfs/spaces.go b/pkg/storage/utils/decomposedfs/spaces.go index 0a5738753c..cd9dcf8a73 100644 --- a/pkg/storage/utils/decomposedfs/spaces.go +++ b/pkg/storage/utils/decomposedfs/spaces.go @@ -709,6 +709,7 @@ func (fs *Decomposedfs) storageSpaceFromNode(ctx context.Context, n *node.Node, } grantMap := make(map[string]*provider.ResourcePermissions, len(grants)) + grantExpiration := make(map[string]*types.Timestamp) groupMap := make(map[string]struct{}) for _, g := range grants { var id string @@ -723,6 +724,9 @@ func (fs *Decomposedfs) storageSpaceFromNode(ctx context.Context, n *node.Node, } grantMap[id] = g.Permissions + if g.Expiration != nil { + grantExpiration[id] = g.Expiration + } } grantMapJSON, err := json.Marshal(grantMap) @@ -730,6 +734,11 @@ func (fs *Decomposedfs) storageSpaceFromNode(ctx context.Context, n *node.Node, return nil, err } + grantExpirationMapJSON, err := json.Marshal(grantExpiration) + if err != nil { + return nil, err + } + groupMapJSON, err := json.Marshal(groupMap) if err != nil { return nil, err @@ -752,6 +761,10 @@ func (fs *Decomposedfs) storageSpaceFromNode(ctx context.Context, n *node.Node, Decoder: "json", Value: grantMapJSON, }, + "grants_expirations": { + Decoder: "json", + Value: grantExpirationMapJSON, + }, "groups": { Decoder: "json", Value: groupMapJSON,