From 7685ddf9a877a1b970b85c0cb71d88beb98906b6 Mon Sep 17 00:00:00 2001 From: Daniel Wood Date: Tue, 5 May 2020 13:48:48 -0700 Subject: [PATCH] Rebase on Master --- config/config.yml_example | 13 +++++++++++++ config/testing/handler_regexwhitelist.yml | 16 ++++++++++++++++ handlers/auth.go | 11 +++++++++++ handlers/handlers_test.go | 8 ++++++++ pkg/cfg/cfg.go | 17 +++++++++++++++++ 5 files changed, 65 insertions(+) create mode 100644 config/testing/handler_regexwhitelist.yml diff --git a/config/config.yml_example b/config/config.yml_example index dec41a80..c90e052a 100644 --- a/config/config.yml_example +++ b/config/config.yml_example @@ -43,6 +43,19 @@ vouch: - alice@yourdomain.com - joe@yourdomain.com + # regexWhiteList - (optional) allows only the listed usernames + # Note: whiteList always takes precidence and disables regexWhiteList + # + # Single-quotes(') are to prevent the yaml parser from misinterpreting the line) + # usernames are usually email addresses (google, most oidc providers) or login/username for github and github enterprise + # + # regexWhiteList: + # - '^bob[4-9]?@yourdomain.com$' + # - '^alice@.+\.com$' + # - '^alice@your(other)?domain\.com$' + # - '^joe@yourdomain\.com$' + # - '^j[aneo]{1,3}@yourdomain\.(org|net|com)$' + jwt: # secret - a random string used to cryptographically sign the jwt # Vouch Proxy complains if the string is less than 44 characters (256 bits as 32 base64 bytes) diff --git a/config/testing/handler_regexwhitelist.yml b/config/testing/handler_regexwhitelist.yml new file mode 100644 index 00000000..1bc46367 --- /dev/null +++ b/config/testing/handler_regexwhitelist.yml @@ -0,0 +1,16 @@ +vouch: + logLevel: debug + domains: + - example.com + + regexWhiteList: + - 'test1?\@(domain|example)\.com' + + jwt: + secret: testingsecret + +oauth: + provider: indieauth + client_id: http://vouch.github.io + auth_url: https://indielogin.com/auth + callback_url: http://vouch.github.io:9090/auth \ No newline at end of file diff --git a/handlers/auth.go b/handlers/auth.go index 99c0f220..d58073a1 100644 --- a/handlers/auth.go +++ b/handlers/auth.go @@ -117,6 +117,17 @@ func verifyUser(u interface{}) (bool, error) { } return false, fmt.Errorf("verifyUser: user.Username not found in WhiteList: %s", user.Username) + // regexWhiteList + case len(cfg.CompiledRegexWhiteList) != 0: + for _, wl := range cfg.CompiledRegexWhiteList { + log.Debugf("Checking claim: '%v' against regex: '%v'", user.Username, wl) + if wl.MatchString(user.Username) { + log.Debugf("VerifyUser: Success! found user.Username in regexWhiteList: %s", user.Username) + return true, nil + } + } + return false, fmt.Errorf("VerifyUser: user.Username not found in regexWhiteList: %s", user.Username) + // TeamWhiteList case len(cfg.Cfg.TeamWhiteList) != 0: for _, team := range user.TeamMemberships { diff --git a/handlers/handlers_test.go b/handlers/handlers_test.go index 6bf97be3..93495492 100644 --- a/handlers/handlers_test.go +++ b/handlers/handlers_test.go @@ -143,6 +143,14 @@ func TestVerifyUserPositiveUserInWhiteList(t *testing.T) { assert.Nil(t, err) } +func TestVerifyUserPositiveUserInRegexWhiteList(t *testing.T) { + setUp("/config/testing/handler_regexwhitelist.yml") + user := &structs.User{Username: "test@example.com", Email: "test@example.com", Name: "Test Name"} + ok, err := VerifyUser(*user) + assert.True(t, ok) + assert.Nil(t, err) +} + func TestVerifyUserPositiveAllowAllUsers(t *testing.T) { setUp("/config/testing/handler_allowallusers.yml") diff --git a/pkg/cfg/cfg.go b/pkg/cfg/cfg.go index 98f4b9a1..de04299a 100644 --- a/pkg/cfg/cfg.go +++ b/pkg/cfg/cfg.go @@ -18,6 +18,7 @@ import ( "os" "path/filepath" "strings" + "regexp" "github.com/mitchellh/mapstructure" @@ -36,6 +37,7 @@ type Config struct { Port int `mapstructure:"port"` Domains []string `mapstructure:"domains"` WhiteList []string `mapstructure:"whitelist"` + RegexWhiteList []string `mapstructure:"regexWhiteList"` TeamWhiteList []string `mapstructure:"teamWhitelist"` AllowAllUsers bool `mapstructure:"allowAllUsers"` PublicAccess bool `mapstructure:"publicAccess"` @@ -162,6 +164,8 @@ var ( Cfg = &Config{} // IsHealthCheck see main.go IsHealthCheck = false + // CompiledRegexWhiteList see auth.go + CompiledRegexWhiteList []*regexp.Regexp ) type cmdLineFlags struct { @@ -392,6 +396,19 @@ func basicTest() error { if Cfg.Cookie.MaxAge > Cfg.JWT.MaxAge { return fmt.Errorf("configuration error: Cookie maxAge (%d) cannot be larger than the JWT maxAge (%d)", Cfg.Cookie.MaxAge, Cfg.JWT.MaxAge) } + // if using regexWhiteList, compile regex statements, and store them in cfg.CompiledRegexWhiteList + if len(Cfg.RegexWhiteList) != 0 { + for i, wl := range Cfg.RegexWhiteList { + //generate regex array + reWhiteList, reWhiteListErr := regexp.Compile(wl) + if reWhiteListErr != nil { + return fmt.Fatalf("Uncompilable regex parameter: '%v'", wl) + } + CompiledRegexWhiteList = append(CompiledRegexWhiteList, reWhiteList) + log.Debugf("Compiled regex parameter '%v'", CompiledRegexWhiteList[i]) + } + log.Debugf("compiled regex array %v", CompiledRegexWhiteList) + } return nil }