Skip to content

Commit

Permalink
Use a URL object in OpenInAppResponse
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 committed Aug 6, 2021
1 parent 74545ea commit c3fb416
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 36 deletions.
3 changes: 3 additions & 0 deletions changelog/unreleased/appprovider-url-object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Enhancement: Use a URL object in OpenInAppResponse

https://github.com/cs3org/reva/pull/1968
2 changes: 1 addition & 1 deletion cmd/reva/open-in-app.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func openInAppCommand() *command {
return formatError(openRes.Status)
}

fmt.Println("App URL: " + openRes.AppUrl)
fmt.Printf("App URL: %+v\n", openRes.AppUrl)

return nil
}
Expand Down
2 changes: 2 additions & 0 deletions examples/ocmd/ocmd-server-1.toml
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,6 @@ prefix = "ocs"

[http.services.ocdav]

[http.services.appprovider]

[http.middlewares.cors]
1 change: 1 addition & 0 deletions examples/storage-references/gateway.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ appauth = "localhost:15000"
[http.services.ocmd]
[http.services.ocdav]
[http.services.ocs]
[http.services.appprovider]
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ require (
github.com/imdario/mergo v0.3.8 // indirect
github.com/jedib0t/go-pretty v4.3.0+incompatible
github.com/mattn/go-sqlite3 v1.14.8
github.com/mileusna/useragent v1.0.2
github.com/minio/minio-go/v7 v7.0.12
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.4.1
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/onsi/ginkgo v1.16.4
github.com/onsi/gomega v1.14.0
github.com/pkg/errors v0.9.1
Expand Down Expand Up @@ -74,6 +74,7 @@ require (
go 1.16

replace (
github.com/cs3org/go-cs3apis => github.com/ishank011/go-cs3apis v0.0.0-20210806135412-33c0570675bf
github.com/eventials/go-tus => github.com/andrewmostello/go-tus v0.0.0-20200314041820-904a9904af9a
github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1
google.golang.org/grpc => google.golang.org/grpc v1.26.0 // temporary downgrade
Expand Down
11 changes: 4 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,6 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e h1:tqSPWQeueWTKnJVMJffz4pz0o1WuQxJ28+5x5JgaHD8=
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4=
github.com/cs3org/go-cs3apis v0.0.0-20210325133324-32b03d75a535/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/cs3org/go-cs3apis v0.0.0-20210802070913-970eec344e59 h1:cj9HxIbmbGn+HPpFP8nZ8oaNUsoFa0+cheCO8FUNoMc=
github.com/cs3org/go-cs3apis v0.0.0-20210802070913-970eec344e59/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -310,6 +307,8 @@ github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/ishank011/go-cs3apis v0.0.0-20210806135412-33c0570675bf h1:wn+wPv/i6zy20sf9PqOhLjfaRyj987uObXSRqeJfdDI=
github.com/ishank011/go-cs3apis v0.0.0-20210806135412-33c0570675bf/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/jedib0t/go-pretty v4.3.0+incompatible h1:CGs8AVhEKg/n9YbUenWmNStRW2PHJzaeDodcfvRAbIo=
github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag=
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
Expand Down Expand Up @@ -352,8 +351,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labkode/go-cs3apis v0.0.0-20210716084248-5b525d721d76 h1:hjsbm/ElPr/+ET5hHt68bawlqL8T2li0MvCR5TJouiU=
github.com/labkode/go-cs3apis v0.0.0-20210716084248-5b525d721d76/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
Expand Down Expand Up @@ -383,6 +380,8 @@ github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvr
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mileusna/useragent v1.0.2 h1:DgVKtiPnjxlb73z9bCwgdUvU2nQNQ97uhgfO8l9uz/w=
github.com/mileusna/useragent v1.0.2/go.mod h1:3d8TOmwL/5I8pJjyVDteHtgDGcefrFUX4ccGOMKNYYc=
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
github.com/minio/minio-go/v7 v7.0.12 h1:/4pxUdwn9w0QEryNkrrWaodIESPRX+NxpO0Q6hVdaAA=
Expand Down Expand Up @@ -413,8 +412,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
Expand Down
2 changes: 1 addition & 1 deletion internal/grpc/services/appregistry/appregistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (s *svc) Close() error {
}

func (s *svc) UnprotectedEndpoints() []string {
return []string{"/cs3.app.registry.v1beta1.RegistryAPI/AddAppProvider"}
return []string{"/cs3.app.registry.v1beta1.RegistryAPI/AddAppProvider", "/cs3.app.registry.v1beta1.RegistryAPI/ListSupportedMimeTypes"}
}

func (s *svc) Register(ss *grpc.Server) {
Expand Down
79 changes: 70 additions & 9 deletions internal/http/services/appprovider/appprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,18 @@ import (
"time"
"unicode/utf8"

appregistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/internal/http/services/ocmd"
"github.com/cs3org/reva/pkg/appctx"
"github.com/cs3org/reva/pkg/rgrpc/status"
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/rhttp/global"
"github.com/cs3org/reva/pkg/rhttp/router"
"github.com/cs3org/reva/pkg/sharedconf"
ua "github.com/mileusna/useragent"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"github.com/rs/zerolog"
Expand All @@ -54,7 +58,7 @@ type Config struct {

func (c *Config) init() {
if c.Prefix == "" {
c.Prefix = "api/v0/wopi/open"
c.Prefix = "app"
}
if c.AccessTokenTTL == 0 {
c.AccessTokenTTL = 86400
Expand Down Expand Up @@ -91,17 +95,20 @@ func (s *svc) Prefix() string {
}

func (s *svc) Unprotected() []string {
return []string{}
return []string{"/list"}
}

func (s *svc) Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
ocmd.WriteError(w, r, ocmd.APIErrorUnimplemented, "only GET requests are supported", errors.New("only GET requests are supported"))
return
var head string
head, r.URL.Path = router.ShiftPath(r.URL.Path)

switch head {
case "list":
s.handleList(w, r)
case "open":
s.handleOpen(w, r)
}

s.handleWopiOpen(w, r)
})
}

Expand All @@ -112,7 +119,61 @@ type WopiResponse struct {
AccessTokenTTL int64 `json:"accesstokenttl"`
}

func (s *svc) handleWopiOpen(w http.ResponseWriter, r *http.Request) {
func filterAppsByUserAgent(mimeTypes map[string]*appregistry.AppProviderList, userAgent string) {
ua := ua.Parse(userAgent)
if ua.Desktop {
return
}

for m, providers := range mimeTypes {
apps := []*appregistry.ProviderInfo{}
for _, p := range providers.AppProviders {
if !p.DesktopOnly {
apps = append(apps, p)
}
}
mimeTypes[m] = &appregistry.AppProviderList{AppProviders: apps}
}
}

func (s *svc) handleList(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
log := appctx.GetLogger(ctx)
log.Info().Msgf("user agent %+v", r.UserAgent())

client, err := pool.GetGatewayServiceClient(s.conf.GatewaySvc)
if err != nil {
ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error getting grpc gateway client", err)
return
}

listRes, err := client.ListSupportedMimeTypes(ctx, &appregistry.ListSupportedMimeTypesRequest{})
if err != nil {
ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error listing supported mime types", err)
return
}
if listRes.Status.Code != rpc.Code_CODE_OK {
ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error listing supported mime types", status.NewErrorFromCode(listRes.Status.Code, "appprovider"))
return
}

mimeTypes := listRes.MimeTypes
filterAppsByUserAgent(mimeTypes, r.UserAgent())

js, err := json.Marshal(map[string]interface{}{"mime-types": mimeTypes})
if err != nil {
ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error marshalling JSON response", err)
return
}

w.Header().Set("Content-Type", "application/json")
if _, err = w.Write(js); err != nil {
ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error writing JSON response", err)
return
}
}

func (s *svc) handleOpen(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

client, err := pool.GetGatewayServiceClient(s.conf.GatewaySvc)
Expand Down Expand Up @@ -141,7 +202,7 @@ func (s *svc) handleWopiOpen(w http.ResponseWriter, r *http.Request) {
return
}

u, err := url.Parse(openRes.AppUrl)
u, err := url.Parse(openRes.AppUrl.AppUrl)
if err != nil {
ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error parsing app URL", err)
return
Expand Down
1 change: 1 addition & 0 deletions internal/http/services/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package loader

import (
// Load core HTTP services
_ "github.com/cs3org/reva/internal/http/services/appprovider"
_ "github.com/cs3org/reva/internal/http/services/datagateway"
_ "github.com/cs3org/reva/internal/http/services/dataprovider"
_ "github.com/cs3org/reva/internal/http/services/helloworld"
Expand Down
4 changes: 2 additions & 2 deletions pkg/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
type Registry interface {
FindProviders(ctx context.Context, mimeType string) ([]*registry.ProviderInfo, error)
ListProviders(ctx context.Context) ([]*registry.ProviderInfo, error)
ListSupportedMimeTypes(ctx context.Context) (map[string]*registry.AppProviderNameList, error)
ListSupportedMimeTypes(ctx context.Context) (map[string]*registry.AppProviderList, error)
AddProvider(ctx context.Context, p *registry.ProviderInfo) error
GetDefaultProviderForMimeType(ctx context.Context, mimeType string) (*registry.ProviderInfo, error)
SetDefaultProviderForMimeType(ctx context.Context, mimeType string, p *registry.ProviderInfo) error
Expand All @@ -40,6 +40,6 @@ type Registry interface {
// Provider is the interface that application providers implement
// for providing the URL of the app which will serve the requested resource.
type Provider interface {
GetAppURL(ctx context.Context, resource *provider.ResourceInfo, viewMode appprovider.OpenInAppRequest_ViewMode, token string) (string, error)
GetAppURL(ctx context.Context, resource *provider.ResourceInfo, viewMode appprovider.OpenInAppRequest_ViewMode, token string) (*appprovider.OpenInAppURL, error)
GetAppProviderInfo(ctx context.Context) (*registry.ProviderInfo, error)
}
9 changes: 6 additions & 3 deletions pkg/app/provider/demo/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ type demoProvider struct {
iframeUIProvider string
}

func (p *demoProvider) GetAppURL(ctx context.Context, resource *provider.ResourceInfo, viewMode appprovider.OpenInAppRequest_ViewMode, token string) (string, error) {
msg := fmt.Sprintf("<iframe src=%s/open/%s?view-mode=%s&access-token=%s />", p.iframeUIProvider, resource.Id.StorageId+":"+resource.Id.OpaqueId, viewMode.String(), token)
return msg, nil
func (p *demoProvider) GetAppURL(ctx context.Context, resource *provider.ResourceInfo, viewMode appprovider.OpenInAppRequest_ViewMode, token string) (*appprovider.OpenInAppURL, error) {
url := fmt.Sprintf("<iframe src=%s/open/%s?view-mode=%s&access-token=%s />", p.iframeUIProvider, resource.Id.StorageId+":"+resource.Id.OpaqueId, viewMode.String(), token)
return &appprovider.OpenInAppURL{
AppUrl: url,
Method: "GET",
}, nil
}

func (p *demoProvider) GetAppProviderInfo(ctx context.Context) (*appregistry.ProviderInfo, error) {
Expand Down
23 changes: 15 additions & 8 deletions pkg/app/provider/wopi/wopi.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,11 @@ type config struct {
IOPSecret string `mapstructure:"iop_secret" docs:";The IOP secret used to connect to the wopiserver."`
WopiURL string `mapstructure:"wopi_url" docs:";The wopiserver's URL."`
AppName string `mapstructure:"app_name" docs:";The App user-friendly name."`
AppIconURI string `mapstructure:"app_icon_uri" docs:";A URI to a static asset which represents the app icon."`
AppURL string `mapstructure:"app_url" docs:";The App URL."`
AppIntURL string `mapstructure:"app_int_url" docs:";The internal app URL in case of dockerized deployments. Defaults to AppURL"`
AppAPIKey string `mapstructure:"app_api_key" docs:";The API key used by the app, if applicable."`
AppDesktopOnly bool `mapstructure:"app_desktop_only" docs:";Whether the app can be opened only on desktop."`
InsecureConnections bool `mapstructure:"insecure_connections"`
}

Expand Down Expand Up @@ -107,19 +109,19 @@ func New(m map[string]interface{}) (app.Provider, error) {
}, nil
}

func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.ResourceInfo, viewMode appprovider.OpenInAppRequest_ViewMode, token string) (string, error) {
func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.ResourceInfo, viewMode appprovider.OpenInAppRequest_ViewMode, token string) (*appprovider.OpenInAppURL, error) {
log := appctx.GetLogger(ctx)

ext := path.Ext(resource.Path)
wopiurl, err := url.Parse(p.conf.WopiURL)
if err != nil {
return "", err
return nil, err
}
wopiurl.Path = path.Join(wopiurl.Path, "/wopi/iop/openinapp")

httpReq, err := rhttp.NewRequest(ctx, "GET", wopiurl.String(), nil)
if err != nil {
return "", err
return nil, err
}

q := httpReq.URL.Query()
Expand Down Expand Up @@ -156,17 +158,20 @@ func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.Resourc

openRes, err := p.wopiClient.Do(httpReq)
if err != nil {
return "", errors.Wrap(err, "wopi: error performing open request to WOPI server")
return nil, errors.Wrap(err, "wopi: error performing open request to WOPI server")
}
defer openRes.Body.Close()

if openRes.StatusCode != http.StatusFound {
return "", errors.Wrap(err, "wopi: unexpected status from WOPI server: "+openRes.Status)
return nil, errors.Wrap(err, "wopi: unexpected status from WOPI server: "+openRes.Status)
}
appFullURL := openRes.Header.Get("Location")

log.Info().Msg(fmt.Sprintf("wopi: returning app URL %s", appFullURL))
return appFullURL, nil
return &appprovider.OpenInAppURL{
AppUrl: appFullURL,
Method: "GET",
}, nil
}

func (p *wopiProvider) GetAppProviderInfo(ctx context.Context) (*appregistry.ProviderInfo, error) {
Expand All @@ -185,8 +190,10 @@ func (p *wopiProvider) GetAppProviderInfo(ctx context.Context) (*appregistry.Pro
}

return &appregistry.ProviderInfo{
Name: p.conf.AppName,
MimeTypes: mimeTypes,
Name: p.conf.AppName,
Icon: p.conf.AppIconURI,
DesktopOnly: p.conf.AppDesktopOnly,
MimeTypes: mimeTypes,
}, nil
}

Expand Down
8 changes: 4 additions & 4 deletions pkg/app/registry/static/static.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,14 @@ func (b *reg) ListProviders(ctx context.Context) ([]*registrypb.ProviderInfo, er
return providers, nil
}

func (b *reg) ListSupportedMimeTypes(ctx context.Context) (map[string]*registrypb.AppProviderNameList, error) {
mimeTypes := make(map[string]*registrypb.AppProviderNameList)
func (b *reg) ListSupportedMimeTypes(ctx context.Context) (map[string]*registrypb.AppProviderList, error) {
mimeTypes := make(map[string]*registrypb.AppProviderList)
for _, p := range b.providers {
for _, m := range p.MimeTypes {
if _, ok := mimeTypes[m]; ok {
mimeTypes[m].AppProviderName = append(mimeTypes[m].AppProviderName, p.Name)
mimeTypes[m].AppProviders = append(mimeTypes[m].AppProviders, p)
} else {
mimeTypes[m] = &registrypb.AppProviderNameList{AppProviderName: []string{p.Name}}
mimeTypes[m] = &registrypb.AppProviderList{AppProviders: []*registrypb.ProviderInfo{p}}
}
}
}
Expand Down

0 comments on commit c3fb416

Please sign in to comment.