From e03461fd0320d41efe982bc5cb968ca59044151c Mon Sep 17 00:00:00 2001 From: verybadsoldier Date: Thu, 27 Apr 2023 23:12:33 +0200 Subject: [PATCH] make trusted SSP HTTP header names configurable --- .vscode/launch.json | 1 + backend/app/api/handlers/v1/controller.go | 28 +++++++++++++++------ backend/app/api/handlers/v1/v1_ctrl_auth.go | 6 +++-- backend/app/api/routes.go | 2 ++ backend/internal/sys/config/conf.go | 10 +++++--- docs/docs/quick-start.md | 2 ++ frontend/lib/api/public.ts | 6 ++++- 7 files changed, 41 insertions(+), 14 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index eb97bae..ef03c90 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -26,6 +26,7 @@ "HBOX_STORAGE_SQLITE_URL": "${workspaceRoot}/backend/.data/homebox.db?_fk=1", "HBOX_OPTIONS_HEADER_SSO_ENABLED": "true", "HBOX_OPTIONS_HEADER_SSO_ALLOWED_IP": "127.0.0.1", + "HBOX_OPTIONS_HEADER_SSO_HEADER_EMAIL": "testuser@test.org", }, }, { diff --git a/backend/app/api/handlers/v1/controller.go b/backend/app/api/handlers/v1/controller.go index 88d934a..a37d170 100644 --- a/backend/app/api/handlers/v1/controller.go +++ b/backend/app/api/handlers/v1/controller.go @@ -55,14 +55,28 @@ func WithHeaderSSOAllowedIP(headerSSOAllowedIP string) func(*V1Controller) { } } +func WithHeaderSSOHeaderName(headerSSOHeaderName string) func(*V1Controller) { + return func(ctrl *V1Controller) { + ctrl.headerSSOHeaderName = headerSSOHeaderName + } +} + +func WithHeaderSSOHeaderEmail(headerSSOHeaderEmail string) func(*V1Controller) { + return func(ctrl *V1Controller) { + ctrl.headerSSOHeaderEmail = headerSSOHeaderEmail + } +} + type V1Controller struct { - repo *repo.AllRepos - svc *services.AllServices - maxUploadSize int64 - isDemo bool - allowRegistration bool - headerSSOEnabled bool - headerSSOAllowedIP string + repo *repo.AllRepos + svc *services.AllServices + maxUploadSize int64 + isDemo bool + allowRegistration bool + headerSSOEnabled bool + headerSSOAllowedIP string + headerSSOHeaderName string + headerSSOHeaderEmail string } type ( diff --git a/backend/app/api/handlers/v1/v1_ctrl_auth.go b/backend/app/api/handlers/v1/v1_ctrl_auth.go index d51f0ef..70458aa 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_auth.go +++ b/backend/app/api/handlers/v1/v1_ctrl_auth.go @@ -105,7 +105,7 @@ func (ctrl *V1Controller) HandleSsoHeaderLogin() errchain.HandlerFunc { log.Info().Msgf("Header SSO Login Attempt allowed from IP '%s'", t[0]) } - email := r.Header.Get("Remote-Email") + email := r.Header.Get(ctrl.headerSSOHeaderEmail) if email == "" { return validate.NewRequestError(errors.New("authentication failed. not SSO header found or empty"), http.StatusInternalServerError) @@ -116,8 +116,10 @@ func (ctrl *V1Controller) HandleSsoHeaderLogin() errchain.HandlerFunc { if err != nil { // user not found -> create it - var username = r.Header.Get("Remote-Name") + // if the name header does not exist then the empty string will be used as name + var username = r.Header.Get(ctrl.headerSSOHeaderName) + // /* TODO: decide how to handle group information provided by HTTP header // if groups are provided, they will be comma-separated. take only the first group var groups = r.Header.Get("Remote-Groups") diff --git a/backend/app/api/routes.go b/backend/app/api/routes.go index 307a54a..b9c80a5 100644 --- a/backend/app/api/routes.go +++ b/backend/app/api/routes.go @@ -56,6 +56,8 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR v1.WithDemoStatus(a.conf.Demo), // Disable Password Change in Demo Mode v1.WithHeaderSSO(a.conf.Options.HeaderSSOEnabled), v1.WithHeaderSSOAllowedIP(a.conf.Options.HeaderSSOAllowedIP), + v1.WithHeaderSSOHeaderEmail(a.conf.Options.HeaderSSOHeaderEmail), + v1.WithHeaderSSOHeaderName(a.conf.Options.HeaderSSOHeaderName), ) r.Get(v1Base("/status"), chain.ToHandlerFunc(v1Ctrl.HandleBase(func() bool { return true }, v1.Build{ diff --git a/backend/internal/sys/config/conf.go b/backend/internal/sys/config/conf.go index 009b59e..4978075 100644 --- a/backend/internal/sys/config/conf.go +++ b/backend/internal/sys/config/conf.go @@ -26,10 +26,12 @@ type Config struct { } type Options struct { - AllowRegistration bool `yaml:"disable_registration" conf:"default:true"` - AutoIncrementAssetID bool `yaml:"auto_increment_asset_id" conf:"default:true"` - HeaderSSOEnabled bool `yaml:"header_sso_enabled" conf:"default:false"` - HeaderSSOAllowedIP string `yaml:"header_sso_allowed_ip" conf:"default:0.0.0.0"` + AllowRegistration bool `yaml:"disable_registration" conf:"default:true"` + AutoIncrementAssetID bool `yaml:"auto_increment_asset_id" conf:"default:true"` + HeaderSSOEnabled bool `yaml:"header_sso_enabled" conf:"default:false"` + HeaderSSOAllowedIP string `yaml:"header_sso_allowed_ip" conf:"default:0.0.0.0"` + HeaderSSOHeaderName string `yaml:"header_sso_header_name" conf:"default:Remote-Name"` + HeaderSSOHeaderEmail string `yaml:"header_sso_header_email" conf:"default:Remote-Email"` } type DebugConf struct { diff --git a/docs/docs/quick-start.md b/docs/docs/quick-start.md index 0e107fd..7d08464 100644 --- a/docs/docs/quick-start.md +++ b/docs/docs/quick-start.md @@ -49,6 +49,8 @@ volumes: | HBOX_OPTIONS_AUTO_INCREMENT_ASSET_ID | true | auto increments the asset_id field for new items | | HBOX_OPTIONS_HEADER_SSO_ENABLED | false | allow login via trusted SSO HTTP headers | | HBOX_OPTIONS_HEADER_SSO_ALLOWED_IP | | request IP being allowed to send trusted SSO HTTP headers | +| HBOX_OPTIONS_HEADER_SSO_HEADER_NAME | | name of the HTTP header that contains the name when using SSO HTTP headers | +| HBOX_OPTIONS_HEADER_SSO_HEADER_EMAIL | | name of the HTTP header that contains the email when using SSO HTTP headers | | HBOX_WEB_MAX_UPLOAD_SIZE | 10 | maximum file upload size supported in MB | | HBOX_STORAGE_DATA | /data/ | path to the data directory, do not change this if you're using docker | | HBOX_STORAGE_SQLITE_URL | /data/homebox.db?_fk=1 | sqlite database url, in you're using docker do not change this | diff --git a/frontend/lib/api/public.ts b/frontend/lib/api/public.ts index 2a52ce4..d88361c 100644 --- a/frontend/lib/api/public.ts +++ b/frontend/lib/api/public.ts @@ -28,7 +28,11 @@ export class PublicApi extends BaseAPI { return this.http.post({ url: route("/users/login-sso-header"), /** TODO: remove header here. Only for testing. Usually the SSO servie will add this */ - headers: { "Remote-Email": "demo@example.com" }, + headers: { + "Remote-Email": "demo3@example.com", + "Remote-Name": "Fritz3", + "Remote-Groups": "admins,local", + }, }); }