Skip to content

Commit

Permalink
feature: Add whitelist and domain support to rulesBuilds on thomseddo…
Browse files Browse the repository at this point in the history
…n#63, respecting the matchWhitelistOrDomain flag
  • Loading branch information
tdorsey committed Jun 6, 2020
1 parent 8ba3f9a commit 21b0939
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 52 deletions.
66 changes: 35 additions & 31 deletions internal/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,53 +59,57 @@ func ValidateCookie(r *http.Request, c *http.Cookie) (string, error) {
// ValidateEmail checks if the given email address matches either a whitelisted
// email address, as defined by the "whitelist" config parameter. Or is part of
// a permitted domain, as defined by the "domains" config parameter
// if an email or domain is added by a rule, it is merged with the config before being evaluated
// in order to respect the match whitelist or domain parameter
func ValidateEmail(email string) bool {

// Do we have any validation to perform?
if len(config.Whitelist) == 0 && len(config.Domains) == 0 && len(config.Rules) == 0 {
return true
}
var whitelists []string
var domains []string

// Email rule validation
if len(config.Rules) > 0 {
// rule validation
for _, rule := range config.Rules {
if rule.Action == "whitelist" {
for _, whitelisted := range rule.Whitelist {
if whitelisted == email {
return true
}
}
for _, whitelisted := range rule.Whitelist {
whitelists = append(whitelists, whitelisted)
}
for _, domain := range rule.Domains {
domains = append(domains, domain)
}
}
}

domains = append(domains, config.Domains...)
whitelists = append(whitelists, config.Whitelist...)

// Email whitelist validation
if len(config.Whitelist) > 0 {
for _, whitelist := range config.Whitelist {
if email == whitelist {
return true
}
}

// If we're not matching *either*, stop here
if !config.MatchWhitelistOrDomain {
return false
for _, whitelist := range whitelists {
if email == whitelist {
return true
}

}

// If there's a whitelist and we're not matching *either*, stop here
if len(whitelists) > 0 && !config.MatchWhitelistOrDomain {
return false
}

// Domain validation
if len(config.Domains) > 0 {
parts := strings.Split(email, "@")
if len(parts) < 2 {
return false
}
for _, domain := range config.Domains {
if domain == parts[1] {
return true
}
for _, domain := range domains {
if emailIsInDomain(email, domain) {
return true
}
}

return false
}
func emailIsInDomain(email string, domain string) bool {
parts := strings.Split(email, "@")
if len(parts) < 2 {
return false
}
if parts[1] == domain {
return true
}
return false
}

Expand Down
122 changes: 105 additions & 17 deletions internal/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,72 @@ func TestAuthValidateEmail(t *testing.T) {
v = ValidateEmail("one@two.com")
assert.True(v, "should allow any domain if email domain is not defined")

// Should allow email whitelisted in rule
// Should allow email specified in a whitelist rule
config.Rules = map[string]*Rule{
"whitelisted-from-rule": {
Action: "whitelist",
Rule: "multiple-ppl",
Rule: "test-whitelist-rule",
Whitelist: []string{"whitelisted-from-rule@example.com"},
},
}

v = ValidateEmail("whitelisted-from-rule@example.com")
assert.True(v, "should allow email in whitelist rule")
assert.True(v, "should allow email from whitelist rule")

// Should allow multiple emails specified in a whitelist rule
config.Rules = map[string]*Rule{
"whitelist-multiple-emails": {
Rule: "whitelist-rule",
Whitelist: []string{"allowed-from-whitelist-multiple-emails1@example.com",
"allowed-from-whitelist-multiple-emails2@example.com"},
},
}

v1 := ValidateEmail("allowed-from-whitelist-multiple-emails@example.com")
v2 := ValidateEmail("allowed-from-whitelist-multiple-emails@example.com")
assert.True((v1 == v2), "should allow emails from a whitelist rule")

// Should allow multiple whitelist rules
config.Rules = map[string]*Rule{
"allowed-from-whitelist-rule1": {
Rule: "whitelist-rule1",
Whitelist: []string{"allowed-from-whitelist-rule1@example.com"},
},
"allowed-from-whitelist-rule2": {
Rule: "whitelist-rule2",
Whitelist: []string{"allowed-from-whitelist-rule2@example.com"},
},
}
v1 = ValidateEmail("allowed-from-whitelist-rule1@example.com")
v2 = ValidateEmail("allowed-from-whitelist-rule2@example.com")
assert.True((v1 == v2), "should allow emails from multiple whitelist rules")

// Should allow domain to be specified in a rule
config.Rules = map[string]*Rule{
"allowed-from-domain-rule": {
Rule: "domain-rule1",
Domains: []string{"example.com"},
},
}

v = ValidateEmail("whitelisted-from-domain@example.com")
assert.True(v, "should allow email from domain rule")

// Should allow multiple domains to be specified in a rule
config.Rules = map[string]*Rule{
"allowed-from-domain-rule-1": {
Rule: "domain-rule1",
Domains: []string{"example.com"},
},
"allowed-from-domain-rule2": {
Rule: "domain-rule2",
Domains: []string{"example.org"},
},
}

v1 = ValidateEmail("allowed-from-domain-rule1@example.org")
v2 = ValidateEmail("allowed-from-domain-rule2@example.com")
assert.True((v1 == v2), "Should allow emails from multiple domain rules")

// Should block non matching domain
config.Domains = []string{"test.com"}
v = ValidateEmail("one@two.com")
Expand Down Expand Up @@ -110,26 +165,59 @@ func TestAuthValidateEmail(t *testing.T) {
config.Domains = []string{"example.com"}
config.Whitelist = []string{"test@test.com"}
config.MatchWhitelistOrDomain = false

v = ValidateEmail("test@test.com")
assert.True(v, "should allow user in whitelist")
assert.True(v, "should allow user from whitelist config if MatchWhitelistOrDomain is disabled")

v = ValidateEmail("test@example.com")
assert.False(v, "should not allow user from valid domain")
assert.False(v, "should not allow user from domain config if a whitelist is specified and MatchWhitelistOrDomain is disabled")

// Should allow only matching email address when
// MatchWhitelistOrDomain is disabled
config.Rules = map[string]*Rule{
"allowed-from-whitelist-rule": {
Rule: "whitelist-rule",
Whitelist: []string{"allowed-from-whitelist-rule@example.com"},
},
"allowed-from-domain-rule": {
Rule: "domain-rule",
Domains: []string{"example.org"},
},
}
config.MatchWhitelistOrDomain = false

v = ValidateEmail("allowed-from-whitelist-rule@example.com")
assert.True(v, "should allow user from whitelist rule if MatchWhitelistOrDomain is disabled")

v = ValidateEmail("not-allowed-from-domain-rule@example.org")
assert.False(v, "should not allow user from domain rule if MatchWhitelistOrDomain is disabled")

v = ValidateEmail("one@two.com")
assert.False(v, "should not allow user not in either")
assert.False(v, "should not allow user not in whitelist or domain")

// Should allow either matching domain or email address when
// MatchWhitelistOrDomain is enabled
config.Domains = []string{"example.com"}
config.Whitelist = []string{"test@test.com"}
// Should allow matching email address or domain from a rule
// when MatchWhitelistOrDomain is enabled
config.Rules = map[string]*Rule{
"allowed-from-whitelist-rule": {
Rule: "whitelist-rule",
Whitelist: []string{"allowed-from-whitelist-rule@example.com"},
},
"allowed-from-domain-rule": {
Rule: "domain-rule",
Domains: []string{"example.org"},
},
}
config.MatchWhitelistOrDomain = true
v = ValidateEmail("test@test.com")
assert.True(v, "should allow user in whitelist")
v = ValidateEmail("test@example.com")
assert.True(v, "should allow user from valid domain")

v = ValidateEmail("allowed-from-whitelist-rule@example.com")
assert.True(v, "should allow user from whitelist rule if MatchWhitelistOrDomain is true")

v = ValidateEmail("not-allowed-from-domain-rule@example.org")
assert.True(v, "should allow user from domain rule if MatchWhitelistOrDomain is enabled")

v = ValidateEmail("one@two.com")
assert.False(v, "should not allow user not in either")
assert.False(v, "should not allow user not in whitelist or domain rule")
}

func TestRedirectUri(t *testing.T) {
assert := assert.New(t)

Expand Down
8 changes: 4 additions & 4 deletions internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,11 @@ func (c *Config) setupProvider(name string) error {

// Rule holds defined rules
type Rule struct {
Action string
Rule string
Provider string
Action string
Rule string
Provider string
Whitelist []string
Domains []string
Domains []string
}

// NewRule creates a new rule object
Expand Down

0 comments on commit 21b0939

Please sign in to comment.