@@ -21,7 +21,7 @@ func GetCommands(cfg *config.Config) cli.Commands {
|
||||
func Execute(cfg *config.Config) error {
|
||||
app := clihelper.DefaultApp(&cli.App{
|
||||
Name: "collaboration",
|
||||
Usage: "Serve WOPI for oCIS",
|
||||
Usage: "Serve WOPI for OpenCloud",
|
||||
Commands: GetCommands(cfg),
|
||||
})
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
defer cancel()
|
||||
|
||||
// prepare components
|
||||
if err := helpers.RegisterOcisService(ctx, cfg, logger); err != nil {
|
||||
if err := helpers.RegisterOpenCloudService(ctx, cfg, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/url"
|
||||
|
||||
occfg "github.com/opencloud-eu/opencloud/pkg/config"
|
||||
ocisdefaults "github.com/opencloud-eu/opencloud/pkg/config/defaults"
|
||||
ocdefaults "github.com/opencloud-eu/opencloud/pkg/config/defaults"
|
||||
"github.com/opencloud-eu/opencloud/pkg/config/envdecode"
|
||||
"github.com/opencloud-eu/opencloud/pkg/shared"
|
||||
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/config"
|
||||
@@ -49,14 +49,14 @@ func Validate(cfg *config.Config) error {
|
||||
"Make sure your %s config contains the proper values "+
|
||||
"(e.g. by running opencloud init or setting it manually in "+
|
||||
"the config/corresponding environment variable): %s",
|
||||
cfg.Service.Name, ocisdefaults.BaseConfigPath(), err.Error())
|
||||
cfg.Service.Name, ocdefaults.BaseConfigPath(), err.Error())
|
||||
}
|
||||
if url.Path != "" {
|
||||
return fmt.Errorf("The WOPI Src must not contain a path in your config for %s. "+
|
||||
"Make sure your %s config contains the proper values "+
|
||||
"(e.g. by running opencloud init or setting it manually in "+
|
||||
"the config/corresponding environment variable)",
|
||||
cfg.Service.Name, ocisdefaults.BaseConfigPath())
|
||||
cfg.Service.Name, ocdefaults.BaseConfigPath())
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -5,7 +5,7 @@ type Wopi struct {
|
||||
WopiSrc string `yaml:"wopisrc" env:"COLLABORATION_WOPI_SRC" desc:"The WOPI source base URL containing schema, host and port. Set this to the schema and domain where the collaboration service is reachable for the wopi app, such as https://office.example.test." introductionVersion:"6.0.0"`
|
||||
Secret string `yaml:"secret" env:"COLLABORATION_WOPI_SECRET" desc:"Used to mint and verify WOPI JWT tokens and encrypt and decrypt the REVA JWT token embedded in the WOPI JWT token." introductionVersion:"6.0.0"`
|
||||
DisableChat bool `yaml:"disable_chat" env:"COLLABORATION_WOPI_DISABLE_CHAT;OC_WOPI_DISABLE_CHAT" desc:"Disable chat in the office web frontend. This feature applies to OnlyOffice and Microsoft." introductionVersion:"7.0.0"`
|
||||
ProxyURL string `yaml:"proxy_url" env:"COLLABORATION_WOPI_PROXY_URL" desc:"The URL to the ownCloud Office365 WOPI proxy. Optional. To use this feature, you need an office365 proxy subscription. If you become part of the Microsoft CSP program (https://learn.microsoft.com/en-us/partner-center/enroll/csp-overview), you can use WebOffice without a proxy." introductionVersion:"7.0.0"`
|
||||
ProxySecret string `yaml:"proxy_secret" env:"COLLABORATION_WOPI_PROXY_SECRET" desc:"Optional, the secret to authenticate against the ownCloud Office365 WOPI proxy. This secret can be obtained from ownCloud via the office365 proxy subscription." introductionVersion:"7.0.0"`
|
||||
ProxyURL string `yaml:"proxy_url" env:"COLLABORATION_WOPI_PROXY_URL" desc:"The URL to the OpenCloud WOPI proxy. Optional. To use this feature, you need an office365 proxy subscription. If you become part of the Microsoft CSP program (https://learn.microsoft.com/en-us/partner-center/enroll/csp-overview), you can use WebOffice without a proxy." introductionVersion:"7.0.0"`
|
||||
ProxySecret string `yaml:"proxy_secret" env:"COLLABORATION_WOPI_PROXY_SECRET" desc:"Optional, the secret to authenticate against the OpenCloud WOPI proxy. This secret can be obtained from ownCloud via the office365 proxy subscription." introductionVersion:"7.0.0"`
|
||||
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:"7.0.0"`
|
||||
}
|
||||
|
||||
@@ -1215,7 +1215,7 @@ func (f *FileConnector) CheckFileInfo(ctx context.Context) (*ConnectorResponse,
|
||||
breadcrumbFolderName = statRes.GetInfo().GetSpace().GetName()
|
||||
}
|
||||
|
||||
ocisURL, err := url.Parse(f.cfg.Commons.OcisURL)
|
||||
ocURL, err := url.Parse(f.cfg.Commons.OcisURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1224,17 +1224,17 @@ func (f *FileConnector) CheckFileInfo(ctx context.Context) (*ConnectorResponse,
|
||||
return nil, err
|
||||
}
|
||||
privateLinkURL := &url.URL{}
|
||||
*privateLinkURL = *ocisURL
|
||||
privateLinkURL.Path = path.Join(ocisURL.Path, "f", storagespace.FormatResourceID(statRes.GetInfo().GetId()))
|
||||
*privateLinkURL = *ocURL
|
||||
privateLinkURL.Path = path.Join(ocURL.Path, "f", storagespace.FormatResourceID(statRes.GetInfo().GetId()))
|
||||
parentFolderURL := &url.URL{}
|
||||
*parentFolderURL = *ocisURL
|
||||
*parentFolderURL = *ocURL
|
||||
if !isPublicShare {
|
||||
parentFolderURL.Path = path.Join(ocisURL.Path, "f", storagespace.FormatResourceID(statRes.GetInfo().GetParentId()))
|
||||
parentFolderURL.Path = path.Join(ocURL.Path, "f", storagespace.FormatResourceID(statRes.GetInfo().GetParentId()))
|
||||
} else {
|
||||
if scopes, ok := ctxpkg.ContextGetScopes(ctx); ok {
|
||||
publicShare := &link.PublicShare{}
|
||||
if err := f.getScopeByKeyPrefix(scopes, "publicshare:", publicShare); err == nil {
|
||||
parentFolderURL.Path = path.Join(ocisURL.Path, "s", publicShare.GetToken())
|
||||
parentFolderURL.Path = path.Join(ocURL.Path, "s", publicShare.GetToken())
|
||||
} else {
|
||||
logger.Error().Err(err).Msg("CheckFileInfo: error getting public share scope")
|
||||
}
|
||||
@@ -1253,8 +1253,8 @@ func (f *FileConnector) CheckFileInfo(ctx context.Context) (*ConnectorResponse,
|
||||
fileinfo.KeyBreadcrumbFolderName: breadcrumbFolderName,
|
||||
fileinfo.KeyBreadcrumbFolderURL: parentFolderURL.String(),
|
||||
|
||||
fileinfo.KeyHostViewURL: createHostUrl("view", ocisURL, f.cfg.App.Name, statRes.GetInfo()),
|
||||
fileinfo.KeyHostEditURL: createHostUrl("write", ocisURL, f.cfg.App.Name, statRes.GetInfo()),
|
||||
fileinfo.KeyHostViewURL: createHostUrl("view", ocURL, f.cfg.App.Name, statRes.GetInfo()),
|
||||
fileinfo.KeyHostEditURL: createHostUrl("write", ocURL, f.cfg.App.Name, statRes.GetInfo()),
|
||||
fileinfo.KeyFileSharingURL: createShareUrl(privateLinkURL),
|
||||
fileinfo.KeyFileVersionURL: createVersionsUrl(privateLinkURL),
|
||||
|
||||
@@ -1328,20 +1328,20 @@ func (f *FileConnector) createDownloadURL(wopiContext middleware.WopiContext, co
|
||||
return downloadURL.String(), nil
|
||||
}
|
||||
|
||||
func createHostUrl(mode string, ocisUrl *url.URL, appName string, info *providerv1beta1.ResourceInfo) string {
|
||||
webUrl := createAppExternalURL(ocisUrl, appName, info)
|
||||
func createHostUrl(mode string, u *url.URL, appName string, info *providerv1beta1.ResourceInfo) string {
|
||||
webUrl := createAppExternalURL(u, appName, info)
|
||||
addURLParams(webUrl, map[string]string{"view_mode": mode})
|
||||
return webUrl.String()
|
||||
}
|
||||
|
||||
func createShareUrl(ocisURL *url.URL) string {
|
||||
shareURL := *ocisURL
|
||||
func createShareUrl(u *url.URL) string {
|
||||
shareURL := *u
|
||||
addURLParams(&shareURL, map[string]string{"details": "sharing"})
|
||||
return shareURL.String()
|
||||
}
|
||||
|
||||
func createVersionsUrl(ocisURL *url.URL) string {
|
||||
versionsURL := *ocisURL
|
||||
func createVersionsUrl(u *url.URL) string {
|
||||
versionsURL := *u
|
||||
addURLParams(&versionsURL, map[string]string{"details": "versions"})
|
||||
return versionsURL.String()
|
||||
}
|
||||
@@ -1354,11 +1354,11 @@ func addURLParams(u *url.URL, params map[string]string) {
|
||||
u.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
func createAppExternalURL(ocisURL *url.URL, appName string, info *providerv1beta1.ResourceInfo) *url.URL {
|
||||
func createAppExternalURL(u *url.URL, appName string, info *providerv1beta1.ResourceInfo) *url.URL {
|
||||
spaceAlias := utils.ReadPlainFromOpaque(info.GetSpace().GetOpaque(), "spaceAlias")
|
||||
appExternalURL := *ocisURL
|
||||
appExternalURL.Path = path.Join(ocisURL.Path, "external-"+strings.ToLower(appName), spaceAlias, info.GetPath())
|
||||
q := ocisURL.Query()
|
||||
appExternalURL := *u
|
||||
appExternalURL.Path = path.Join(u.Path, "external-"+strings.ToLower(appName), spaceAlias, info.GetPath())
|
||||
q := u.Query()
|
||||
q.Add("fileId", storagespace.FormatResourceID(info.GetId()))
|
||||
appExternalURL.RawQuery = q.Encode()
|
||||
return &appExternalURL
|
||||
|
||||
@@ -16,10 +16,10 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/config"
|
||||
)
|
||||
|
||||
// RegisterOcisService will register this service.
|
||||
// RegisterOpenCloudService will register this service.
|
||||
// There are no explicit requirements for the context, and it will be passed
|
||||
// without changes to the underlying RegisterService method.
|
||||
func RegisterOcisService(ctx context.Context, cfg *config.Config, logger log.Logger) error {
|
||||
func RegisterOpenCloudService(ctx context.Context, cfg *config.Config, logger log.Logger) error {
|
||||
svc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name+"."+cfg.App.Name, cfg.GRPC.Protocol, cfg.GRPC.Addr, version.GetString())
|
||||
return registry.RegisterService(ctx, logger, svc, cfg.Debug.Addr)
|
||||
}
|
||||
|
||||
@@ -31,19 +31,19 @@ func CollaborationTracingMiddleware(next http.Handler) http.Handler {
|
||||
wopiFile := wopiContext.FileReference
|
||||
|
||||
attrs := []attribute.KeyValue{
|
||||
attribute.String("ocis.wopi.sessionid", r.Header.Get("X-WOPI-SessionId")),
|
||||
attribute.String("ocis.wopi.method", wopiMethod),
|
||||
attribute.String("ocis.wopi.resource.id.storage", wopiFile.GetResourceId().GetStorageId()),
|
||||
attribute.String("ocis.wopi.resource.id.opaque", wopiFile.GetResourceId().GetOpaqueId()),
|
||||
attribute.String("ocis.wopi.resource.id.space", wopiFile.GetResourceId().GetSpaceId()),
|
||||
attribute.String("ocis.wopi.resource.path", wopiFile.GetPath()),
|
||||
attribute.String("wopi.session.id", r.Header.Get("X-WOPI-SessionId")),
|
||||
attribute.String("wopi.method", wopiMethod),
|
||||
attribute.String("cs3.resource.id.storage", wopiFile.GetResourceId().GetStorageId()),
|
||||
attribute.String("cs3.resource.id.opaque", wopiFile.GetResourceId().GetOpaqueId()),
|
||||
attribute.String("cs3.resource.id.space", wopiFile.GetResourceId().GetSpaceId()),
|
||||
attribute.String("cs3.resource.path", wopiFile.GetPath()),
|
||||
}
|
||||
|
||||
if wopiUser, ok := ctxpkg.ContextGetUser(r.Context()); ok {
|
||||
attrs = append(attrs, []attribute.KeyValue{
|
||||
attribute.String("ocis.wopi.user.idp", wopiUser.GetId().GetIdp()),
|
||||
attribute.String("ocis.wopi.user.opaque", wopiUser.GetId().GetOpaqueId()),
|
||||
attribute.String("ocis.wopi.user.type", wopiUser.GetId().GetType().String()),
|
||||
attribute.String("cs3.user.idp", wopiUser.GetId().GetIdp()),
|
||||
attribute.String("cs3.user.opaque", wopiUser.GetId().GetOpaqueId()),
|
||||
attribute.String("cs3.user.type", wopiUser.GetId().GetType().String()),
|
||||
}...)
|
||||
}
|
||||
span.SetAttributes(attrs...)
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
// If no proxy URL and proxy secret are configured, the URL will be generated
|
||||
// as a direct URL that contains the file reference.
|
||||
// Example:
|
||||
// https:/ocis.team/wopi/files/12312678470610632091729803710923
|
||||
// https:/cloud.example.test/wopi/files/12312678470610632091729803710923
|
||||
func GenerateWopiSrc(fileRef string, cfg *config.Config) (*url.URL, error) {
|
||||
wopiSrcURL, err := url.Parse(cfg.Wopi.WopiSrc)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,7 +16,7 @@ var _ = Describe("Wopisrc Test", func() {
|
||||
BeforeEach(func() {
|
||||
c = &config.Config{
|
||||
Wopi: config.Wopi{
|
||||
WopiSrc: "https://ocis.team/wopi/files",
|
||||
WopiSrc: "https://cloud.example.test/wopi/files",
|
||||
ProxyURL: "https://cloud.proxy.com",
|
||||
ProxySecret: "secret",
|
||||
},
|
||||
@@ -25,7 +25,7 @@ var _ = Describe("Wopisrc Test", func() {
|
||||
When("WopiSrc URL is incorrect", func() {
|
||||
c = &config.Config{
|
||||
Wopi: config.Wopi{
|
||||
WopiSrc: "https:&//ocis.team/wopi/files",
|
||||
WopiSrc: "https:&//cloud.example.test/wopi/files",
|
||||
},
|
||||
}
|
||||
url, err := wopisrc.GenerateWopiSrc("123456", c)
|
||||
@@ -35,7 +35,7 @@ var _ = Describe("Wopisrc Test", func() {
|
||||
When("proxy URL is incorrect", func() {
|
||||
c = &config.Config{
|
||||
Wopi: config.Wopi{
|
||||
WopiSrc: "https://ocis.team/wopi/files",
|
||||
WopiSrc: "https://cloud.example.test/wopi/files",
|
||||
ProxyURL: "cloud",
|
||||
ProxySecret: "secret",
|
||||
},
|
||||
@@ -48,7 +48,7 @@ var _ = Describe("Wopisrc Test", func() {
|
||||
It("should generate a WOPI src URL as a jwt token", func() {
|
||||
url, err := wopisrc.GenerateWopiSrc("123456", c)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(url.String()).To(Equal("https://cloud.proxy.com/wopi/files/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1IjoiaHR0cHM6Ly9vY2lzLnRlYW0vd29waS9maWxlcy8iLCJmIjoiMTIzNDU2In0.6ol9PQXGKktKfAri8tsJ4X_a9rIeosJ7id6KTQW6Ui0"))
|
||||
Expect(url.String()).To(Equal("https://cloud.proxy.com/wopi/files/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1IjoiaHR0cHM6Ly9jbG91ZC5leGFtcGxlLnRlc3Qvd29waS9maWxlcy8iLCJmIjoiMTIzNDU2In0.LzyGPanHKxjLlIPoyfGU4cAUxzy3FAmBqMIqLCSHclg"))
|
||||
})
|
||||
})
|
||||
When("proxy URL and proxy secret are not configured", func() {
|
||||
@@ -57,7 +57,7 @@ var _ = Describe("Wopisrc Test", func() {
|
||||
c.Wopi.ProxySecret = ""
|
||||
url, err := wopisrc.GenerateWopiSrc("123456", c)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(url.String()).To(Equal("https://ocis.team/wopi/files/123456"))
|
||||
Expect(url.String()).To(Equal("https://cloud.example.test/wopi/files/123456"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user