From db07dbc4875a71d23e083ca5665772fc2caabf72 Mon Sep 17 00:00:00 2001 From: Giuseppe Lo Presti Date: Tue, 28 Feb 2023 18:40:37 +0100 Subject: [PATCH] Decorate friendly name in case of OCM users --- .../packages/app/provider/wopi/_index.md | 22 +++++------ pkg/app/provider/wopi/wopi.go | 39 ++++++++++++------- pkg/auth/scope/publicshare.go | 6 +-- pkg/utils/utils.go | 4 +- 4 files changed, 40 insertions(+), 31 deletions(-) diff --git a/docs/content/en/docs/config/packages/app/provider/wopi/_index.md b/docs/content/en/docs/config/packages/app/provider/wopi/_index.md index dec3634b108..966e30ef8cd 100644 --- a/docs/content/en/docs/config/packages/app/provider/wopi/_index.md +++ b/docs/content/en/docs/config/packages/app/provider/wopi/_index.md @@ -9,7 +9,7 @@ description: > # _struct: config_ {{% dir name="mime_types" type="[]string" default=nil %}} -Inherited from the appprovider. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L64) +Inherited from the appprovider. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L68) {{< highlight toml >}} [app.provider.wopi] mime_types = nil @@ -17,7 +17,7 @@ mime_types = nil {{% /dir %}} {{% dir name="iop_secret" type="string" default="" %}} -The IOP secret used to connect to the wopiserver. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L65) +The IOP secret used to connect to the wopiserver. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L69) {{< highlight toml >}} [app.provider.wopi] iop_secret = "" @@ -25,7 +25,7 @@ iop_secret = "" {{% /dir %}} {{% dir name="wopi_url" type="string" default="" %}} -The wopiserver's URL. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L66) +The wopiserver's URL. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L70) {{< highlight toml >}} [app.provider.wopi] wopi_url = "" @@ -33,7 +33,7 @@ wopi_url = "" {{% /dir %}} {{% dir name="app_name" type="string" default="" %}} -The App user-friendly name. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L67) +The App user-friendly name. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L71) {{< highlight toml >}} [app.provider.wopi] app_name = "" @@ -41,7 +41,7 @@ app_name = "" {{% /dir %}} {{% dir name="app_icon_uri" type="string" default="" %}} -A URI to a static asset which represents the app icon. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L68) +A URI to a static asset which represents the app icon. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L72) {{< highlight toml >}} [app.provider.wopi] app_icon_uri = "" @@ -49,7 +49,7 @@ app_icon_uri = "" {{% /dir %}} {{% dir name="folder_base_url" type="string" default="" %}} -The base URL to generate links to navigate back to the containing folder. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L69) +The base URL to generate links to navigate back to the containing folder. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L73) {{< highlight toml >}} [app.provider.wopi] folder_base_url = "" @@ -57,7 +57,7 @@ folder_base_url = "" {{% /dir %}} {{% dir name="app_url" type="string" default="" %}} -The App URL. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L70) +The App URL. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L74) {{< highlight toml >}} [app.provider.wopi] app_url = "" @@ -65,7 +65,7 @@ app_url = "" {{% /dir %}} {{% dir name="app_int_url" type="string" default="" %}} -The internal app URL in case of dockerized deployments. Defaults to AppURL [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L71) +The internal app URL in case of dockerized deployments. Defaults to AppURL [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L75) {{< highlight toml >}} [app.provider.wopi] app_int_url = "" @@ -73,7 +73,7 @@ app_int_url = "" {{% /dir %}} {{% dir name="app_api_key" type="string" default="" %}} -The API key used by the app, if applicable. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L72) +The API key used by the app, if applicable. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L76) {{< highlight toml >}} [app.provider.wopi] app_api_key = "" @@ -81,7 +81,7 @@ app_api_key = "" {{% /dir %}} {{% dir name="jwt_secret" type="string" default="" %}} -The JWT secret to be used to retrieve the token TTL. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L73) +The JWT secret to be used to retrieve the token TTL. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L77) {{< highlight toml >}} [app.provider.wopi] jwt_secret = "" @@ -89,7 +89,7 @@ jwt_secret = "" {{% /dir %}} {{% dir name="app_desktop_only" type="bool" default=false %}} -Specifies if the app can be opened only on desktop. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L74) +Specifies if the app can be opened only on desktop. [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/app/provider/wopi/wopi.go#L78) {{< highlight toml >}} [app.provider.wopi] app_desktop_only = false diff --git a/pkg/app/provider/wopi/wopi.go b/pkg/app/provider/wopi/wopi.go index e3f503f2a25..5af85c0cea8 100644 --- a/pkg/app/provider/wopi/wopi.go +++ b/pkg/app/provider/wopi/wopi.go @@ -58,6 +58,8 @@ import ( const publicLinkURLPrefix = "/files/link/public/" +const ocmLinkURLPrefix = "/files/spaces/sciencemesh/" + func init() { registry.Register("wopi", New) } @@ -158,7 +160,6 @@ func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.Resourc } else { q.Add("userid", u.Id.OpaqueId+"@"+u.Id.Idp) } - q.Add("username", u.DisplayName) scopes, ok := ctxpkg.ContextGetScopes(ctx) if !ok { @@ -168,19 +169,27 @@ func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.Resourc // TODO (lopresti) consolidate with the templating implemented in the edge branch; // here we assume the FolderBaseURL looks like `https://` and we - // either append `/files/spaces/` or publicLinkURLPrefix + `/` + // either append `/files/spaces/` or the proper URL prefix + `/` var rPath string + var pathErr error if _, ok := utils.HasPublicShareRole(u); ok { - // we are in a public link - q.Del("username") // on public shares default to "Guest xyz" - var err error - rPath, err = getPathForPublicLink(ctx, scopes, resource) - if err != nil { - log.Warn().Err(err).Msg("wopi: failed to extract relative path from public link scope") + // we are in a public link, username is not set so it will default to "Guest xyz" + rPath, pathErr = getPathForExternalLink(ctx, scopes, resource, publicLinkURLPrefix) + if pathErr != nil { + log.Warn().Err(pathErr).Msg("wopi: failed to extract relative path from public link scope") + } + } else if u.Username == "" { + // OCM users have no username: use displayname@Idp + q.Add("username", u.DisplayName+"@"+u.Id.Idp) + // and resolve the folder + rPath, pathErr = getPathForExternalLink(ctx, scopes, resource, ocmLinkURLPrefix) + if pathErr != nil { + log.Warn().Err(pathErr).Msg("wopi: failed to extract relative path from ocm link scope") } } else { // in all other cases use the resource's path rPath = "/files/spaces/" + path.Dir(resource.Path) + q.Add("username", u.DisplayName) } if rPath != "" { fu, err := url.JoinPath(p.conf.FolderBaseURL, rPath) @@ -472,13 +481,13 @@ func parseWopiDiscovery(body io.Reader) (map[string]map[string]string, error) { return appURLs, nil } -func getPathForPublicLink(ctx context.Context, scopes map[string]*authpb.Scope, resource *provider.ResourceInfo) (string, error) { - pubShares, err := scope.GetPublicSharesFromScopes(scopes) +func getPathForExternalLink(ctx context.Context, scopes map[string]*authpb.Scope, resource *provider.ResourceInfo, pathPrefix string) (string, error) { + shares, err := scope.GetPublicOcmSharesFromScopes(scopes) if err != nil { return "", err } - if len(pubShares) > 1 { - return "", errors.New("More than one public share found in the scope, lookup not implemented") + if len(shares) > 1 { + return "", errors.New("More than one public or OCM share found in the scope, lookup not implemented") } client, err := pool.GetGatewayServiceClient(pool.Endpoint(sharedconf.GetGatewaySVC(""))) @@ -487,7 +496,7 @@ func getPathForPublicLink(ctx context.Context, scopes map[string]*authpb.Scope, } statRes, err := client.Stat(ctx, &provider.StatRequest{ Ref: &provider.Reference{ - ResourceId: pubShares[0].ResourceId, + ResourceId: shares[0].ResourceId, }, }) if err != nil { @@ -496,7 +505,7 @@ func getPathForPublicLink(ctx context.Context, scopes map[string]*authpb.Scope, if statRes.Info.Path == resource.Path { // this is a direct link to the resource - return publicLinkURLPrefix + pubShares[0].Token, nil + return pathPrefix + shares[0].Token, nil } // otherwise we are in a subfolder of the public link relPath, err := filepath.Rel(statRes.Info.Path, resource.Path) @@ -506,5 +515,5 @@ func getPathForPublicLink(ctx context.Context, scopes map[string]*authpb.Scope, if strings.HasPrefix(relPath, "../") { return "", errors.New("Scope path does not contain target resource") } - return path.Join(publicLinkURLPrefix+pubShares[0].Token, path.Dir(relPath)), nil + return path.Join(pathPrefix+shares[0].Token, path.Dir(relPath)), nil } diff --git a/pkg/auth/scope/publicshare.go b/pkg/auth/scope/publicshare.go index e70410bf21b..d72aca267ff 100644 --- a/pkg/auth/scope/publicshare.go +++ b/pkg/auth/scope/publicshare.go @@ -136,11 +136,11 @@ func AddPublicShareScope(share *link.PublicShare, role authpb.Role, scopes map[s return scopes, nil } -// GetPublicSharesFromScopes returns all the public shares in the given scope. -func GetPublicSharesFromScopes(scopes map[string]*authpb.Scope) ([]*link.PublicShare, error) { +// GetPublicOcmSharesFromScopes returns all public and OCM shares in the given scope. +func GetPublicOcmSharesFromScopes(scopes map[string]*authpb.Scope) ([]*link.PublicShare, error) { var shares []*link.PublicShare for k, s := range scopes { - if strings.HasPrefix(k, "publicshare:") { + if strings.HasPrefix(k, "publicshare:") || strings.HasPrefix(k, "ocmshare:") { res := s.Resource if res.Decoder != "json" { return nil, errtypes.InternalError("resource should be json encoded") diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 008f4c25845..d4948bfe20e 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -368,7 +368,7 @@ func HasPublicShareRole(u *userpb.User) (string, bool) { return "", false } -// HasPermissions returns true if all permissions defined in the stuict toCheck +// HasPermissions returns true if all permissions defined in the struct toCheck // are set in the target. func HasPermissions(target, toCheck *provider.ResourcePermissions) bool { targetStruct := reflect.ValueOf(target).Elem() @@ -383,7 +383,7 @@ func HasPermissions(target, toCheck *provider.ResourcePermissions) bool { return true } -// UserIsLightweight returns true if the user is a lightweith +// UserIsLightweight returns true if the user is a lightweight // or federated account. func UserIsLightweight(u *userpb.User) bool { return u.Id.Type == userpb.UserType_USER_TYPE_FEDERATED ||