Add validation for notifier configuration.

This commit is contained in:
Clement Michaud 2020-01-21 21:15:40 +01:00 committed by Amir Zarrinkafsh
parent 9b5b091a44
commit ea86b62527
5 changed files with 190 additions and 13 deletions

View File

@ -5,14 +5,6 @@ type FileSystemNotifierConfiguration struct {
Filename string `yaml:"filename"` Filename string `yaml:"filename"`
} }
// EmailNotifierConfiguration represents the configuration of the email service notifier (like GMAIL API).
type EmailNotifierConfiguration struct {
Username string `yaml:"username"`
Password string `yaml:"password"`
Sender string `yaml:"sender"`
Service string `yaml:"service"`
}
// SMTPNotifierConfiguration represents the configuration of the SMTP server to send emails with. // SMTPNotifierConfiguration represents the configuration of the SMTP server to send emails with.
type SMTPNotifierConfiguration struct { type SMTPNotifierConfiguration struct {
Username string `yaml:"username"` Username string `yaml:"username"`
@ -28,6 +20,5 @@ type SMTPNotifierConfiguration struct {
// NotifierConfiguration represents the configuration of the notifier to use when sending notifications to users. // NotifierConfiguration represents the configuration of the notifier to use when sending notifications to users.
type NotifierConfiguration struct { type NotifierConfiguration struct {
FileSystem *FileSystemNotifierConfiguration `yaml:"filesystem"` FileSystem *FileSystemNotifierConfiguration `yaml:"filesystem"`
Email *EmailNotifierConfiguration `yaml:"email"`
SMTP *SMTPNotifierConfiguration `yaml:"smtp"` SMTP *SMTPNotifierConfiguration `yaml:"smtp"`
} }

View File

@ -35,5 +35,11 @@ func Validate(configuration *schema.Configuration, validator *schema.StructValid
ValidateTOTP(configuration.TOTP, validator) ValidateTOTP(configuration.TOTP, validator)
} }
if configuration.Notifier == nil {
validator.Push(fmt.Errorf("A notifier configuration must be provided"))
} else {
ValidateNotifier(configuration.Notifier, validator)
}
ValidateSQLStorage(configuration.Storage, validator) ValidateSQLStorage(configuration.Storage, validator)
} }

View File

@ -5,6 +5,7 @@ import (
"github.com/authelia/authelia/internal/configuration/schema" "github.com/authelia/authelia/internal/configuration/schema"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func newDefaultConfig() schema.Configuration { func newDefaultConfig() schema.Configuration {
@ -25,6 +26,11 @@ func newDefaultConfig() schema.Configuration {
Path: "abc", Path: "abc",
}, },
} }
config.Notifier = &schema.NotifierConfiguration{
FileSystem: &schema.FileSystemNotifierConfiguration{
Filename: "/tmp/file",
},
}
return config return config
} }
@ -34,7 +40,7 @@ func TestShouldNotUpdateConfig(t *testing.T) {
Validate(&config, validator) Validate(&config, validator)
assert.Len(t, validator.Errors(), 0) require.Len(t, validator.Errors(), 0)
assert.Equal(t, 9090, config.Port) assert.Equal(t, 9090, config.Port)
assert.Equal(t, "info", config.LogsLevel) assert.Equal(t, "info", config.LogsLevel)
} }
@ -46,7 +52,7 @@ func TestShouldValidateAndUpdatePort(t *testing.T) {
Validate(&config, validator) Validate(&config, validator)
assert.Len(t, validator.Errors(), 0) require.Len(t, validator.Errors(), 0)
assert.Equal(t, 8080, config.Port) assert.Equal(t, 8080, config.Port)
} }
@ -57,7 +63,7 @@ func TestShouldValidateAndUpdateHost(t *testing.T) {
Validate(&config, validator) Validate(&config, validator)
assert.Len(t, validator.Errors(), 0) require.Len(t, validator.Errors(), 0)
assert.Equal(t, "0.0.0.0", config.Host) assert.Equal(t, "0.0.0.0", config.Host)
} }
@ -68,6 +74,20 @@ func TestShouldValidateAndUpdateLogsLevel(t *testing.T) {
Validate(&config, validator) Validate(&config, validator)
assert.Len(t, validator.Errors(), 0) require.Len(t, validator.Errors(), 0)
assert.Equal(t, "info", config.LogsLevel) assert.Equal(t, "info", config.LogsLevel)
} }
func TestShouldEnsureNotifierConfigIsProvided(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
Validate(&config, validator)
require.Len(t, validator.Errors(), 0)
config.Notifier = nil
Validate(&config, validator)
require.Len(t, validator.Errors(), 1)
assert.EqualError(t, validator.Errors()[0], "A notifier configuration must be provided")
}

View File

@ -0,0 +1,40 @@
package validator
import "github.com/authelia/authelia/internal/configuration/schema"
import "fmt"
// ValidateSession validates and update session configuration.
func ValidateNotifier(configuration *schema.NotifierConfiguration, validator *schema.StructValidator) {
if configuration.SMTP == nil && configuration.FileSystem == nil {
validator.Push(fmt.Errorf("Notifier should be either `smtp` or `filesystem`"))
return
}
if configuration.SMTP != nil && configuration.FileSystem != nil {
validator.Push(fmt.Errorf("Notifier should be either `smtp` or `filesystem`"))
return
}
if configuration.FileSystem != nil {
if configuration.FileSystem.Filename == "" {
validator.Push(fmt.Errorf("Filename of filesystem notifier must not be empty"))
}
return
}
if configuration.SMTP != nil {
if configuration.SMTP.Host == "" {
validator.Push(fmt.Errorf("Host of SMTP notifier must be provided"))
}
if configuration.SMTP.Port == 0 {
validator.Push(fmt.Errorf("Port of SMTP notifier must be provided"))
}
if configuration.SMTP.Sender == "" {
validator.Push(fmt.Errorf("Sender of SMTP notifier must be provided"))
}
return
}
}

View File

@ -0,0 +1,120 @@
package validator
import (
"testing"
"github.com/authelia/authelia/internal/configuration/schema"
"github.com/stretchr/testify/suite"
)
type NotifierSuite struct {
suite.Suite
configuration schema.NotifierConfiguration
}
func (s *NotifierSuite) SetupTest() {
s.configuration.SMTP = &schema.SMTPNotifierConfiguration{
Username: "john",
Password: "password",
Sender: "admin@example.com",
Host: "example.com",
Port: 25,
}
}
func (s *NotifierSuite) TestShouldEnsureAtLeastSMTPOrFilesystemIsProvided() {
validator := schema.NewStructValidator()
ValidateNotifier(&s.configuration, validator)
errors := validator.Errors()
s.Require().Len(errors, 0)
s.configuration.SMTP = nil
ValidateNotifier(&s.configuration, validator)
errors = validator.Errors()
s.Require().Len(errors, 1)
s.Assert().EqualError(errors[0], "Notifier should be either `smtp` or `filesystem`")
}
func (s *NotifierSuite) TestShouldEnsureEitherSMTPOrFilesystemIsProvided() {
validator := schema.NewStructValidator()
ValidateNotifier(&s.configuration, validator)
errors := validator.Errors()
s.Require().Len(errors, 0)
s.configuration.FileSystem = &schema.FileSystemNotifierConfiguration{
Filename: "test",
}
ValidateNotifier(&s.configuration, validator)
errors = validator.Errors()
s.Require().Len(errors, 1)
s.Assert().EqualError(errors[0], "Notifier should be either `smtp` or `filesystem`")
}
func (s *NotifierSuite) TestShouldEnsureFilenameOfFilesystemNotifierIsProvided() {
validator := schema.NewStructValidator()
s.configuration.SMTP = nil
s.configuration.FileSystem = &schema.FileSystemNotifierConfiguration{
Filename: "test",
}
ValidateNotifier(&s.configuration, validator)
errors := validator.Errors()
s.Require().Len(errors, 0)
s.configuration.FileSystem.Filename = ""
ValidateNotifier(&s.configuration, validator)
errors = validator.Errors()
s.Require().Len(errors, 1)
s.Assert().EqualError(errors[0], "Filename of filesystem notifier must not be empty")
}
func (s *NotifierSuite) TestShouldEnsureHostAndPortOfSMTPNotifierAreProvided() {
s.configuration.FileSystem = nil
validator := schema.NewStructValidator()
ValidateNotifier(&s.configuration, validator)
errors := validator.Errors()
s.Require().Len(errors, 0)
s.configuration.SMTP.Host = ""
s.configuration.SMTP.Port = 0
ValidateNotifier(&s.configuration, validator)
errors = validator.Errors()
s.Require().Len(errors, 2)
s.Assert().EqualError(errors[0], "Host of SMTP notifier must be provided")
s.Assert().EqualError(errors[1], "Port of SMTP notifier must be provided")
}
func (s *NotifierSuite) TestShouldEnsureSenderOfSMTPNotifierAreProvided() {
s.configuration.FileSystem = nil
validator := schema.NewStructValidator()
ValidateNotifier(&s.configuration, validator)
errors := validator.Errors()
s.Require().Len(errors, 0)
s.configuration.SMTP.Sender = ""
ValidateNotifier(&s.configuration, validator)
errors = validator.Errors()
s.Require().Len(errors, 1)
s.Assert().EqualError(errors[0], "Sender of SMTP notifier must be provided")
}
func TestNotifierSuite(t *testing.T) {
suite.Run(t, new(NotifierSuite))
}