Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

collaboration fixes #9165

Merged
merged 9 commits into from
May 31, 2024
Merged

collaboration fixes #9165

merged 9 commits into from
May 31, 2024

Conversation

wkloucek
Copy link
Contributor

@wkloucek wkloucek commented May 14, 2024

Description

  • owncloud.dev lists a default for COLLABORATION_JWT_SECRET, is fixed by leveraging ocis init
    image
  • separates REVA jwt and WOPI jwt secret
  • COLLABORATION_CS3API_GATEWAY_NAME wasn't listed on owncloud.dev. because of a superfluous whitespace

Related Issue

  • none

Motivation and Context

How Has This Been Tested?

  • not yet tested -> TODO

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Technical debt
  • Tests only (no source changes)

Checklist:

  • Code changes
  • Unit tests added
  • Acceptance tests added
  • Documentation ticket raised:

Copy link

update-docs bot commented May 14, 2024

Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a changelog item based on your changes.

@wkloucek
Copy link
Contributor Author

@micbar @jvillafanez do those changes make sense? If yes, could you please bring them to a mergeable state or open another PR? If you have questions, I'm happy to answer those. I just didn't know how to put this feedback into an ticket 😆

@jvillafanez
Copy link
Member

owncloud.dev lists a default for COLLABORATION_JWT_SECRET, is fixed by leveraging ocis init

Any better alternative? It seems weird to me having to partially configure a service that I won't use (the service isn't started by default because we need an external WOPI app).
If there are no better options, we probably should include a comment in the default collaboration config to say that the JWT token will be initialized during the init command, otherwise it might be confusing if we don't find the default JWT token within the collaboration service

@wkloucek
Copy link
Contributor Author

It seems weird to me having to partially configure a service that I won't use (the service isn't started by default because we need an external WOPI app).

The idea of ocis server and ocis init is to pretend there are no services and make it easier for users to use oCIS. Therefore this is by design.

Right now there is no other deployment method than "pretend there are no services" except the oCIS Helm Chart from what I know.

If there are no better options, we probably should include a comment in the default collaboration config to say that the JWT token will be initialized during the init command, otherwise it might be confusing if we don't find the default JWT token within the collaboration service

Actually the validation step are missing, compare

// Validate validates the configuration
func Validate(cfg *config.Config) error {
return nil
}
to eg.
if cfg.MachineAuthAPIKey == "" {
return shared.MissingMachineAuthApiKeyError(cfg.Service.Name)
}

@butonic
Copy link
Member

butonic commented May 15, 2024

there are some changes in this PR that I also made in #9148

@wkloucek
Copy link
Contributor Author

there are some changes in this PR that I also made in #9148

#9148 looks interesting, too. I didn't get so far when looking at it in owncloud/ocis-charts#567

@@ -289,6 +294,10 @@ func CreateConfig(insecure, forceOverwrite bool, configPath, adminPassword strin
if err != nil {
return fmt.Errorf("could not generate random password for tokenmanager: %s", err)
}
collaborationJwtSecret, err := generators.GenerateRandomPassword(passwordLength)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just saying that the original code used the uniuri lib, which used alphanumeric characters. Current code will also include additional symbols. I don't know if they could cause issues

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question!

@jvillafanez
Copy link
Member

Code looks fine to me, except for the "settings.json" file which should be removed

2403905
2403905 previously approved these changes May 22, 2024
@@ -85,3 +85,11 @@ func MissingServiceAccountSecret(service string) error {
"the config/corresponding environment variable).",
service, defaults.BaseConfigPath())
}

func MissingWOPISecretError(service string) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the wopi secret is a different thing then our internal jwt secret. so we need a seperate error for it. IIRC this becomes relevant when using the office365 proxy.

Comment on lines +159 to +167
type WopiApp struct {
Insecure bool `yaml:"insecure"`
Secret string `yaml:"secret"`
}

type Collaboration struct {
WopiApp WopiApp `yaml:"wopiapp"`
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when initializing ocis we initialize all secrets and insecure flags. In a subsequent PR I'll allow running the collaboration service behind the proxy. Then configuring the secrets this will become more mandatory. Might as well do it now.

Comment on lines 25 to 30
* `COLLABORATION_HTTP_ADDR`:\
The external address of the collaboration service. The target app (onlyoffice, collabora, etc) will use this address to read and write files from Infinite Scale.\
For example: `https://wopiserver.example.com`.
* `COLLABORATION_WOPIAPP_INSECURE`:\
In case you are using a self signed certificate for the WOPI app you can tell the collaboration service to allow an insecure connection.

* `COLLABORATION_HTTP_SCHEME`:\
The scheme to be used when accessing the collaboration service. Either `http` or `https`. This will be used to finally build the URL that the WOPI app needs in order to contact the collaboration service.
* `COLLABORATION_WOPIAPP_WOPISRC`:\
The external address of the collaboration service. The target app (onlyoffice, collabora, etc) will use this address to read and write files from Infinite Scale. \
For example: `https://wopi.example.com`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All other services use {SERVICENAME}_HTTP_ADDR to set the bind address. We should not change this here.

Instead we can configure the COLLABORATION_WOPIAPP_WOPISRC directly.

JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;COLLABORATION_JWT_SECRET" desc:"Used as JWT token and to encrypt access token." introductionVersion:"5.1"`
TokenManager *TokenManager `yaml:"token_manager"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OCIS_JWT_SECRET is used to verify the signature of reva acces tokens. The WOPI secret secures communication bewenn the collaboration service and the WOPI application. That is why I changed this to follow the usual tokenmanager pattern and introduced COLLABORATION_WOPIAPP_SECRET.

GRPC: config.GRPC{
Addr: "0.0.0.0:9301",
Namespace: "com.owncloud.collaboration",
Addr: "127.0.0.1:9301",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grpc can listen to localhost by default

@@ -44,12 +40,13 @@ func DefaultConfig() *config.Config {
Zpages: false,
},
WopiApp: config.WopiApp{
Addr: "https://127.0.0.1:8080",
Addr: "https://127.0.0.1:9980",
Copy link
Member

@butonic butonic May 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9980 is the default used by collabora

Insecure: false,
WopiSrc: "https://localhost:9300",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the collaboration service is started standalone it is reachable on localhost. Config doc string and README give an example when running on a different domain.

@butonic
Copy link
Member

butonic commented May 24, 2024

@jvillafanez @2403905 I rebased and updated and commented the PR, please try this out. I have collabora running in a docker container, run ocis and then use this VSCode config for the collaboration service:

			{
				"name": "wopiserver.ocis.test collaboration",
				"type": "go",
				"request": "launch",
				"mode": "debug",
				"program": "${workspaceFolder:ocis}/ocis/cmd/ocis",
				"args": [
					"collaboration", "server"
				],
				"env": {
					"REVA_GATEWAY": "com.owncloud.api.gateway",
					//"COLLABORATION_WOPIAPP_ADDR": "https://onlyoffice.ocis.test",
					"COLLABORATION_WOPIAPP_ADDR": "https://collabora.ocis.test",
					// share the registry with the ocis 
					"MICRO_REGISTRY_ADDRESS": "127.0.0.1:9233",
					"COLLABORATION_WOPIAPP_WOPISRC": "https://wopiserver.ocis.test", // needs to be routed to the collaboration service from within the collabore container
					
					// set some hardcoded secrets
					// collaboration
					"COLLABORATION_WOPIAPP_SECRET": "some-wopi-secret",
					"OCIS_JWT_SECRET": "some-ocis-jwt-secret", // same JWT secret as used for ocis
				}
			},

@butonic butonic force-pushed the collaboration-fixes branch 2 times, most recently from 1a77f37 to dd99a79 Compare May 24, 2024 12:26
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
@butonic
Copy link
Member

butonic commented May 24, 2024

@ScharfViktor how do we set the secrets for the collaboration service in CI?

Comment on lines 7 to 8
WopiSrc string `yaml:"wopisrc" env:"COLLABORATION_WOPIAPP_WOPISRC" desc:"The WOPISrc base URL containing schema, host and port. Path will be set to /wopi/files/{fileid} if not given. {fileid} will be replaced with the WOPI file id. Set this to the schema and domain where the collaboration service is reachable for the wopi app, such as https://office.owncloud.test." introductionVersion:"5.1"`
Secret string `yaml:"secret" env:"COLLABORATION_WOPIAPP_SECRET" desc:"Used to mint and verify WOPI JWT tokens and encrypt and decrypt the REVA JWT token embedded in the WOPI JWT token." introductionVersion:"5.1"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the right place for those properties.
The WopiApp should refer to Collabora / OnlyOffice... however, the WopiSrc is generated in the collaboration service and refers to the collaboration service (it's the externally accessible address so Collabora / OnlyOffice can access to the service). It could be confusing as it seems to be related to the Collabora / OnlyOffice app.

The Secret is generated in the collaboration service. With this changes it seems that you might need to match something in Collabora / OnlyOffice.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put WopiSrc and Secret into the wopiapp because they are both used to communicate with the wopi app. The wopisrc is the entpoint the app should use and the secret is used for the wopi access token JWT. This secret actually need to match the secret of the wopi proxy, so I think they are fine as wopi app related properties.

When we set up a second wopi server for another application we need to change these variables as well.

That is unless we want to make one collaboration service fit to handle multiple wopi apps, as the python wopiserver ... @micbar what is the plan here? I mean technically it would be possible ... then COLLABORATION_WOPIAPP_WOPISRC could be COLLABORATION_WOPISRC. The secret should still be dedicated per app though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'll need to discuss plans because I assumed we want to "link" one collaboration service to one wopi app. We could spawn multiple replicas of the collaboration service, but all of them would be "linked" to the same wopi app.

I don't see a good use case for using multiple wopi apps at the same time. The main problem is that, having multiple wopi apps available, we have to assume that the same file could be opened an multiple wopi apps by different users at the same time. This is a terrible idea because userA could overwrite the changes of userB (which is something to avoid and the reason of using the wopi apps)

Comment on lines +81 to +84
_ = chi.Walk(mux, func(method string, route string, handler stdhttp.Handler, middlewares ...func(stdhttp.Handler) stdhttp.Handler) error {
options.Logger.Debug().Str("method", method).Str("route", route).Int("middlewares", len(middlewares)).Msg("serving endpoint")
return nil
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to keep this? Walking though the routes seems potentially expensive and I'm not sure if we want do that for something that should be fixed after development.
I mean, unless you're debugging during development, I don't think the routes will change, and I don't think we expect dynamic changes in production.

Copy link
Member

@butonic butonic May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only for startup and helps tremendously to see what is actually being routed. also sometimes a list of all routes is required for security theatre... 😞

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, then maybe include a comment? Just to make sure we don't accidentally remove this

Scheme: s.config.HTTP.Scheme,
Host: s.config.HTTP.Addr,
Path: path.Join("wopi", "files", fileRef),
wopiSrcURL, err := url.Parse(strings.Replace(s.config.WopiApp.WopiSrc, "{fileid}", fileRef, 1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of things:
I guess we might want to allow pointing the WopiSrc to a different server... but why? I'd expect the URLs always to point to this server.
Having a variable {fileid} in the URL doesn't seem a good idea. It will likely confuse the admin and we'll have to manage that scenario. It seems better for the admin to provide the server's URL so we can build the rest on our own.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be overly flexible here, yes. The hostname will be different when running the wopi server behind a reverse proxy. In kubernetes we can bypass the ingress and make wopi applications directy tock to the collaboration service without even exposing it.

COLLABORATION_WOPIAPP_WOPISRC should be set to just the domain. But we could announce different WOPI_SRC endpoints for every wopi app ...

If an admin specifies a domain AND a path we could also die when parsing the url in the config validation ...

@ScharfViktor
Copy link
Contributor

@ScharfViktor how do we set the secrets for the collaboration service in CI?

we can set secrets here
https://drone.owncloud.com/owncloud/ocis/settings/secrets

and use it like:

"OCIS_JWT_SECRET": {
            "from_secret": "ocis_jwt_secret",
        },

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
@butonic butonic force-pushed the collaboration-fixes branch 3 times, most recently from 16f2d52 to e9f9100 Compare May 30, 2024 11:26
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
Copy link
Contributor

@micbar micbar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice progress. Two nitpicks, but then we should merge it.

services/collaboration/README.md Outdated Show resolved Hide resolved
services/collaboration/README.md Outdated Show resolved Hide resolved
Co-authored-by: Michael Barz <michael.barz@zeitgestalten.eu>
@butonic
Copy link
Member

butonic commented May 31, 2024

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
Copy link

sonarcloud bot commented May 31, 2024

Quality Gate Failed Quality Gate failed

Failed conditions
4 New Bugs (required ≤ 0)

See analysis details on SonarCloud

Catch issues before they fail your Quality Gate with our IDE extension SonarLint

@butonic butonic merged commit 3db878e into owncloud:master May 31, 2024
3 of 4 checks passed
@butonic
Copy link
Member

butonic commented May 31, 2024

SonarCloud 'Bugs' were unrelated to this PR

ownclouders pushed a commit that referenced this pull request May 31, 2024
@wkloucek wkloucek deleted the collaboration-fixes branch May 31, 2024 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants