Skip to content

Commit

Permalink
poc: server side space defaults
Browse files Browse the repository at this point in the history
Signed-off-by: jkoberg <[email protected]>
  • Loading branch information
kobergj committed Mar 7, 2024
1 parent 53fcb80 commit edbc82b
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 0 deletions.
1 change: 1 addition & 0 deletions services/graph/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Spaces struct {
ExtendedSpacePropertiesCacheTTL int `yaml:"extended_space_properties_cache_ttl" env:"GRAPH_SPACES_EXTENDED_SPACE_PROPERTIES_CACHE_TTL" desc:"Max TTL in seconds for the spaces property cache." introductionVersion:"pre5.0"`
UsersCacheTTL int `yaml:"users_cache_ttl" env:"GRAPH_SPACES_USERS_CACHE_TTL" desc:"Max TTL in seconds for the spaces users cache." introductionVersion:"pre5.0"`
GroupsCacheTTL int `yaml:"groups_cache_ttl" env:"GRAPH_SPACES_GROUPS_CACHE_TTL" desc:"Max TTL in seconds for the spaces groups cache." introductionVersion:"pre5.0"`
TemplatePath string `yaml:"template_path" env:"GRAPH_SPACES_TEMPLATE_PATH" desc:"The path to a folder containg files and folder that should be created on any space." introductionVersion:"5.0"`
}

type LDAP struct {
Expand Down
21 changes: 21 additions & 0 deletions services/graph/pkg/service/v0/drives.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"io/fs"
"math"
"net/http"
"net/url"
Expand Down Expand Up @@ -488,6 +489,26 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
}

ctx, cs3, err := g.getCS3Client(gatewayClient, resp.GetStorageSpace().GetRoot())
if err != nil {
logger.Error().Err(err).Msg("could not get cs3 client")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "could not get cs3 client, aborting")
return
}

fsys, err := fs.Sub(_spaceTemplateFS, "spacetemplate")
if err != nil {
logger.Error().Err(err).Msg("could not create drive: error parsing fs")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
}

if err := applyTemplate(ctx, cs3, gatewayClient, resp.GetStorageSpace().GetRoot(), fsys.(fs.ReadDirFS)); err != nil {
logger.Error().Err(err).Msg("could not apply template to space")
return
}

render.Status(r, http.StatusCreated)
render.JSON(w, r, newDrive)
}
Expand Down
6 changes: 6 additions & 0 deletions services/graph/pkg/service/v0/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package svc
import (
"crypto/tls"
"crypto/x509"
"embed"
"errors"
"fmt"
"net/http"
Expand Down Expand Up @@ -35,6 +36,11 @@ const (
displayNameAttr = "displayName"
)

var (
//go:embed spacetemplate/*
_spaceTemplateFS embed.FS
)

// Service defines the service handlers.
type Service interface {
ServeHTTP(http.ResponseWriter, *http.Request)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Space description goes here
97 changes: 97 additions & 0 deletions services/graph/pkg/service/v0/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@ package svc
import (
"context"
"encoding/json"
"errors"
"io"
"io/fs"
"net/http"
"os"
"path/filepath"
"reflect"
"strings"

gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
cs3User "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
v1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/v2/pkg/storage/utils/metadata"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"
"golang.org/x/sync/errgroup"
Expand Down Expand Up @@ -425,3 +433,92 @@ func cs3ReceivedShareToLibreGraphPermissions(ctx context.Context, logger *log.Lo

return permission, nil
}

func (g Graph) getCS3Client(gwc gateway.GatewayAPIClient, root *storageprovider.ResourceId) (context.Context, *metadata.CS3, error) {
mdc := metadata.NewCS3(g.config.Reva.Address, "com.owncloud.api.storage-users")
mdc.SpaceRoot = root
ctx, err := utils.GetServiceUserContext(g.config.ServiceAccount.ServiceAccountID, gwc, g.config.ServiceAccount.ServiceAccountSecret)
return ctx, mdc, err
}

func applyTemplate(ctx context.Context, mdc *metadata.CS3, gwc gateway.GatewayAPIClient, root *storageprovider.ResourceId, fsys fs.ReadDirFS) error {
entries, err := fsys.ReadDir(".")
if err != nil {
return err
}

updateSpaceRequest := &storageprovider.UpdateStorageSpaceRequest{
// Prepare the object to apply the diff from. The properties on StorageSpace will overwrite
// the original storage space.
StorageSpace: &storageprovider.StorageSpace{
Id: &storageprovider.StorageSpaceId{
OpaqueId: storagespace.FormatResourceID(*root),
},
Root: root,
},
}

updateSpaceRequest.StorageSpace.Opaque, err = uploadFolder(ctx, mdc, "", "", updateSpaceRequest.StorageSpace.Opaque, fsys, entries)
if err != nil {
return err
}

if len(updateSpaceRequest.StorageSpace.Opaque.Map) == 0 {
return nil
}

resp, err := gwc.UpdateStorageSpace(ctx, updateSpaceRequest)
switch {
case err != nil:
return err
case resp.Status.Code == rpc.Code_CODE_OK:
return nil
default:
return errors.New(resp.Status.Message)
}
}

func uploadFolder(ctx context.Context, mdc *metadata.CS3, pathOnDisc, pathOnSpace string, opaque *v1beta1.Opaque, fsys fs.ReadDirFS, entries []os.DirEntry) (*v1beta1.Opaque, error) {
for _, entry := range entries {
spacePath := filepath.Join(pathOnSpace, entry.Name())
discPath := filepath.Join(pathOnDisc, entry.Name())

if entry.IsDir() {
err := mdc.MakeDirIfNotExist(ctx, spacePath)
if err != nil {
return opaque, err
}

entries, err := fsys.ReadDir(discPath)
if err != nil {
return opaque, err
}

opaque, err = uploadFolder(ctx, mdc, discPath, spacePath, opaque, fsys, entries)
if err != nil {
return opaque, err
}
continue
}

b, err := fs.ReadFile(fsys, discPath)
if err != nil {
return opaque, err
}

if err := mdc.SimpleUpload(ctx, spacePath, b); err != nil {
return opaque, err
}

// TODO: use upload to avoid second stat
i, err := mdc.Stat(ctx, spacePath)
if err != nil {
return opaque, err
}

identifier := strings.TrimSuffix(entry.Name(), filepath.Ext(entry.Name()))
opaque = utils.AppendPlainToOpaque(opaque, identifier, storagespace.FormatResourceID(*i.Id))
}

return opaque, nil
}

0 comments on commit edbc82b

Please sign in to comment.