Skip to content

Commit

Permalink
Register app from the appprovider grpc service
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 committed Jun 30, 2021
1 parent 723dff6 commit cb1aaeb
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 48 deletions.
31 changes: 29 additions & 2 deletions internal/grpc/services/appprovider/appprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@ import (
"context"

providerpb "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
registrypb "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
"github.com/cs3org/reva/pkg/app"
"github.com/cs3org/reva/pkg/app/provider/registry"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/rgrpc"
"github.com/cs3org/reva/pkg/rgrpc/status"
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/sharedconf"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"google.golang.org/grpc"
Expand All @@ -42,14 +46,18 @@ type service struct {
}

type config struct {
Driver string `mapstructure:"driver"`
Drivers map[string]map[string]interface{} `mapstructure:"drivers"`
Driver string `mapstructure:"driver"`
Drivers map[string]map[string]interface{} `mapstructure:"drivers"`
AppProviderURL string `mapstructure:"app_provider_url"`
GatewaySvc string `mapstructure:"gatewaysvc"`
}

func (c *config) init() {
if c.Driver == "" {
c.Driver = "demo"
}
c.AppProviderURL = sharedconf.GetGatewaySVC(c.AppProviderURL)
c.GatewaySvc = sharedconf.GetGatewaySVC(c.GatewaySvc)
}

func parseConfig(m map[string]interface{}) (*config, error) {
Expand All @@ -73,6 +81,25 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) {
return nil, err
}

ctx := context.Background()
pInfo, err := provider.GetAppProviderInfo(ctx)
if err != nil {
return nil, err
}
pInfo.Address = c.AppProviderURL

client, err := pool.GetGatewayServiceClient(c.GatewaySvc)
if err != nil {
return nil, err
}
res, err := client.AddAppProvider(ctx, &registrypb.AddAppProviderRequest{Provider: pInfo})
if err != nil {
return nil, err
}
if res.Status.Code != rpc.Code_CODE_OK {
return nil, status.NewErrorFromCode(res.Status.Code, "appprovider")
}

service := &service{
conf: c,
provider: provider,
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{}
return []string{"/cs3.app.registry.v1beta1.UserAPI/AddAppProvider"}
}

func (s *svc) Register(ss *grpc.Server) {
Expand Down
1 change: 1 addition & 0 deletions pkg/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ type Registry interface {
// 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, app, token string) (string, error)
GetAppProviderInfo(ctx context.Context) (*registry.ProviderInfo, error)
}
7 changes: 7 additions & 0 deletions pkg/app/provider/demo/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/cs3org/reva/pkg/app"

appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
appregistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/pkg/app/provider/registry"
"github.com/mitchellh/mapstructure"
Expand All @@ -43,6 +44,12 @@ func (p *demoProvider) GetAppURL(ctx context.Context, resource *provider.Resourc
return msg, nil
}

func (p *demoProvider) GetAppProviderInfo(ctx context.Context) (*appregistry.ProviderInfo, error) {
return &appregistry.ProviderInfo{
Name: "demo-app",
}, nil
}

type config struct {
IFrameUIProvider string `mapstructure:"iframe_ui_provider"`
}
Expand Down
84 changes: 39 additions & 45 deletions pkg/app/provider/wopi/wopi.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (

"github.com/beevik/etree"
appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
appregistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/pkg/app"
"github.com/cs3org/reva/pkg/app/provider/registry"
Expand All @@ -52,8 +53,8 @@ type config struct {
WopiURL string `mapstructure:"wopi_url" docs:";The wopiserver's URL."`
AppName string `mapstructure:"app_name" docs:";The App user-friendly name."`
AppURL string `mapstructure:"app_url" docs:";The App URL."`
AppIntURL string `mapstructure:"app_int_url" docs:";The App internal 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."`
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."`
}

func parseConfig(m map[string]interface{}) (*config, error) {
Expand Down Expand Up @@ -81,13 +82,11 @@ func New(m map[string]interface{}) (app.Provider, error) {
if c.AppIntURL == "" {
c.AppIntURL = c.AppURL
}

appURLs, err := getAppURLs(c)
if err != nil {
return nil, err
if c.IOPSecret == "" {
c.IOPSecret = os.Getenv("REVA_APPPROVIDER_IOPSECRET")
}

err = registerApp(c, appURLs)
appURLs, err := getAppURLs(c)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -149,13 +148,11 @@ func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.Resourc
q.Add("appviewurl", url)
}
}
httpReq.URL.RawQuery = q.Encode()

if p.conf.AppAPIKey != "" {
httpReq.Header.Set("ApiKey", p.conf.AppAPIKey)
}
if p.conf.IOPSecret == "" {
p.conf.IOPSecret = os.Getenv("REVA_APPPROVIDER_IOPSECRET")
}
httpReq.URL.RawQuery = q.Encode()

httpReq.Header.Set("Authorization", "Bearer "+p.conf.IOPSecret)
httpReq.Header.Set("TokenHeader", token)
Expand All @@ -175,6 +172,27 @@ func (p *wopiProvider) GetAppURL(ctx context.Context, resource *provider.Resourc
return appFullURL, nil
}

func (p *wopiProvider) GetAppProviderInfo(ctx context.Context) (*appregistry.ProviderInfo, error) {
// Initially we store the mime types in a map to avoid duplicates
mimeTypesMap := make(map[string]bool)
for _, extensions := range p.appURLs {
for ext := range extensions {
m := mime.Detect(false, ext)
mimeTypesMap[m] = true
}
}
// TODO register these mimetypes in the AppRegistry
mimeTypes := make([]string, 0, len(mimeTypesMap))
for m := range mimeTypesMap {
mimeTypes = append(mimeTypes, m)
}

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

func getAppURLs(c *config) (map[string]map[string]string, error) {
// Initialize WOPI URLs by discovery
httpcl := rhttp.GetHTTPClient(
Expand All @@ -199,7 +217,12 @@ func getAppURLs(c *config) (map[string]map[string]string, error) {

var appURLs map[string]map[string]string

if discRes.StatusCode == http.StatusNotFound {
if discRes.StatusCode == http.StatusOK {
appURLs, err = parseWopiDiscovery(discRes.Body)
if err != nil {
return nil, errors.Wrap(err, "error parsing wopi discovery response")
}
} else if discRes.StatusCode == http.StatusNotFound {
// this may be a bridge-supported app
discReq, err = http.NewRequest("GET", c.AppIntURL, nil)
if err != nil {
Expand Down Expand Up @@ -229,40 +252,12 @@ func getAppURLs(c *config) (map[string]map[string]string, error) {
} else if c.AppName == "Etherpad" {
appURLs = getEtherpadExtensions(c.AppURL)
}
} else if discRes.StatusCode == http.StatusOK {
var netZoneName string
if c.AppName == "Collabora" {
netZoneName = "external-http"

} else if c.AppName == "Office Online" {
netZoneName = "external-https"
}
appURLs, err = parseWopiDiscovery(discRes.Body, netZoneName)
if err != nil {
return nil, errors.Wrap(err, "error parsing wopi discovery response")
}
}
return appURLs, nil
}

func registerApp(c *config, appURLs map[string]map[string]string) error {
// Initially we store the mime types in a map to avoid duplicates
mimeTypesMap := make(map[string]bool)
for _, extensions := range appURLs {
for ext := range extensions {
m := mime.Detect(false, ext)
mimeTypesMap[m] = true
}
}
// TODO register these mimetypes in the AppRegistry
mimeTypes := make([]string, 0, len(mimeTypesMap))
for m := range mimeTypesMap {
mimeTypes = append(mimeTypes, m)
}
return nil
}

func parseWopiDiscovery(body io.Reader, netZoneName string) (map[string]map[string]string, error) {
func parseWopiDiscovery(body io.Reader) (map[string]map[string]string, error) {
appURLs := make(map[string]map[string]string)

doc := etree.NewDocument()
Expand All @@ -271,11 +266,10 @@ func parseWopiDiscovery(body io.Reader, netZoneName string) (map[string]map[stri
}
root := doc.SelectElement("wopi-discovery")

for _, netZone := range root.SelectElements("net-zone") {
nameAttr := netZone.SelectAttr("name")
for _, netzone := range root.SelectElements("net-zone") {

if nameAttr.Value == netZoneName {
for _, app := range netZone.SelectElements("app") {
if strings.Contains(netzone.SelectAttrValue("name", ""), "external") {
for _, app := range netzone.SelectElements("app") {
for _, action := range app.SelectElements("action") {
access := action.SelectAttrValue("name", "")
if access == "view" || access == "edit" {
Expand Down

0 comments on commit cb1aaeb

Please sign in to comment.