diff --git a/cmd/serve.go b/cmd/serve.go index df44a203310d8eec099bb8d0bdf79f4524c08d8b..1eb4b57ef18fdc870bd9aa59e63a33c3563022b1 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -226,6 +226,9 @@ func init() { flags.String("onlyoffice-url", "", "URL for the OnlyOffice server") checkNoErr(viper.BindPFlag("office.default.onlyoffice_url", flags.Lookup("onlyoffice-url"))) + flags.String("onlyoffice-inbox-secret", "", "Secret used for signing requests to the OnlyOffice server") + checkNoErr(viper.BindPFlag("office.default.onlyoffice_inbox_secret", flags.Lookup("onlyoffice-inbox-secret"))) + flags.String("password-reset-interval", "15m", "minimal duration between two password reset") checkNoErr(viper.BindPFlag("password_reset_interval", flags.Lookup("password-reset-interval"))) diff --git a/cozy.example.yaml b/cozy.example.yaml index 252ad7daa3f00d103528ded23f067f66c20f88d3..3ab4cbeeca28ba3637a4af6ba3221c7613410a65 100644 --- a/cozy.example.yaml +++ b/cozy.example.yaml @@ -257,6 +257,7 @@ move: office: default: onlyoffice_url: https://documentserver.cozycloud.cc/ + onlyoffice_inbox_secret: inbox_secret # [internal usage] Cloudery configuration clouderies: diff --git a/docs/docker.md b/docs/docker.md index 177a2dcdd8af24394a8ea86c28ebbee5938f10fe..25c04672bf852b2952cc528bdccda4d99b11e64e 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -67,7 +67,7 @@ $ docker run -it --rm --name=oodev --net=host cozy/onlyoffice-dev and run the stack with: ```bash -$ cozy-stack serve --disable-csp --onlyoffice-url=http://localhost:8000/ +$ cozy-stack serve --disable-csp --onlyoffice-url=http://localhost:8000/ --onlyoffice-inbox-secret=inbox_secret ``` If you need to rebuild it, you can do that with: diff --git a/docs/office.md b/docs/office.md index 6e1f56b6562f1b828c72d9f8c5e8b6e9c4be6176..1ae664540b1132d9bae84391f414170095cc9ce1 100644 --- a/docs/office.md +++ b/docs/office.md @@ -88,6 +88,7 @@ Content-Type: application/vnd.api+json "public_name": "Bob", "onlyoffice": { "url": "https://documentserver/", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.t-IDcSemACt8x4iTMCda8Yhe3iZaWbvV5XKSTbuAn0M", "documentType": "word", "document": { "filetype": "docx", diff --git a/model/office/open.go b/model/office/open.go index 070ecb68fbc9dd02bb8916708022d37248a5a220..b7f70480b8525e5a75d539915654ff13a93cbdf5 100644 --- a/model/office/open.go +++ b/model/office/open.go @@ -9,6 +9,7 @@ import ( "github.com/cozy/cozy-stack/pkg/consts" "github.com/cozy/cozy-stack/pkg/couchdb" "github.com/cozy/cozy-stack/pkg/jsonapi" + jwt "gopkg.in/dgrijalva/jwt-go.v3" ) type apiOfficeURL struct { @@ -23,21 +24,22 @@ type apiOfficeURL struct { } type onlyOffice struct { - URL string `json:"url"` - Type string `json:"documentType"` - Doc struct { - Filetype string `json:"filetype"` + URL string `json:"url,omitempty"` + Token string `json:"token,omitempty"` + Type string `json:"documentType"` + Doc struct { + Filetype string `json:"filetype,omitempty"` Key string `json:"key"` - Title string `json:"title"` + Title string `json:"title,omitempty"` URL string `json:"url"` Info struct { Owner string `json:"owner,omitempty"` - Uploaded string `json:"uploaded"` + Uploaded string `json:"uploaded,omitempty"` } `json:"info"` } `json:"document"` Editor struct { Callback string `json:"callbackUrl"` - Lang string `json:"lang"` + Lang string `json:"lang,omitempty"` Mode string `json:"mode"` } `json:"editor"` } @@ -53,6 +55,25 @@ func (o *apiOfficeURL) Included() []jsonapi.Object { return nil } func (o *apiOfficeURL) Links() *jsonapi.LinksList { return nil } func (o *apiOfficeURL) Fetch(field string) []string { return nil } +func (o *apiOfficeURL) sign(cfg *config.Office) (string, error) { + if cfg == nil || cfg.InboxSecret == "" { + return "", nil + } + + claims := *o.OO + claims.URL = "" + claims.Doc.Filetype = "" + claims.Doc.Title = "" + claims.Doc.Info.Owner = "" + claims.Doc.Info.Uploaded = "" + claims.Editor.Lang = "" + token := jwt.NewWithClaims(jwt.SigningMethodHS256, &claims) + return token.SignedString([]byte(cfg.InboxSecret)) +} + +// Valid is a method of the jwt.Claims interface +func (o *onlyOffice) Valid() error { return nil } + // Opener can be used to find the parameters for opening an office document. type Opener struct { *sharing.FileOpener @@ -154,6 +175,11 @@ func (o *Opener) openLocalDocument(memberIndex int, readOnly bool) (*apiOfficeUR doc.OO.Editor.Lang = o.Inst.Locale doc.OO.Editor.Mode = mode + token, err := doc.sign(cfg) + if err != nil { + return nil, err + } + doc.OO.Token = token return &doc, nil } diff --git a/pkg/config/config/config.go b/pkg/config/config/config.go index 16e7a6311fd78e6bfe89e51054855ee7cb78d3f8..1bbcb31f8641774166b0121dfc54093504292e0d 100644 --- a/pkg/config/config/config.go +++ b/pkg/config/config/config.go @@ -221,6 +221,7 @@ type Move struct { // documents type Office struct { OnlyOfficeURL string + InboxSecret string } // Notifications contains the configuration for the mobile push-notification @@ -947,14 +948,17 @@ func makeOffice(v *viper.Viper) (map[string]Office, error) { if !ok { return nil, errors.New("Bad format in the office section of the configuration file") } + inbox, _ := ctx["onlyoffice_inbox_secret"].(string) office[k] = Office{ OnlyOfficeURL: url, + InboxSecret: inbox, } } if url := v.GetString("office.default.onlyoffice_url"); url != "" { office[DefaultInstanceContext] = Office{ OnlyOfficeURL: url, + InboxSecret: v.GetString("office.default.onlyoffice_inbox_secret"), } } diff --git a/scripts/onlyoffice-dev/Dockerfile b/scripts/onlyoffice-dev/Dockerfile index b6ba452819ce790fc7c8d4d76c00e3afed97ee41..eef64e0f7d3809a3141355da640a86a008bea0ad 100644 --- a/scripts/onlyoffice-dev/Dockerfile +++ b/scripts/onlyoffice-dev/Dockerfile @@ -57,6 +57,7 @@ RUN echo "#!/bin/sh\nexit 0" > /usr/sbin/policy-rc.d && \ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 0x8320ca65cb2de8e5 && \ apt-get -y update && \ apt-get -yq install onlyoffice-documentserver && \ + cp /usr/bin/local.json /etc/onlyoffice/documentserver/local.json && \ service postgresql stop && \ service rabbitmq-server stop && \ apt-get clean && \ diff --git a/scripts/onlyoffice-dev/local.json b/scripts/onlyoffice-dev/local.json new file mode 100644 index 0000000000000000000000000000000000000000..b40e87b188fa393cc8e7382a975a3ee880b45c6a --- /dev/null +++ b/scripts/onlyoffice-dev/local.json @@ -0,0 +1,43 @@ +{ + "services": { + "CoAuthoring": { + "sql": { + "type": "postgres", + "dbHost": "localhost", + "dbPort": "5432", + "dbName": "onlyoffice", + "dbUser": "onlyoffice", + "dbPass": "onlyoffice" + }, + "token": { + "enable": { + "request": { + "inbox": true, + "outbox": true + }, + "browser": true + }, + "inbox": { + "header": "Authorization" + }, + "outbox": { + "header": "Authorization" + } + }, + "secret": { + "inbox": { + "string": "inbox_secret" + }, + "outbox": { + "string": "outbox_secret" + }, + "session": { + "string": "session_secret" + } + } + } + }, + "rabbitmq": { + "url": "amqp://guest:guest@localhost" + } +}