Merge pull request #3633 from fschade/fix-collaboration-extension-handling

feat(collaboration): let admins disable wopi extensions
This commit is contained in:
Florian Schade authored and GitHub committed 2026-10-02 13:37:02 +02:00
commit c10b106f1b
4 files changed
+46 -3

No files matched your search

+5
View File
@@ -52,6 +52,11 @@ There are a few variables that you need to set:
* `COLLABORATION_WOPI_ENABLE_MOBILE`:\
Enables the mobile web view of the office web frontend. Only applies to EuroOffice. `ce` offers the mobile view for reading only, `de` and `ee` also for editing, so set `COLLABORATION_APP_PRODUCT_EDITION` accordingly.
* `COLLABORATION_WOPI_DISABLED_EXTENSIONS`:\
A comma separated list of file extensions the app must not offer, even though the document server announces them.\
The webUI offers no editor of this app for them and opening such a file with it fails.\
For example: `COLLABORATION_WOPI_DISABLED_EXTENSIONS=docx,xlsx,pptx`.
The application can be customized further by changing the `COLLABORATION_APP_*` options to better describe the application.
## Storing
@@ -10,4 +10,6 @@ type Wopi struct {
ShortTokens bool `yaml:"short_tokens" env:"COLLABORATION_WOPI_SHORTTOKENS" desc:"Use short access tokens for WOPI access. This is useful for office packages, like Microsoft Office Online, which have URL length restrictions. If enabled, a persistent store must be configured." introductionVersion:"1.0.0"`
EnableMobile bool `yaml:"enable_mobile" env:"COLLABORATION_WOPI_ENABLE_MOBILE" desc:"Enable the mobile web view of the office web frontend. This feature applies to EuroOffice, where the product edition decides whether it covers editing as well." introductionVersion:"%%NEXT%%"`
DisabledExtensions []string `yaml:"disabled_extensions" env:"COLLABORATION_WOPI_DISABLED_EXTENSIONS" desc:"A comma separated list of file extensions the office web frontend must not offer, for example 'docx,xlsx'. Extensions are matched case-insensitively, with or without the leading dot." introductionVersion:"%%NEXT%%"`
}
@@ -110,7 +110,7 @@ func GetAppURLs(cfg *config.Config, logger log.Logger) (map[string]map[string]st
var appURLs map[string]map[string]string
appURLs, err = parseWopiDiscovery(httpResp.Body)
appURLs, err = parseWopiDiscovery(httpResp.Body, cfg.Wopi.DisabledExtensions)
if err != nil {
logger.Error().
Err(err).
@@ -123,10 +123,16 @@ func GetAppURLs(cfg *config.Config, logger log.Logger) (map[string]map[string]st
return appURLs, nil
}
// parseWopiDiscovery parses the response of the "/hosting/discovery" endpoint
func parseWopiDiscovery(body io.Reader) (map[string]map[string]string, error) {
// parseWopiDiscovery parses the response of the "/hosting/discovery" endpoint.
// Extensions listed in disabledExtensions are left out.
func parseWopiDiscovery(body io.Reader, disabledExtensions []string) (map[string]map[string]string, error) {
appURLs := make(map[string]map[string]string)
disabled := make(map[string]struct{}, len(disabledExtensions))
for _, ext := range disabledExtensions {
disabled[strings.ToLower(strings.TrimPrefix(strings.TrimSpace(ext), "."))] = struct{}{}
}
doc := etree.NewDocument()
if _, err := doc.ReadFrom(body); err != nil {
return nil, err
@@ -147,6 +153,10 @@ func parseWopiDiscovery(body io.Reader) (map[string]map[string]string, error) {
continue
}
if _, ok := disabled[strings.ToLower(ext)]; ok {
continue
}
u, err := url.Parse(urlString)
if err != nil {
continue
@@ -366,6 +366,32 @@ var _ = Describe("Discovery", func() {
Expect(appUrls).To(Equal(expectedAppUrls))
})
It("Skips the disabled extensions", func() {
cfg := &config.Config{
App: config.App{
Addr: srv.URL + "/good",
Insecure: true,
},
Wopi: config.Wopi{
// written the way an admin might, the match ignores dot and case
DisabledExtensions: []string{"docx", ".DJVU", " xls ", "odt"},
},
}
logger := log.NopLogger()
appUrls, err := helpers.GetAppURLs(cfg, logger)
expectedAppUrls := map[string]map[string]string{
"view": {
".pdf": "https://cloud.opencloud.test/hosting/wopi/word/view",
".xlsb": "https://cloud.opencloud.test/hosting/wopi/cell/view",
},
}
Expect(err).To(Succeed())
Expect(appUrls).To(Equal(expectedAppUrls))
})
It("Wrong discovery URL", func() {
cfg := &config.Config{
App: config.App{