diff --git a/go.mod b/go.mod index 1547dc5d332..d800107a274 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/blevesearch/bleve/v2 v2.3.5 github.com/coreos/go-oidc/v3 v3.4.0 github.com/cs3org/go-cs3apis v0.0.0-20221012090518-ef2996678965 - github.com/cs3org/reva/v2 v2.12.1-0.20230203122123-cd2b2a5feca9 + github.com/cs3org/reva/v2 v2.12.1-0.20230208154945-81b9c3e9d310 github.com/disintegration/imaging v1.6.2 github.com/ggwhite/go-masker v1.0.9 github.com/go-chi/chi/v5 v5.0.7 diff --git a/go.sum b/go.sum index 84488feb897..01b13e3ebeb 100644 --- a/go.sum +++ b/go.sum @@ -284,6 +284,8 @@ github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7N github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= github.com/c0rby/go-cs3apis v0.0.0-20230110100311-5b424f1baa35 h1:bbpRY/l4z5MTH+TRGZdkIqDM9JXQQewJdO1o+80zcok= github.com/c0rby/go-cs3apis v0.0.0-20230110100311-5b424f1baa35/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= +github.com/c0rby/reva/v2 v2.0.0-20230125143632-a7e24c8dd66b h1:PKbmBHmUzd5d9GdpBlJY2p0a3dqg7YboEYg0Kolt3xs= +github.com/c0rby/reva/v2 v2.0.0-20230125143632-a7e24c8dd66b/go.mod h1:u73Df9JAZsDj43GIjQIb3DO1PLJuPutZXkRqQH0oGXA= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= @@ -343,8 +345,8 @@ github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3p github.com/crewjam/saml v0.4.6/go.mod h1:ZBOXnNPFzB3CgOkRm7Nd6IVdkG+l/wF+0ZXLqD96t1A= github.com/crewjam/saml v0.4.9 h1:X2jDv4dv3IvfT9t+RhADavzNFAcq3fVxzTCIH3G605U= github.com/crewjam/saml v0.4.9/go.mod h1:9Zh6dWPtB3MSzTRt8fIFH60Z351QQ+s7hCU3J/tTlA4= -github.com/cs3org/reva/v2 v2.12.1-0.20230203122123-cd2b2a5feca9 h1:iokM4RfMgO0HhIERr1MWjRJkIwTt4XhL3fOSc3emlhY= -github.com/cs3org/reva/v2 v2.12.1-0.20230203122123-cd2b2a5feca9/go.mod h1:u73Df9JAZsDj43GIjQIb3DO1PLJuPutZXkRqQH0oGXA= +github.com/cs3org/reva/v2 v2.12.1-0.20230208154945-81b9c3e9d310 h1:UIsxP51vo9Z7OJTclC6yYetgtAPZaoLJ8d41c6WkT+o= +github.com/cs3org/reva/v2 v2.12.1-0.20230208154945-81b9c3e9d310/go.mod h1:u73Df9JAZsDj43GIjQIb3DO1PLJuPutZXkRqQH0oGXA= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= diff --git a/services/graph/pkg/service/v0/drives.go b/services/graph/pkg/service/v0/drives.go index 0bd90a616cc..398bc29c38c 100644 --- a/services/graph/pkg/service/v0/drives.go +++ b/services/graph/pkg/service/v0/drives.go @@ -11,6 +11,7 @@ import ( "sort" "strconv" "strings" + "time" "github.com/CiscoM31/godata" gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" @@ -540,107 +541,7 @@ func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, spa } spaceID := storagespace.FormatResourceID(spaceRid) - var permissions []libregraph.Permission - if space.Opaque != nil { - var permissionsMap map[string]*storageprovider.ResourcePermissions - var groupsMap map[string]struct{} - - opaqueGrants, ok := space.Opaque.Map["grants"] - if ok { - err := json.Unmarshal(opaqueGrants.Value, &permissionsMap) - if err != nil { - logger.Debug(). - Err(err). - Interface("space", space.Root). - Bytes("grants", opaqueGrants.Value). - Msg("unable to parse space: failed to read spaces grants") - } - } - - opaqueGroups, ok := space.Opaque.Map["groups"] - if ok { - err := json.Unmarshal(opaqueGroups.Value, &groupsMap) - if err != nil { - logger.Debug(). - Err(err). - Interface("space", space.Root). - Bytes("groups", opaqueGroups.Value). - Msg("unable to parse space: failed to read spaces groups") - } - } - - if len(permissionsMap) != 0 { - managerIdentities := []libregraph.IdentitySet{} - editorIdentities := []libregraph.IdentitySet{} - viewerIdentities := []libregraph.IdentitySet{} - - for id, perm := range permissionsMap { - // This temporary variable is necessary since we need to pass a pointer to the - // libregraph.Identity and if we pass the pointer from the loop every identity - // will have the same id. - tmp := id - var identitySet libregraph.IdentitySet - if _, ok := groupsMap[id]; ok { - var group libregraph.Group - if item := g.groupsCache.Get(id); item == nil { - if requestedGroup, err := g.identityBackend.GetGroup(ctx, id, url.Values{}); err == nil { - group = *requestedGroup - g.groupsCache.Set(id, group, ttlcache.DefaultTTL) - } - } else { - group = item.Value() - } - - identitySet = libregraph.IdentitySet{Group: &libregraph.Identity{Id: &tmp, DisplayName: group.GetDisplayName()}} - } else { - var user libregraph.User - if item := g.usersCache.Get(id); item == nil { - if requestedUser, err := g.identityBackend.GetUser(ctx, id, &godata.GoDataRequest{}); err == nil { - user = *requestedUser - g.usersCache.Set(id, user, ttlcache.DefaultTTL) - } - } else { - user = item.Value() - } - - identitySet = libregraph.IdentitySet{User: &libregraph.Identity{Id: &tmp, DisplayName: user.GetDisplayName()}} - } - - // we need to map the permissions to the roles - switch { - // having RemoveGrant qualifies you as a manager - case perm.RemoveGrant: - managerIdentities = append(managerIdentities, identitySet) - // InitiateFileUpload means you are an editor - case perm.InitiateFileUpload: - editorIdentities = append(editorIdentities, identitySet) - // Stat permission at least makes you a viewer - case perm.Stat: - viewerIdentities = append(viewerIdentities, identitySet) - } - } - - permissions = make([]libregraph.Permission, 0, 3) - if len(managerIdentities) != 0 { - permissions = append(permissions, libregraph.Permission{ - GrantedToIdentities: managerIdentities, - Roles: []string{"manager"}, - }) - } - if len(editorIdentities) != 0 { - permissions = append(permissions, libregraph.Permission{ - GrantedToIdentities: editorIdentities, - Roles: []string{"editor"}, - }) - } - if len(viewerIdentities) != 0 { - permissions = append(permissions, libregraph.Permission{ - GrantedToIdentities: viewerIdentities, - Roles: []string{"viewer"}, - }) - } - } - } + permissions := g.cs3PermissionsToLibreGraph(ctx, space) drive := &libregraph.Drive{ Id: libregraph.PtrString(spaceID), @@ -736,6 +637,112 @@ func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, spa return drive, nil } +func (g Graph) cs3PermissionsToLibreGraph(ctx context.Context, space *storageprovider.StorageSpace) []libregraph.Permission { + if space.Opaque == nil { + return nil + } + logger := g.logger.SubloggerWithRequestID(ctx) + + var permissionsMap map[string]*storageprovider.ResourcePermissions + opaqueGrants, ok := space.Opaque.Map["grants"] + if ok { + err := json.Unmarshal(opaqueGrants.Value, &permissionsMap) + if err != nil { + logger.Debug(). + Err(err). + Interface("space", space.Root). + Bytes("grants", opaqueGrants.Value). + Msg("unable to parse space: failed to read spaces grants") + } + } + if len(permissionsMap) == 0 { + return nil + } + + var permissionsExpirations map[string]*types.Timestamp + opaqueGrantsExpirations, ok := space.Opaque.Map["grants_expirations"] + if ok { + err := json.Unmarshal(opaqueGrantsExpirations.Value, &permissionsExpirations) + if err != nil { + logger.Debug(). + Err(err). + Interface("space", space.Root). + Bytes("grants_expirations", opaqueGrantsExpirations.Value). + Msg("unable to parse space: failed to read spaces grants expirations") + } + } + + var groupsMap map[string]struct{} + opaqueGroups, ok := space.Opaque.Map["groups"] + if ok { + err := json.Unmarshal(opaqueGroups.Value, &groupsMap) + if err != nil { + logger.Debug(). + Err(err). + Interface("space", space.Root). + Bytes("groups", opaqueGroups.Value). + Msg("unable to parse space: failed to read spaces groups") + } + } + + permissions := make([]libregraph.Permission, 0, len(permissionsMap)) + for id, perm := range permissionsMap { + // This temporary variable is necessary since we need to pass a pointer to the + // libregraph.Identity and if we pass the pointer from the loop every identity + // will have the same id. + tmp := id + var identitySet libregraph.IdentitySet + if _, ok := groupsMap[id]; ok { + var group libregraph.Group + if item := g.groupsCache.Get(id); item == nil { + if requestedGroup, err := g.identityBackend.GetGroup(ctx, id, url.Values{}); err == nil { + group = *requestedGroup + g.groupsCache.Set(id, group, ttlcache.DefaultTTL) + } + } else { + group = item.Value() + } + + identitySet = libregraph.IdentitySet{Group: &libregraph.Identity{Id: &tmp, DisplayName: group.GetDisplayName()}} + } else { + var user libregraph.User + if item := g.usersCache.Get(id); item == nil { + if requestedUser, err := g.identityBackend.GetUser(ctx, id, &godata.GoDataRequest{}); err == nil { + user = *requestedUser + g.usersCache.Set(id, user, ttlcache.DefaultTTL) + } + } else { + user = item.Value() + } + + identitySet = libregraph.IdentitySet{User: &libregraph.Identity{Id: &tmp, DisplayName: user.GetDisplayName()}} + } + + p := libregraph.Permission{ + GrantedToIdentities: []libregraph.IdentitySet{identitySet}, + } + + if exp := permissionsExpirations[id]; exp != nil { + p.ExpirationDateTime = libregraph.PtrTime(time.Unix(int64(exp.GetSeconds()), int64(exp.GetNanos()))) + } + + // we need to map the permissions to the roles + switch { + // having RemoveGrant qualifies you as a manager + case perm.RemoveGrant: + p.SetRoles([]string{"manager"}) + // InitiateFileUpload means you are an editor + case perm.InitiateFileUpload: + p.SetRoles([]string{"editor"}) + // Stat permission at least makes you a viewer + case perm.Stat: + p.SetRoles([]string{"viewer"}) + } + permissions = append(permissions, p) + } + return permissions +} + func (g Graph) getDriveQuota(ctx context.Context, space *storageprovider.StorageSpace) (libregraph.Quota, error) { logger := g.logger.SubloggerWithRequestID(ctx) client := g.GetGatewayClient()