From 83ccded6f013ef53cfb465e8b0a6cdbeae2a4715 Mon Sep 17 00:00:00 2001 From: Sebastian Mancke Date: Tue, 9 Jan 2018 23:16:04 +0100 Subject: [PATCH] rename redirect config parameters allow-redirects -> redirect redirect-query-parameter -> redirect-query-parameter check-referer-on-redirects -> redirect-check-referer whitelist-domains-file -> redirect-host-file --- caddy/setup.go | 4 +- caddy/setup_test.go | 106 ++++++++++++++++++++--------------------- login/config.go | 88 +++++++++++++++++----------------- login/config_test.go | 84 ++++++++++++++++---------------- login/redirect.go | 17 ++++--- login/redirect_test.go | 10 ++-- 6 files changed, 157 insertions(+), 152 deletions(-) diff --git a/caddy/setup.go b/caddy/setup.go index 926608f..8a83206 100644 --- a/caddy/setup.go +++ b/caddy/setup.go @@ -43,8 +43,8 @@ func setup(c *caddy.Controller) error { config.Template = filepath.Join(httpserver.GetConfig(c).Root, config.Template) } - if config.WhitelistDomainsFile != "" && !filepath.IsAbs(config.WhitelistDomainsFile) { - config.WhitelistDomainsFile = filepath.Join(httpserver.GetConfig(c).Root, config.WhitelistDomainsFile) + if config.RedirectHostFile != "" && !filepath.IsAbs(config.RedirectHostFile) { + config.RedirectHostFile = filepath.Join(httpserver.GetConfig(c).Root, config.RedirectHostFile) } if len(args) == 1 { diff --git a/caddy/setup_test.go b/caddy/setup_test.go index 613db2f..7dc0987 100644 --- a/caddy/setup_test.go +++ b/caddy/setup_test.go @@ -28,15 +28,15 @@ func TestSetup(t *testing.T) { }`, shouldErr: false, config: login.Config{ - JwtSecret: "jwtsecret", - JwtExpiry: 24 * time.Hour, - SuccessURL: "/", - AllowRedirects: true, - RedirectQueryParameter: "backTo", - CheckRefererOnRedirects: true, - LoginPath: "/login", - CookieName: "jwt_token", - CookieHTTPOnly: true, + JwtSecret: "jwtsecret", + JwtExpiry: 24 * time.Hour, + SuccessURL: "/", + Redirect: true, + RedirectQueryParameter: "backTo", + RedirectCheckReferer: true, + LoginPath: "/login", + CookieName: "jwt_token", + CookieHTTPOnly: true, Backends: login.Options{ "simple": map[string]string{ "bob": "secret", @@ -50,10 +50,10 @@ func TestSetup(t *testing.T) { success_url successurl jwt_expiry 42h login_path /foo/bar - allow_redirects true + redirect true redirect_query_parameter comingFrom - check_referer_on_redirects true - whitelist_domains_file domainWhitelist.txt + redirect_check_referer true + redirect_host_file domainWhitelist.txt cookie_name cookiename cookie_http_only false cookie_domain example.com @@ -63,18 +63,18 @@ func TestSetup(t *testing.T) { }`, shouldErr: false, config: login.Config{ - JwtSecret: "jwtsecret", - JwtExpiry: 42 * time.Hour, - SuccessURL: "successurl", - AllowRedirects: true, - RedirectQueryParameter: "comingFrom", - CheckRefererOnRedirects: true, - WhitelistDomainsFile: "domainWhitelist.txt", - LoginPath: "/foo/bar", - CookieName: "cookiename", - CookieDomain: "example.com", - CookieExpiry: 23*time.Hour + 23*time.Minute, - CookieHTTPOnly: false, + JwtSecret: "jwtsecret", + JwtExpiry: 42 * time.Hour, + SuccessURL: "successurl", + Redirect: true, + RedirectQueryParameter: "comingFrom", + RedirectCheckReferer: true, + RedirectHostFile: "domainWhitelist.txt", + LoginPath: "/foo/bar", + CookieName: "cookiename", + CookieDomain: "example.com", + CookieExpiry: 23*time.Hour + 23*time.Minute, + CookieHTTPOnly: false, Backends: login.Options{ "simple": map[string]string{ "bob": "secret", @@ -98,15 +98,15 @@ func TestSetup(t *testing.T) { }`, shouldErr: false, config: login.Config{ - JwtSecret: "jwtsecret", - JwtExpiry: 24 * time.Hour, - SuccessURL: "/", - AllowRedirects: true, - RedirectQueryParameter: "backTo", - CheckRefererOnRedirects: true, - LoginPath: "/context/login", - CookieName: "cookiename", - CookieHTTPOnly: true, + JwtSecret: "jwtsecret", + JwtExpiry: 24 * time.Hour, + SuccessURL: "/", + Redirect: true, + RedirectQueryParameter: "backTo", + RedirectCheckReferer: true, + LoginPath: "/context/login", + CookieName: "cookiename", + CookieHTTPOnly: true, Backends: login.Options{ "simple": map[string]string{ "bob": "secret", @@ -125,15 +125,15 @@ func TestSetup(t *testing.T) { }`, shouldErr: false, config: login.Config{ - JwtSecret: "jwtsecret", - JwtExpiry: 24 * time.Hour, - SuccessURL: "/", - AllowRedirects: true, - RedirectQueryParameter: "backTo", - CheckRefererOnRedirects: true, - LoginPath: "/login", - CookieName: "cookiename", - CookieHTTPOnly: true, + JwtSecret: "jwtsecret", + JwtExpiry: 24 * time.Hour, + SuccessURL: "/", + Redirect: true, + RedirectQueryParameter: "backTo", + RedirectCheckReferer: true, + LoginPath: "/login", + CookieName: "cookiename", + CookieHTTPOnly: true, Backends: login.Options{ "simple": map[string]string{ "bob": "secret", @@ -150,15 +150,15 @@ func TestSetup(t *testing.T) { }`, shouldErr: false, config: login.Config{ - JwtSecret: "jwtsecret", - JwtExpiry: 24 * time.Hour, - SuccessURL: "/", - AllowRedirects: true, - RedirectQueryParameter: "backTo", - CheckRefererOnRedirects: true, - LoginPath: "/login", - CookieName: "jwt_token", - CookieHTTPOnly: true, + JwtSecret: "jwtsecret", + JwtExpiry: 24 * time.Hour, + SuccessURL: "/", + Redirect: true, + RedirectQueryParameter: "backTo", + RedirectCheckReferer: true, + LoginPath: "/login", + CookieName: "jwt_token", + CookieHTTPOnly: true, Backends: login.Options{ "simple": map[string]string{ "bob": "secret", @@ -197,7 +197,7 @@ func TestSetup(t *testing.T) { func TestSetup_RelativeFiles(t *testing.T) { caddyfile := `loginsrv { template myTemplate.tpl - whitelist_domains_file redirectDomains.txt + redirect_host_file redirectDomains.txt simple bob=secret }` root, _ := ioutil.TempDir("", "") @@ -216,5 +216,5 @@ func TestSetup_RelativeFiles(t *testing.T) { middleware := mids[len(mids)-1](nil).(*CaddyHandler) Equal(t, root+"/myTemplate.tpl", middleware.config.Template) - Equal(t, root+"/redirectDomains.txt", middleware.config.WhitelistDomainsFile) + Equal(t, root+"/redirectDomains.txt", middleware.config.RedirectHostFile) } diff --git a/login/config.go b/login/config.go index 2759b80..2f695b8 100644 --- a/login/config.go +++ b/login/config.go @@ -23,24 +23,24 @@ func init() { // DefaultConfig for the loginsrv handler func DefaultConfig() *Config { return &Config{ - Host: "localhost", - Port: "6789", - LogLevel: "info", - JwtSecret: jwtDefaultSecret, - JwtExpiry: 24 * time.Hour, - JwtRefreshes: 0, - SuccessURL: "/", - AllowRedirects: true, - RedirectQueryParameter: "backTo", - CheckRefererOnRedirects: true, - WhitelistDomainsFile: "", - LogoutURL: "", - LoginPath: "/login", - CookieName: "jwt_token", - CookieHTTPOnly: true, - Backends: Options{}, - Oauth: Options{}, - GracePeriod: 5 * time.Second, + Host: "localhost", + Port: "6789", + LogLevel: "info", + JwtSecret: jwtDefaultSecret, + JwtExpiry: 24 * time.Hour, + JwtRefreshes: 0, + SuccessURL: "/", + Redirect: true, + RedirectQueryParameter: "backTo", + RedirectCheckReferer: true, + RedirectHostFile: "", + LogoutURL: "", + LoginPath: "/login", + CookieName: "jwt_token", + CookieHTTPOnly: true, + Backends: Options{}, + Oauth: Options{}, + GracePeriod: 5 * time.Second, } } @@ -48,28 +48,28 @@ const envPrefix = "LOGINSRV_" // Config for the loginsrv handler type Config struct { - Host string - Port string - LogLevel string - TextLogging bool - JwtSecret string - JwtExpiry time.Duration - JwtRefreshes int - SuccessURL string - AllowRedirects bool - RedirectQueryParameter string - CheckRefererOnRedirects bool - WhitelistDomainsFile string - LogoutURL string - Template string - LoginPath string - CookieName string - CookieExpiry time.Duration - CookieDomain string - CookieHTTPOnly bool - Backends Options - Oauth Options - GracePeriod time.Duration + Host string + Port string + LogLevel string + TextLogging bool + JwtSecret string + JwtExpiry time.Duration + JwtRefreshes int + SuccessURL string + Redirect bool + RedirectQueryParameter string + RedirectCheckReferer bool + RedirectHostFile string + LogoutURL string + Template string + LoginPath string + CookieName string + CookieExpiry time.Duration + CookieDomain string + CookieHTTPOnly bool + Backends Options + Oauth Options + GracePeriod time.Duration } // Options is the configuration structure for oauth and backend provider @@ -112,10 +112,10 @@ func (c *Config) ConfigureFlagSet(f *flag.FlagSet) { f.DurationVar(&c.CookieExpiry, "cookie-expiry", c.CookieExpiry, "The expiry duration for the cookie, e.g. 2h or 3h30m. Default is browser session") f.StringVar(&c.CookieDomain, "cookie-domain", c.CookieDomain, "The optional domain parameter for the cookie") f.StringVar(&c.SuccessURL, "success-url", c.SuccessURL, "The url to redirect after login") - f.BoolVar(&c.AllowRedirects, "allow-redirects", c.AllowRedirects, "Allow dynamic redirects by parameter") - f.StringVar(&c.RedirectQueryParameter, "redirect-query-parameter", c.RedirectQueryParameter, "Allow dynamic redirects by parameter") - f.BoolVar(&c.CheckRefererOnRedirects, "check-referer-on-redirects", c.CheckRefererOnRedirects, "When redirecting check that the referer is the same domain") - f.StringVar(&c.WhitelistDomainsFile, "whitelist-domains-file", c.WhitelistDomainsFile, "A file containing a list of domains that redirects are allowed to, one domain per line") + f.BoolVar(&c.Redirect, "redirect", c.Redirect, "Allow dynamic overwriting of the the success by query parameter") + f.StringVar(&c.RedirectQueryParameter, "redirect-query-parameter", c.RedirectQueryParameter, "URL parameter for the redirect target") + f.BoolVar(&c.RedirectCheckReferer, "redirect-check-referer", c.RedirectCheckReferer, "When redirecting check that the referer is the same domain") + f.StringVar(&c.RedirectHostFile, "redirect-host-file", c.RedirectHostFile, "A file containing a list of domains that redirects are allowed to, one domain per line") f.StringVar(&c.LogoutURL, "logout-url", c.LogoutURL, "The url or path to redirect after logout") f.StringVar(&c.Template, "template", c.Template, "An alternative template for the login form") diff --git a/login/config_test.go b/login/config_test.go index 93ace72..b7f8a35 100644 --- a/login/config_test.go +++ b/login/config_test.go @@ -29,10 +29,10 @@ func TestConfig_ReadConfig(t *testing.T) { "--jwt-secret=jwtsecret", "--jwt-expiry=42h42m", "--success-url=successurl", - "--allow-redirects=false", + "--redirect=false", "--redirect-query-parameter=comingFrom", - "--check-referer-on-redirects=false", - "--whitelist-domains-file=File", + "--redirect-check-referer=false", + "--redirect-host-file=File", "--logout-url=logouturl", "--template=template", "--login-path=loginpath", @@ -47,24 +47,24 @@ func TestConfig_ReadConfig(t *testing.T) { } expected := &Config{ - Host: "host", - Port: "port", - LogLevel: "loglevel", - TextLogging: true, - JwtSecret: "jwtsecret", - JwtExpiry: 42*time.Hour + 42*time.Minute, - SuccessURL: "successurl", - AllowRedirects: false, - RedirectQueryParameter: "comingFrom", - CheckRefererOnRedirects: false, - WhitelistDomainsFile: "File", - LogoutURL: "logouturl", - Template: "template", - LoginPath: "loginpath", - CookieName: "cookiename", - CookieExpiry: 23 * time.Minute, - CookieDomain: "*.example.com", - CookieHTTPOnly: false, + Host: "host", + Port: "port", + LogLevel: "loglevel", + TextLogging: true, + JwtSecret: "jwtsecret", + JwtExpiry: 42*time.Hour + 42*time.Minute, + SuccessURL: "successurl", + Redirect: false, + RedirectQueryParameter: "comingFrom", + RedirectCheckReferer: false, + RedirectHostFile: "File", + LogoutURL: "logouturl", + Template: "template", + LoginPath: "loginpath", + CookieName: "cookiename", + CookieExpiry: 23 * time.Minute, + CookieDomain: "*.example.com", + CookieHTTPOnly: false, Backends: Options{ "simple": map[string]string{}, "foo": map[string]string{}, @@ -91,10 +91,10 @@ func TestConfig_ReadConfigFromEnv(t *testing.T) { NoError(t, os.Setenv("LOGINSRV_JWT_SECRET", "jwtsecret")) NoError(t, os.Setenv("LOGINSRV_JWT_EXPIRY", "42h42m")) NoError(t, os.Setenv("LOGINSRV_SUCCESS_URL", "successurl")) - NoError(t, os.Setenv("LOGINSRV_ALLOW_REDIRECTS", "false")) + NoError(t, os.Setenv("LOGINSRV_REDIRECT", "false")) NoError(t, os.Setenv("LOGINSRV_REDIRECT_QUERY_PARAMETER", "comingFrom")) - NoError(t, os.Setenv("LOGINSRV_CHECK_REFERER_ON_REDIRECTS", "false")) - NoError(t, os.Setenv("LOGINSRV_WHITELIST_DOMAINS_FILE", "File")) + NoError(t, os.Setenv("LOGINSRV_REDIRECT_CHECK_REFERER", "false")) + NoError(t, os.Setenv("LOGINSRV_REDIRECT_HOST_FILE", "File")) NoError(t, os.Setenv("LOGINSRV_LOGOUT_URL", "logouturl")) NoError(t, os.Setenv("LOGINSRV_TEMPLATE", "template")) NoError(t, os.Setenv("LOGINSRV_LOGIN_PATH", "loginpath")) @@ -107,24 +107,24 @@ func TestConfig_ReadConfigFromEnv(t *testing.T) { NoError(t, os.Setenv("LOGINSRV_GRACE_PERIOD", "4s")) expected := &Config{ - Host: "host", - Port: "port", - LogLevel: "loglevel", - TextLogging: true, - JwtSecret: "jwtsecret", - JwtExpiry: 42*time.Hour + 42*time.Minute, - SuccessURL: "successurl", - AllowRedirects: false, - RedirectQueryParameter: "comingFrom", - CheckRefererOnRedirects: false, - WhitelistDomainsFile: "File", - LogoutURL: "logouturl", - Template: "template", - LoginPath: "loginpath", - CookieName: "cookiename", - CookieExpiry: 23 * time.Minute, - CookieDomain: "*.example.com", - CookieHTTPOnly: false, + Host: "host", + Port: "port", + LogLevel: "loglevel", + TextLogging: true, + JwtSecret: "jwtsecret", + JwtExpiry: 42*time.Hour + 42*time.Minute, + SuccessURL: "successurl", + Redirect: false, + RedirectQueryParameter: "comingFrom", + RedirectCheckReferer: false, + RedirectHostFile: "File", + LogoutURL: "logouturl", + Template: "template", + LoginPath: "loginpath", + CookieName: "cookiename", + CookieExpiry: 23 * time.Minute, + CookieDomain: "*.example.com", + CookieHTTPOnly: false, Backends: Options{ "simple": map[string]string{ "foo": "bar", diff --git a/login/redirect.go b/login/redirect.go index 650c972..b6907cf 100644 --- a/login/redirect.go +++ b/login/redirect.go @@ -35,10 +35,10 @@ func (h *Handler) deleteRedirectCookie(w http.ResponseWriter, r *http.Request) { } func (h *Handler) allowRedirect(r *http.Request) bool { - if !h.config.AllowRedirects { + if !h.config.Redirect { return false } - if !h.config.CheckRefererOnRedirects { + if !h.config.RedirectCheckReferer { return true } @@ -56,7 +56,7 @@ func (h *Handler) allowRedirect(r *http.Request) bool { func (h *Handler) redirectURL(r *http.Request, w http.ResponseWriter) string { targetURL, foundTarget := h.getRedirectTarget(r) - if foundTarget && h.config.AllowRedirects { + if foundTarget && h.config.Redirect { sameHost := targetURL.Host == "" || r.Host == targetURL.Host if sameHost && targetURL.Path != "" { return targetURL.Path @@ -93,9 +93,14 @@ func (h *Handler) getRedirectTarget(r *http.Request) (*url.URL, bool) { } func (h *Handler) isRedirectDomainWhitelisted(r *http.Request, host string) bool { - f, err := os.Open(h.config.WhitelistDomainsFile) + if h.config.RedirectHostFile == "" { + logging.Application(r.Header).Warnf("redirect attempt to '%s', but no whitelist domain file given", host) + return false + } + + f, err := os.Open(h.config.RedirectHostFile) if err != nil { - logging.Application(r.Header).Warnf("can't open redirect whitelist domains file '%s'", h.config.WhitelistDomainsFile) + logging.Application(r.Header).Warnf("can't open redirect whitelist domains file '%s'", h.config.RedirectHostFile) return false } defer f.Close() @@ -106,6 +111,6 @@ func (h *Handler) isRedirectDomainWhitelisted(r *http.Request, host string) bool return true } } - logging.Application(r.Header).Warnf("domain '%s' not in redirect whitelist", host) + logging.Application(r.Header).Warnf("redirect attempt to '%s', but not in redirect whitelist", host) return false } diff --git a/login/redirect_test.go b/login/redirect_test.go index fd25740..4f3328e 100644 --- a/login/redirect_test.go +++ b/login/redirect_test.go @@ -28,9 +28,9 @@ func TestRedirect(t *testing.T) { } func TestRedirect_NotAllowed(t *testing.T) { - // redirect to SuccessURL if AllowRedirects is false + // redirect to SuccessURL if Redirect is false cfg := DefaultConfig() - cfg.AllowRedirects = false + cfg.Redirect = false h := &Handler{ backends: []Backend{ NewSimpleBackend(map[string]string{"bob": "secret"}), @@ -55,9 +55,9 @@ func TestRedirect_NonMatchingReferrer(t *testing.T) { setCookieList = readSetCookies(recorder.Header()) Equal(t, 0, len(setCookieList)) - // set redirect cookie with mismatch referer if CheckRefererOnRedirects is false + // set redirect cookie with mismatch referer if RedirectCheckReferer is false cfg := DefaultConfig() - cfg.CheckRefererOnRedirects = false + cfg.RedirectCheckReferer = false h := &Handler{ backends: []Backend{ NewSimpleBackend(map[string]string{"bob": "secret"}), @@ -93,7 +93,7 @@ func TestRedirect_Whitelisting(t *testing.T) { // redirect to success url if domains whitelist file doesn't exist cfg := DefaultConfig() - cfg.WhitelistDomainsFile = whitelistFile.Name() + cfg.RedirectHostFile = whitelistFile.Name() h := &Handler{ backends: []Backend{ NewSimpleBackend(map[string]string{"bob": "secret"}),