Merge pull request #2739 from owncloud/spaces-registry

[full-ci] Spaces registry
This commit is contained in:
Michael Barz
2022-01-11 17:18:46 +01:00
committed by GitHub
39 changed files with 947 additions and 972 deletions

View File

@@ -6,15 +6,15 @@ import (
"path"
"path/filepath"
"github.com/cs3org/reva/pkg/auth/scope"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
v1beta11 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/pkg/auth/scope"
revactx "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/token"
"github.com/cs3org/reva/pkg/token/manager/jwt"
"github.com/cs3org/reva/pkg/utils"
"github.com/owncloud/ocis/accounts/pkg/config"
"github.com/owncloud/ocis/accounts/pkg/proto/v0"
olog "github.com/owncloud/ocis/ocis-pkg/log"
@@ -22,16 +22,12 @@ import (
"google.golang.org/grpc/metadata"
)
const (
storageMountPath = "/meta"
)
// CS3Repo provides a cs3 implementation of the Repo interface
type CS3Repo struct {
cfg *config.Config
tm token.Manager
storageProvider provider.ProviderAPIClient
metadataStorage metadatastorage.MetadataStorage
metadataStorage *metadatastorage.MetadataStorage
}
// NewCS3Repo creates a new cs3 repo
@@ -54,12 +50,22 @@ func NewCS3Repo(cfg *config.Config) (Repo, error) {
return nil, err
}
return CS3Repo{
r := CS3Repo{
cfg: cfg,
tm: tokenManager,
storageProvider: client,
metadataStorage: ms,
}, nil
metadataStorage: &ms,
}
ctx, err := r.getAuthenticatedContext(context.Background())
if err != nil {
return nil, err
}
if err := ms.Init(ctx, cfg.ServiceUser); err != nil {
return nil, err
}
return r, nil
}
// WriteAccount writes an account via cs3 and modifies the provided account (e.g. with a generated id).
@@ -102,7 +108,8 @@ func (r CS3Repo) LoadAccounts(ctx context.Context, a *[]*proto.Account) (err err
res, err := r.storageProvider.ListContainer(ctx, &provider.ListContainerRequest{
Ref: &provider.Reference{
Path: path.Join(storageMountPath, accountsFolder),
ResourceId: r.metadataStorage.SpaceRoot,
Path: utils.MakeRelativePath(accountsFolder),
},
})
if err != nil {
@@ -142,7 +149,8 @@ func (r CS3Repo) DeleteAccount(ctx context.Context, id string) (err error) {
resp, err := r.storageProvider.Delete(ctx, &provider.DeleteRequest{
Ref: &provider.Reference{
Path: path.Join(storageMountPath, accountsFolder, id),
ResourceId: r.metadataStorage.SpaceRoot,
Path: utils.MakeRelativePath(filepath.Join("/", accountsFolder, id)),
},
})
@@ -197,7 +205,8 @@ func (r CS3Repo) LoadGroups(ctx context.Context, g *[]*proto.Group) (err error)
res, err := r.storageProvider.ListContainer(ctx, &provider.ListContainerRequest{
Ref: &provider.Reference{
Path: path.Join(storageMountPath, groupsFolder),
ResourceId: r.metadataStorage.SpaceRoot,
Path: utils.MakeRelativePath(groupsFolder),
},
})
if err != nil {
@@ -237,7 +246,8 @@ func (r CS3Repo) DeleteGroup(ctx context.Context, id string) (err error) {
resp, err := r.storageProvider.Delete(ctx, &provider.DeleteRequest{
Ref: &provider.Reference{
Path: path.Join(storageMountPath, groupsFolder, id),
ResourceId: r.metadataStorage.SpaceRoot,
Path: utils.MakeRelativePath(filepath.Join(groupsFolder, id)),
},
})
@@ -289,13 +299,14 @@ func (r CS3Repo) groupURL(id string) string {
}
func (r CS3Repo) makeRootDirIfNotExist(ctx context.Context, folder string) error {
return MakeDirIfNotExist(ctx, r.storageProvider, folder)
return MakeDirIfNotExist(ctx, r.storageProvider, r.metadataStorage.SpaceRoot, folder)
}
// MakeDirIfNotExist will create a root node in the metadata storage. Requires an authenticated context.
func MakeDirIfNotExist(ctx context.Context, sp provider.ProviderAPIClient, folder string) error {
func MakeDirIfNotExist(ctx context.Context, sp provider.ProviderAPIClient, root *provider.ResourceId, folder string) error {
var rootPathRef = &provider.Reference{
Path: path.Join(storageMountPath, folder),
ResourceId: root,
Path: utils.MakeRelativePath(folder),
}
resp, err := sp.Stat(ctx, &provider.StatRequest{

9
go.mod
View File

@@ -31,6 +31,7 @@ require (
github.com/gofrs/uuid v4.2.0+incompatible
github.com/golang-jwt/jwt/v4 v4.2.0
github.com/golang/protobuf v1.5.2
github.com/google/uuid v1.3.0
github.com/gookit/config/v2 v2.0.27
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.2
@@ -76,6 +77,7 @@ require (
require (
contrib.go.opencensus.io/exporter/prometheus v0.4.0 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e // indirect
github.com/BurntSushi/toml v0.4.1 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
@@ -141,7 +143,6 @@ require (
github.com/gomodule/redigo v1.8.6 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gookit/goutil v0.4.0 // indirect
github.com/gorilla/schema v1.2.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
@@ -213,7 +214,6 @@ require (
github.com/sony/gobreaker v0.5.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/steveyen/gtreap v0.1.0 // indirect
github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f // indirect
github.com/tus/tusd v1.8.0 // indirect
github.com/wk8/go-ordered-map v0.2.0 // indirect
github.com/xanzy/ssh-agent v0.3.1 // indirect
@@ -242,3 +242,8 @@ require (
stash.kopano.io/kgol/kcc-go/v5 v5.0.1 // indirect
stash.kopano.io/kgol/oidc-go v0.3.2 // indirect
)
//replace github.com/cs3org/reva => github.com/cs3org/reva v1.16.1-0.20211208164450-3abd76eecf8b
//replace github.com/cs3org/reva => ../reva
replace github.com/cs3org/reva => github.com/cs3org/reva v1.16.1-0.20220111150347-1b21aefbf8db

7
go.sum
View File

@@ -84,6 +84,7 @@ github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzS
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e h1:ZU22z/2YRFLyf/P4ZwUYSdNCWsMEI0VeyrFoI2rAhJQ=
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CiscoM31/godata v1.0.5 h1:AITXpa/5ybXEq59A0nqUGiS7ZXVJnQtFw5o09tyN/UA=
@@ -323,8 +324,8 @@ 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-20211214102047-7ce3134d7bf8 h1:PqOprF37OvwCbAN5W23znknGk6N/LMayqLAeP904FHE=
github.com/cs3org/go-cs3apis v0.0.0-20211214102047-7ce3134d7bf8/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/cs3org/reva v1.17.1-0.20220105095955-fa1d1fc01d85 h1:4MjQ95MeeffQA9dCraON4YXBwkxVmJpxSNMKnn0ryZA=
github.com/cs3org/reva v1.17.1-0.20220105095955-fa1d1fc01d85/go.mod h1:WqO2/NkAmx1qes09G92lGPxxyroQgnZetJrCPItCcDo=
github.com/cs3org/reva v1.16.1-0.20220111150347-1b21aefbf8db h1:YCzbz8N0OHkO6AcA2SfXHCc02Y/DqSkO+hm8Pj+eDZ4=
github.com/cs3org/reva v1.16.1-0.20220111150347-1b21aefbf8db/go.mod h1:WqO2/NkAmx1qes09G92lGPxxyroQgnZetJrCPItCcDo=
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=
@@ -1277,8 +1278,6 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/studio-b12/gowebdav v0.0.0-20210917133250-a3a86976a1df/go.mod h1:gCcfDlA1Y7GqOaeEKw5l9dOGx1VLdc/HuQSlQAaZ30s=
github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f h1:L2NE7BXnSlSLoNYZ0lCwZDjdnYjCNYC71k9ClZUTFTs=
github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/thanhpk/randstr v1.0.4 h1:IN78qu/bR+My+gHCvMEXhR/i5oriVHcTB/BJJIRTsNo=

View File

@@ -15,8 +15,6 @@ import (
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
v1beta11 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
ctxpkg "github.com/cs3org/reva/pkg/ctx"
@@ -213,7 +211,7 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
return
}
csr := provider.CreateStorageSpaceRequest{
csr := storageprovider.CreateStorageSpaceRequest{
Owner: us,
Type: driveType,
Name: spaceName,
@@ -226,7 +224,7 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
return
}
if resp.GetStatus().GetCode() != v1beta11.Code_CODE_OK {
if resp.GetStatus().GetCode() != cs3rpc.Code_CODE_OK {
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "")
return
}
@@ -266,32 +264,34 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
return
}
root := &storageprovider.ResourceId{}
identifierParts := strings.Split(driveID, "!")
if len(identifierParts) != 2 {
switch len(identifierParts) {
case 1:
root.StorageId, root.OpaqueId = identifierParts[0], identifierParts[0]
case 2:
root.StorageId, root.OpaqueId = identifierParts[0], identifierParts[1]
default:
errorcode.GeneralException.Render(w, r, http.StatusBadRequest, fmt.Sprintf("invalid resource id: %v", driveID))
w.WriteHeader(http.StatusInternalServerError)
return
}
storageID, opaqueID := identifierParts[0], identifierParts[1]
client, err := g.GetClient()
if err != nil {
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
}
updateSpaceRequest := &provider.UpdateStorageSpaceRequest{
updateSpaceRequest := &storageprovider.UpdateStorageSpaceRequest{
// Prepare the object to apply the diff from. The properties on StorageSpace will overwrite
// the original storage space.
StorageSpace: &provider.StorageSpace{
StorageSpace: &storageprovider.StorageSpace{
Id: &storageprovider.StorageSpaceId{
OpaqueId: driveID,
},
Root: &provider.ResourceId{
StorageId: storageID,
OpaqueId: opaqueID,
OpaqueId: root.StorageId + "!" + root.OpaqueId,
},
Root: root,
},
}
@@ -321,9 +321,9 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
return
}
if resp.GetStatus().GetCode() != v1beta11.Code_CODE_OK {
if resp.GetStatus().GetCode() != cs3rpc.Code_CODE_OK {
switch resp.Status.GetCode() {
case v1beta11.Code_CODE_NOT_FOUND:
case cs3rpc.Code_CODE_NOT_FOUND:
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, resp.GetStatus().GetMessage())
return
default:
@@ -395,17 +395,16 @@ func formatDriveItems(mds []*storageprovider.ResourceInfo) ([]*libregraph.DriveI
func cs3StorageSpaceToDrive(baseURL *url.URL, space *storageprovider.StorageSpace) (*libregraph.Drive, error) {
rootID := space.Root.StorageId + "!" + space.Root.OpaqueId
if space.Root.StorageId == space.Root.OpaqueId {
// omit opaqueid
rootID = space.Root.StorageId
}
drive := &libregraph.Drive{
Id: &space.Id.OpaqueId,
Id: &rootID,
Name: &space.Name,
//"createdDateTime": "string (timestamp)", // TODO read from StorageSpace ... needs Opaque for now
//"description": "string", // TODO read from StorageSpace ... needs Opaque for now
Owner: &libregraph.IdentitySet{
User: &libregraph.Identity{
Id: &space.Owner.Id.OpaqueId,
// DisplayName: , TODO read and cache from users provider
},
},
DriveType: &space.SpaceType,
Root: &libregraph.DriveItem{
Id: &rootID,
@@ -420,6 +419,15 @@ func cs3StorageSpaceToDrive(baseURL *url.URL, space *storageprovider.StorageSpac
drive.Root.WebDavUrl = &webDavURL
}
// TODO The public space has no owner ... should we even show it?
if space.Owner != nil && space.Owner.Id != nil {
drive.Owner = &libregraph.IdentitySet{
User: &libregraph.Identity{
Id: &space.Owner.Id.OpaqueId,
// DisplayName: , TODO read and cache from users provider
},
}
}
if space.Mtime != nil {
lastModified := cs3TimestampToTime(space.Mtime)
drive.LastModifiedDateTime = &lastModified
@@ -447,27 +455,26 @@ func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, mds []*storag
if err != nil {
return nil, err
}
qta, err := g.getDriveQuota(ctx, mds[i])
res.Quota, err = g.getDriveQuota(ctx, mds[i])
if err != nil {
return nil, err
}
res.Quota = &qta
responses = append(responses, res)
}
return responses, nil
}
func (g Graph) getDriveQuota(ctx context.Context, space *storageprovider.StorageSpace) (libregraph.Quota, error) {
func (g Graph) getDriveQuota(ctx context.Context, space *storageprovider.StorageSpace) (*libregraph.Quota, error) {
client, err := g.GetClient()
if err != nil {
g.logger.Error().Err(err).Msg("error creating grpc client")
return libregraph.Quota{}, err
return nil, err
}
req := &gateway.GetQuotaRequest{
Ref: &provider.Reference{
ResourceId: &provider.ResourceId{
Ref: &storageprovider.Reference{
ResourceId: &storageprovider.ResourceId{
StorageId: space.Root.StorageId,
OpaqueId: space.Root.OpaqueId,
},
@@ -478,10 +485,13 @@ func (g Graph) getDriveQuota(ctx context.Context, space *storageprovider.Storage
switch {
case err != nil:
g.logger.Error().Err(err).Msg("error sending get quota grpc request")
return libregraph.Quota{}, err
return nil, nil
case res.Status.Code == cs3rpc.Code_CODE_UNIMPLEMENTED:
// TODO well duh
return nil, nil
case res.Status.Code != cs3rpc.Code_CODE_OK:
g.logger.Error().Err(err).Msg("error sending sending get quota grpc request")
return libregraph.Quota{}, err
return nil, err
}
total := int64(res.TotalBytes)
@@ -496,7 +506,7 @@ func (g Graph) getDriveQuota(ctx context.Context, space *storageprovider.Storage
state := calculateQuotaState(total, used)
qta.State = &state
return qta, nil
return &qta, nil
}
func calculateQuotaState(total int64, used int64) (state string) {
@@ -514,16 +524,16 @@ func calculateQuotaState(total int64, used int64) (state string) {
}
}
func getQuota(quota *libregraph.Quota, defaultQuota string) *provider.Quota {
func getQuota(quota *libregraph.Quota, defaultQuota string) *storageprovider.Quota {
switch {
case quota != nil && quota.Total != nil:
if q := *quota.Total; q >= 0 {
return &provider.Quota{QuotaMaxBytes: uint64(q)}
return &storageprovider.Quota{QuotaMaxBytes: uint64(q)}
}
fallthrough
case defaultQuota != "":
if q, err := strconv.ParseInt(defaultQuota, 10, 64); err == nil && q >= 0 {
return &provider.Quota{QuotaMaxBytes: uint64(q)}
return &storageprovider.Quota{QuotaMaxBytes: uint64(q)}
}
fallthrough
default:

View File

@@ -19,6 +19,7 @@ import (
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/token"
"github.com/cs3org/reva/pkg/token/manager/jwt"
"github.com/cs3org/reva/pkg/utils"
"google.golang.org/grpc/metadata"
"github.com/owncloud/ocis/ocis-pkg/indexer/index"
@@ -93,6 +94,14 @@ func (idx *Autoincrement) Init() error {
}
idx.metadataStorage = &m
ctx, err := idx.getAuthenticatedContext(context.Background())
if err != nil {
return err
}
if err := idx.metadataStorage.Init(ctx, idx.cs3conf.ServiceUser); err != nil {
return err
}
if err := idx.makeDirIfNotExists(idx.indexBaseDir); err != nil {
return err
}
@@ -162,10 +171,14 @@ func (idx *Autoincrement) Remove(id string, v string) error {
return err
}
deletePath := path.Join("/meta", idx.indexRootDir, v)
deletePath := path.Join("/", idx.indexRootDir, v)
resp, err := idx.storageProvider.Delete(ctx, &provider.DeleteRequest{
Ref: &provider.Reference{
Path: deletePath,
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(deletePath),
},
})
@@ -203,7 +216,11 @@ func (idx *Autoincrement) Search(pattern string) ([]string, error) {
res, err := idx.storageProvider.ListContainer(ctx, &provider.ListContainerRequest{
Ref: &provider.Reference{
Path: path.Join("/meta", idx.indexRootDir),
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(idx.indexRootDir),
},
})
@@ -289,8 +306,10 @@ func (idx *Autoincrement) makeDirIfNotExists(folder string) error {
if err != nil {
return err
}
return storage.MakeDirIfNotExist(ctx, idx.storageProvider, folder)
return storage.MakeDirIfNotExist(ctx, idx.storageProvider, &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
}, folder)
}
func (idx *Autoincrement) next() (int, error) {
@@ -301,7 +320,11 @@ func (idx *Autoincrement) next() (int, error) {
res, err := idx.storageProvider.ListContainer(ctx, &provider.ListContainerRequest{
Ref: &provider.Reference{
Path: path.Join("/meta", idx.indexRootDir), //TODO:
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(idx.indexRootDir),
},
})
@@ -348,5 +371,5 @@ func (idx *Autoincrement) Delete() error {
return err
}
return deleteIndexRoot(ctx, idx.storageProvider, idx.indexRootDir)
return deleteIndexRoot(ctx, idx.storageProvider, idx.cs3conf.ServiceUser.UUID, idx.indexRootDir)
}

View File

@@ -3,16 +3,20 @@ package cs3
import (
"context"
"fmt"
"path"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/pkg/utils"
)
func deleteIndexRoot(ctx context.Context, storageProvider provider.ProviderAPIClient, indexRootDir string) error {
func deleteIndexRoot(ctx context.Context, storageProvider provider.ProviderAPIClient, spaceid, indexRootDir string) error {
res, err := storageProvider.Delete(ctx, &provider.DeleteRequest{
Ref: &provider.Reference{
Path: path.Join("/meta", indexRootDir),
ResourceId: &provider.ResourceId{
StorageId: spaceid,
OpaqueId: spaceid,
},
Path: utils.MakeRelativePath(indexRootDir),
},
})
if err != nil {

View File

@@ -15,6 +15,7 @@ import (
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/token"
"github.com/cs3org/reva/pkg/token/manager/jwt"
"github.com/cs3org/reva/pkg/utils"
idxerrs "github.com/owncloud/ocis/ocis-pkg/indexer/errors"
"github.com/owncloud/ocis/ocis-pkg/indexer/index"
"github.com/owncloud/ocis/ocis-pkg/indexer/option"
@@ -95,6 +96,14 @@ func (idx *NonUnique) Init() error {
}
idx.metadataStorage = &m
ctx, err := idx.getAuthenticatedContext(context.Background())
if err != nil {
return err
}
if err := idx.metadataStorage.Init(ctx, idx.cs3conf.ServiceUser); err != nil {
return err
}
if err := idx.makeDirIfNotExists(idx.indexBaseDir); err != nil {
return err
}
@@ -119,7 +128,11 @@ func (idx *NonUnique) Lookup(v string) ([]string, error) {
res, err := idx.storageProvider.ListContainer(ctx, &provider.ListContainerRequest{
Ref: &provider.Reference{
Path: path.Join("/meta", idx.indexRootDir, v),
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(path.Join("/", idx.indexRootDir, v)),
},
})
@@ -172,10 +185,14 @@ func (idx *NonUnique) Remove(id string, v string) error {
return err
}
deletePath := path.Join("/meta", idx.indexRootDir, v, id)
deletePath := path.Join("/", idx.indexRootDir, v, id)
resp, err := idx.storageProvider.Delete(ctx, &provider.DeleteRequest{
Ref: &provider.Reference{
Path: deletePath,
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(deletePath),
},
})
@@ -187,10 +204,14 @@ func (idx *NonUnique) Remove(id string, v string) error {
return &idxerrs.NotFoundErr{TypeName: idx.typeName, Key: idx.indexBy, Value: v}
}
toStat := path.Join("/meta", idx.indexRootDir, v)
toStat := path.Join("/", idx.indexRootDir, v)
lcResp, err := idx.storageProvider.ListContainer(ctx, &provider.ListContainerRequest{
Ref: &provider.Reference{
Path: toStat,
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(toStat),
},
})
if err != nil {
@@ -198,10 +219,14 @@ func (idx *NonUnique) Remove(id string, v string) error {
}
if len(lcResp.Infos) == 0 {
deletePath = path.Join("/meta", idx.indexRootDir, v)
deletePath = path.Join("/", idx.indexRootDir, v)
_, err := idx.storageProvider.Delete(ctx, &provider.DeleteRequest{
Ref: &provider.Reference{
Path: deletePath,
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(deletePath),
},
})
if err != nil {
@@ -245,7 +270,11 @@ func (idx *NonUnique) Search(pattern string) ([]string, error) {
matches := make([]string, 0)
res, err := idx.storageProvider.ListContainer(ctx, &provider.ListContainerRequest{
Ref: &provider.Reference{
Path: path.Join("/meta", idx.indexRootDir),
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(idx.indexRootDir),
},
})
@@ -266,7 +295,11 @@ func (idx *NonUnique) Search(pattern string) ([]string, error) {
for i := range foldersMatched {
res, _ := idx.storageProvider.ListContainer(ctx, &provider.ListContainerRequest{
Ref: &provider.Reference{
Path: foldersMatched[i],
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(foldersMatched[i]),
},
})
@@ -303,7 +336,10 @@ func (idx *NonUnique) makeDirIfNotExists(folder string) error {
if err != nil {
return err
}
return storage.MakeDirIfNotExist(ctx, idx.storageProvider, folder)
return storage.MakeDirIfNotExist(ctx, idx.storageProvider, &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
}, folder)
}
func (idx *NonUnique) createSymlink(oldname, newname string) error {
@@ -356,5 +392,5 @@ func (idx *NonUnique) Delete() error {
return err
}
return deleteIndexRoot(ctx, idx.storageProvider, idx.indexRootDir)
return deleteIndexRoot(ctx, idx.storageProvider, idx.cs3conf.ServiceUser.UUID, idx.indexRootDir)
}

View File

@@ -32,7 +32,7 @@ package cs3
// sut := NewNonUniqueIndexWithOptions(
// option.WithTypeName(GetTypeFQN(User{})),
// option.WithIndexBy("UserName"),
// option.WithFilesDir(path.Join(cfg.Repo.Disk.Path, "/meta")),
// option.WithFilesDir(path.Join(cfg.Repo.Disk.Path, "/")),
// option.WithDataDir(cfg.Repo.Disk.Path),
// option.WithDataURL(cfg.Repo.CS3.DataURL),
// option.WithDataPrefix(cfg.Repo.CS3.DataPrefix),

View File

@@ -15,6 +15,7 @@ import (
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/token"
"github.com/cs3org/reva/pkg/token/manager/jwt"
"github.com/cs3org/reva/pkg/utils"
idxerrs "github.com/owncloud/ocis/ocis-pkg/indexer/errors"
"github.com/owncloud/ocis/ocis-pkg/indexer/index"
"github.com/owncloud/ocis/ocis-pkg/indexer/option"
@@ -90,6 +91,14 @@ func (idx *Unique) Init() error {
}
idx.metadataStorage = &m
ctx, err := idx.getAuthenticatedContext(context.Background())
if err != nil {
return err
}
if err := idx.metadataStorage.Init(ctx, idx.cs3conf.ServiceUser); err != nil {
return err
}
if err := idx.makeDirIfNotExists(idx.indexBaseDir); err != nil {
return err
}
@@ -162,10 +171,14 @@ func (idx *Unique) Remove(id string, v string) error {
return err
}
deletePath := path.Join("/meta", idx.indexRootDir, v)
deletePath := path.Join("/", idx.indexRootDir, v)
resp, err := idx.storageProvider.Delete(ctx, &provider.DeleteRequest{
Ref: &provider.Reference{
Path: deletePath,
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(deletePath),
},
})
@@ -212,7 +225,11 @@ func (idx *Unique) Search(pattern string) ([]string, error) {
res, err := idx.storageProvider.ListContainer(ctx, &provider.ListContainerRequest{
Ref: &provider.Reference{
Path: path.Join("/meta", idx.indexRootDir),
ResourceId: &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
},
Path: utils.MakeRelativePath(idx.indexRootDir),
},
})
@@ -299,7 +316,10 @@ func (idx *Unique) makeDirIfNotExists(folder string) error {
if err != nil {
return err
}
return storage.MakeDirIfNotExist(ctx, idx.storageProvider, folder)
return storage.MakeDirIfNotExist(ctx, idx.storageProvider, &provider.ResourceId{
StorageId: idx.cs3conf.ServiceUser.UUID,
OpaqueId: idx.cs3conf.ServiceUser.UUID,
}, folder)
}
func (idx *Unique) getAuthenticatedContext(ctx context.Context) (context.Context, error) {
@@ -318,5 +338,5 @@ func (idx *Unique) Delete() error {
return err
}
return deleteIndexRoot(ctx, idx.storageProvider, idx.indexRootDir)
return deleteIndexRoot(ctx, idx.storageProvider, idx.cs3conf.ServiceUser.UUID, idx.indexRootDir)
}

View File

@@ -32,7 +32,7 @@ package cs3
// sut := NewUniqueIndexWithOptions(
// option.WithTypeName(GetTypeFQN(User{})),
// option.WithIndexBy("UserName"),
// option.WithFilesDir(path.Join(cfg.Repo.Disk.Path, "/meta")),
// option.WithFilesDir(path.Join(cfg.Repo.Disk.Path, "/")),
// option.WithDataDir(cfg.Repo.Disk.Path),
// option.WithDataURL(cfg.Repo.CS3.DataURL),
// option.WithDataPrefix(cfg.Repo.CS3.DataPrefix),
@@ -82,7 +82,7 @@ package cs3
// sut := NewUniqueIndexWithOptions(
// option.WithTypeName(GetTypeFQN(User{})),
// option.WithIndexBy("UserName"),
// option.WithFilesDir(path.Join(cfg.Repo.Disk.Path, "/meta")),
// option.WithFilesDir(path.Join(cfg.Repo.Disk.Path, "/")),
// option.WithDataDir(cfg.Repo.Disk.Path),
// option.WithDataURL(cfg.Repo.CS3.DataURL),
// option.WithDataPrefix(cfg.Repo.CS3.DataPrefix),

View File

@@ -6,20 +6,20 @@ import (
"errors"
"io/ioutil"
"net/http"
"path"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
v1beta11 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
revactx "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/utils"
"github.com/owncloud/ocis/accounts/pkg/config"
"google.golang.org/grpc/metadata"
)
const (
storageMountPath = "/meta"
)
func NewMetadataStorage(providerAddr string) (s MetadataStorage, err error) {
p, err := pool.GetStorageProviderServiceClient(providerAddr)
if err != nil {
return MetadataStorage{}, err
@@ -36,17 +36,56 @@ func NewMetadataStorage(providerAddr string) (s MetadataStorage, err error) {
type MetadataStorage struct {
storageProvider provider.ProviderAPIClient
dataGatewayClient *http.Client
SpaceRoot *provider.ResourceId
}
func (r MetadataStorage) SimpleUpload(ctx context.Context, uploadpath string, content []byte) error {
// init creates the metadata space
func (ms *MetadataStorage) Init(ctx context.Context, serviceUser config.ServiceUser) (err error) {
// FIXME change CS3 api to allow sending a space id
cssr, err := ms.storageProvider.CreateStorageSpace(ctx, &provider.CreateStorageSpaceRequest{
Opaque: &typesv1beta1.Opaque{
Map: map[string]*typesv1beta1.OpaqueEntry{
"spaceid": {
Decoder: "plain",
Value: []byte(serviceUser.UUID),
},
},
},
Owner: &user.User{
Id: &user.UserId{
OpaqueId: serviceUser.UUID,
},
Groups: []string{},
UidNumber: serviceUser.UID,
GidNumber: serviceUser.GID,
},
Name: "Metadata",
Type: "metadata",
})
switch {
case err != nil:
return err
case cssr.Status.Code == v1beta11.Code_CODE_OK:
ms.SpaceRoot = cssr.StorageSpace.Root
case cssr.Status.Code == v1beta11.Code_CODE_ALREADY_EXISTS:
// TODO make CreateStorageSpace return existing space?
ms.SpaceRoot = &provider.ResourceId{StorageId: serviceUser.UUID, OpaqueId: serviceUser.UUID}
default:
return errtypes.NewErrtypeFromStatus(cssr.Status)
}
return nil
}
func (ms MetadataStorage) SimpleUpload(ctx context.Context, uploadpath string, content []byte) error {
ref := provider.InitiateFileUploadRequest{
Ref: &provider.Reference{
Path: path.Join(storageMountPath, uploadpath),
ResourceId: ms.SpaceRoot,
Path: utils.MakeRelativePath(uploadpath),
},
}
res, err := r.storageProvider.InitiateFileUpload(ctx, &ref)
res, err := ms.storageProvider.InitiateFileUpload(ctx, &ref)
if err != nil {
return err
}
@@ -70,7 +109,7 @@ func (r MetadataStorage) SimpleUpload(ctx context.Context, uploadpath string, co
md, _ := metadata.FromOutgoingContext(ctx)
req.Header.Add(revactx.TokenHeader, md.Get(revactx.TokenHeader)[0])
resp, err := r.dataGatewayClient.Do(req)
resp, err := ms.dataGatewayClient.Do(req)
if err != nil {
return err
}
@@ -80,14 +119,15 @@ func (r MetadataStorage) SimpleUpload(ctx context.Context, uploadpath string, co
return nil
}
func (r MetadataStorage) SimpleDownload(ctx context.Context, downloadpath string) (content []byte, err error) {
func (ms MetadataStorage) SimpleDownload(ctx context.Context, downloadpath string) (content []byte, err error) {
ref := provider.InitiateFileDownloadRequest{
Ref: &provider.Reference{
Path: path.Join(storageMountPath, downloadpath),
ResourceId: ms.SpaceRoot,
Path: utils.MakeRelativePath(downloadpath),
},
}
res, err := r.storageProvider.InitiateFileDownload(ctx, &ref)
res, err := ms.storageProvider.InitiateFileDownload(ctx, &ref)
if err != nil {
return []byte{}, err
}
@@ -95,13 +135,13 @@ func (r MetadataStorage) SimpleDownload(ctx context.Context, downloadpath string
var endpoint string
for _, proto := range res.GetProtocols() {
if proto.Protocol == "simple" {
if proto.Protocol == "spaces" {
endpoint = proto.GetDownloadEndpoint()
break
}
}
if endpoint == "" {
return []byte{}, errors.New("metadata storage doesn't support the simple download protocol")
return []byte{}, errors.New("metadata storage doesn't support the spaces download protocol")
}
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
@@ -111,7 +151,7 @@ func (r MetadataStorage) SimpleDownload(ctx context.Context, downloadpath string
md, _ := metadata.FromOutgoingContext(ctx)
req.Header.Add(revactx.TokenHeader, md.Get(revactx.TokenHeader)[0])
resp, err := r.dataGatewayClient.Do(req)
resp, err := ms.dataGatewayClient.Do(req)
if err != nil {
return []byte{}, err
}

View File

@@ -7,23 +7,22 @@ import (
"github.com/urfave/cli/v2"
)
// StorageHomeCommand is the entrypoint for the storage-home command.
func StorageHomeCommand(cfg *config.Config) *cli.Command {
// StorageSharesCommand is the entrypoint for the storage-shares command.
func StorageSharesCommand(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "storage-home",
Usage: "start storage and data provider for /home mount",
Name: "storage-shares",
Usage: "start storage and data provider for shares jail",
Category: "extensions",
//Flags: flagset.StorageHomeWithConfig(cfg.Storage),
Before: func(ctx *cli.Context) error {
return ParseStorageCommon(ctx, cfg)
},
Action: func(c *cli.Context) error {
origCmd := command.StorageHome(cfg.Storage)
origCmd := command.StorageShares(cfg.Storage)
return handleOriginalAction(c, origCmd)
},
}
}
func init() {
register.AddCommand(StorageHomeCommand)
register.AddCommand(StorageSharesCommand)
}

View File

@@ -108,8 +108,8 @@ func NewService(options ...Option) (*Service, error) {
s.ServicesRegistry["storage-authbasic"] = storage.NewAuthBasic
s.ServicesRegistry["storage-authbearer"] = storage.NewAuthBearer
s.ServicesRegistry["storage-authmachine"] = storage.NewAuthMachine
s.ServicesRegistry["storage-home"] = storage.NewStorageHome
s.ServicesRegistry["storage-users"] = storage.NewStorageUsers
s.ServicesRegistry["storage-shares"] = storage.NewStorageShares
s.ServicesRegistry["storage-public-link"] = storage.NewStoragePublicLink
s.ServicesRegistry["storage-appprovider"] = storage.NewAppProvider

View File

@@ -480,6 +480,22 @@ func assertUsersSame(t *testing.T, expected, actual User, quotaAvailable bool) {
}
}
func findAccount(t *testing.T, username string) (*accountsProto.Account, error) {
cl := accountsProto.NewAccountsService("com.owncloud.api.accounts", service.Client())
req := &accountsProto.ListAccountsRequest{
Query: "preferred_name eq '" + username + "'",
}
res, err := cl.ListAccounts(context.Background(), req)
if err != nil {
return nil, err
}
if len(res.Accounts) == 0 {
return nil, fmt.Errorf("username %s not found", username)
}
return res.Accounts[0], err
}
func deleteAccount(t *testing.T, id string) (*empty.Empty, error) {
cl := accountsProto.NewAccountsService("com.owncloud.api.accounts", service.Client())
@@ -1431,12 +1447,17 @@ func TestGetSingleUser(t *testing.T) {
t.Fatal(err)
}
a, err := findAccount(t, user.ID)
if err != nil {
t.Fatal(err)
}
formatpart := getFormatString(format)
res, err := sendRequest(
"GET",
fmt.Sprintf("/%v/cloud/user%v", ocsVersion, formatpart),
"",
&User{ID: user.ID},
&User{ID: a.Id},
[]string{ssvc.BundleUUIDRoleUser},
)

View File

@@ -19,6 +19,7 @@ import (
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/token/manager/jwt"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0"
"github.com/owncloud/ocis/ocs/pkg/service/v0/data"
"github.com/owncloud/ocis/ocs/pkg/service/v0/response"
@@ -197,7 +198,7 @@ func (o Ocs) AddUser(w http.ResponseWriter, r *http.Request) {
}
newAccount := &accounts.Account{
Id: userid,
Id: uuid.New().String(),
DisplayName: displayname,
PreferredName: userid,
OnPremisesSamAccountName: userid,
@@ -398,77 +399,51 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
o.logger.Error().Err(err).Msg("error securing a connection to Reva gateway")
}
homeResp, err := gwc.GetHome(ctx, &provider.GetHomeRequest{})
if err != nil {
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not get home").Error()))
return
}
if homeResp.Status.Code != rpcv1beta1.Code_CODE_OK {
o.logger.Error().
Str("stat_status_code", homeResp.Status.Code.String()).
Str("stat_message", homeResp.Status.Message).
Msg("DeleteUser: could not get user home: get failed")
return
}
statResp, err := gwc.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{
Path: homeResp.Path,
lsRes, err := gwc.ListStorageSpaces(ctx, &provider.ListStorageSpacesRequest{
Filters: []*provider.ListStorageSpacesRequest_Filter{
{
Type: provider.ListStorageSpacesRequest_Filter_TYPE_OWNER,
Term: &provider.ListStorageSpacesRequest_Filter_Owner{
Owner: &revauser.UserId{
Idp: o.config.IdentityManagement.Address,
OpaqueId: account.Id,
},
},
},
{
Type: provider.ListStorageSpacesRequest_Filter_TYPE_SPACE_TYPE,
Term: &provider.ListStorageSpacesRequest_Filter_SpaceType{
SpaceType: "personal",
},
},
},
})
if err != nil {
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not stat home").Error()))
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not list owned personal spaces").Error()))
return
}
if statResp.Status.Code != rpcv1beta1.Code_CODE_OK {
if lsRes.Status.Code != rpcv1beta1.Code_CODE_OK {
o.logger.Error().
Str("stat_status_code", statResp.Status.Code.String()).
Str("stat_message", statResp.Status.Message).
Msg("DeleteUser: could not delete user home: stat failed")
Interface("status", lsRes.Status).
Msg("DeleteUser: could not list personal spaces")
return
}
delReq := &provider.DeleteRequest{
Ref: &provider.Reference{
ResourceId: statResp.Info.Id,
},
}
delResp, err := gwc.Delete(ctx, delReq)
if err != nil {
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not delete home").Error()))
return
}
if delResp.Status.Code != rpcv1beta1.Code_CODE_OK {
o.logger.Error().
Str("stat_status_code", statResp.Status.Code.String()).
Str("stat_message", statResp.Status.Message).
Msg("DeleteUser: could not delete user home: delete failed")
return
}
req := &provider.PurgeRecycleRequest{
Ref: &provider.Reference{
Path: homeResp.Path,
},
}
purgeRecycleResponse, err := gwc.PurgeRecycle(ctx, req)
if err != nil {
o.mustRender(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "could not delete trash").Error()))
return
}
if purgeRecycleResponse.Status.Code != rpcv1beta1.Code_CODE_OK {
o.logger.Error().
Str("stat_status_code", statResp.Status.Code.String()).
Str("stat_message", statResp.Status.Message).
Msg("DeleteUser: could not delete user trash: delete failed")
return
for _, space := range lsRes.StorageSpaces {
dsRes, err := gwc.DeleteStorageSpace(ctx, &provider.DeleteStorageSpaceRequest{
Id: space.Id,
})
if err != nil {
o.logger.Error().Err(err).Msg("DeleteUser: could not make delete space request")
continue
}
if dsRes.Status.Code != rpcv1beta1.Code_CODE_OK && dsRes.Status.Code != rpcv1beta1.Code_CODE_NOT_FOUND {
o.logger.Error().
Interface("status", dsRes.Status).
Msg("DeleteUser: could not delete space")
continue
}
}
}

View File

@@ -201,6 +201,7 @@ func frontendConfigFromStruct(c *cli.Context, cfg *config.Config, filesCfg map[s
"resource_info_cache_ttl": cfg.Reva.Frontend.OCSResourceInfoCacheTTL,
"prefix": cfg.Reva.Frontend.OCSPrefix,
"additional_info_attribute": cfg.Reva.Frontend.OCSAdditionalInfoAttribute,
"machine_auth_apikey": cfg.Reva.AuthMachineConfig.MachineAuthAPIKey,
"cache_warmup_driver": cfg.Reva.Frontend.OCSCacheWarmupDriver,
"cache_warmup_drivers": map[string]interface{}{
"cbox": map[string]interface{}{

View File

@@ -179,9 +179,8 @@ func gatewayConfigFromStruct(c *cli.Context, cfg *config.Config, logger log.Logg
"storageregistry": map[string]interface{}{
"driver": cfg.Reva.StorageRegistry.Driver,
"drivers": map[string]interface{}{
"static": map[string]interface{}{
"home_provider": cfg.Reva.StorageRegistry.HomeProvider,
"rules": rules(cfg, logger),
"spaces": map[string]interface{}{
"providers": spacesProviders(cfg, logger),
},
},
},
@@ -191,7 +190,7 @@ func gatewayConfigFromStruct(c *cli.Context, cfg *config.Config, logger log.Logg
return rcfg
}
func rules(cfg *config.Config, logger log.Logger) map[string]map[string]interface{} {
func spacesProviders(cfg *config.Config, logger log.Logger) map[string]map[string]interface{} {
// if a list of rules is given it overrides the generated rules from below
if len(cfg.Reva.StorageRegistry.Rules) > 0 {
@@ -219,18 +218,47 @@ func rules(cfg *config.Config, logger log.Logger) map[string]map[string]interfac
}
// generate rules based on default config
ret := map[string]map[string]interface{}{
cfg.Reva.StorageHome.MountPath: {"address": cfg.Reva.StorageHome.Endpoint},
cfg.Reva.StorageHome.AlternativeID: {"address": cfg.Reva.StorageHome.Endpoint},
cfg.Reva.StorageUsers.MountPath: {"address": cfg.Reva.StorageUsers.Endpoint},
cfg.Reva.StorageUsers.MountID + ".*": {"address": cfg.Reva.StorageUsers.Endpoint},
cfg.Reva.StoragePublicLink.MountPath: {"address": cfg.Reva.StoragePublicLink.Endpoint},
cfg.Reva.StoragePublicLink.MountID: {"address": cfg.Reva.StoragePublicLink.Endpoint},
return map[string]map[string]interface{}{
cfg.Reva.StorageUsers.Endpoint: {
"spaces": map[string]interface{}{
"personal": map[string]interface{}{
"mount_point": "/users",
"path_template": "/users/{{.Space.Owner.Id.OpaqueId}}",
},
"project": map[string]interface{}{
"mount_point": "/projects",
"path_template": "/projects/{{.Space.Name}}",
},
},
},
cfg.Reva.StorageShares.Endpoint: {
"spaces": map[string]interface{}{
"virtual": map[string]interface{}{
// The root of the share jail is mounted here
"mount_point": "/users/{{.CurrentUser.Id.OpaqueId}}/Shares",
},
"grant": map[string]interface{}{
// Grants are relative to a space root that the gateway will determine with a stat
"mount_point": ".",
},
"mountpoint": map[string]interface{}{
// The jail needs to be filled with mount points
// .Space.Name is a path relative to the mount point
"mount_point": "/users/{{.CurrentUser.Id.OpaqueId}}/Shares",
"path_template": "/users/{{.CurrentUser.Id.OpaqueId}}/Shares/{{.Space.Name}}",
},
},
},
// public link storage returns the mount id of the actual storage
cfg.Reva.StoragePublicLink.Endpoint: {
"spaces": map[string]interface{}{
"public": map[string]interface{}{
"mount_point": "/public",
},
},
},
// medatada storage not part of the global namespace
}
return ret
}
func mimetypes(cfg *config.Config, logger log.Logger) []map[string]interface{} {

View File

@@ -21,9 +21,9 @@ func GetCommands(cfg *config.Config) cli.Commands {
AuthBearer(cfg),
AuthMachine(cfg),
Sharing(cfg),
StorageHome(cfg),
StorageUsers(cfg),
StoragePublicLink(cfg),
StorageShares(cfg),
StorageUsers(cfg),
StorageMetadata(cfg),
Health(cfg),
}

View File

@@ -1,132 +0,0 @@
package storagedrivers
import (
"github.com/owncloud/ocis/storage/pkg/config"
)
func HomeDrivers(cfg *config.Config) map[string]interface{} {
return map[string]interface{}{
"eos": map[string]interface{}{
"namespace": cfg.Reva.UserStorage.EOS.Root,
"shadow_namespace": cfg.Reva.UserStorage.EOS.ShadowNamespace,
"uploads_namespace": cfg.Reva.UserStorage.EOS.UploadsNamespace,
"share_folder": cfg.Reva.UserStorage.EOS.ShareFolder,
"eos_binary": cfg.Reva.UserStorage.EOS.EosBinary,
"xrdcopy_binary": cfg.Reva.UserStorage.EOS.XrdcopyBinary,
"master_url": cfg.Reva.UserStorage.EOS.MasterURL,
"slave_url": cfg.Reva.UserStorage.EOS.SlaveURL,
"cache_directory": cfg.Reva.UserStorage.EOS.CacheDirectory,
"sec_protocol": cfg.Reva.UserStorage.EOS.SecProtocol,
"keytab": cfg.Reva.UserStorage.EOS.Keytab,
"single_username": cfg.Reva.UserStorage.EOS.SingleUsername,
"enable_logging": cfg.Reva.UserStorage.EOS.EnableLogging,
"show_hidden_sys_files": cfg.Reva.UserStorage.EOS.ShowHiddenSysFiles,
"force_single_user_mode": cfg.Reva.UserStorage.EOS.ForceSingleUserMode,
"use_keytab": cfg.Reva.UserStorage.EOS.UseKeytab,
"gatewaysvc": cfg.Reva.UserStorage.EOS.GatewaySVC,
},
"eoshome": map[string]interface{}{
"namespace": cfg.Reva.UserStorage.EOS.Root,
"shadow_namespace": cfg.Reva.UserStorage.EOS.ShadowNamespace,
"uploads_namespace": cfg.Reva.UserStorage.EOS.UploadsNamespace,
"share_folder": cfg.Reva.UserStorage.EOS.ShareFolder,
"eos_binary": cfg.Reva.UserStorage.EOS.EosBinary,
"xrdcopy_binary": cfg.Reva.UserStorage.EOS.XrdcopyBinary,
"master_url": cfg.Reva.UserStorage.EOS.MasterURL,
"slave_url": cfg.Reva.UserStorage.EOS.SlaveURL,
"cache_directory": cfg.Reva.UserStorage.EOS.CacheDirectory,
"sec_protocol": cfg.Reva.UserStorage.EOS.SecProtocol,
"keytab": cfg.Reva.UserStorage.EOS.Keytab,
"single_username": cfg.Reva.UserStorage.EOS.SingleUsername,
"user_layout": cfg.Reva.UserStorage.EOS.UserLayout,
"enable_logging": cfg.Reva.UserStorage.EOS.EnableLogging,
"show_hidden_sys_files": cfg.Reva.UserStorage.EOS.ShowHiddenSysFiles,
"force_single_user_mode": cfg.Reva.UserStorage.EOS.ForceSingleUserMode,
"use_keytab": cfg.Reva.UserStorage.EOS.UseKeytab,
"gatewaysvc": cfg.Reva.UserStorage.EOS.GatewaySVC,
},
"eosgrpc": map[string]interface{}{
"namespace": cfg.Reva.UserStorage.EOS.Root,
"shadow_namespace": cfg.Reva.UserStorage.EOS.ShadowNamespace,
"share_folder": cfg.Reva.UserStorage.EOS.ShareFolder,
"eos_binary": cfg.Reva.UserStorage.EOS.EosBinary,
"xrdcopy_binary": cfg.Reva.UserStorage.EOS.XrdcopyBinary,
"master_url": cfg.Reva.UserStorage.EOS.MasterURL,
"master_grpc_uri": cfg.Reva.UserStorage.EOS.GrpcURI,
"slave_url": cfg.Reva.UserStorage.EOS.SlaveURL,
"cache_directory": cfg.Reva.UserStorage.EOS.CacheDirectory,
"sec_protocol": cfg.Reva.UserStorage.EOS.SecProtocol,
"keytab": cfg.Reva.UserStorage.EOS.Keytab,
"single_username": cfg.Reva.UserStorage.EOS.SingleUsername,
"user_layout": cfg.Reva.UserStorage.EOS.UserLayout,
"enable_logging": cfg.Reva.UserStorage.EOS.EnableLogging,
"show_hidden_sys_files": cfg.Reva.UserStorage.EOS.ShowHiddenSysFiles,
"force_single_user_mode": cfg.Reva.UserStorage.EOS.ForceSingleUserMode,
"use_keytab": cfg.Reva.UserStorage.EOS.UseKeytab,
"enable_home": true,
"gatewaysvc": cfg.Reva.UserStorage.EOS.GatewaySVC,
},
"local": map[string]interface{}{
"root": cfg.Reva.UserStorage.Local.Root,
"share_folder": cfg.Reva.UserStorage.Local.ShareFolder,
},
"localhome": map[string]interface{}{
"root": cfg.Reva.UserStorage.Local.Root,
"share_folder": cfg.Reva.UserStorage.Local.ShareFolder,
"user_layout": cfg.Reva.UserStorage.Local.UserLayout,
},
"owncloud": map[string]interface{}{
"datadirectory": cfg.Reva.UserStorage.OwnCloud.Root,
"upload_info_dir": cfg.Reva.UserStorage.OwnCloud.UploadInfoDir,
"share_folder": cfg.Reva.UserStorage.OwnCloud.ShareFolder,
"user_layout": cfg.Reva.UserStorage.OwnCloud.UserLayout,
"redis": cfg.Reva.UserStorage.OwnCloud.Redis,
"enable_home": true,
"scan": cfg.Reva.UserStorage.OwnCloud.Scan,
"userprovidersvc": cfg.Reva.Users.Endpoint,
},
"owncloudsql": map[string]interface{}{
"datadirectory": cfg.Reva.UserStorage.OwnCloudSQL.Root,
"upload_info_dir": cfg.Reva.UserStorage.OwnCloudSQL.UploadInfoDir,
"share_folder": cfg.Reva.UserStorage.OwnCloudSQL.ShareFolder,
"user_layout": cfg.Reva.UserStorage.OwnCloudSQL.UserLayout,
"enable_home": true,
"dbusername": cfg.Reva.UserStorage.OwnCloudSQL.DBUsername,
"dbpassword": cfg.Reva.UserStorage.OwnCloudSQL.DBPassword,
"dbhost": cfg.Reva.UserStorage.OwnCloudSQL.DBHost,
"dbport": cfg.Reva.UserStorage.OwnCloudSQL.DBPort,
"dbname": cfg.Reva.UserStorage.OwnCloudSQL.DBName,
"userprovidersvc": cfg.Reva.Users.Endpoint,
},
"ocis": map[string]interface{}{
"root": cfg.Reva.UserStorage.OCIS.Root,
"enable_home": true,
"user_layout": cfg.Reva.UserStorage.OCIS.UserLayout,
"share_folder": cfg.Reva.UserStorage.OCIS.ShareFolder,
"treetime_accounting": true,
"treesize_accounting": true,
"owner": cfg.Reva.UserStorage.OCIS.ServiceUserUUID, // the accounts service system account uuid
},
"s3": map[string]interface{}{
"region": cfg.Reva.UserStorage.S3.Region,
"access_key": cfg.Reva.UserStorage.S3.AccessKey,
"secret_key": cfg.Reva.UserStorage.S3.SecretKey,
"endpoint": cfg.Reva.UserStorage.S3.Endpoint,
"bucket": cfg.Reva.UserStorage.S3.Bucket,
},
"s3ng": map[string]interface{}{
"root": cfg.Reva.UserStorage.S3NG.Root,
"enable_home": true,
"user_layout": cfg.Reva.UserStorage.S3NG.UserLayout,
"treetime_accounting": true,
"treesize_accounting": true,
"owner": cfg.Reva.UserStorage.S3NG.ServiceUserUUID, // the accounts service system account uuid
"share_folder": cfg.Reva.UserStorage.S3NG.ShareFolder,
"s3.region": cfg.Reva.UserStorage.S3NG.Region,
"s3.access_key": cfg.Reva.UserStorage.S3NG.AccessKey,
"s3.secret_key": cfg.Reva.UserStorage.S3NG.SecretKey,
"s3.endpoint": cfg.Reva.UserStorage.S3NG.Endpoint,
"s3.bucket": cfg.Reva.UserStorage.S3NG.Bucket,
},
}
}

View File

@@ -132,7 +132,6 @@ func storageMetadataFromStruct(c *cli.Context, cfg *config.Config) map[string]in
},
"services": map[string]interface{}{
"storageprovider": map[string]interface{}{
"mount_path": "/meta",
"driver": cfg.Reva.StorageMetadata.Driver,
"drivers": storagedrivers.MetadataDrivers(cfg),
"data_server_url": cfg.Reva.StorageMetadata.DataServerURL,

View File

@@ -101,7 +101,6 @@ func storagePublicLinkConfigFromStruct(c *cli.Context, cfg *config.Config) map[s
},
"services": map[string]interface{}{
"publicstorageprovider": map[string]interface{}{
"mount_path": cfg.Reva.StoragePublicLink.MountPath,
"mount_id": cfg.Reva.StoragePublicLink.MountID,
"gateway_addr": cfg.Reva.Gateway.Endpoint,
},

View File

@@ -12,7 +12,6 @@ import (
"github.com/gofrs/uuid"
"github.com/oklog/run"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/storage/pkg/command/storagedrivers"
"github.com/owncloud/ocis/storage/pkg/config"
"github.com/owncloud/ocis/storage/pkg/server/debug"
"github.com/owncloud/ocis/storage/pkg/tracing"
@@ -20,13 +19,13 @@ import (
"github.com/urfave/cli/v2"
)
// StorageHome is the entrypoint for the storage-home command.
func StorageHome(cfg *config.Config) *cli.Command {
// StorageShares is the entrypoint for the storage-shares command.
func StorageShares(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "storage-home",
Usage: "start storage-home service",
Name: "storage-shares",
Usage: "start storage-shares service",
Before: func(c *cli.Context) error {
return ParseConfig(c, cfg, "storage-home")
return ParseConfig(c, cfg, "storage-shares")
},
Action: func(c *cli.Context) error {
logger := NewLogger(cfg)
@@ -40,7 +39,7 @@ func StorageHome(cfg *config.Config) *cli.Command {
uuid := uuid.Must(uuid.NewV4())
pidFile := path.Join(os.TempDir(), "revad-"+c.Command.Name+"-"+uuid.String()+".pid")
rcfg := storageHomeConfigFromStruct(c, cfg)
rcfg := storageSharesConfigFromStruct(c, cfg)
gr.Add(func() error {
runtime.RunWithOptions(
@@ -59,7 +58,7 @@ func StorageHome(cfg *config.Config) *cli.Command {
debugServer, err := debug.Server(
debug.Name(c.Command.Name+"-debug"),
debug.Addr(cfg.Reva.StorageHome.DebugAddr),
debug.Addr(cfg.Reva.StorageShares.DebugAddr),
debug.Logger(logger),
debug.Context(ctx),
debug.Config(cfg),
@@ -74,7 +73,7 @@ func StorageHome(cfg *config.Config) *cli.Command {
cancel()
})
if !cfg.Reva.StorageHome.Supervised {
if !cfg.Reva.StorageShares.Supervised {
sync.Trap(&gr, cancel)
}
@@ -83,11 +82,11 @@ func StorageHome(cfg *config.Config) *cli.Command {
}
}
// storageHomeConfigFromStruct will adapt an oCIS config struct into a reva mapstructure to start a reva service.
func storageHomeConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]interface{} {
// storageSharesConfigFromStruct will adapt an oCIS config struct into a reva mapstructure to start a reva service.
func storageSharesConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]interface{} {
rcfg := map[string]interface{}{
"core": map[string]interface{}{
"max_cpus": cfg.Reva.StorageHome.MaxCPUs,
"max_cpus": cfg.Reva.StorageShares.MaxCPUs,
"tracing_enabled": cfg.Tracing.Enabled,
"tracing_endpoint": cfg.Tracing.Endpoint,
"tracing_collector": cfg.Tracing.Collector,
@@ -99,38 +98,17 @@ func storageHomeConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]
"skip_user_groups_in_token": cfg.Reva.SkipUserGroupsInToken,
},
"grpc": map[string]interface{}{
"network": cfg.Reva.StorageHome.GRPCNetwork,
"address": cfg.Reva.StorageHome.GRPCAddr,
// TODO build services dynamically
"network": cfg.Reva.StorageShares.GRPCNetwork,
"address": cfg.Reva.StorageShares.GRPCAddr,
"services": map[string]interface{}{
"storageprovider": map[string]interface{}{
"driver": cfg.Reva.StorageHome.Driver,
"drivers": storagedrivers.HomeDrivers(cfg),
"mount_path": cfg.Reva.StorageHome.MountPath,
"mount_id": cfg.Reva.StorageHome.MountID,
"expose_data_server": cfg.Reva.StorageHome.ExposeDataServer,
"data_server_url": cfg.Reva.StorageHome.DataServerURL,
"tmp_folder": cfg.Reva.StorageHome.TempFolder,
},
},
},
"http": map[string]interface{}{
"network": cfg.Reva.StorageHome.HTTPNetwork,
"address": cfg.Reva.StorageHome.HTTPAddr,
// TODO build services dynamically
"services": map[string]interface{}{
"dataprovider": map[string]interface{}{
"prefix": cfg.Reva.StorageHome.HTTPPrefix,
"driver": cfg.Reva.StorageHome.Driver,
"drivers": storagedrivers.HomeDrivers(cfg),
"timeout": 86400,
"insecure": cfg.Reva.StorageHome.DataProvider.Insecure,
"disable_tus": false,
"sharesstorageprovider": map[string]interface{}{
"usershareprovidersvc": cfg.Reva.Sharing.Endpoint,
"gateway_addr": cfg.Reva.Gateway.Endpoint,
},
},
},
}
if cfg.Reva.StorageHome.ReadOnly {
if cfg.Reva.StorageShares.ReadOnly {
gcfg := rcfg["grpc"].(map[string]interface{})
gcfg["interceptors"] = map[string]interface{}{
"readonly": map[string]interface{}{},
@@ -139,35 +117,35 @@ func storageHomeConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]
return rcfg
}
// StorageHomeSutureService allows for the storage-home command to be embedded and supervised by a suture supervisor tree.
type StorageHomeSutureService struct {
// StorageSharesSutureService allows for the storage-shares command to be embedded and supervised by a suture supervisor tree.
type StorageSharesSutureService struct {
cfg *config.Config
}
// NewStorageHomeSutureService creates a new storage.StorageHomeSutureService
func NewStorageHome(cfg *ociscfg.Config) suture.Service {
// NewStorageShares creates a new storage.StorageSharesSutureService
func NewStorageShares(cfg *ociscfg.Config) suture.Service {
cfg.Storage.Commons = cfg.Commons
return StorageHomeSutureService{
return StorageSharesSutureService{
cfg: cfg.Storage,
}
}
func (s StorageHomeSutureService) Serve(ctx context.Context) error {
s.cfg.Reva.StorageHome.Context = ctx
func (s StorageSharesSutureService) Serve(ctx context.Context) error {
s.cfg.Reva.StorageShares.Context = ctx
f := &flag.FlagSet{}
cmdFlags := StorageHome(s.cfg).Flags
cmdFlags := StorageShares(s.cfg).Flags
for k := range cmdFlags {
if err := cmdFlags[k].Apply(f); err != nil {
return err
}
}
cliCtx := cli.NewContext(nil, f, nil)
if StorageHome(s.cfg).Before != nil {
if err := StorageHome(s.cfg).Before(cliCtx); err != nil {
if StorageShares(s.cfg).Before != nil {
if err := StorageShares(s.cfg).Before(cliCtx); err != nil {
return err
}
}
if err := StorageHome(s.cfg).Action(cliCtx); err != nil {
if err := StorageShares(s.cfg).Action(cliCtx); err != nil {
return err
}

View File

@@ -106,7 +106,6 @@ func storageUsersConfigFromStruct(c *cli.Context, cfg *config.Config) map[string
"storageprovider": map[string]interface{}{
"driver": cfg.Reva.StorageUsers.Driver,
"drivers": storagedrivers.UserDrivers(cfg),
"mount_path": cfg.Reva.StorageUsers.MountPath,
"mount_id": cfg.Reva.StorageUsers.MountID,
"expose_data_server": cfg.Reva.StorageUsers.ExposeDataServer,
"data_server_url": cfg.Reva.StorageUsers.DataServerURL,

View File

@@ -2,10 +2,6 @@ package config
import (
"context"
"os"
"path"
"github.com/owncloud/ocis/ocis-pkg/config/defaults"
"github.com/owncloud/ocis/ocis-pkg/shared"
)
@@ -195,7 +191,6 @@ type DataProvider struct {
type StoragePort struct {
Port
Driver string `ocisConfig:"driver"`
MountPath string `ocisConfig:"mount_path"`
MountID string `ocisConfig:"mount_id"`
AlternativeID string `ocisConfig:"alternative_id"`
ExposeDataServer bool `ocisConfig:"expose_data_server"`
@@ -473,7 +468,7 @@ type Reva struct {
AuthMachine Port `ocisConfig:"auth_machine"`
AuthMachineConfig AuthMachineConfig `ocisConfig:"auth_machine_config"`
Sharing Sharing `ocisConfig:"sharing"`
StorageHome StoragePort `ocisConfig:"storage_home"`
StorageShares StoragePort `ocisConfig:"storage_shares"`
StorageUsers StoragePort `ocisConfig:"storage_users"`
StoragePublicLink PublicStorage `ocisConfig:"storage_public_link"`
StorageMetadata StoragePort `ocisConfig:"storage_metadata"`
@@ -521,441 +516,6 @@ func New() *Config {
return &Config{}
}
func DefaultConfig() *Config {
return &Config{
// log is inherited
Debug: Debug{
Addr: "127.0.0.1:9109",
},
Reva: Reva{
JWTSecret: "Pive-Fumkiu4",
SkipUserGroupsInToken: false,
TransferSecret: "replace-me-with-a-transfer-secret",
TransferExpires: 24 * 60 * 60,
OIDC: OIDC{
Issuer: "https://localhost:9200",
Insecure: false,
IDClaim: "preferred_username",
},
LDAP: LDAP{
Hostname: "localhost",
Port: 9126,
CACert: path.Join(defaults.BaseDataPath(), "ldap", "ldap.crt"),
Insecure: false,
BaseDN: "dc=ocis,dc=test",
LoginFilter: "(&(objectclass=posixAccount)(|(cn={{login}})(mail={{login}})))",
UserFilter: "(&(objectclass=posixAccount)(|(ownclouduuid={{.OpaqueId}})(cn={{.OpaqueId}})))",
UserAttributeFilter: "(&(objectclass=posixAccount)({{attr}}={{value}}))",
UserFindFilter: "(&(objectclass=posixAccount)(|(cn={{query}}*)(displayname={{query}}*)(mail={{query}}*)))",
UserGroupFilter: "(&(objectclass=posixGroup)(ownclouduuid={{.OpaqueId}}*))",
GroupFilter: "(&(objectclass=posixGroup)(|(ownclouduuid={{.OpaqueId}})(cn={{.OpaqueId}})))",
GroupAttributeFilter: "(&(objectclass=posixGroup)({{attr}}={{value}}))",
GroupFindFilter: "(&(objectclass=posixGroup)(|(cn={{query}}*)(displayname={{query}}*)(mail={{query}}*)))",
GroupMemberFilter: "(&(objectclass=posixAccount)(ownclouduuid={{.OpaqueId}}*))",
BindDN: "cn=reva,ou=sysusers,dc=ocis,dc=test",
BindPassword: "reva",
IDP: "https://localhost:9200",
UserSchema: LDAPUserSchema{
UID: "ownclouduuid",
Mail: "mail",
DisplayName: "displayname",
CN: "cn",
UIDNumber: "uidnumber",
GIDNumber: "gidnumber",
},
GroupSchema: LDAPGroupSchema{
GID: "cn",
Mail: "mail",
DisplayName: "cn",
CN: "cn",
GIDNumber: "gidnumber",
},
},
UserGroupRest: UserGroupRest{
RedisAddress: "localhost:6379",
},
UserOwnCloudSQL: UserOwnCloudSQL{
DBUsername: "owncloud",
DBPassword: "secret",
DBHost: "mysql",
DBPort: 3306,
DBName: "owncloud",
Idp: "https://localhost:9200",
Nobody: 90,
JoinUsername: false,
JoinOwnCloudUUID: false,
EnableMedialSearch: false,
},
OCDav: OCDav{
WebdavNamespace: "/home/",
DavFilesNamespace: "/users/",
},
Archiver: Archiver{
MaxNumFiles: 10000,
MaxSize: 1073741824,
ArchiverURL: "/archiver",
},
UserStorage: StorageConfig{
EOS: DriverEOS{
DriverCommon: DriverCommon{
Root: "/eos/dockertest/reva",
ShareFolder: "/Shares",
UserLayout: "{{substr 0 1 .Username}}/{{.Username}}",
},
ShadowNamespace: "", // Defaults to path.Join(c.Namespace, ".shadow")
UploadsNamespace: "", // Defaults to path.Join(c.Namespace, ".uploads")
EosBinary: "/usr/bin/eos",
XrdcopyBinary: "/usr/bin/xrdcopy",
MasterURL: "root://eos-mgm1.eoscluster.cern.ch:1094",
SlaveURL: "root://eos-mgm1.eoscluster.cern.ch:1094",
CacheDirectory: os.TempDir(),
GatewaySVC: "127.0.0.1:9142",
},
Local: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "local", "users"),
ShareFolder: "/Shares",
UserLayout: "{{.Username}}",
EnableHome: false,
},
OwnCloud: DriverOwnCloud{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "owncloud"),
ShareFolder: "/Shares",
UserLayout: "{{.Id.OpaqueId}}",
EnableHome: false,
},
UploadInfoDir: path.Join(defaults.BaseDataPath(), "storage", "uploadinfo"),
Redis: ":6379",
Scan: true,
},
OwnCloudSQL: DriverOwnCloudSQL{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "owncloud"),
ShareFolder: "/Shares",
UserLayout: "{{.Username}}",
EnableHome: false,
},
UploadInfoDir: path.Join(defaults.BaseDataPath(), "storage", "uploadinfo"),
DBUsername: "owncloud",
DBPassword: "owncloud",
DBHost: "",
DBPort: 3306,
DBName: "owncloud",
},
S3: DriverS3{
DriverCommon: DriverCommon{},
Region: "default",
AccessKey: "",
SecretKey: "",
Endpoint: "",
Bucket: "",
},
S3NG: DriverS3NG{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "users"),
ShareFolder: "/Shares",
UserLayout: "{{.Id.OpaqueId}}",
EnableHome: false,
},
ServiceUserUUID: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad",
Region: "default",
AccessKey: "",
SecretKey: "",
Endpoint: "",
Bucket: "",
},
OCIS: DriverOCIS{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "users"),
ShareFolder: "/Shares",
UserLayout: "{{.Id.OpaqueId}}",
},
ServiceUserUUID: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad",
},
},
MetadataStorage: StorageConfig{
EOS: DriverEOS{
DriverCommon: DriverCommon{
Root: "/eos/dockertest/reva",
ShareFolder: "/Shares",
UserLayout: "{{substr 0 1 .Username}}/{{.Username}}",
EnableHome: false,
},
ShadowNamespace: "",
UploadsNamespace: "",
EosBinary: "/usr/bin/eos",
XrdcopyBinary: "/usr/bin/xrdcopy",
MasterURL: "root://eos-mgm1.eoscluster.cern.ch:1094",
GrpcURI: "",
SlaveURL: "root://eos-mgm1.eoscluster.cern.ch:1094",
CacheDirectory: os.TempDir(),
EnableLogging: false,
ShowHiddenSysFiles: false,
ForceSingleUserMode: false,
UseKeytab: false,
SecProtocol: "",
Keytab: "",
SingleUsername: "",
GatewaySVC: "127.0.0.1:9142",
},
Local: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "local", "metadata"),
},
OwnCloud: DriverOwnCloud{},
OwnCloudSQL: DriverOwnCloudSQL{},
S3: DriverS3{
DriverCommon: DriverCommon{},
Region: "default",
},
S3NG: DriverS3NG{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "metadata"),
ShareFolder: "",
UserLayout: "{{.Id.OpaqueId}}",
EnableHome: false,
},
ServiceUserUUID: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad",
Region: "default",
AccessKey: "",
SecretKey: "",
Endpoint: "",
Bucket: "",
},
OCIS: DriverOCIS{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "metadata"),
ShareFolder: "",
UserLayout: "{{.Id.OpaqueId}}",
EnableHome: false,
},
ServiceUserUUID: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad",
},
},
Frontend: FrontendPort{
Port: Port{
MaxCPUs: "",
LogLevel: "",
GRPCNetwork: "",
GRPCAddr: "",
HTTPNetwork: "tcp",
HTTPAddr: "127.0.0.1:9140",
Protocol: "",
Endpoint: "",
DebugAddr: "127.0.0.1:9141",
Services: []string{"datagateway", "ocdav", "ocs", "appprovider"},
Config: nil,
Context: nil,
Supervised: false,
},
AppProviderInsecure: false,
AppProviderPrefix: "",
ArchiverInsecure: false,
ArchiverPrefix: "archiver",
DatagatewayPrefix: "data",
Favorites: false,
OCDavInsecure: false,
OCDavPrefix: "",
OCSPrefix: "ocs",
OCSSharePrefix: "/Shares",
OCSHomeNamespace: "/home",
PublicURL: "https://localhost:9200",
OCSCacheWarmupDriver: "",
OCSAdditionalInfoAttribute: "{{.Mail}}",
OCSResourceInfoCacheTTL: 0,
Middleware: Middleware{},
},
DataGateway: DataGatewayPort{
Port: Port{},
PublicURL: "",
},
Gateway: Gateway{
Port: Port{
Endpoint: "127.0.0.1:9142",
DebugAddr: "127.0.0.1:9143",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9142",
},
CommitShareToStorageGrant: true,
CommitShareToStorageRef: true,
DisableHomeCreationOnLogin: false,
ShareFolder: "Shares",
LinkGrants: "",
HomeMapping: "",
EtagCacheTTL: 0,
},
StorageRegistry: StorageRegistry{
Driver: "static",
HomeProvider: "/home",
JSON: "",
},
AppRegistry: AppRegistry{
Driver: "static",
MimetypesJSON: "",
},
Users: Users{
Port: Port{
Endpoint: "localhost:9144",
DebugAddr: "127.0.0.1:9145",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9144",
Services: []string{"userprovider"},
},
Driver: "ldap",
UserGroupsCacheExpiration: 5,
},
Groups: Groups{
Port: Port{
Endpoint: "localhost:9160",
DebugAddr: "127.0.0.1:9161",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9160",
Services: []string{"groupprovider"},
},
Driver: "ldap",
GroupMembersCacheExpiration: 5,
},
AuthProvider: Users{
Port: Port{},
Driver: "ldap",
UserGroupsCacheExpiration: 0,
},
AuthBasic: Port{
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9146",
DebugAddr: "127.0.0.1:9147",
Services: []string{"authprovider"},
Endpoint: "localhost:9146",
},
AuthBearer: Port{
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9148",
DebugAddr: "127.0.0.1:9149",
Services: []string{"authprovider"},
Endpoint: "localhost:9148",
},
AuthMachine: Port{
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9166",
DebugAddr: "127.0.0.1:9167",
Services: []string{"authprovider"},
Endpoint: "localhost:9166",
},
AuthMachineConfig: AuthMachineConfig{
MachineAuthAPIKey: "change-me-please",
},
Sharing: Sharing{
Port: Port{
Endpoint: "localhost:9150",
DebugAddr: "127.0.0.1:9151",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9150",
Services: []string{"usershareprovider", "publicshareprovider"},
},
UserDriver: "json",
UserJSONFile: path.Join(defaults.BaseDataPath(), "storage", "shares.json"),
UserSQLUsername: "",
UserSQLPassword: "",
UserSQLHost: "",
UserSQLPort: 1433,
UserSQLName: "",
PublicDriver: "json",
PublicJSONFile: path.Join(defaults.BaseDataPath(), "storage", "publicshares.json"),
PublicPasswordHashCost: 11,
PublicEnableExpiredSharesCleanup: true,
PublicJanitorRunInterval: 60,
UserStorageMountID: "",
},
StorageHome: StoragePort{
Port: Port{
Endpoint: "localhost:9154",
DebugAddr: "127.0.0.1:9156",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9154",
HTTPNetwork: "tcp",
HTTPAddr: "127.0.0.1:9155",
},
Driver: "ocis",
ReadOnly: false,
MountPath: "/home",
AlternativeID: "1284d238-aa92-42ce-bdc4-0b0000009154",
MountID: "1284d238-aa92-42ce-bdc4-0b0000009157",
DataServerURL: "http://localhost:9155/data",
HTTPPrefix: "data",
TempFolder: path.Join(defaults.BaseDataPath(), "tmp", "home"),
},
StorageUsers: StoragePort{
Port: Port{
Endpoint: "localhost:9157",
DebugAddr: "127.0.0.1:9159",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9157",
HTTPNetwork: "tcp",
HTTPAddr: "127.0.0.1:9158",
},
MountPath: "/users",
MountID: "1284d238-aa92-42ce-bdc4-0b0000009157",
Driver: "ocis",
DataServerURL: "http://localhost:9158/data",
HTTPPrefix: "data",
TempFolder: path.Join(defaults.BaseDataPath(), "tmp", "users"),
},
StoragePublicLink: PublicStorage{
StoragePort: StoragePort{
Port: Port{
Endpoint: "localhost:9178",
DebugAddr: "127.0.0.1:9179",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9178",
},
MountPath: "/public",
MountID: "e1a73ede-549b-4226-abdf-40e69ca8230d",
},
PublicShareProviderAddr: "",
UserProviderAddr: "",
},
StorageMetadata: StoragePort{
Port: Port{
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9215",
HTTPNetwork: "tcp",
HTTPAddr: "127.0.0.1:9216",
DebugAddr: "127.0.0.1:9217",
},
Driver: "ocis",
ExposeDataServer: false,
DataServerURL: "http://localhost:9216/data",
TempFolder: path.Join(defaults.BaseDataPath(), "tmp", "metadata"),
DataProvider: DataProvider{},
},
AppProvider: AppProvider{
Port: Port{
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9164",
DebugAddr: "127.0.0.1:9165",
Endpoint: "localhost:9164",
Services: []string{"appprovider"},
},
ExternalAddr: "127.0.0.1:9164",
WopiDriver: WopiDriver{},
AppsURL: "/app/list",
OpenURL: "/app/open",
NewURL: "/app/new",
},
Configs: nil,
UploadMaxChunkSize: 1e+8,
UploadHTTPMethodOverride: "",
ChecksumSupportedTypes: []string{"sha1", "md5", "adler32"},
ChecksumPreferredUploadType: "",
DefaultUploadProtocol: "tus",
},
Tracing: Tracing{
Service: "storage",
Type: "jaeger",
},
Asset: Asset{},
}
}
// StructMappings binds a set of environment variables to a destination on cfg. Iterating over this set and editing the
// Destination value of a binding will alter the original value, as it is a pointer to its memory address. This lets
// us propagate changes easier.
@@ -993,10 +553,6 @@ func structMappings(cfg *Config) []shared.EnvBinding {
EnvVars: []string{"OCIS_INSECURE", "STORAGE_METADATA_DATAPROVIDER_INSECURE"},
Destination: &cfg.Reva.StorageMetadata.DataProvider.Insecure,
},
{
EnvVars: []string{"OCIS_INSECURE", "STORAGE_HOME_DATAPROVIDER_INSECURE"},
Destination: &cfg.Reva.StorageHome.DataProvider.Insecure,
},
{
EnvVars: []string{"OCIS_INSECURE", "STORAGE_FRONTEND_APPPROVIDER_INSECURE"},
Destination: &cfg.Reva.Frontend.AppProviderInsecure,
@@ -1025,10 +581,6 @@ func structMappings(cfg *Config) []shared.EnvBinding {
EnvVars: []string{"STORAGE_USERS_DRIVER"},
Destination: &cfg.Reva.StorageUsers.Driver,
},
{
EnvVars: []string{"STORAGE_HOME_DRIVER"},
Destination: &cfg.Reva.StorageHome.Driver,
},
{
EnvVars: []string{"STORAGE_USERS_DRIVER_OWNCLOUD_DATADIR"},
Destination: &cfg.Reva.UserStorage.OwnCloud.Root,
@@ -1418,37 +970,21 @@ func structMappings(cfg *Config) []shared.EnvBinding {
EnvVars: []string{"STORAGE_APPPROVIDER_ENDPOINT"},
Destination: &cfg.Reva.AppProvider.Endpoint,
},
{
EnvVars: []string{"STORAGE_HOME_ENDPOINT"},
Destination: &cfg.Reva.StorageHome.Endpoint,
},
{
EnvVars: []string{"STORAGE_HOME_MOUNT_PATH"},
Destination: &cfg.Reva.StorageHome.MountPath,
},
{
EnvVars: []string{"STORAGE_HOME_MOUNT_ID"},
Destination: &cfg.Reva.StorageHome.MountID,
},
{
EnvVars: []string{"STORAGE_USERS_ENDPOINT"},
Destination: &cfg.Reva.StorageUsers.Endpoint,
},
{
EnvVars: []string{"STORAGE_USERS_MOUNT_PATH"},
Destination: &cfg.Reva.StorageUsers.MountPath,
},
{
EnvVars: []string{"STORAGE_USERS_MOUNT_ID"},
Destination: &cfg.Reva.StorageUsers.MountID,
},
{
EnvVars: []string{"STORAGE_PUBLIC_LINK_ENDPOINT"},
Destination: &cfg.Reva.StoragePublicLink.Endpoint,
EnvVars: []string{"STORAGE_SHARES_ENDPOINT"},
Destination: &cfg.Reva.StorageShares.Endpoint,
},
{
EnvVars: []string{"STORAGE_PUBLIC_LINK_MOUNT_PATH"},
Destination: &cfg.Reva.StoragePublicLink.MountPath,
EnvVars: []string{"STORAGE_PUBLIC_LINK_ENDPOINT"},
Destination: &cfg.Reva.StoragePublicLink.Endpoint,
},
// groups
@@ -1695,48 +1231,6 @@ func structMappings(cfg *Config) []shared.EnvBinding {
Destination: &cfg.Reva.Sharing.UserSQLName,
},
// storage home
{
EnvVars: []string{"STORAGE_HOME_DEBUG_ADDR"},
Destination: &cfg.Reva.StorageHome.DebugAddr,
},
{
EnvVars: []string{"STORAGE_HOME_GRPC_NETWORK"},
Destination: &cfg.Reva.StorageHome.GRPCNetwork,
},
{
EnvVars: []string{"STORAGE_HOME_GRPC_ADDR"},
Destination: &cfg.Reva.StorageHome.GRPCAddr,
},
{
EnvVars: []string{"STORAGE_HOME_HTTP_NETWORK"},
Destination: &cfg.Reva.StorageHome.HTTPNetwork,
},
{
EnvVars: []string{"STORAGE_HOME_HTTP_ADDR"},
Destination: &cfg.Reva.StorageHome.HTTPAddr,
},
{
EnvVars: []string{"OCIS_STORAGE_READ_ONLY", "STORAGE_HOME_READ_ONLY"},
Destination: &cfg.Reva.StorageHome.ReadOnly,
},
{
EnvVars: []string{"STORAGE_HOME_EXPOSE_DATA_SERVER"},
Destination: &cfg.Reva.StorageHome.ExposeDataServer,
},
{
EnvVars: []string{"STORAGE_HOME_DATA_SERVER_URL"},
Destination: &cfg.Reva.StorageHome.DataServerURL,
},
{
EnvVars: []string{"STORAGE_HOME_HTTP_PREFIX"},
Destination: &cfg.Reva.StorageHome.HTTPPrefix,
},
{
EnvVars: []string{"STORAGE_HOME_TMP_FOLDER"},
Destination: &cfg.Reva.StorageHome.TempFolder,
},
// storage metadata
{
EnvVars: []string{"STORAGE_METADATA_DEBUG_ADDR"},
@@ -1827,6 +1321,32 @@ func structMappings(cfg *Config) []shared.EnvBinding {
Destination: &cfg.Reva.StorageUsers.TempFolder,
},
// storage shares
{
EnvVars: []string{"STORAGE_SHARES_DEBUG_ADDR"},
Destination: &cfg.Reva.StorageShares.DebugAddr,
},
{
EnvVars: []string{"STORAGE_SHARES_GRPC_NETWORK"},
Destination: &cfg.Reva.StorageShares.GRPCNetwork,
},
{
EnvVars: []string{"STORAGE_SHARES_GRPC_ADDR"},
Destination: &cfg.Reva.StorageShares.GRPCAddr,
},
{
EnvVars: []string{"STORAGE_SHARES_HTTP_NETWORK"},
Destination: &cfg.Reva.StorageShares.HTTPNetwork,
},
{
EnvVars: []string{"STORAGE_SHARES_HTTP_ADDR"},
Destination: &cfg.Reva.StorageShares.HTTPAddr,
},
{
EnvVars: []string{"OCIS_STORAGE_READ_ONLY", "STORAGE_SHARES_READ_ONLY"},
Destination: &cfg.Reva.StorageShares.ReadOnly,
},
// tracing
{
EnvVars: []string{"OCIS_TRACING_ENABLED", "STORAGE_TRACING_ENABLED"},

View File

@@ -0,0 +1,436 @@
package config
import (
"os"
"path"
"github.com/owncloud/ocis/ocis-pkg/config/defaults"
)
func DefaultConfig() *Config {
return &Config{
// log is inherited
Debug: Debug{
Addr: "127.0.0.1:9109",
},
Reva: Reva{
JWTSecret: "Pive-Fumkiu4",
SkipUserGroupsInToken: false,
TransferSecret: "replace-me-with-a-transfer-secret",
TransferExpires: 24 * 60 * 60,
OIDC: OIDC{
Issuer: "https://localhost:9200",
Insecure: false,
IDClaim: "preferred_username",
},
LDAP: LDAP{
Hostname: "localhost",
Port: 9126,
CACert: path.Join(defaults.BaseDataPath(), "ldap", "ldap.crt"),
Insecure: false,
BaseDN: "dc=ocis,dc=test",
LoginFilter: "(&(objectclass=posixAccount)(|(cn={{login}})(mail={{login}})))",
UserFilter: "(&(objectclass=posixAccount)(|(ownclouduuid={{.OpaqueId}})(cn={{.OpaqueId}})))",
UserAttributeFilter: "(&(objectclass=posixAccount)({{attr}}={{value}}))",
UserFindFilter: "(&(objectclass=posixAccount)(|(cn={{query}}*)(displayname={{query}}*)(mail={{query}}*)))",
UserGroupFilter: "(&(objectclass=posixGroup)(cn={{.}}*))", // FIXME (&(objectclass=posixGroup)(ownclouduuid={{.OpaqueId}}*)) in reva the template is executed with a string. IIRC rhaferkamp mentioned this
GroupFilter: "(&(objectclass=posixGroup)(|(ownclouduuid={{.OpaqueId}})(cn={{.OpaqueId}})))",
GroupAttributeFilter: "(&(objectclass=posixGroup)({{attr}}={{value}}))",
GroupFindFilter: "(&(objectclass=posixGroup)(|(cn={{query}}*)(displayname={{query}}*)(mail={{query}}*)))",
GroupMemberFilter: "(&(objectclass=posixAccount)(ownclouduuid={{.OpaqueId}}*))",
BindDN: "cn=reva,ou=sysusers,dc=ocis,dc=test",
BindPassword: "reva",
IDP: "https://localhost:9200",
UserSchema: LDAPUserSchema{
UID: "ownclouduuid",
Mail: "mail",
DisplayName: "displayname",
CN: "cn",
UIDNumber: "uidnumber",
GIDNumber: "gidnumber",
},
GroupSchema: LDAPGroupSchema{
GID: "cn",
Mail: "mail",
DisplayName: "cn",
CN: "cn",
GIDNumber: "gidnumber",
},
},
UserGroupRest: UserGroupRest{
RedisAddress: "localhost:6379",
},
UserOwnCloudSQL: UserOwnCloudSQL{
DBUsername: "owncloud",
DBPassword: "secret",
DBHost: "mysql",
DBPort: 3306,
DBName: "owncloud",
Idp: "https://localhost:9200",
Nobody: 90,
JoinUsername: false,
JoinOwnCloudUUID: false,
EnableMedialSearch: false,
},
OCDav: OCDav{
WebdavNamespace: "/users/{{.Id.OpaqueId}}",
DavFilesNamespace: "/users/{{.Id.OpaqueId}}",
},
Archiver: Archiver{
MaxNumFiles: 10000,
MaxSize: 1073741824,
ArchiverURL: "/archiver",
},
UserStorage: StorageConfig{
EOS: DriverEOS{
DriverCommon: DriverCommon{
Root: "/eos/dockertest/reva",
ShareFolder: "/Shares",
UserLayout: "{{substr 0 1 .Username}}/{{.Username}}",
},
ShadowNamespace: "", // Defaults to path.Join(c.Namespace, ".shadow")
UploadsNamespace: "", // Defaults to path.Join(c.Namespace, ".uploads")
EosBinary: "/usr/bin/eos",
XrdcopyBinary: "/usr/bin/xrdcopy",
MasterURL: "root://eos-mgm1.eoscluster.cern.ch:1094",
SlaveURL: "root://eos-mgm1.eoscluster.cern.ch:1094",
CacheDirectory: os.TempDir(),
GatewaySVC: "127.0.0.1:9142",
},
Local: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "local", "users"),
ShareFolder: "/Shares",
UserLayout: "{{.Username}}",
EnableHome: false,
},
OwnCloud: DriverOwnCloud{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "owncloud"),
ShareFolder: "/Shares",
UserLayout: "{{.Id.OpaqueId}}",
EnableHome: false,
},
UploadInfoDir: path.Join(defaults.BaseDataPath(), "storage", "uploadinfo"),
Redis: ":6379",
Scan: true,
},
OwnCloudSQL: DriverOwnCloudSQL{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "owncloud"),
ShareFolder: "/Shares",
UserLayout: "{{.Username}}",
EnableHome: false,
},
UploadInfoDir: path.Join(defaults.BaseDataPath(), "storage", "uploadinfo"),
DBUsername: "owncloud",
DBPassword: "owncloud",
DBHost: "",
DBPort: 3306,
DBName: "owncloud",
},
S3: DriverS3{
DriverCommon: DriverCommon{},
Region: "default",
AccessKey: "",
SecretKey: "",
Endpoint: "",
Bucket: "",
},
S3NG: DriverS3NG{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "users"),
ShareFolder: "/Shares",
UserLayout: "{{.Id.OpaqueId}}",
EnableHome: false,
},
ServiceUserUUID: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad",
Region: "default",
AccessKey: "",
SecretKey: "",
Endpoint: "",
Bucket: "",
},
OCIS: DriverOCIS{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "users"),
ShareFolder: "/Shares",
UserLayout: "{{.Id.OpaqueId}}",
},
ServiceUserUUID: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad",
},
},
MetadataStorage: StorageConfig{
EOS: DriverEOS{
DriverCommon: DriverCommon{
Root: "/eos/dockertest/reva",
ShareFolder: "/Shares",
UserLayout: "{{substr 0 1 .Username}}/{{.Username}}",
EnableHome: false,
},
ShadowNamespace: "",
UploadsNamespace: "",
EosBinary: "/usr/bin/eos",
XrdcopyBinary: "/usr/bin/xrdcopy",
MasterURL: "root://eos-mgm1.eoscluster.cern.ch:1094",
GrpcURI: "",
SlaveURL: "root://eos-mgm1.eoscluster.cern.ch:1094",
CacheDirectory: os.TempDir(),
EnableLogging: false,
ShowHiddenSysFiles: false,
ForceSingleUserMode: false,
UseKeytab: false,
SecProtocol: "",
Keytab: "",
SingleUsername: "",
GatewaySVC: "127.0.0.1:9142",
},
Local: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "local", "metadata"),
},
OwnCloud: DriverOwnCloud{},
OwnCloudSQL: DriverOwnCloudSQL{},
S3: DriverS3{
DriverCommon: DriverCommon{},
Region: "default",
},
S3NG: DriverS3NG{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "metadata"),
ShareFolder: "",
UserLayout: "{{.Id.OpaqueId}}",
EnableHome: false,
},
ServiceUserUUID: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad",
Region: "default",
AccessKey: "",
SecretKey: "",
Endpoint: "",
Bucket: "",
},
OCIS: DriverOCIS{
DriverCommon: DriverCommon{
Root: path.Join(defaults.BaseDataPath(), "storage", "metadata"),
ShareFolder: "",
UserLayout: "{{.Id.OpaqueId}}",
EnableHome: false,
},
ServiceUserUUID: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad",
},
},
Frontend: FrontendPort{
Port: Port{
MaxCPUs: "",
LogLevel: "",
GRPCNetwork: "",
GRPCAddr: "",
HTTPNetwork: "tcp",
HTTPAddr: "127.0.0.1:9140",
Protocol: "",
Endpoint: "",
DebugAddr: "127.0.0.1:9141",
Services: []string{"datagateway", "ocdav", "ocs", "appprovider"},
Config: nil,
Context: nil,
Supervised: false,
},
AppProviderInsecure: false,
AppProviderPrefix: "",
ArchiverInsecure: false,
ArchiverPrefix: "archiver",
DatagatewayPrefix: "data",
Favorites: false,
OCDavInsecure: false, // true?
OCDavPrefix: "",
OCSPrefix: "ocs",
OCSSharePrefix: "/Shares",
OCSHomeNamespace: "/users/{{.Id.OpaqueId}}",
PublicURL: "https://localhost:9200",
OCSCacheWarmupDriver: "",
OCSAdditionalInfoAttribute: "{{.Mail}}",
OCSResourceInfoCacheTTL: 0,
Middleware: Middleware{},
},
DataGateway: DataGatewayPort{
Port: Port{},
PublicURL: "",
},
Gateway: Gateway{
Port: Port{
Endpoint: "127.0.0.1:9142",
DebugAddr: "127.0.0.1:9143",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9142",
},
CommitShareToStorageGrant: true,
CommitShareToStorageRef: true,
DisableHomeCreationOnLogin: false,
ShareFolder: "Shares",
LinkGrants: "",
HomeMapping: "",
EtagCacheTTL: 0,
},
StorageRegistry: StorageRegistry{
Driver: "spaces",
HomeProvider: "/home", // unused for spaces, static currently not supported
JSON: "",
},
AppRegistry: AppRegistry{
Driver: "static",
MimetypesJSON: "",
},
Users: Users{
Port: Port{
Endpoint: "localhost:9144",
DebugAddr: "127.0.0.1:9145",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9144",
Services: []string{"userprovider"},
},
Driver: "ldap",
UserGroupsCacheExpiration: 5,
},
Groups: Groups{
Port: Port{
Endpoint: "localhost:9160",
DebugAddr: "127.0.0.1:9161",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9160",
Services: []string{"groupprovider"},
},
Driver: "ldap",
GroupMembersCacheExpiration: 5,
},
AuthProvider: Users{
Port: Port{},
Driver: "ldap",
UserGroupsCacheExpiration: 0,
},
AuthBasic: Port{
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9146",
DebugAddr: "127.0.0.1:9147",
Services: []string{"authprovider"},
Endpoint: "localhost:9146",
},
AuthBearer: Port{
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9148",
DebugAddr: "127.0.0.1:9149",
Services: []string{"authprovider"},
Endpoint: "localhost:9148",
},
AuthMachine: Port{
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9166",
DebugAddr: "127.0.0.1:9167",
Services: []string{"authprovider"},
Endpoint: "localhost:9166",
},
AuthMachineConfig: AuthMachineConfig{
MachineAuthAPIKey: "change-me-please",
},
Sharing: Sharing{
Port: Port{
Endpoint: "localhost:9150",
DebugAddr: "127.0.0.1:9151",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9150",
Services: []string{"usershareprovider", "publicshareprovider"},
},
UserDriver: "json",
UserJSONFile: path.Join(defaults.BaseDataPath(), "storage", "shares.json"),
UserSQLUsername: "",
UserSQLPassword: "",
UserSQLHost: "",
UserSQLPort: 1433,
UserSQLName: "",
PublicDriver: "json",
PublicJSONFile: path.Join(defaults.BaseDataPath(), "storage", "publicshares.json"),
PublicPasswordHashCost: 11,
PublicEnableExpiredSharesCleanup: true,
PublicJanitorRunInterval: 60,
UserStorageMountID: "",
},
StorageShares: StoragePort{
Port: Port{
Endpoint: "localhost:9154",
DebugAddr: "127.0.0.1:9156",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9154",
HTTPNetwork: "tcp",
HTTPAddr: "127.0.0.1:9155",
},
ReadOnly: false,
AlternativeID: "1284d238-aa92-42ce-bdc4-0b0000009154",
MountID: "1284d238-aa92-42ce-bdc4-0b0000009157",
},
StorageUsers: StoragePort{
Port: Port{
Endpoint: "localhost:9157",
DebugAddr: "127.0.0.1:9159",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9157",
HTTPNetwork: "tcp",
HTTPAddr: "127.0.0.1:9158",
},
MountID: "1284d238-aa92-42ce-bdc4-0b0000009157",
Driver: "ocis",
DataServerURL: "http://localhost:9158/data",
HTTPPrefix: "data",
TempFolder: path.Join(defaults.BaseDataPath(), "tmp", "users"),
},
StoragePublicLink: PublicStorage{
StoragePort: StoragePort{
Port: Port{
Endpoint: "localhost:9178",
DebugAddr: "127.0.0.1:9179",
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9178",
},
MountID: "7993447f-687f-490d-875c-ac95e89a62a4",
},
PublicShareProviderAddr: "",
UserProviderAddr: "",
},
StorageMetadata: StoragePort{
Port: Port{
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9215",
HTTPNetwork: "tcp",
HTTPAddr: "127.0.0.1:9216",
DebugAddr: "127.0.0.1:9217",
},
Driver: "ocis",
ExposeDataServer: false,
DataServerURL: "http://localhost:9216/data",
TempFolder: path.Join(defaults.BaseDataPath(), "tmp", "metadata"),
DataProvider: DataProvider{},
},
AppProvider: AppProvider{
Port: Port{
GRPCNetwork: "tcp",
GRPCAddr: "127.0.0.1:9164",
DebugAddr: "127.0.0.1:9165",
Endpoint: "localhost:9164",
Services: []string{"appprovider"},
},
ExternalAddr: "127.0.0.1:9164",
WopiDriver: WopiDriver{},
AppsURL: "/app/list",
OpenURL: "/app/open",
NewURL: "/app/new",
},
Configs: nil,
UploadMaxChunkSize: 1e+8,
UploadHTTPMethodOverride: "",
ChecksumSupportedTypes: []string{"sha1", "md5", "adler32"},
ChecksumPreferredUploadType: "",
DefaultUploadProtocol: "tus",
},
Tracing: Tracing{
Service: "storage",
Type: "jaeger",
},
Asset: Asset{},
}
}

View File

@@ -341,21 +341,14 @@ File and sync features in a shared scenario
- [apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature:48](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature#L48)
#### [Shares received in different ways are not merged](https://github.com/owncloud/ocis/issues/2711)
- [apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature:553](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature#L553)
- [apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature:554](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature#L554)
- [apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature:598](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature#L598)
- [apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature:599](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature#L599)
- [apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature:621](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature#L621)
- [apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature:622](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature#L622)
#### [file_target of a auto-renamed file is not correct directly after sharing](https://github.com/owncloud/core/issues/32322)
- [apiShareManagementBasicToShares/deleteShareFromShares.feature:59](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L59)
- [apiShareManagementToShares/mergeShare.feature:89](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/mergeShare.feature#L89)
#### [Listing shares via ocs API does not show path for parent folders](https://github.com/owncloud/ocis/issues/1231)
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:290](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L290)
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:291](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L291)
#### [Cannot move a file to a shared folder](https://github.com/owncloud/ocis/issues/2146)
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:509](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L515)
@@ -417,18 +410,6 @@ cannot share a folder with create permission
- [apiSharePublicLink1/changingPublicLinkShare.feature:51](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/changingPublicLinkShare.feature#L51)
- [apiSharePublicLink1/changingPublicLinkShare.feature:90](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/changingPublicLinkShare.feature#L90)
#### [Public link enforce permissions](https://github.com/owncloud/ocis/issues/1269)
- [apiSharePublicLink1/createPublicLinkShare.feature:141](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/createPublicLinkShare.feature#L141)
- [apiSharePublicLink1/createPublicLinkShare.feature:142](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/createPublicLinkShare.feature#L142)
- [apiSharePublicLink1/createPublicLinkShare.feature:218](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/createPublicLinkShare.feature#L218)
- [apiSharePublicLink1/createPublicLinkShare.feature:219](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/createPublicLinkShare.feature#L219)
#### [Ability to return error messages in Webdav response bodies](https://github.com/owncloud/ocis/issues/1293)
- [apiSharePublicLink1/createPublicLinkShare.feature:105](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/createPublicLinkShare.feature#L105)
- [apiSharePublicLink1/createPublicLinkShare.feature:106](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/createPublicLinkShare.feature#L106)
#### [various sharing settings cannot be set](https://github.com/owncloud/ocis/issues/1328)
- [apiSharePublicLink1/createPublicLinkShare.feature:319](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/createPublicLinkShare.feature#L319)
@@ -600,11 +581,6 @@ _getting and setting quota_
- [apiWebdavProperties1/getQuota.feature:27](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/getQuota.feature#L27)
- [apiWebdavProperties1/getQuota.feature:28](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/getQuota.feature#L28)
#### [cannot get share-types webdav property](https://github.com/owncloud/ocis/issues/567)
- [apiWebdavProperties2/getFileProperties.feature:174](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L174)
- [apiWebdavProperties2/getFileProperties.feature:175](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L175)
#### [Private link support](https://github.com/owncloud/product/issues/201)
#### [oc:privatelink property not returned in webdav responses](https://github.com/owncloud/product/issues/262)
- [apiWebdavProperties2/getFileProperties.feature:232](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L232)
@@ -657,12 +633,9 @@ Scenario Outline: Moving a file into a shared folder as the sharee and as the sh
- [apiWebdavMove2/moveFile.feature:290](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFile.feature#L290)
- [apiWebdavMove2/moveFile.feature:291](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFile.feature#L291)
#### [User loses accepted share if owner changes the contents of the file](https://github.com/owncloud/ocis/issues/2706)
- [apiVersions/fileVersionsSharingToShares.feature:32](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiVersions/fileVersionsSharingToShares.feature#L32)
#### [restoring an older version of a shared file deletes the share](https://github.com/owncloud/ocis/issues/765)
- [apiShareManagementToShares/acceptShares.feature:587](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L587)
- [apiVersions/fileVersionsSharingToShares.feature:43](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiVersions/fileVersionsSharingToShares.feature#L43)
#### [not possible to move file into a received folder](https://github.com/owncloud/ocis/issues/764)
- [apiVersions/fileVersionsSharingToShares.feature:219](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiVersions/fileVersionsSharingToShares.feature#L219)
@@ -866,9 +839,6 @@ _ocs: api compatibility, return correct status code_
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:670](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L670)
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:671](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L671)
#### [OCIS-storage overwriting a file as share receiver, does not create a new file version for the sharer](https://github.com/owncloud/ocis/issues/766)
- [apiVersions/fileVersionsSharingToShares.feature:294](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiVersions/fileVersionsSharingToShares.feature#L294)
#### [deleting a share with wrong authentication returns OCS status 996 / HTTP 500](https://github.com/owncloud/ocis/issues/1229)
- [apiShareManagementBasicToShares/deleteShareFromShares.feature:250](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L250)
- [apiShareManagementBasicToShares/deleteShareFromShares.feature:251](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L251)
@@ -1066,9 +1036,6 @@ API, search, favorites, config, capabilities, not existing endpoints, CORS and o
#### [Trying to access another user's file gives http 403 instead of 404](https://github.com/owncloud/ocis/issues/2175)
_ocdav: api compatibility, return correct status code_
- [apiAuthWebDav/webDavDELETEAuth.feature:38](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavDELETEAuth.feature#L38) Scenario: send DELETE requests to another user's webDav endpoints as normal user
- [apiAuthWebDav/webDavPROPFINDAuth.feature:39](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavPROPFINDAuth.feature#L39) Scenario: send PROPFIND requests to another user's webDav endpoints as normal user
- [apiAuthWebDav/webDavPROPPATCHAuth.feature:40](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavPROPPATCHAuth.feature#L40) Scenario: send PROPPATCH requests to another user's webDav endpoints as normal user
- [apiAuthWebDav/webDavMKCOLAuth.feature:36](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavMKCOLAuth.feature#L36) Scenario: send MKCOL requests to another user's webDav endpoints as normal user
#### [trying to lock file of another user gives http 200](https://github.com/owncloud/ocis/issues/2176)
@@ -1082,6 +1049,9 @@ _ocdav: api compatibility, return correct status code_
_ocdav: api compatibility, return correct status code_
- [apiAuthWebDav/webDavPOSTAuth.feature:40](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavPOSTAuth.feature#L40) Scenario: send POST requests to another user's webDav endpoints as normal user
#### Another users space literally does not exist because it is not listed as a space for him, 404 seems correct, expects 403
- [apiAuthWebDav/webDavPUTAuth.feature:40](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavPUTAuth.feature#L40)
#### [Using double slash in URL to access a folder gives 501 and other status codes](https://github.com/owncloud/ocis/issues/1667)
- [apiAuthWebDav/webDavSpecialURLs.feature:13](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavSpecialURLs.feature#L13)
- [apiAuthWebDav/webDavSpecialURLs.feature:24](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiAuthWebDav/webDavSpecialURLs.feature#L24)
@@ -1138,12 +1108,6 @@ And other missing implementation of favorites
- [apiFavorites/favorites.feature:149](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favorites.feature#L149)
- [apiFavorites/favorites.feature:176](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favorites.feature#L176)
- [apiFavorites/favorites.feature:177](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favorites.feature#L177)
- [apiFavorites/favoritesSharingToShares.feature:21](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favoritesSharingToShares.feature#L21)
- [apiFavorites/favoritesSharingToShares.feature:22](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favoritesSharingToShares.feature#L22)
- [apiFavorites/favoritesSharingToShares.feature:35](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favoritesSharingToShares.feature#L35)
- [apiFavorites/favoritesSharingToShares.feature:36](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favoritesSharingToShares.feature#L36)
- [apiFavorites/favoritesSharingToShares.feature:48](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favoritesSharingToShares.feature#L48)
- [apiFavorites/favoritesSharingToShares.feature:49](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favoritesSharingToShares.feature#L49)
- [apiFavorites/favoritesSharingToShares.feature:62](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favoritesSharingToShares.feature#L62)
- [apiFavorites/favoritesSharingToShares.feature:63](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favoritesSharingToShares.feature#L63)
@@ -1351,10 +1315,6 @@ Scenario Outline: Unauthenticated call
#### [Share inaccessible if folder with same name was deleted and recreated](https://github.com/owncloud/ocis/issues/1787)
- [apiShareReshareToShares1/reShare.feature:269](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L269)
- [apiShareReshareToShares1/reShare.feature:270](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L270)
- [apiShareReshareToShares1/reShare.feature:287](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L287)
- [apiShareReshareToShares1/reShare.feature:288](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L288)
- [apiShareReshareToShares1/reShare.feature:305](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L305)
- [apiShareReshareToShares1/reShare.feature:306](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L306)
#### [Trying to accept a share with invalid ID gives incorrect OCS and HTTP status](https://github.com/owncloud/ocis/issues/2111)
- [apiShareOperationsToShares2/shareAccessByID.feature:85](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/shareAccessByID.feature#L85)
@@ -1461,22 +1421,18 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
- [apiWebdavUpload1/uploadFileToBlacklistedName.feature:66](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavUpload1/uploadFileToBlacklistedName.feature#L66)
- [apiWebdavUpload1/uploadFileToBlacklistedName.feature:67](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavUpload1/uploadFileToBlacklistedName.feature#L67)
### [not possible to overwrite a received shared file](https://github.com/owncloud/ocis/issues/2267)
- [apiShareOperationsToShares1/changingFilesShare.feature:114](https://github.com/owncloud/web/blob/master/tests/acceptance/features/apiShareOperationsToShares1/changingFilesShare.feature#L114)
### [Allow public link sharing only for certain groups feature not implemented]
#### [Allow public link sharing only for certain groups feature not implemented]
- [apiSharePublicLink2/allowGroupToCreatePublicLinks.feature:35](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/allowGroupToCreatePublicLinks.feature#L35)
- [apiSharePublicLink2/allowGroupToCreatePublicLinks.feature:91](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/allowGroupToCreatePublicLinks.feature#L91)
### [Cannot download preview of shared received file after the shareowner has changed the file content](https://github.com/owncloud/ocis/issues/2538)
- [apiWebdavPreviews/previews.feature:196](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L196)
#### [Cannot download preview of shared received file after the shareowner has changed the file content](https://github.com/owncloud/ocis/issues/2538)
- [apiWebdavPreviews/previews.feature:217](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L217)
- [apiWebdavPreviews/previews.feature:233](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L233)
### [Preview of text file with UTF content does not render correctly](https://github.com/owncloud/ocis/issues/2570)
#### [Preview of text file with UTF content does not render correctly](https://github.com/owncloud/ocis/issues/2570)
- [apiWebdavPreviews/previews.feature:208](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L208)
### [Share path in the response is different between share states](https://github.com/owncloud/ocis/issues/2540)
#### [Share path in the response is different between share states](https://github.com/owncloud/ocis/issues/2540)
- [apiShareManagementToShares/acceptShares.feature:65](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L65)
- [apiShareManagementToShares/acceptShares.feature:93](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L93)
- [apiShareManagementToShares/acceptShares.feature:228](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L228)
@@ -1488,6 +1444,6 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
- [apiShareOperationsToShares2/shareAccessByID.feature:124](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/shareAccessByID.feature#L124)
- [apiShareOperationsToShares2/shareAccessByID.feature:125](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/shareAccessByID.feature#L125)
### [Content-type is not multipart/byteranges when downloading file with Range Header](https://github.com/owncloud/ocis/issues/2677)
#### [Content-type is not multipart/byteranges when downloading file with Range Header](https://github.com/owncloud/ocis/issues/2677)
- [apiWebdavOperations/downloadFile.feature:169](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/downloadFile.feature#L169)
- [apiWebdavOperations/downloadFile.feature:170](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavOperations/downloadFile.feature#L170)

View File

@@ -1,14 +1,23 @@
## Scenarios from OCIS API tests that are expected to fail with OCIS storage
#### [downloading the /Shares folder using the archiver endpoint does not work](https://github.com/owncloud/ocis/issues/2751)
- [apiArchiver/downloadById.feature:134](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadById.feature#L134)
- [apiArchiver/downloadById.feature:135](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadById.feature#L135)
#### [downloading an archive with invalid path returns HTTP/500](https://github.com/owncloud/ocis/issues/2768)
- [apiArchiver/downloadByPath.feature:69](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/apiArchiver/downloadByPath.feature#L69)
- [apiArchiver/downloadByPath.feature:69]
#### [downloading an archive with non existing / accessible id returns HTTP/500](https://github.com/owncloud/ocis/issues/2795)
- [apiArchiver/downloadById.feature:69](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadByPath.feature#L69)
#### [Hardcoded call to /home/..., but /home no longer exists](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/apiArchiver/downloadByPath.feature#L26)
- [apiArchiver/downloadByPath.feature:26](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadByPath.feature#L26)
- [apiArchiver/downloadByPath.feature:27](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadByPath.feature#L27)
- [apiArchiver/downloadByPath.feature:44](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadByPath.feature#L44)
- [apiArchiver/downloadByPath.feature:45](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadByPath.feature#L45)
- [apiArchiver/downloadByPath.feature:48](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadByPath.feature#L48)
- [apiArchiver/downloadByPath.feature:69](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadByPath.feature#L69)
- [apiArchiver/downloadByPath.feature:74](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadByPath.feature#L74)
- [apiArchiver/downloadByPath.feature:132](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadByPath.feature#L132)
- [apiArchiver/downloadByPath.feature:133](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadByPath.feature#L133)
### Tries to download /Shares/ folder but it cannot be downloaded any more directly
- [apiArchiver/downloadById.feature:134](https://github.com/owncloud/web/blob/master/tests/acceptance/features/apiArchiver/downloadById.feature#L134)
- [apiArchiver/downloadById.feature:135](https://github.com/owncloud/web/blob/master/tests/acceptance/features/apiArchiver/downloadById.feature#L135)
#### [Overwriting a file in the space within the allowed quota does not work](https://github.com/owncloud/ocis/issues/2829)
- [apiSpaces/quota.feature:56](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpaces/quota.feature#L56)

View File

@@ -122,8 +122,6 @@ Other free text and markdown formatting can be used elsewhere in the document if
- [webUIRestrictSharing/restrictSharing.feature:56](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRestrictSharing/restrictSharing.feature#L56)
### [First request with a recreated user returns a 401 error](https://github.com/owncloud/ocis/issues/1675)
- [webUISharingAutocompletion/shareAutocompletion.feature:56](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAutocompletion/shareAutocompletion.feature#L56)
- [webUISharingAutocompletion/shareAutocompletion.feature:66](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAutocompletion/shareAutocompletion.feature#L66)
- [webUISharingAutocompletion/shareAutocompletion.feature:128](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAutocompletion/shareAutocompletion.feature#L128)
- [webUISharingAutocompletion/shareAutocompletion.feature:141](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAutocompletion/shareAutocompletion.feature#L141)
@@ -510,3 +508,13 @@ Other free text and markdown formatting can be used elsewhere in the document if
### [shares are not listed with full paths](https://github.com/owncloud/ocis/issues/2462)
- [webUISharingPublicBasic/publicLinkCreate.feature:88](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicBasic/publicLinkCreate.feature#L88)
### Shares folder cannot be deleted and is always visible
- [webUIDeleteFilesFolders/deleteFilesFolders.feature:77](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIDeleteFilesFolders/deleteFilesFolders.feature#L77)
- [webUIDeleteFilesFolders/deleteFilesFolders.feature:89](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIDeleteFilesFolders/deleteFilesFolders.feature#L89)
- [webUISharingAcceptShares/acceptShares.feature:72](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L72)
- [webUIOperationsWithFolderShares/accessToSharesFolder.feature:14](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIOperationsWithFolderShares/accessToSharesFolder.feature#L14)
### [web config update is not properly reflected after the ocis start](https://github.com/owncloud/ocis/issues/2944)
- [webUIFiles/breadcrumb.feature:50](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFiles/breadcrumb.feature#L50)

View File

@@ -70,7 +70,7 @@ Feature: download multiple resources bundled into an archive
Given user "Brian" has been created with default attributes and without skeleton files
And user "Alice" has uploaded file with content "some data" to "/textfile0.txt"
When user "Brian" downloads the archive of "/textfile0.txt" of user "Alice" using the resource id
Then the HTTP status code should be "400"
Then the HTTP status code should be "404"
Scenario: download multiple shared items as share receiver

View File

@@ -26,7 +26,7 @@ Feature: Share spaces
When user "Brian" lists all available spaces via the GraphApi
Then the json responded should contain a space "Share space to Brian" with these key and value pairs:
| key | value |
| driveType | share |
| driveType | project |
| id | %space_id% |
| name | Share space to Brian |
| quota@@@state | normal |
@@ -55,7 +55,7 @@ Feature: Share spaces
When user "Brian" lists all available spaces via the GraphApi
Then the json responded should contain a space "Unshare space" with these key and value pairs:
| key | value |
| driveType | share |
| driveType | project |
| id | %space_id% |
| name | Unshare space |
When user "Alice" unshares a space "Unshare space" to user "Brian"

View File

@@ -39,7 +39,6 @@ type Thumbnail struct {
FileSystemStorage FileSystemStorage `ocisConfig:"filesystem_storage"`
WebdavAllowInsecure bool `ocisConfig:"webdav_allow_insecure" env:"OCIS_INSECURE;THUMBNAILS_WEBDAVSOURCE_INSECURE"`
CS3AllowInsecure bool `ocisConfig:"cs3_allow_insecure" env:"OCIS_INSECURE;THUMBNAILS_CS3SOURCE_INSECURE"`
RevaGateway string `ocisConfig:"reva_gateway" env:"REVA_GATEWAY"`
WebdavNamespace string `ocisConfig:"webdav_namespace" env:"STORAGE_WEBDAV_NAMESPACE"`
RevaGateway string `ocisConfig:"reva_gateway" env:"REVA_GATEWAY"` //TODO: use REVA config
FontMapFile string `ocisConfig:"font_map_file" env:"THUMBNAILS_TXT_FONTMAP_FILE"`
}

View File

@@ -34,7 +34,6 @@ func DefaultConfig() *Config {
},
WebdavAllowInsecure: true,
RevaGateway: "127.0.0.1:9142",
WebdavNamespace: "/home",
CS3AllowInsecure: false,
},
}

View File

@@ -30,8 +30,7 @@ func NewService(opts ...Option) v0proto.ThumbnailServiceHandler {
logger.Fatal().Err(err).Msg("resolutions not configured correctly")
}
svc := Thumbnail{
serviceID: options.Config.GRPC.Namespace + "." + options.Config.Service.Name,
webdavNamespace: options.Config.Thumbnail.WebdavNamespace,
serviceID: options.Config.GRPC.Namespace + "." + options.Config.Service.Name,
manager: thumbnail.NewSimpleManager(
resolutions,
options.ThumbnailStorage,
@@ -52,7 +51,6 @@ func NewService(opts ...Option) v0proto.ThumbnailServiceHandler {
// Thumbnail implements the GRPC handler.
type Thumbnail struct {
serviceID string
webdavNamespace string
manager thumbnail.Manager
webdavSource imgsource.Source
cs3Source imgsource.Source
@@ -145,6 +143,7 @@ func (g Thumbnail) handleWebdavSource(ctx context.Context, req *v0proto.GetThumb
}
var auth, statPath string
if src.IsPublicLink {
q := imgURL.Query()
var rsp *gateway.AuthenticateResponse
@@ -174,7 +173,7 @@ func (g Thumbnail) handleWebdavSource(ctx context.Context, req *v0proto.GetThumb
statPath = path.Join("/public", src.PublicLinkToken, req.Filepath)
} else {
auth = src.RevaAuthorization
statPath = path.Join(g.webdavNamespace, req.Filepath)
statPath = req.Filepath
}
sRes, err := g.stat(statPath, auth)
if err != nil {

View File

@@ -58,7 +58,7 @@ func (s CS3) Get(ctx context.Context, path string) (io.ReadCloser, error) {
}
var ep, tk string
for _, p := range rsp.Protocols {
if p.Protocol == "simple" {
if p.Protocol == "spaces" {
ep, tk = p.DownloadEndpoint, p.Token
}
}

View File

@@ -19,7 +19,8 @@ type Config struct {
HTTP HTTP `ocisConfig:"http"`
OcisPublicURL string `ocisConfig:"ocis_public_url" env:"OCIS_URL;OCIS_PUBLIC_URL"`
WebdavNamespace string `ocisConfig:"webdav_namespace" env:"STORAGE_WEBDAV_NAMESPACE"`
WebdavNamespace string `ocisConfig:"webdav_namespace" env:"STORAGE_WEBDAV_NAMESPACE"` //TODO: prevent this cross config
RevaGateway string `ocisConfig:"reva_gateway" env:"REVA_GATEWAY"`
Context context.Context
}

View File

@@ -29,6 +29,7 @@ func DefaultConfig() *Config {
Collector: "",
},
OcisPublicURL: "https://127.0.0.1:9200",
WebdavNamespace: "/home",
WebdavNamespace: "/users/{{.Id.OpaqueId}}",
RevaGateway: "127.0.0.1:9142",
}
}

View File

@@ -33,11 +33,13 @@ type ThumbnailRequest struct {
Height int32
// In case of a public share the public link token.
PublicLinkToken string
// The username from the requested URL
Username string
}
// ParseThumbnailRequest extracts all required parameters from a http request.
func ParseThumbnailRequest(r *http.Request) (*ThumbnailRequest, error) {
fp, err := extractFilePath(r)
fp, username, err := extractFilePath(r)
if err != nil {
return nil, err
}
@@ -55,6 +57,7 @@ func ParseThumbnailRequest(r *http.Request) (*ThumbnailRequest, error) {
Width: int32(width),
Height: int32(height),
PublicLinkToken: chi.URLParam(r, "token"),
Username: username,
}, nil
}
@@ -64,23 +67,23 @@ func ParseThumbnailRequest(r *http.Request) (*ThumbnailRequest, error) {
//
// User and filepath are dynamic and filepath can contain slashes
// So using the URLParam function is not possible.
func extractFilePath(r *http.Request) (string, error) {
func extractFilePath(r *http.Request) (string, string, error) {
user := chi.URLParam(r, "user")
user, err := url.QueryUnescape(user)
if err != nil {
return "", errors.New("could not unescape user")
return "", "", errors.New("could not unescape user")
}
if user != "" {
parts := strings.SplitN(r.URL.Path, user, 2)
return parts[1], nil
return parts[1], user, nil
}
token := chi.URLParam(r, "token")
if token != "" {
parts := strings.SplitN(r.URL.Path, token, 2)
return parts[1], nil
return parts[1], "", nil
}
return "", errors.New("could not extract file path")
return "", "", errors.New("could not extract file path")
}
func parseDimensions(q url.Values) (int64, int64, error) {

View File

@@ -24,7 +24,7 @@ func Server(opts ...Option) (http.Service, error) {
http.Flags(options.Flags...),
)
handle := svc.NewService(
handle, err := svc.NewService(
svc.Logger(options.Logger),
svc.Config(options.Config),
svc.Middleware(
@@ -48,6 +48,9 @@ func Server(opts ...Option) (http.Service, error) {
),
),
)
if err != nil {
return http.Service{}, err
}
{
handle = svc.NewInstrument(handle, options.Metrics)

View File

@@ -3,11 +3,17 @@ package svc
import (
"encoding/xml"
"net/http"
"path"
"path/filepath"
"strings"
gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/storage/utils/templates"
"github.com/go-chi/render"
merrors "go-micro.dev/v4/errors"
"google.golang.org/grpc/metadata"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/service/grpc"
@@ -38,17 +44,24 @@ type Service interface {
}
// NewService returns a service implementation for Service.
func NewService(opts ...Option) Service {
func NewService(opts ...Option) (Service, error) {
options := newOptions(opts...)
conf := options.Config
m := chi.NewMux()
m.Use(options.Middleware...)
gwc, err := pool.GetGatewayServiceClient(conf.RevaGateway)
if err != nil {
return nil, err
}
svc := Webdav{
config: options.Config,
config: conf,
log: options.Logger,
mux: m,
thumbnailsClient: thumbnails.NewThumbnailService("com.owncloud.api.thumbnails", grpc.DefaultClient),
revaClient: gwc,
}
m.Route(options.Config.HTTP.Root, func(r chi.Router) {
@@ -57,7 +70,7 @@ func NewService(opts ...Option) Service {
r.Head("/remote.php/dav/public-files/{token}/*", svc.PublicThumbnailHead)
})
return svc
return svc, nil
}
// Webdav defines implements the business logic for Service.
@@ -66,6 +79,7 @@ type Webdav struct {
log log.Logger
mux *chi.Mux
thumbnailsClient thumbnails.ThumbnailService
revaClient gatewayv1beta1.GatewayAPIClient
}
// ServeHTTP implements the Service interface.
@@ -83,6 +97,18 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
}
t := r.Header.Get(TokenHeader)
ctx := metadata.AppendToOutgoingContext(r.Context(), TokenHeader, t)
userRes, err := g.revaClient.GetUserByClaim(ctx, &userv1beta1.GetUserByClaimRequest{
Claim: "username",
Value: tr.Username,
})
if err != nil || userRes.Status.Code != rpcv1beta1.Code_CODE_OK {
g.log.Error().Err(err).Msg("could not get user")
renderError(w, r, errInternalError("could not get user"))
return
}
fullPath := filepath.Join(templates.WithUser(userRes.User, g.config.WebdavNamespace), tr.Filepath)
rsp, err := g.thumbnailsClient.GetThumbnail(r.Context(), &thumbnails.GetThumbnailRequest{
Filepath: strings.TrimLeft(tr.Filepath, "/"),
ThumbnailType: extensionToThumbnailType(strings.TrimLeft(tr.Extension, ".")),
@@ -90,7 +116,7 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
Height: tr.Height,
Source: &thumbnails.GetThumbnailRequest_Cs3Source{
Cs3Source: &thumbnails.CS3Source{
Path: path.Join(g.config.WebdavNamespace, tr.Filepath),
Path: fullPath,
Authorization: t,
},
},