diff --git a/pkg/app/provider/wopi/wopi.go b/pkg/app/provider/wopi/wopi.go index 4469f65c27a..98ae2b8a0d8 100644 --- a/pkg/app/provider/wopi/wopi.go +++ b/pkg/app/provider/wopi/wopi.go @@ -125,7 +125,7 @@ func New(m map[string]interface{}) (app.Provider, error) { } wopiClient := rhttp.GetHTTPClient( - rhttp.Timeout(time.Duration(5*int64(time.Second))), + rhttp.Timeout(time.Duration(10*int64(time.Second))), rhttp.Insecure(c.InsecureConnections), ) wopiClient.CheckRedirect = func(req *http.Request, via []*http.Request) error { @@ -184,30 +184,25 @@ func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.Resourc // either append `/files/spaces/` or the proper URL prefix + `/` var rPath string var pathErr error - _, ok = utils.HasPublicShareRole(u) + _, pubrole := utils.HasPublicShareRole(u) + _, ocmrole := utils.HasOCMShareRole(u) switch { - case ok: + case pubrole: // we are in a public link, username is not set so it will default to "Guest xyz" ut = anonymous 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") } - case u.Username == "": + case ocmrole: // OCM users have no username: use displayname@Idp ut = ocm - idpURL, e := url.Parse(u.Id.Idp) - if e != nil { - q.Add("username", u.DisplayName+" @ "+u.Id.Idp) - } else { - q.Add("username", u.DisplayName+" @ "+idpURL.Hostname()) - } + 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") } - q.Add("usertype", "ocm") default: // in all other cases use the resource's path if ut == invalid { @@ -508,12 +503,25 @@ func parseWopiDiscovery(body io.Reader) (map[string]map[string]string, error) { } func getPathForExternalLink(ctx context.Context, scopes map[string]*authpb.Scope, resource *provider.ResourceInfo, pathPrefix string) (string, error) { - shares, err := scope.GetPublicOcmSharesFromScopes(scopes) + pubshares, err := scope.GetPublicSharesFromScopes(scopes) + if err != nil { + return "", err + } + ocmshares, err := scope.GetOCMSharesFromScopes(scopes) if err != nil { return "", err } - if len(shares) > 1 { - return "", errors.New("More than one public or OCM share found in the scope, lookup not implemented") + var resID *provider.ResourceId + var token string + switch { + case len(pubshares) == 1: + resID = pubshares[0].ResourceId + token = pubshares[0].Token + case len(ocmshares) == 1: + resID = ocmshares[0].ResourceId + token = ocmshares[0].Token + default: + return "", errors.New("Either one public xor OCM share is supported, lookups not implemented") } client, err := pool.GetGatewayServiceClient(pool.Endpoint(sharedconf.GetGatewaySVC(""))) @@ -522,7 +530,7 @@ func getPathForExternalLink(ctx context.Context, scopes map[string]*authpb.Scope } statRes, err := client.Stat(ctx, &provider.StatRequest{ Ref: &provider.Reference{ - ResourceId: shares[0].ResourceId, + ResourceId: resID, }, }) if err != nil { @@ -531,7 +539,7 @@ func getPathForExternalLink(ctx context.Context, scopes map[string]*authpb.Scope if statRes.Info.Path == resource.Path { // this is a direct link to the resource - return pathPrefix + shares[0].Token, nil + return pathPrefix + token, nil } // otherwise we are in a subfolder of the public link relPath, err := filepath.Rel(statRes.Info.Path, resource.Path) @@ -541,5 +549,5 @@ func getPathForExternalLink(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(pathPrefix+shares[0].Token, path.Dir(relPath)), nil + return path.Join(pathPrefix+token, path.Dir(relPath)), nil } diff --git a/pkg/auth/scope/ocmshare.go b/pkg/auth/scope/ocmshare.go index 19f7793b76c..9a9fbcf37c4 100644 --- a/pkg/auth/scope/ocmshare.go +++ b/pkg/auth/scope/ocmshare.go @@ -32,6 +32,7 @@ import ( provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" registry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1" types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" + "github.com/cs3org/reva/pkg/errtypes" "github.com/cs3org/reva/pkg/utils" "github.com/rs/zerolog" ) @@ -134,3 +135,23 @@ func AddOCMShareScope(share *ocmv1beta1.Share, role authpb.Role, scopes map[stri } return scopes, nil } + +// GetOCMSharesFromScopes returns all OCM shares in the given scope. +func GetOCMSharesFromScopes(scopes map[string]*authpb.Scope) ([]*ocmv1beta1.Share, error) { + var shares []*ocmv1beta1.Share + for k, s := range scopes { + if strings.HasPrefix(k, "ocmshare:") { + res := s.Resource + if res.Decoder != "json" { + return nil, errtypes.InternalError("resource should be json encoded") + } + var share ocmv1beta1.Share + err := utils.UnmarshalJSONToProtoV1(res.Value, &share) + if err != nil { + return nil, err + } + shares = append(shares, &share) + } + } + return shares, nil +} diff --git a/pkg/auth/scope/publicshare.go b/pkg/auth/scope/publicshare.go index d72aca267ff..692275440df 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 } -// GetPublicOcmSharesFromScopes returns all public and OCM shares in the given scope. -func GetPublicOcmSharesFromScopes(scopes map[string]*authpb.Scope) ([]*link.PublicShare, error) { +// GetPublicSharesFromScopes returns all public shares in the given scope. +func GetPublicSharesFromScopes(scopes map[string]*authpb.Scope) ([]*link.PublicShare, error) { var shares []*link.PublicShare for k, s := range scopes { - if strings.HasPrefix(k, "publicshare:") || strings.HasPrefix(k, "ocmshare:") { + if strings.HasPrefix(k, "publicshare:") { res := s.Resource if res.Decoder != "json" { return nil, errtypes.InternalError("resource should be json encoded")