2021-01-16 10:05:41 +00:00
package validator
import (
2021-03-05 04:18:31 +00:00
"fmt"
2022-04-01 11:38:49 +00:00
"regexp"
2021-01-16 10:05:41 +00:00
"testing"
2021-04-14 10:53:23 +00:00
"github.com/stretchr/testify/assert"
2021-01-16 10:05:41 +00:00
"github.com/stretchr/testify/suite"
2021-08-11 01:04:35 +00:00
"github.com/authelia/authelia/v4/internal/configuration/schema"
2021-01-16 10:05:41 +00:00
)
type AccessControl struct {
suite . Suite
2022-02-28 03:15:01 +00:00
config * schema . Configuration
validator * schema . StructValidator
2021-01-16 10:05:41 +00:00
}
func ( suite * AccessControl ) SetupTest ( ) {
suite . validator = schema . NewStructValidator ( )
2022-02-28 03:15:01 +00:00
suite . config = & schema . Configuration {
AccessControl : schema . AccessControlConfiguration {
DefaultPolicy : policyDeny ,
Networks : schema . DefaultACLNetwork ,
Rules : schema . DefaultACLRule ,
} ,
}
2021-01-16 10:05:41 +00:00
}
func ( suite * AccessControl ) TestShouldValidateCompleteConfiguration ( ) {
2022-02-28 03:15:01 +00:00
ValidateAccessControl ( suite . config , suite . validator )
2021-01-16 10:05:41 +00:00
suite . Assert ( ) . False ( suite . validator . HasWarnings ( ) )
suite . Assert ( ) . False ( suite . validator . HasErrors ( ) )
}
2022-04-01 11:38:49 +00:00
func ( suite * AccessControl ) TestShouldValidateEitherDomainsOrDomainsRegex ( ) {
domainsRegex := regexp . MustCompile ( ` ^abc.example.com$ ` )
suite . config . AccessControl . Rules = [ ] schema . ACLRule {
{
Domains : [ ] string { "abc.example.com" } ,
Policy : "bypass" ,
} ,
{
DomainsRegex : [ ] regexp . Regexp { * domainsRegex } ,
Policy : "bypass" ,
} ,
{
Policy : "bypass" ,
} ,
}
ValidateRules ( suite . config , suite . validator )
suite . Assert ( ) . False ( suite . validator . HasWarnings ( ) )
suite . Require ( ) . Len ( suite . validator . Errors ( ) , 1 )
assert . EqualError ( suite . T ( ) , suite . validator . Errors ( ) [ 0 ] , "access control: rule #3: rule is invalid: must have the option 'domain' or 'domain_regex' configured" )
}
2021-01-16 10:05:41 +00:00
func ( suite * AccessControl ) TestShouldRaiseErrorInvalidDefaultPolicy ( ) {
2022-02-28 03:15:01 +00:00
suite . config . AccessControl . DefaultPolicy = testInvalidPolicy
2021-01-16 10:05:41 +00:00
2022-02-28 03:15:01 +00:00
ValidateAccessControl ( suite . config , suite . validator )
2021-01-16 10:05:41 +00:00
suite . Assert ( ) . False ( suite . validator . HasWarnings ( ) )
suite . Require ( ) . Len ( suite . validator . Errors ( ) , 1 )
2022-02-28 03:15:01 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 0 ] , "access control: option 'default_policy' must be one of 'bypass', 'one_factor', 'two_factor', 'deny' but it is configured as 'invalid'" )
2021-01-16 10:05:41 +00:00
}
func ( suite * AccessControl ) TestShouldRaiseErrorInvalidNetworkGroupNetwork ( ) {
2022-02-28 03:15:01 +00:00
suite . config . AccessControl . Networks = [ ] schema . ACLNetwork {
2021-01-16 10:05:41 +00:00
{
2021-03-05 04:18:31 +00:00
Name : "internal" ,
2021-01-16 10:05:41 +00:00
Networks : [ ] string { "abc.def.ghi.jkl" } ,
} ,
}
2022-02-28 03:15:01 +00:00
ValidateAccessControl ( suite . config , suite . validator )
2021-01-16 10:05:41 +00:00
suite . Assert ( ) . False ( suite . validator . HasWarnings ( ) )
suite . Require ( ) . Len ( suite . validator . Errors ( ) , 1 )
2022-02-28 03:15:01 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 0 ] , "access control: networks: network group 'internal' is invalid: the network 'abc.def.ghi.jkl' is not a valid IP or CIDR notation" )
2021-01-16 10:05:41 +00:00
}
2021-04-14 10:53:23 +00:00
func ( suite * AccessControl ) TestShouldRaiseErrorWithNoRulesDefined ( ) {
2022-02-28 03:15:01 +00:00
suite . config . AccessControl . Rules = [ ] schema . ACLRule { }
2021-01-16 10:05:41 +00:00
2022-02-28 03:15:01 +00:00
ValidateRules ( suite . config , suite . validator )
2021-01-16 10:05:41 +00:00
suite . Assert ( ) . False ( suite . validator . HasWarnings ( ) )
2021-04-14 10:53:23 +00:00
suite . Require ( ) . Len ( suite . validator . Errors ( ) , 1 )
2022-02-28 03:15:01 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 0 ] , "access control: 'default_policy' option 'deny' is invalid: when no rules are specified it must be 'two_factor' or 'one_factor'" )
2021-04-14 10:53:23 +00:00
}
func ( suite * AccessControl ) TestShouldRaiseWarningWithNoRulesDefined ( ) {
2022-02-28 03:15:01 +00:00
suite . config . AccessControl . Rules = [ ] schema . ACLRule { }
2021-04-14 10:53:23 +00:00
2022-02-28 03:15:01 +00:00
suite . config . AccessControl . DefaultPolicy = policyTwoFactor
2021-04-14 10:53:23 +00:00
2022-02-28 03:15:01 +00:00
ValidateRules ( suite . config , suite . validator )
2021-04-14 10:53:23 +00:00
suite . Assert ( ) . False ( suite . validator . HasErrors ( ) )
suite . Require ( ) . Len ( suite . validator . Warnings ( ) , 1 )
2022-02-28 03:15:01 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Warnings ( ) [ 0 ] , "access control: no rules have been specified so the 'default_policy' of 'two_factor' is going to be applied to all requests" )
2021-04-14 10:53:23 +00:00
}
func ( suite * AccessControl ) TestShouldRaiseErrorsWithEmptyRules ( ) {
2022-02-28 03:15:01 +00:00
suite . config . AccessControl . Rules = [ ] schema . ACLRule {
{ } ,
{
Policy : "wrong" ,
} ,
}
2021-04-14 10:53:23 +00:00
2022-02-28 03:15:01 +00:00
ValidateRules ( suite . config , suite . validator )
2021-04-14 10:53:23 +00:00
suite . Assert ( ) . False ( suite . validator . HasWarnings ( ) )
suite . Require ( ) . Len ( suite . validator . Errors ( ) , 4 )
2021-01-16 10:05:41 +00:00
2022-04-01 11:38:49 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 0 ] , "access control: rule #1: rule is invalid: must have the option 'domain' or 'domain_regex' configured" )
2022-02-28 03:15:01 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 1 ] , "access control: rule #1: rule 'policy' option '' is invalid: must be one of 'deny', 'two_factor', 'one_factor' or 'bypass'" )
2022-04-01 11:38:49 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 2 ] , "access control: rule #2: rule is invalid: must have the option 'domain' or 'domain_regex' configured" )
2022-02-28 03:15:01 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 3 ] , "access control: rule #2: rule 'policy' option 'wrong' is invalid: must be one of 'deny', 'two_factor', 'one_factor' or 'bypass'" )
2021-01-16 10:05:41 +00:00
}
func ( suite * AccessControl ) TestShouldRaiseErrorInvalidPolicy ( ) {
2022-02-28 03:15:01 +00:00
suite . config . AccessControl . Rules = [ ] schema . ACLRule {
2021-01-16 10:05:41 +00:00
{
Domains : [ ] string { "public.example.com" } ,
2021-01-20 12:07:40 +00:00
Policy : testInvalidPolicy ,
2021-01-16 10:05:41 +00:00
} ,
}
2022-02-28 03:15:01 +00:00
ValidateRules ( suite . config , suite . validator )
2021-01-16 10:05:41 +00:00
suite . Assert ( ) . False ( suite . validator . HasWarnings ( ) )
suite . Require ( ) . Len ( suite . validator . Errors ( ) , 1 )
2022-02-28 03:15:01 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 0 ] , "access control: rule #1 (domain 'public.example.com'): rule 'policy' option 'invalid' is invalid: must be one of 'deny', 'two_factor', 'one_factor' or 'bypass'" )
2021-01-16 10:05:41 +00:00
}
func ( suite * AccessControl ) TestShouldRaiseErrorInvalidNetwork ( ) {
2022-02-28 03:15:01 +00:00
suite . config . AccessControl . Rules = [ ] schema . ACLRule {
2021-01-16 10:05:41 +00:00
{
Domains : [ ] string { "public.example.com" } ,
Policy : "bypass" ,
Networks : [ ] string { "abc.def.ghi.jkl/32" } ,
} ,
}
2022-02-28 03:15:01 +00:00
ValidateRules ( suite . config , suite . validator )
2021-01-16 10:05:41 +00:00
suite . Assert ( ) . False ( suite . validator . HasWarnings ( ) )
suite . Require ( ) . Len ( suite . validator . Errors ( ) , 1 )
2022-02-28 03:15:01 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 0 ] , "access control: rule #1 (domain 'public.example.com'): the network 'abc.def.ghi.jkl/32' is not a valid Group Name, IP, or CIDR notation" )
2021-01-16 10:05:41 +00:00
}
2021-03-05 04:18:31 +00:00
func ( suite * AccessControl ) TestShouldRaiseErrorInvalidMethod ( ) {
2022-02-28 03:15:01 +00:00
suite . config . AccessControl . Rules = [ ] schema . ACLRule {
2021-03-05 04:18:31 +00:00
{
Domains : [ ] string { "public.example.com" } ,
Policy : "bypass" ,
Methods : [ ] string { "GET" , "HOP" } ,
} ,
}
2022-02-28 03:15:01 +00:00
ValidateRules ( suite . config , suite . validator )
2021-03-05 04:18:31 +00:00
suite . Assert ( ) . False ( suite . validator . HasWarnings ( ) )
suite . Require ( ) . Len ( suite . validator . Errors ( ) , 1 )
2022-04-01 10:53:10 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 0 ] , "access control: rule #1 (domain 'public.example.com'): 'methods' option 'HOP' is invalid: must be one of 'GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'TRACE', 'CONNECT', 'OPTIONS', 'COPY', 'LOCK', 'MKCOL', 'MOVE', 'PROPFIND', 'PROPPATCH', 'UNLOCK'" )
2021-03-05 04:18:31 +00:00
}
2021-01-16 10:05:41 +00:00
func ( suite * AccessControl ) TestShouldRaiseErrorInvalidSubject ( ) {
2021-03-05 04:18:31 +00:00
domains := [ ] string { "public.example.com" }
subjects := [ ] [ ] string { { "invalid" } }
2022-02-28 03:15:01 +00:00
suite . config . AccessControl . Rules = [ ] schema . ACLRule {
2021-01-16 10:05:41 +00:00
{
2021-03-05 04:18:31 +00:00
Domains : domains ,
2021-01-16 10:05:41 +00:00
Policy : "bypass" ,
2021-03-05 04:18:31 +00:00
Subjects : subjects ,
2021-01-16 10:05:41 +00:00
} ,
}
2022-02-28 03:15:01 +00:00
ValidateRules ( suite . config , suite . validator )
2021-01-16 10:05:41 +00:00
2021-03-05 04:18:31 +00:00
suite . Require ( ) . Len ( suite . validator . Warnings ( ) , 0 )
suite . Require ( ) . Len ( suite . validator . Errors ( ) , 2 )
2021-01-16 10:05:41 +00:00
2022-02-28 03:15:01 +00:00
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 0 ] , "access control: rule #1 (domain 'public.example.com'): 'subject' option 'invalid' is invalid: must start with 'user:' or 'group:'" )
suite . Assert ( ) . EqualError ( suite . validator . Errors ( ) [ 1 ] , fmt . Sprintf ( errAccessControlRuleBypassPolicyInvalidWithSubjects , ruleDescriptor ( 1 , suite . config . AccessControl . Rules [ 0 ] ) ) )
2021-01-16 10:05:41 +00:00
}
func TestAccessControl ( t * testing . T ) {
suite . Run ( t , new ( AccessControl ) )
}
2021-04-14 10:53:23 +00:00
func TestShouldReturnCorrectResultsForValidNetworkGroups ( t * testing . T ) {
config := schema . AccessControlConfiguration {
Networks : schema . DefaultACLNetwork ,
}
validNetwork := IsNetworkGroupValid ( config , "internal" )
2021-07-15 11:02:03 +00:00
invalidNetwork := IsNetworkGroupValid ( config , loopback )
2021-04-14 10:53:23 +00:00
assert . True ( t , validNetwork )
assert . False ( t , invalidNetwork )
}