Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions changelog/unreleased/add-oidc-web-env-vars.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Enhancement: Add OIDC env vars to expand external IDP compatibility

Added two new environment variables, OC_OIDC_CLIENT_SECRET /
WEB_OIDC_CLIENT_SECRET and WEB_OIDC_CLIENT_AUTHENTICATION to
control additional functionality of the frontend's OAuth code exchanges.
Both are passed to the frontend to control oidc-client-ts.

https://github.com/opencloud-eu/opencloud/issues/2345
4 changes: 3 additions & 1 deletion services/web/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@ type WebConfig struct {

// OIDC defines the available oidc configuration
type OIDC struct {
MetadataURL string `json:"metadata_url,omitempty" yaml:"metadata_url" env:"WEB_OIDC_METADATA_URL" desc:"URL for the OIDC well-known configuration endpoint. Defaults to the OpenCloud API URL + '/.well-known/openid-configuration'." introductionVersion:"1.0.0"`
Authority string `json:"authority,omitempty" yaml:"authority" env:"OC_URL;OC_OIDC_ISSUER;WEB_OIDC_AUTHORITY" desc:"URL of the OIDC issuer. It defaults to URL of the builtin IDP." introductionVersion:"1.0.0"`
MetadataURL string `json:"metadata_url,omitempty" yaml:"metadata_url" env:"WEB_OIDC_METADATA_URL" desc:"URL for the OIDC well-known configuration endpoint. Defaults to the OpenCloud API URL + '/.well-known/openid-configuration'." introductionVersion:"1.0.0"`
ClientID string `json:"client_id,omitempty" yaml:"client_id" env:"OC_OIDC_CLIENT_ID;WEB_OIDC_CLIENT_ID" desc:"The OIDC client ID which OpenCloud Web uses. This client needs to be set up in your IDP. Note that this setting has no effect when using the builtin IDP." introductionVersion:"1.0.0"`
ClientSecret string `json:"client_secret,omitempty" yaml:"client_secret" env:"OC_OIDC_CLIENT_SECRET;WEB_OIDC_CLIENT_SECRET" desc:"The OIDC client secret which OpenCloud Web uses. Useful when some external IDPs require a client secret be sent despite PKCE. This client needs to be set up in your IDP. Note that this setting has no effect when using the builtin IDP." introductionVersion:"%%NEXT%%"`
ResponseType string `json:"response_type,omitempty" yaml:"response_type" env:"WEB_OIDC_RESPONSE_TYPE" desc:"The OIDC response type to use for authentication." introductionVersion:"1.0.0"`
Scope string `json:"scope,omitempty" yaml:"scope" env:"WEB_OIDC_SCOPE" desc:"OIDC scopes to request during authentication to authorize access to user details. Defaults to 'openid profile email'. Values are separated by blank. More example values but not limited to are 'address' or 'phone' etc." introductionVersion:"1.0.0"`
ClientAuthentication string `json:"client_authentication,omitempty" yaml:"client_authentication" env:"WEB_OIDC_CLIENT_AUTHENTICATION" desc:"Client authentication method that is used to authenticate when using the token endpoint (default 'client_secret_post'). 'client_secret_basic' using the HTTP Basic authentication scheme, 'client_secret_post' including the client credentials in the request body, 'client_secret_jwt' using a JWT signed with the client secret." introductionVersion:"%%NEXT%%"`
PostLogoutRedirectURI string `json:"post_logout_redirect_uri,omitempty" yaml:"post_logout_redirect_uri" env:"WEB_OIDC_POST_LOGOUT_REDIRECT_URI" desc:"This value needs to point to a valid and reachable web page. The web client will trigger a redirect to that page directly after the logout action. The default value is empty and redirects to the login page." introductionVersion:"1.0.0"`
}

Expand Down
13 changes: 8 additions & 5 deletions services/web/pkg/config/defaults/defaultconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,14 @@ func DefaultConfig() *config.Config {
Server: "https://localhost:9200",
Theme: "",
OpenIDConnect: config.OIDC{
MetadataURL: "",
Authority: "https://localhost:9200",
ClientID: "web",
ResponseType: "code",
Scope: "openid profile email",
MetadataURL: "",
Authority: "https://localhost:9200",
ClientID: "web",
ClientSecret: "",
ResponseType: "code",
Scope: "openid profile email",
ClientAuthentication: "client_secret_post",
PostLogoutRedirectURI: "",
},
Apps: []string{"files", "search", "text-editor", "pdf-viewer", "external", "admin-settings", "epub-reader", "preview", "app-store"},
Options: config.Options{
Expand Down
73 changes: 73 additions & 0 deletions services/web/pkg/config/oidc_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package config_test

import (
"os"
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/opencloud-eu/opencloud/services/web/pkg/config"
"github.com/opencloud-eu/opencloud/services/web/pkg/config/parser"
)

func TestOIDCWebConfiguration(t *testing.T) {
Describe("OIDC Configuration Environment Decoding", func() {
var (
testEnvVars map[string]string
savedEnv map[string]string
)

BeforeEach(func() {
testEnvVars = map[string]string{
"WEB_OIDC_AUTHORITY": "https://idp.example.com",
"WEB_OIDC_METADATA_URL": "https://idp.example.com/.well-known/openid-configuration",
"WEB_OIDC_CLIENT_ID": "web",
"WEB_OIDC_CLIENT_SECRET": "secret",
"WEB_OIDC_RESPONSE_TYPE": "code",
"WEB_OIDC_SCOPE": "openid profile email",
"WEB_OIDC_CLIENT_AUTHENTICATION": "client_secret_post",
"WEB_OIDC_POST_LOGOUT_REDIRECT_URI": "https://app.example.com/login",
}

// pretend env are callee saved
// not sure what the standards for env vars between tests are
savedEnv = make(map[string]string)
for k := range testEnvVars {
if val, exists := os.LookupEnv(k); exists {
savedEnv[k] = val
}
}

for k, v := range testEnvVars {
err := os.Setenv(k, v)
Expect(err).To(BeNil())
}
})

AfterEach(func() {
// restore
for k := range testEnvVars {
err := os.Unsetenv(k)
Expect(err).To(BeNil())
}
})

It("successfully decodes OIDC environment variables into the struct", func() {
var cfg config.Config

err := parser.ParseConfig(&cfg)
Expect(err).To(BeNil())

oidcCfg := &cfg.Web.Config.OpenIDConnect

Expect(oidcCfg.Authority).To(Equal("https://idp.example.com"))
Expect(oidcCfg.MetadataURL).To(Equal("https://idp.example.com/.well-known/openid-configuration"))
Expect(oidcCfg.ClientID).To(Equal("web"))
Expect(oidcCfg.ClientSecret).To(Equal("secret"))
Expect(oidcCfg.ResponseType).To(Equal("code"))
Expect(oidcCfg.Scope).To(Equal("openid profile email"))
Expect(oidcCfg.ClientAuthentication).To(Equal("client_secret_post"))
Expect(oidcCfg.PostLogoutRedirectURI).To(Equal("https://app.example.com/login"))
})
})
}