mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-05 11:51:16 -06:00
use opaque as space props transport
This commit is contained in:
2
go.mod
2
go.mod
@@ -257,4 +257,4 @@ require (
|
||||
stash.kopano.io/kgol/oidc-go v0.3.2 // indirect
|
||||
)
|
||||
|
||||
replace github.com/cs3org/reva => ../reva
|
||||
replace github.com/cs3org/reva => github.com/micbar/reva v1.9.1-0.20220210130539-d274bcbe266c
|
||||
|
||||
4
go.sum
4
go.sum
@@ -333,8 +333,6 @@ github.com/crewjam/saml v0.4.5/go.mod h1:qCJQpUtZte9R1ZjUBcW8qtCNlinbO363ooNl02S
|
||||
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19 h1:1jqPH58jCxvbaJ9WLIJ7W2/m622bWS6ChptzljSG6IQ=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/reva v1.16.1-0.20220208091630-7660ee26dce7 h1:6U5hiLJ1vl3J8aoscg6qZLrpFvp5/Y4RnxZ2xS4RQWA=
|
||||
github.com/cs3org/reva v1.16.1-0.20220208091630-7660ee26dce7/go.mod h1:EAKoGXYmyIKmUSq/fgmAsTGHgrgwSb1PffGiA/AmgSo=
|
||||
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=
|
||||
@@ -985,6 +983,8 @@ github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 h1:Z/i1e+gTZrmcGeZy
|
||||
github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103/go.mod h1:o9YPB5aGP8ob35Vy6+vyq3P3bWe7NQWzf+JLiXCiMaE=
|
||||
github.com/mennanov/fieldmask-utils v0.5.0 h1:8em4akN0NM3hmmrg8VbvOPfdS4SSBdbFd53m9VtfOg0=
|
||||
github.com/mennanov/fieldmask-utils v0.5.0/go.mod h1:lah2lHczE2ff+7SqnNKpB+YzaO7M3h5iNO4LgPTJheM=
|
||||
github.com/micbar/reva v1.9.1-0.20220210130539-d274bcbe266c h1:wHd+DF2ZWUmoNCeBVNjsx23rJUkW67+0sPa07QaOxMk=
|
||||
github.com/micbar/reva v1.9.1-0.20220210130539-d274bcbe266c/go.mod h1:EAKoGXYmyIKmUSq/fgmAsTGHgrgwSb1PffGiA/AmgSo=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/cs3org/reva/pkg/utils"
|
||||
"github.com/go-chi/render"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
"github.com/owncloud/ocis/graph/pkg/service/v0/errorcode"
|
||||
@@ -77,14 +76,11 @@ func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) {
|
||||
render.JSON(w, r, &listResponse{Value: files})
|
||||
}
|
||||
|
||||
func (g Graph) getDriveItem(ctx context.Context, root *storageprovider.ResourceId, relativePath string) (*libregraph.DriveItem, error) {
|
||||
|
||||
func (g Graph) getDriveItem(ctx context.Context, root *storageprovider.ResourceId) (*libregraph.DriveItem, error) {
|
||||
client := g.GetGatewayClient()
|
||||
|
||||
ref := &storageprovider.Reference{
|
||||
ResourceId: root,
|
||||
// the path is always relative to the root of the drive, not the location of the .config/ocis/space.yaml file
|
||||
Path: utils.MakeRelativePath(relativePath),
|
||||
}
|
||||
res, err := client.Stat(ctx, &storageprovider.StatRequest{Ref: ref})
|
||||
if err != nil {
|
||||
@@ -93,10 +89,23 @@ func (g Graph) getDriveItem(ctx context.Context, root *storageprovider.ResourceI
|
||||
if res.Status.Code != cs3rpc.Code_CODE_OK {
|
||||
return nil, fmt.Errorf("could not stat %s: %s", ref, res.Status.Message)
|
||||
}
|
||||
|
||||
return cs3ResourceToDriveItem(res.Info)
|
||||
}
|
||||
|
||||
func (g Graph) getPathForDriveItem(ctx context.Context, ID *storageprovider.ResourceId) (*string, error) {
|
||||
client := g.GetGatewayClient()
|
||||
var path *string
|
||||
res, err := client.GetPath(ctx, &storageprovider.GetPathRequest{ResourceId: ID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if res.Status.Code != cs3rpc.Code_CODE_OK {
|
||||
return nil, fmt.Errorf("could not stat %s: %s", ID, res.Status.Message)
|
||||
}
|
||||
path = &res.Path
|
||||
return path, err
|
||||
}
|
||||
|
||||
func formatDriveItems(mds []*storageprovider.ResourceInfo) ([]*libregraph.DriveItem, error) {
|
||||
responses := make([]*libregraph.DriveItem, 0, len(mds))
|
||||
for i := range mds {
|
||||
@@ -145,85 +154,44 @@ func cs3ResourceToDriveItem(res *storageprovider.ResourceInfo) (*libregraph.Driv
|
||||
return driveItem, nil
|
||||
}
|
||||
|
||||
func (g Graph) getDriveMetadata(ctx context.Context, space *storageprovider.StorageSpace) (map[string]string, error) {
|
||||
client := g.GetGatewayClient()
|
||||
sResp, err := client.Stat(
|
||||
ctx,
|
||||
&storageprovider.StatRequest{
|
||||
Ref: &storageprovider.Reference{
|
||||
ResourceId: &storageprovider.ResourceId{
|
||||
StorageId: space.Root.StorageId,
|
||||
OpaqueId: space.Root.OpaqueId,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
g.logger.Debug().Err(err).Interface("space", space).Msg("transport error")
|
||||
return nil, err
|
||||
}
|
||||
if sResp.Status.Code != cs3rpc.Code_CODE_OK {
|
||||
g.logger.Debug().Interface("space", space).Msg("space not found")
|
||||
return nil, fmt.Errorf("space not found")
|
||||
}
|
||||
md := sResp.Info.ArbitraryMetadata.GetMetadata()
|
||||
if md == nil {
|
||||
g.logger.Error().Err(err).Interface("space", space).Msg("could not read metadata from space")
|
||||
return nil, fmt.Errorf("could not read metadata from space")
|
||||
}
|
||||
return md, nil
|
||||
}
|
||||
|
||||
func (g Graph) setSpaceMetadata(ctx context.Context, metadata map[string]string, resourceID *storageprovider.ResourceId) error {
|
||||
if len(metadata) == 0 {
|
||||
return nil
|
||||
}
|
||||
client := g.GetGatewayClient()
|
||||
resMd, err := client.SetArbitraryMetadata(
|
||||
ctx,
|
||||
&storageprovider.SetArbitraryMetadataRequest{
|
||||
ArbitraryMetadata: &storageprovider.ArbitraryMetadata{
|
||||
Metadata: metadata,
|
||||
},
|
||||
Ref: &storageprovider.Reference{
|
||||
ResourceId: resourceID,
|
||||
},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
g.logger.Error().Msg("transport error, could not set metadata")
|
||||
return err
|
||||
}
|
||||
if resMd.Status.Code != cs3rpc.Code_CODE_OK {
|
||||
g.logger.Error().Msg("could not set metadata")
|
||||
return fmt.Errorf("could not set metadata")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g Graph) GetSpecialSpaceItems(ctx context.Context, baseURL *url.URL, spaceRootID *storageprovider.ResourceId, metadata map[string]string) []libregraph.DriveItem {
|
||||
func (g Graph) GetSpecialSpaceItems(ctx context.Context, baseURL *url.URL, space *storageprovider.StorageSpace) []libregraph.DriveItem {
|
||||
var spaceItems []libregraph.DriveItem
|
||||
if metadata == nil {
|
||||
if space.Opaque == nil {
|
||||
return spaceItems
|
||||
}
|
||||
if readmePath, ok := metadata[ReadmePathAttrName]; ok {
|
||||
readmeItem, err := g.getDriveItem(ctx, spaceRootID, readmePath)
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err).Str(ReadmePathAttrName, readmePath).Msg("Could not get readme Item")
|
||||
} else {
|
||||
readmeItem.SpecialFolder = &libregraph.SpecialFolder{Name: libregraph.PtrString(ReadmePathSpecialFolderName)}
|
||||
readmeItem.WebDavUrl = libregraph.PtrString(baseURL.String() + filepath.Join(spaceRootID.OpaqueId, readmePath))
|
||||
spaceItems = append(spaceItems, *readmeItem)
|
||||
metadata := space.Opaque.Map
|
||||
if readmeAttr, ok := metadata[ReadmeSpecialFolderName]; ok {
|
||||
readmeID := string(readmeAttr.Value)
|
||||
if readmeID != "" {
|
||||
readmeItem, err := g.getDriveItem(ctx, &storageprovider.ResourceId{StorageId: space.Root.StorageId, OpaqueId: readmeID})
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err).Str("ID", readmeID).Msg("Could not get readme Item")
|
||||
}
|
||||
readmePath, err := g.getPathForDriveItem(ctx, &storageprovider.ResourceId{StorageId: space.Root.StorageId, OpaqueId: readmeID})
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err).Str("ID", readmeID).Msg("Could not get readme path")
|
||||
} else {
|
||||
readmeItem.SpecialFolder = &libregraph.SpecialFolder{Name: libregraph.PtrString(ReadmeSpecialFolderName)}
|
||||
readmeItem.WebDavUrl = libregraph.PtrString(baseURL.String() + filepath.Join(space.Root.OpaqueId, *readmePath))
|
||||
spaceItems = append(spaceItems, *readmeItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
if imagePath, ok := metadata[SpaceImageAttrName]; ok {
|
||||
imageItem, err := g.getDriveItem(ctx, spaceRootID, imagePath)
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err).Str(SpaceImageAttrName, imagePath).Msg("Could not get image Item")
|
||||
} else {
|
||||
imageItem.SpecialFolder = &libregraph.SpecialFolder{Name: libregraph.PtrString(SpaceImageSpecialFolderName)}
|
||||
imageItem.WebDavUrl = libregraph.PtrString(baseURL.String() + filepath.Join(spaceRootID.OpaqueId, imagePath))
|
||||
spaceItems = append(spaceItems, *imageItem)
|
||||
if metadataAttr, ok := metadata[SpaceImageSpecialFolderName]; ok {
|
||||
imageID := string(metadataAttr.Value)
|
||||
if imageID != "" {
|
||||
imageItem, err := g.getDriveItem(ctx, &storageprovider.ResourceId{StorageId: space.Root.StorageId, OpaqueId: imageID})
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err).Str("ID", imageID).Msg("Could not get image Item")
|
||||
}
|
||||
imagePath, err := g.getPathForDriveItem(ctx, &storageprovider.ResourceId{StorageId: space.Root.StorageId, OpaqueId: imageID})
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err).Str("ID", imageID).Msg("Could not get image path")
|
||||
} else {
|
||||
imageItem.SpecialFolder = &libregraph.SpecialFolder{Name: libregraph.PtrString(SpaceImageSpecialFolderName)}
|
||||
imageItem.WebDavUrl = libregraph.PtrString(baseURL.String() + filepath.Join(space.Root.OpaqueId, *imagePath))
|
||||
spaceItems = append(spaceItems, *imageItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
return spaceItems
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"math"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -192,6 +191,18 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
|
||||
Quota: getQuota(drive.Quota, g.config.Spaces.DefaultQuota),
|
||||
}
|
||||
|
||||
spaceDescription := *drive.Description
|
||||
if spaceDescription != "" {
|
||||
csr.Opaque = &types.Opaque{
|
||||
Map: map[string]*types.OpaqueEntry{
|
||||
"permissions": {
|
||||
Decoder: "plain",
|
||||
Value: []byte(spaceDescription),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := client.CreateStorageSpace(r.Context(), &csr)
|
||||
if err != nil {
|
||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
|
||||
@@ -265,6 +276,7 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
|
||||
},
|
||||
}
|
||||
|
||||
// Use the Opaque prop of the request
|
||||
if restore, _ := strconv.ParseBool(r.Header.Get("restore")); restore {
|
||||
updateSpaceRequest.Opaque = &types.Opaque{
|
||||
Map: map[string]*types.OpaqueEntry{
|
||||
@@ -276,38 +288,29 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// Use the Opaque prop of the space
|
||||
opaque := make(map[string]*types.OpaqueEntry)
|
||||
spaceDescription := *drive.Description
|
||||
if spaceDescription != "" {
|
||||
opaque["description"] = &types.OpaqueEntry{
|
||||
Decoder: "plain",
|
||||
Value: []byte(spaceDescription),
|
||||
}
|
||||
}
|
||||
|
||||
for _, special := range drive.Special {
|
||||
if special.Id != nil {
|
||||
opaque[*special.SpecialFolder.Name] = &types.OpaqueEntry{
|
||||
Decoder: "plain",
|
||||
Value: []byte(*special.Id),
|
||||
}
|
||||
}
|
||||
}
|
||||
updateSpaceRequest.StorageSpace.Opaque = &types.Opaque{Map: opaque}
|
||||
|
||||
if drive.Name != nil {
|
||||
updateSpaceRequest.StorageSpace.Name = *drive.Name
|
||||
}
|
||||
metadata := make(map[string]string)
|
||||
for _, specialItem := range drive.Special {
|
||||
|
||||
baseUrl, err := url.Parse(g.config.Spaces.WebDavBase + g.config.Spaces.WebDavPath + driveID)
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err)
|
||||
}
|
||||
newURL, err := filepath.Rel(baseUrl.String(), *specialItem.WebDavUrl)
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err)
|
||||
}
|
||||
switch *specialItem.SpecialFolder.Name {
|
||||
case SpaceImageSpecialFolderName:
|
||||
metadata[SpaceImageAttrName] = newURL
|
||||
case ReadmePathSpecialFolderName:
|
||||
metadata[ReadmePathAttrName] = newURL
|
||||
}
|
||||
}
|
||||
|
||||
if drive.Description != nil {
|
||||
metadata[SpaceDescriptionAttrName] = *drive.Description
|
||||
}
|
||||
|
||||
if metadata != nil {
|
||||
err = g.setSpaceMetadata(r.Context(), metadata, root)
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
if drive.Quota.HasTotal() {
|
||||
user := ctxpkg.ContextMustGetUser(r.Context())
|
||||
@@ -360,33 +363,15 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
|
||||
render.JSON(w, r, spaces[0])
|
||||
}
|
||||
|
||||
func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, mds []*storageprovider.StorageSpace) ([]*libregraph.Drive, error) {
|
||||
responses := make([]*libregraph.Drive, 0, len(mds))
|
||||
for i := range mds {
|
||||
res, err := g.cs3StorageSpaceToDrive(baseURL, mds[i])
|
||||
func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, storageSpaces []*storageprovider.StorageSpace) ([]*libregraph.Drive, error) {
|
||||
responses := make([]*libregraph.Drive, 0, len(storageSpaces))
|
||||
for _, storageSpace := range storageSpaces {
|
||||
res, err := g.cs3StorageSpaceToDrive(baseURL, storageSpace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
md, err := g.getDriveMetadata(ctx, mds[i])
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err).Interface("space", mds[i]).Msg("error reading extendedSpaceProperties")
|
||||
continue
|
||||
}
|
||||
|
||||
if sd, ok := md[SpaceDescriptionAttrName]; ok {
|
||||
res.Description = libregraph.PtrString(sd)
|
||||
}
|
||||
res.Special = g.GetSpecialSpaceItems(
|
||||
ctx,
|
||||
baseURL,
|
||||
&storageprovider.ResourceId{
|
||||
StorageId: mds[i].Root.StorageId,
|
||||
OpaqueId: mds[i].Root.OpaqueId,
|
||||
},
|
||||
md,
|
||||
)
|
||||
|
||||
res.Quota, err = g.getDriveQuota(ctx, mds[i])
|
||||
res.Special = g.GetSpecialSpaceItems(ctx, baseURL, storageSpace)
|
||||
res.Quota, err = g.getDriveQuota(ctx, storageSpace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -502,6 +487,11 @@ func (g Graph) cs3StorageSpaceToDrive(baseURL *url.URL, space *storageprovider.S
|
||||
Permissions: permissions,
|
||||
},
|
||||
}
|
||||
if space.Opaque != nil {
|
||||
if description, ok := space.Opaque.Map["description"]; ok {
|
||||
drive.Description = libregraph.PtrString(string(description.Value))
|
||||
}
|
||||
}
|
||||
|
||||
if space.Opaque != nil && space.Opaque.Map != nil {
|
||||
v, ok := space.Opaque.Map["trashed"]
|
||||
|
||||
@@ -23,6 +23,8 @@ type GatewayClient interface {
|
||||
// Returns the home path for the given authenticated user.
|
||||
// When a user has access to multiple storage providers, one of them is the home.
|
||||
GetHome(ctx context.Context, in *provider.GetHomeRequest, opts ...grpc.CallOption) (*provider.GetHomeResponse, error)
|
||||
// GetPath does a path lookup for a resource by ID
|
||||
GetPath(ctx context.Context, in *provider.GetPathRequest, opts ...grpc.CallOption) (*provider.GetPathResponse, error)
|
||||
// Returns a list of resource information
|
||||
// for the provided reference.
|
||||
// MUST return CODE_NOT_FOUND if the reference does not exists.
|
||||
@@ -39,8 +41,6 @@ type GatewayClient interface {
|
||||
ListStorageSpaces(ctx context.Context, in *provider.ListStorageSpacesRequest, opts ...grpc.CallOption) (*provider.ListStorageSpacesResponse, error)
|
||||
// Updates a storage space.
|
||||
UpdateStorageSpace(ctx context.Context, in *provider.UpdateStorageSpaceRequest, opts ...grpc.CallOption) (*provider.UpdateStorageSpaceResponse, error)
|
||||
// SetArbitraryMetadata stores key value metadata
|
||||
SetArbitraryMetadata(ctx context.Context, in *provider.SetArbitraryMetadataRequest, opts ...grpc.CallOption) (*provider.SetArbitraryMetadataResponse, error)
|
||||
// Deletes a storage space.
|
||||
DeleteStorageSpace(ctx context.Context, in *provider.DeleteStorageSpaceRequest, opts ...grpc.CallOption) (*provider.DeleteStorageSpaceResponse, error)
|
||||
// Returns the quota available under the provided
|
||||
@@ -92,9 +92,6 @@ const (
|
||||
NoSpaceFoundMessage = "space with id `%s` not found"
|
||||
ListStorageSpacesTransportErr = "transport error sending list storage spaces grpc request"
|
||||
ListStorageSpacesReturnsErr = "list storage spaces grpc request returns an errorcode in the response"
|
||||
ReadmePathAttrName = "space.readme"
|
||||
ReadmePathSpecialFolderName = "readme"
|
||||
SpaceImageAttrName = "space.image"
|
||||
ReadmeSpecialFolderName = "readme"
|
||||
SpaceImageSpecialFolderName = "image"
|
||||
SpaceDescriptionAttrName = "space.description"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user