Skip to content

Commit 13c697f

Browse files
committed
Allow to override domains and whitelist in rules
1 parent 3e6ccc8 commit 13c697f

File tree

5 files changed

+92
-27
lines changed

5 files changed

+92
-27
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ All options can be supplied in any of the following ways, in the following prece
262262
- ``Path(`path`, `/articles/{category}/{id:[0-9]+}`, ...)``
263263
- ``PathPrefix(`/products/`, `/articles/{category}/{id:[0-9]+}`)``
264264
- ``Query(`foo=bar`, `bar=baz`)``
265+
- `whitelist` - optional, same usage as [`whitelist`](#whitelist).
266+
- `domains` - optional, same usage as [`domain`](#domain).
265267

266268
For example:
267269
```
@@ -283,7 +285,7 @@ You can restrict who can login with the following parameters:
283285
* `domain` - Use this to limit logins to a specific domain, e.g. test.com only
284286
* `whitelist` - Use this to only allow specific users to login e.g. [email protected] only
285287

286-
Note, if you pass `whitelist` then only this is checked and `domain` is effectively ignored.
288+
Note, if you pass `whitelist` then only this is checked and `domain` is effectively ignored. If you set `domains` or `whitelist` on a rules, the global configuration is ignored.
287289

288290
### Forwarded Headers
289291

internal/auth.go

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,31 +56,51 @@ func ValidateCookie(r *http.Request, c *http.Cookie) (string, error) {
5656
}
5757

5858
// Validate email
59-
func ValidateEmail(email string) bool {
59+
func ValidateEmail(email string, rule string) bool {
6060
found := false
61-
if len(config.Whitelist) > 0 {
62-
for _, whitelist := range config.Whitelist {
63-
if email == whitelist {
64-
found = true
65-
}
66-
}
61+
62+
_, ruleExists := config.Rules[rule]
63+
if ruleExists && len(config.Rules[rule].Whitelist) > 0 {
64+
found = ValidateWhitelist(email, config.Rules[rule].Whitelist)
65+
} else if ruleExists && len(config.Rules[rule].Domains) > 0 {
66+
found = ValidateDomains(email, config.Rules[rule].Domains)
67+
} else if len(config.Whitelist) > 0 {
68+
found = ValidateWhitelist(email, config.Whitelist)
6769
} else if len(config.Domains) > 0 {
68-
parts := strings.Split(email, "@")
69-
if len(parts) < 2 {
70-
return false
71-
}
72-
for _, domain := range config.Domains {
73-
if domain == parts[1] {
74-
found = true
75-
}
76-
}
70+
found = ValidateDomains(email, config.Domains)
7771
} else {
7872
return true
7973
}
8074

8175
return found
8276
}
8377

78+
// Validate email is in whitelist
79+
func ValidateWhitelist(email string, whitelist CommaSeparatedList) bool {
80+
found := false
81+
for _, whitelist := range whitelist {
82+
if email == whitelist {
83+
found = true
84+
}
85+
}
86+
return found
87+
}
88+
89+
// Validate email match a domains
90+
func ValidateDomains(email string, domains CommaSeparatedList) bool {
91+
found := false
92+
parts := strings.Split(email, "@")
93+
if len(parts) < 2 {
94+
return false
95+
}
96+
for _, domain := range domains {
97+
if domain == parts[1] {
98+
found = true
99+
}
100+
}
101+
return found
102+
}
103+
84104
// OAuth Methods
85105

86106
// Get login url

internal/auth_test.go

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,32 +67,65 @@ func TestAuthValidateEmail(t *testing.T) {
6767
config, _ = NewConfig([]string{})
6868

6969
// Should allow any
70-
v := ValidateEmail("[email protected]")
70+
v := ValidateEmail("[email protected]", "default")
7171
assert.True(v, "should allow any domain if email domain is not defined")
72-
v = ValidateEmail("[email protected]")
72+
v = ValidateEmail("[email protected]", "default")
7373
assert.True(v, "should allow any domain if email domain is not defined")
7474

7575
// Should block non matching domain
7676
config.Domains = []string{"test.com"}
77-
v = ValidateEmail("[email protected]")
77+
v = ValidateEmail("[email protected]", "default")
7878
assert.False(v, "should not allow user from another domain")
7979

8080
// Should allow matching domain
8181
config.Domains = []string{"test.com"}
82-
v = ValidateEmail("[email protected]")
82+
v = ValidateEmail("[email protected]", "default")
8383
assert.True(v, "should allow user from allowed domain")
8484

8585
// Should block non whitelisted email address
8686
config.Domains = []string{}
8787
config.Whitelist = []string{"[email protected]"}
88-
v = ValidateEmail("[email protected]")
88+
v = ValidateEmail("[email protected]", "default")
8989
assert.False(v, "should not allow user not in whitelist")
9090

9191
// Should allow matching whitelisted email address
9292
config.Domains = []string{}
9393
config.Whitelist = []string{"[email protected]"}
94-
v = ValidateEmail("[email protected]")
94+
v = ValidateEmail("[email protected]", "default")
9595
assert.True(v, "should allow user in whitelist")
96+
97+
// Should allow matching whitelisted in rules email address
98+
config.Domains = []string{"globaltestdomain.com"}
99+
config.Whitelist = []string{}
100+
config.Rules = map[string]*Rule{"test": NewRule()}
101+
config.Rules["test"].Whitelist = []string{"[email protected]"}
102+
// Validation for user in the rule whitelist
103+
v = ValidateEmail("[email protected]", "test")
104+
assert.True(v, "should allow user in rule whitelist")
105+
// Validation for user not in the rule whitelist
106+
v = ValidateEmail("[email protected]", "test")
107+
assert.False(v, "should not allow user not in rule whitelist")
108+
// Validation for user in global domain but not in rule
109+
v = ValidateEmail("[email protected]", "test")
110+
assert.False(v, "should not allow user in global but not in rule")
111+
// Validation for user in the whitelist, but that not this rule
112+
v = ValidateEmail("[email protected]", "default")
113+
assert.False(v, "should not allow user not in the rule whitelisted")
114+
115+
// Should allow matching domains
116+
config.Domains = []string{"globaltestdomain.com"}
117+
config.Whitelist = []string{}
118+
config.Rules = map[string]*Rule{"test": NewRule()}
119+
config.Rules["test"].Domains = []string{"test.com"}
120+
// Validation for user in the rule domains
121+
v = ValidateEmail("[email protected]", "test")
122+
assert.True(v, "should allow user in rule domains")
123+
// Validation for user not in the rule whitelist
124+
v = ValidateEmail("[email protected]", "test")
125+
assert.False(v, "should not allow user not in rule domains")
126+
// Validation for user in the whitelist, but that not this rule
127+
v = ValidateEmail("[email protected]", "default")
128+
assert.False(v, "should not allow user not in the rule")
96129
}
97130

98131
// TODO: Split google tests out

internal/config.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,14 @@ func (c *Config) parseUnknownFlag(option string, arg flags.SplitArgument, args [
213213
rule.Rule = val
214214
case "provider":
215215
rule.Provider = val
216+
case "whitelist":
217+
list := CommaSeparatedList{}
218+
list.UnmarshalFlag(val)
219+
rule.Whitelist = list
220+
case "domains":
221+
list := CommaSeparatedList{}
222+
list.UnmarshalFlag(val)
223+
rule.Domains = list
216224
default:
217225
return args, fmt.Errorf("inavlid route param: %v", option)
218226
}
@@ -266,9 +274,11 @@ func (c Config) String() string {
266274
}
267275

268276
type Rule struct {
269-
Action string
270-
Rule string
271-
Provider string
277+
Action string
278+
Rule string
279+
Provider string
280+
Whitelist CommaSeparatedList
281+
Domains CommaSeparatedList
272282
}
273283

274284
func NewRule() *Rule {

internal/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (s *Server) AuthHandler(rule string) http.HandlerFunc {
9090
}
9191

9292
// Validate user
93-
valid := ValidateEmail(email)
93+
valid := ValidateEmail(email, rule)
9494
if !valid {
9595
logger.WithFields(logrus.Fields{
9696
"email": email,

0 commit comments

Comments
 (0)