authelia/cmd/authelia/main.go
James Elliott 29a900226d
[FEATURE] Enhance LDAP/SMTP TLS Configuration and Unify Them (#1557)
* add new directive in the global scope `certificates_directory` which is used to bulk load certs and trust them in Authelia
* this is in ADDITION to system certs and are trusted by both LDAP and SMTP
* added a shared TLSConfig struct to be used by both SMTP and LDAP, and anything else in the future that requires tuning the TLS
* remove usage of deprecated LDAP funcs Dial and DialTLS in favor of DialURL which is also easier to use
* use the server name from LDAP URL or SMTP host when validating the certificate unless otherwise defined in the TLS section
* added temporary translations from the old names to the new ones for all deprecated options
* added docs
* updated example configuration
* final deprecations to be done in 4.28.0
* doc updates
* fix misc linting issues
* uniform deprecation notices for ease of final removal
* added additional tests covering previously uncovered areas and the new configuration options
* add non-fatal to certificate loading when system certs could not be loaded
* adjust timeout of Suite ShortTimeouts
* add warnings pusher for the StructValidator
* make the schema suites uninform
* utilize the warnings in the StructValidator
* fix test suite usage for skip_verify
* extract LDAP filter parsing into it's own function to make it possible to test
* test LDAP filter parsing
* update ErrorContainer interface
* add tests to the StructValidator
* add NewTLSConfig test
* move baseDN for users/groups into parsed values
* add tests to cover many of the outstanding areas in LDAP
* add explicit deferred LDAP conn close to UpdatePassword
* add some basic testing to SMTP notifier
* suggestions from code review
2021-01-04 21:28:55 +11:00

156 lines
4.4 KiB
Go

package main
import (
"fmt"
"os"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/authelia/authelia/internal/authentication"
"github.com/authelia/authelia/internal/authorization"
"github.com/authelia/authelia/internal/commands"
"github.com/authelia/authelia/internal/configuration"
"github.com/authelia/authelia/internal/logging"
"github.com/authelia/authelia/internal/middlewares"
"github.com/authelia/authelia/internal/notification"
"github.com/authelia/authelia/internal/regulation"
"github.com/authelia/authelia/internal/server"
"github.com/authelia/authelia/internal/session"
"github.com/authelia/authelia/internal/storage"
"github.com/authelia/authelia/internal/utils"
)
var configPathFlag string
//nolint:gocyclo // TODO: Consider refactoring/simplifying, time permitting.
func startServer() {
config, errs := configuration.Read(configPathFlag)
if len(errs) > 0 {
for _, err := range errs {
logging.Logger().Error(err)
}
os.Exit(1)
}
autheliaCertPool, errs, nonFatalErrs := utils.NewX509CertPool(config.CertificatesDirectory, config)
if len(errs) > 0 {
for _, err := range errs {
logging.Logger().Error(err)
}
os.Exit(2)
}
if len(nonFatalErrs) > 0 {
for _, err := range nonFatalErrs {
logging.Logger().Warn(err)
}
}
if err := logging.InitializeLogger(config.LogFormat, config.LogFilePath); err != nil {
logging.Logger().Fatalf("Cannot initialize logger: %v", err)
}
switch config.LogLevel {
case "info":
logging.Logger().Info("Logging severity set to info")
logging.SetLevel(logrus.InfoLevel)
case "debug":
logging.Logger().Info("Logging severity set to debug")
logging.SetLevel(logrus.DebugLevel)
case "trace":
logging.Logger().Info("Logging severity set to trace")
logging.SetLevel(logrus.TraceLevel)
}
if os.Getenv("ENVIRONMENT") == "dev" {
logging.Logger().Info("===> Authelia is running in development mode. <===")
}
var storageProvider storage.Provider
switch {
case config.Storage.PostgreSQL != nil:
storageProvider = storage.NewPostgreSQLProvider(*config.Storage.PostgreSQL)
case config.Storage.MySQL != nil:
storageProvider = storage.NewMySQLProvider(*config.Storage.MySQL)
case config.Storage.Local != nil:
storageProvider = storage.NewSQLiteProvider(config.Storage.Local.Path)
default:
logging.Logger().Fatalf("Unrecognized storage backend")
}
var userProvider authentication.UserProvider
switch {
case config.AuthenticationBackend.File != nil:
userProvider = authentication.NewFileUserProvider(config.AuthenticationBackend.File)
case config.AuthenticationBackend.Ldap != nil:
userProvider = authentication.NewLDAPUserProvider(*config.AuthenticationBackend.Ldap, autheliaCertPool)
default:
logging.Logger().Fatalf("Unrecognized authentication backend")
}
var notifier notification.Notifier
switch {
case config.Notifier.SMTP != nil:
notifier = notification.NewSMTPNotifier(*config.Notifier.SMTP, autheliaCertPool)
case config.Notifier.FileSystem != nil:
notifier = notification.NewFileNotifier(*config.Notifier.FileSystem)
default:
logging.Logger().Fatalf("Unrecognized notifier")
}
if !config.Notifier.DisableStartupCheck {
_, err := notifier.StartupCheck()
if err != nil {
logging.Logger().Fatalf("Error during notifier startup check: %s", err)
}
}
clock := utils.RealClock{}
authorizer := authorization.NewAuthorizer(config.AccessControl)
sessionProvider := session.NewProvider(config.Session)
regulator := regulation.NewRegulator(config.Regulation, storageProvider, clock)
providers := middlewares.Providers{
Authorizer: authorizer,
UserProvider: userProvider,
Regulator: regulator,
StorageProvider: storageProvider,
Notifier: notifier,
SessionProvider: sessionProvider,
}
server.StartServer(*config, providers)
}
func main() {
rootCmd := &cobra.Command{
Use: "authelia",
Run: func(cmd *cobra.Command, args []string) {
startServer()
},
}
rootCmd.Flags().StringVar(&configPathFlag, "config", "", "Configuration file")
versionCmd := &cobra.Command{
Use: "version",
Short: "Show the version of Authelia",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Authelia version %s, build %s\n", BuildTag, BuildCommit)
},
}
rootCmd.AddCommand(versionCmd, commands.HashPasswordCmd,
commands.ValidateConfigCmd, commands.CertificatesCmd)
if err := rootCmd.Execute(); err != nil {
logging.Logger().Fatal(err)
}
}