Merge pull request #6544 from kobergj/DisableWopiChat

[full-ci] DisableWopiChat envvar
This commit is contained in:
Michael Barz
2023-06-16 15:52:01 +02:00
committed by GitHub
11 changed files with 38 additions and 82 deletions

View File

@@ -0,0 +1,5 @@
Enhancement: Allow disabling wopi chat
Add a configreva for the new reva disable-chat feature
https://github.com/owncloud/ocis/pull/6544

2
go.mod
View File

@@ -13,7 +13,7 @@ require (
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/coreos/go-oidc/v3 v3.6.0
github.com/cs3org/go-cs3apis v0.0.0-20230516150832-730ac860c71d
github.com/cs3org/reva/v2 v2.14.1-0.20230615141102-1906a729ee5a
github.com/cs3org/reva/v2 v2.14.1-0.20230616125400-b30fdde17262
github.com/disintegration/imaging v1.6.2
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
github.com/egirna/icap-client v0.1.1

4
go.sum
View File

@@ -625,8 +625,8 @@ github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo
github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4=
github.com/crewjam/saml v0.4.13 h1:TYHggH/hwP7eArqiXSJUvtOPNzQDyQ7vwmwEqlFWhMc=
github.com/crewjam/saml v0.4.13/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA=
github.com/cs3org/reva/v2 v2.14.1-0.20230615141102-1906a729ee5a h1:T+504loI0dvksiutkzF4ciLfIJD/LJtJFdFJ6d7I7dA=
github.com/cs3org/reva/v2 v2.14.1-0.20230615141102-1906a729ee5a/go.mod h1:E32krZG159YflDSjDWfx/QGIC2529PS5LiPnGNHu3d0=
github.com/cs3org/reva/v2 v2.14.1-0.20230616125400-b30fdde17262 h1:qtK30bpLgJsUha9XbJseTksGXaNQtTteynVZEobL1fw=
github.com/cs3org/reva/v2 v2.14.1-0.20230616125400-b30fdde17262/go.mod h1:E32krZG159YflDSjDWfx/QGIC2529PS5LiPnGNHu3d0=
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=

View File

@@ -69,6 +69,7 @@ type WOPIDriver struct {
AppInternalURL string `yaml:"app_internal_url" env:"APP_PROVIDER_WOPI_APP_INTERNAL_URL" desc:"Internal URL to the app, like in your DMZ."`
AppName string `yaml:"app_name" env:"APP_PROVIDER_WOPI_APP_NAME" desc:"Human readable app name."`
AppURL string `yaml:"app_url" env:"APP_PROVIDER_WOPI_APP_URL" desc:"URL for end users to access the app."`
AppDisableChat bool `yaml:"app_disable_chat" env:"APP_PROVIDER_WOPI_DISABLE_CHAT" desc:"Disable the chat functionality of the office app."`
Insecure bool `yaml:"insecure" env:"APP_PROVIDER_WOPI_INSECURE" desc:"Disable TLS certificate validation for requests to the WOPI server and the web office application. Do not set this in production environments."`
IopSecret string `yaml:"wopi_server_iop_secret" env:"APP_PROVIDER_WOPI_WOPI_SERVER_IOP_SECRET" desc:"Shared secret of the CS3org WOPI server."`
WopiURL string `yaml:"wopi_server_external_url" env:"APP_PROVIDER_WOPI_WOPI_SERVER_EXTERNAL_URL" desc:"External url of the CS3org WOPI server."`

View File

@@ -40,6 +40,7 @@ func AppProviderConfigFromStruct(cfg *config.Config) map[string]interface{} {
"app_int_url": cfg.Drivers.WOPI.AppInternalURL,
"app_name": cfg.Drivers.WOPI.AppName,
"app_url": cfg.Drivers.WOPI.AppURL,
"app_disable_chat": cfg.Drivers.WOPI.AppDisableChat,
"insecure_connections": cfg.Drivers.WOPI.Insecure,
"iop_secret": cfg.Drivers.WOPI.IopSecret,
"jwt_secret": cfg.TokenManager.JWTSecret,

View File

@@ -69,6 +69,7 @@ type config struct {
JWTSecret string `mapstructure:"jwt_secret" docs:";The JWT secret to be used to retrieve the token TTL."`
AppDesktopOnly bool `mapstructure:"app_desktop_only" docs:"false;Specifies if the app can be opened only on desktop."`
InsecureConnections bool `mapstructure:"insecure_connections"`
AppDisableChat bool `mapstructure:"app_disable_chat"`
}
func parseConfig(m map[string]interface{}) (*config, error) {
@@ -246,20 +247,23 @@ func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.Resourc
return nil, err
}
appFullURL := result["app-url"].(string)
url, err := url.Parse(result["app-url"].(string))
if err != nil {
return nil, err
}
urlQuery := url.Query()
if language != "" {
url, err := url.Parse(appFullURL)
if err != nil {
return nil, err
}
urlQuery := url.Query()
urlQuery.Set("ui", language) // OnlyOffice
urlQuery.Set("lang", language) // Collabora
urlQuery.Set("UI_LLCC", language) // Office365
url.RawQuery = urlQuery.Encode()
appFullURL = url.String()
}
if p.conf.AppDisableChat {
urlQuery.Set("dchat", "1") // OnlyOffice disable chat
}
url.RawQuery = urlQuery.Encode()
appFullURL := url.String()
// Depending on whether wopi server returned any form parameters or not,
// we decide whether the request method is POST or GET

View File

@@ -43,8 +43,7 @@ const tracerName = "providercache"
// Cache holds share information structured by provider and space
type Cache struct {
lockMapLock sync.Mutex
lockMap map[string]*sync.Mutex
lockMap sync.Map
Providers map[string]*Spaces
@@ -106,16 +105,9 @@ func (s *Shares) UnmarshalJSON(data []byte) error {
// LockSpace locks the cache for a given space and returns an unlock function
func (c *Cache) LockSpace(spaceID string) func() {
lock := c.lockMap[spaceID]
if lock == nil {
c.lockMapLock.Lock()
lock = c.lockMap[spaceID]
if lock == nil {
c.lockMap[spaceID] = &sync.Mutex{}
lock = c.lockMap[spaceID]
}
c.lockMapLock.Unlock()
}
v, _ := c.lockMap.LoadOrStore(spaceID, &sync.Mutex{})
lock := v.(*sync.Mutex)
lock.Lock()
return func() { lock.Unlock() }
}
@@ -126,7 +118,7 @@ func New(s metadata.Storage, ttl time.Duration) Cache {
Providers: map[string]*Spaces{},
storage: s,
ttl: ttl,
lockMap: map[string]*sync.Mutex{},
lockMap: sync.Map{},
}
}

View File

@@ -44,8 +44,7 @@ const tracerName = "receivedsharecache"
// It functions as an in-memory cache with a persistence layer
// The storage is sharded by user
type Cache struct {
lockMapLock sync.Mutex
lockMap map[string]*sync.Mutex
lockMap sync.Map
ReceivedSpaces map[string]*Spaces
@@ -79,21 +78,14 @@ func New(s metadata.Storage, ttl time.Duration) Cache {
ReceivedSpaces: map[string]*Spaces{},
storage: s,
ttl: ttl,
lockMap: map[string]*sync.Mutex{},
lockMap: sync.Map{},
}
}
func (c *Cache) lockUser(userID string) func() {
lock := c.lockMap[userID]
if lock == nil {
c.lockMapLock.Lock()
lock = c.lockMap[userID]
if lock == nil {
c.lockMap[userID] = &sync.Mutex{}
lock = c.lockMap[userID]
}
c.lockMapLock.Unlock()
}
v, _ := c.lockMap.LoadOrStore(userID, &sync.Mutex{})
lock := v.(*sync.Mutex)
lock.Lock()
return func() { lock.Unlock() }
}

View File

@@ -43,8 +43,7 @@ const tracerName = "sharecache"
// It functions as an in-memory cache with a persistence layer
// The storage is sharded by user/group
type Cache struct {
lockMapLock sync.Mutex
lockMap map[string]*sync.Mutex
lockMap sync.Map
UserShares map[string]*UserShareCache
@@ -69,16 +68,9 @@ type SpaceShareIDs struct {
}
func (c *Cache) lockUser(userID string) func() {
lock := c.lockMap[userID]
if lock == nil {
c.lockMapLock.Lock()
lock = c.lockMap[userID]
if lock == nil {
c.lockMap[userID] = &sync.Mutex{}
lock = c.lockMap[userID]
}
c.lockMapLock.Unlock()
}
v, _ := c.lockMap.LoadOrStore(userID, &sync.Mutex{})
lock := v.(*sync.Mutex)
lock.Lock()
return func() { lock.Unlock() }
}
@@ -91,7 +83,7 @@ func New(s metadata.Storage, namespace, filename string, ttl time.Duration) Cach
namespace: namespace,
filename: filename,
ttl: ttl,
lockMap: map[string]*sync.Mutex{},
lockMap: sync.Map{},
}
}

View File

@@ -294,37 +294,6 @@ func ReadNode(ctx context.Context, lu PathLookup, spaceID, nodeID string, canLis
}
return nil, errtypes.InternalError("Missing parent ID on node")
}
// TODO why do we stat the parent? to determine if the current node is in the trash we would need to traverse all parents...
// we need to traverse all parents for permissions anyway ...
// - we can compare to space root owner with the current user
// - we can compare the share permissions on the root for spaces, which would work for managers
// - for non managers / owners we need to traverse all path segments because an intermediate node might have been shared
// - if we want to support negative acls we need to traverse the path for all users (but the owner)
// for trashed items we need to check all parents
// - one of them might have the trash suffix ...
// - options:
// - move deleted nodes in a trash folder that is still part of the tree (aka freedesktop org trash spec)
// - shares should still be removed, which requires traversing all trashed children ... and it should be undoable ...
// - what if a trashed file is restored? will child items be accessible by a share?
// - compare paths of trash root items and the trashed file?
// - to determine the relative path of a file we would need to traverse all intermediate nodes anyway
// - recursively mark all children as trashed ... async ... it is ok when that is not synchronous
// - how do we pick up if an error occurs? write a journal somewhere? activity log / delta?
// - stat requests will not pick up trashed items at all
// - recursively move all children into the trash folder?
// - no need to write an additional trash entry
// - can be made more robust with a journal
// - same recursion mechanism can be used to purge items? sth we still need to do
// - flag the two above options with dtime
if !skipParentCheck {
_, err = os.Stat(n.ParentPath())
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil, errtypes.NotFound(err.Error())
}
return nil, err
}
}
if revisionSuffix == "" {
n.BlobID = attrs.String(prefixes.BlobIDAttr)

2
vendor/modules.txt vendored
View File

@@ -352,7 +352,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1
github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1
github.com/cs3org/go-cs3apis/cs3/tx/v1beta1
github.com/cs3org/go-cs3apis/cs3/types/v1beta1
# github.com/cs3org/reva/v2 v2.14.1-0.20230615141102-1906a729ee5a
# github.com/cs3org/reva/v2 v2.14.1-0.20230616125400-b30fdde17262
## explicit; go 1.20
github.com/cs3org/reva/v2/cmd/revad/internal/grace
github.com/cs3org/reva/v2/cmd/revad/runtime