diff options
Diffstat (limited to 'experimental')
| -rw-r--r-- | experimental/embed/config.go | 71 | ||||
| -rw-r--r-- | experimental/embed/config_test.go | 195 | ||||
| -rw-r--r-- | experimental/embed/context.go | 44 | ||||
| -rw-r--r-- | experimental/embed/context_test.go | 43 | ||||
| -rw-r--r-- | experimental/embed/doc.go | 13 | ||||
| -rw-r--r-- | experimental/embed/embed.go | 7 | ||||
| -rw-r--r-- | experimental/embed/embed_test.go | 19 | ||||
| -rw-r--r-- | experimental/embed/provider/authentication.go | 22 | ||||
| -rw-r--r-- | experimental/embed/provider/general.go | 113 | ||||
| -rw-r--r-- | experimental/embed/provider/notification.go | 24 | ||||
| -rw-r--r-- | experimental/embed/provider/storage.go | 29 | ||||
| -rw-r--r-- | experimental/embed/types.go | 24 | ||||
| -rw-r--r-- | experimental/embed/types_test.go | 15 |
13 files changed, 619 insertions, 0 deletions
diff --git a/experimental/embed/config.go b/experimental/embed/config.go new file mode 100644 index 000000000..81d21463b --- /dev/null +++ b/experimental/embed/config.go @@ -0,0 +1,71 @@ +package embed + +import ( + "fmt" + + "github.com/authelia/authelia/v4/internal/configuration" + "github.com/authelia/authelia/v4/internal/configuration/schema" + "github.com/authelia/authelia/v4/internal/configuration/validator" +) + +// NewConfiguration builds a new configuration given a list of paths and filters. The filters can either be nil or +// generated using NewNamedConfigFileFilters. This function essentially operates the same as Authelia does normally in +// configuration steps. +func NewConfiguration(paths []string, filters []configuration.BytesFilter) (keys []string, config *schema.Configuration, val *schema.StructValidator, err error) { + sources := configuration.NewDefaultSourcesWithDefaults( + paths, + filters, + configuration.DefaultEnvPrefix, + configuration.DefaultEnvDelimiter, + []configuration.Source{configuration.NewMapSource(configuration.Defaults())}) + + val = schema.NewStructValidator() + + var definitions *schema.Definitions + + if definitions, err = configuration.LoadDefinitions(val, sources...); err != nil { + return nil, nil, nil, err + } + + config = &schema.Configuration{} + + if keys, err = configuration.LoadAdvanced( + val, + "", + config, + definitions, + sources...); err != nil { + return nil, nil, nil, err + } + + return keys, config, val, nil +} + +// ValidateConfigurationAndKeys performs all configuration validation steps. The provided *schema.StructValidator should +// at minimum be checked for errors before continuing. +func ValidateConfigurationAndKeys(config *schema.Configuration, keys []string, val *schema.StructValidator) { + ValidateConfigurationKeys(keys, val) + ValidateConfiguration(config, val) +} + +// ValidateConfigurationKeys just the keys validation steps. The provided *schema.StructValidator should +// at minimum be checked for errors before continuing. This should be used prior to using ValidateConfiguration. +func ValidateConfigurationKeys(keys []string, val *schema.StructValidator) { + validator.ValidateKeys(keys, configuration.GetMultiKeyMappedDeprecationKeys(), configuration.DefaultEnvPrefix, val) +} + +// ValidateConfiguration just the configuration validation steps. The provided *schema.StructValidator should +// at minimum be checked for errors before continuing. This should be used after using ValidateConfigurationKeys. +func ValidateConfiguration(config *schema.Configuration, val *schema.StructValidator) { + validator.ValidateConfiguration(config, val) +} + +// NewNamedConfigFileFilters allows configuring a set of file filters. The officially supported filter has the name +// 'template'. The only other one at this stage is 'expand-env' which is deprecated. +func NewNamedConfigFileFilters(names ...string) (filters []configuration.BytesFilter, err error) { + if filters, err = configuration.NewFileFilters(names); err != nil { + return nil, fmt.Errorf("error occurred loading filters: %w", err) + } + + return filters, nil +} diff --git a/experimental/embed/config_test.go b/experimental/embed/config_test.go new file mode 100644 index 000000000..eb0ce6e2f --- /dev/null +++ b/experimental/embed/config_test.go @@ -0,0 +1,195 @@ +package embed + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/authelia/authelia/v4/internal/configuration" +) + +func TestNewConfiguration(t *testing.T) { + testCases := []struct { + name string + paths []string + filters []configuration.BytesFilter + keys []string + warnings []string + errors []string + err string + }{ + { + name: "ShouldHandleWebAuthn", + paths: []string{"../../internal/configuration/test_resources/config.webauthn.yml"}, + keys: []string{ + "server.endpoints.rate_limits.reset_password_finish.enable", + "server.endpoints.rate_limits.reset_password_start.enable", + "server.endpoints.rate_limits.second_factor_duo.enable", + "server.endpoints.rate_limits.second_factor_totp.enable", + "server.endpoints.rate_limits.session_elevation_finish.enable", + "server.endpoints.rate_limits.session_elevation_start.enable", + "webauthn.selection_criteria.attachment", + "webauthn.selection_criteria.discoverability", + "webauthn.selection_criteria.user_verification", + }, + warnings: nil, + errors: []string{ + "identity_validation: reset_password: option 'jwt_secret' is required when the reset password functionality isn't disabled", + "authentication_backend: you must ensure either the 'file' or 'ldap' authentication backend is configured", + "access_control: 'default_policy' option 'deny' is invalid: when no rules are specified it must be 'two_factor' or 'one_factor'", + "session: option 'cookies' is required", + "storage: option 'encryption_key' is required", + "storage: configuration for a 'local', 'mysql' or 'postgres' database must be provided", + "notifier: you must ensure either the 'smtp' or 'filesystem' notifier is configured", + }, + }, + { + name: "ShouldHandleConfigWithDefinitions", + paths: []string{"../../internal/configuration/test_resources/config_with_definitions.yml"}, + keys: []string{ + "access_control.default_policy", + "access_control.networks", + "access_control.networks[].name", + "access_control.networks[].networks", + "access_control.rules", + "access_control.rules[].domain", + "access_control.rules[].networks", + "access_control.rules[].policy", + "access_control.rules[].resources", + "access_control.rules[].subject", + "authentication_backend.ldap.additional_groups_dn", + "authentication_backend.ldap.additional_users_dn", + "authentication_backend.ldap.address", + "authentication_backend.ldap.attributes.group_name", + "authentication_backend.ldap.attributes.mail", + "authentication_backend.ldap.attributes.username", + "authentication_backend.ldap.base_dn", + "authentication_backend.ldap.groups_filter", + "authentication_backend.ldap.tls.private_key", + "authentication_backend.ldap.user", + "authentication_backend.ldap.users_filter", + "authentication_backend.refresh_interval", + "definitions.network.lan", + "definitions.user_attributes.example.expression", + "duo_api.hostname", + "duo_api.integration_key", + "log.level", + "notifier.smtp.address", + "notifier.smtp.disable_require_tls", + "notifier.smtp.sender", + "notifier.smtp.username", + "regulation.ban_time", + "regulation.find_time", + "regulation.max_retries", + "server.address", + "server.endpoints.authz.auth-request.authn_strategies", + "server.endpoints.authz.auth-request.authn_strategies[].name", + "server.endpoints.authz.auth-request.implementation", + "server.endpoints.authz.ext-authz.authn_strategies", + "server.endpoints.authz.ext-authz.authn_strategies[].name", + "server.endpoints.authz.ext-authz.implementation", + "server.endpoints.authz.forward-auth.authn_strategies", + "server.endpoints.authz.forward-auth.authn_strategies[].name", + "server.endpoints.authz.forward-auth.implementation", + "server.endpoints.authz.legacy.implementation", + "server.endpoints.rate_limits.reset_password_finish.enable", + "server.endpoints.rate_limits.reset_password_start.enable", + "server.endpoints.rate_limits.second_factor_duo.enable", + "server.endpoints.rate_limits.second_factor_totp.enable", + "server.endpoints.rate_limits.session_elevation_finish.enable", + "server.endpoints.rate_limits.session_elevation_start.enable", + "session.cookies", + "session.cookies[].authelia_url", + "session.cookies[].default_redirection_url", + "session.cookies[].domain", + "session.expiration", + "session.inactivity", + "session.name", + "session.redis.high_availability.sentinel_name", + "session.redis.host", + "session.redis.port", + "storage.mysql.address", + "storage.mysql.database", + "storage.mysql.username", + "totp.issuer", + "webauthn.selection_criteria.discoverability", + "webauthn.selection_criteria.user_verification", + }, + warnings: nil, + errors: []string{ + "duo_api: option 'secret_key' is required when duo is enabled but it's absent", + "identity_validation: reset_password: option 'jwt_secret' is required when the reset password functionality isn't disabled", + "authentication_backend: ldap: option 'password' is required", + "session: option 'secret' is required when using the 'redis' provider", + "storage: option 'encryption_key' is required", + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Run("Individual", func(t *testing.T) { + keys, config, val, err := NewConfiguration(tc.paths, tc.filters) + + assert.Equal(t, tc.keys, keys) + + if tc.err != "" { + assert.EqualError(t, err, tc.err) + assert.Nil(t, config) + } else { + assert.NoError(t, err) + assert.NotNil(t, config) + ValidateConfigurationKeys(keys, val) + ValidateConfiguration(config, val) + } + + require.Len(t, val.Warnings(), len(tc.warnings)) + require.Len(t, val.Errors(), len(tc.errors)) + + for i, err := range val.Warnings() { + assert.EqualError(t, err, tc.warnings[i]) + } + + for i, err := range val.Errors() { + assert.EqualError(t, err, tc.errors[i]) + } + }) + t.Run("Combined", func(t *testing.T) { + keys, config, val, err := NewConfiguration(tc.paths, tc.filters) + + assert.Equal(t, tc.keys, keys) + + if tc.err != "" { + assert.EqualError(t, err, tc.err) + assert.Nil(t, config) + } else { + assert.NoError(t, err) + assert.NotNil(t, config) + ValidateConfigurationAndKeys(config, keys, val) + } + + require.Len(t, val.Warnings(), len(tc.warnings)) + require.Len(t, val.Errors(), len(tc.errors)) + + for i, err := range val.Warnings() { + assert.EqualError(t, err, tc.warnings[i]) + } + + for i, err := range val.Errors() { + assert.EqualError(t, err, tc.errors[i]) + } + }) + }) + } +} + +func TestNewNamedConfigFileFilters(t *testing.T) { + filters, err := NewNamedConfigFileFilters("abc") + assert.Nil(t, filters) + assert.EqualError(t, err, "error occurred loading filters: invalid filter named 'abc'") + + filters, err = NewNamedConfigFileFilters("template") + assert.NotNil(t, filters) + assert.NoError(t, err) +} diff --git a/experimental/embed/context.go b/experimental/embed/context.go new file mode 100644 index 000000000..84cf483aa --- /dev/null +++ b/experimental/embed/context.go @@ -0,0 +1,44 @@ +package embed + +import ( + "context" + + "github.com/sirupsen/logrus" + + "github.com/authelia/authelia/v4/internal/configuration/schema" + "github.com/authelia/authelia/v4/internal/middlewares" +) + +// Context is an interface used in various areas of Authelia to simplify access to important elements like the +// configuration, providers, and logger. +type Context interface { + GetLogger() *logrus.Entry + GetProviders() middlewares.Providers + GetConfiguration() *schema.Configuration + + context.Context +} + +type ctxEmbed struct { + Configuration *Configuration + Providers Providers + Logger *logrus.Entry + + context.Context +} + +func (c *ctxEmbed) GetConfiguration() *schema.Configuration { + return c.Configuration.ToInternal() +} + +func (c *ctxEmbed) GetProviders() middlewares.Providers { + return c.Providers.ToInternal() +} + +func (c *ctxEmbed) GetLogger() *logrus.Entry { + return c.Logger +} + +var ( + _ middlewares.Context = (*ctxEmbed)(nil) +) diff --git a/experimental/embed/context_test.go b/experimental/embed/context_test.go new file mode 100644 index 000000000..cb5a2486e --- /dev/null +++ b/experimental/embed/context_test.go @@ -0,0 +1,43 @@ +package embed + +import ( + "testing" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + + "github.com/authelia/authelia/v4/internal/logging" +) + +func TestContext(t *testing.T) { + ctx := &ctxEmbed{} + + assert.Nil(t, ctx.GetConfiguration()) + assert.Nil(t, ctx.GetLogger()) + + providers := ctx.GetProviders() + + assert.Nil(t, providers.StorageProvider) + assert.Nil(t, providers.Notifier) + assert.Nil(t, providers.UserProvider) + assert.Nil(t, providers.SessionProvider) + assert.Nil(t, providers.MetaDataService) + assert.Nil(t, providers.Metrics) + assert.Nil(t, providers.Templates) + assert.Nil(t, providers.Random) + assert.Nil(t, providers.OpenIDConnect) + assert.Nil(t, providers.UserAttributeResolver) + assert.Nil(t, providers.Authorizer) + assert.Nil(t, providers.NTP) + assert.Nil(t, providers.TOTP) +} + +func TestContextWithValues(t *testing.T) { + ctx := &ctxEmbed{ + Configuration: &Configuration{}, + Logger: logrus.NewEntry(logging.Logger()), + } + + assert.NotNil(t, ctx.GetConfiguration()) + assert.NotNil(t, ctx.GetLogger()) +} diff --git a/experimental/embed/doc.go b/experimental/embed/doc.go new file mode 100644 index 000000000..9e9d4d09b --- /dev/null +++ b/experimental/embed/doc.go @@ -0,0 +1,13 @@ +// Package embed provides tooling useful to embed Authelia into an external go process. This package is considered +// experimental and as such is not supported by the standard versioning policy. It's strongly recommended that care is +// taken when integrating with this package and appropriate tests are conducted when upgrading. +// +// This package and all subpackages are intended to facilitate differing levels of embedability within Authelia. It's +// likely this package and subpackages will break often. +// +// The following considerations should be made in using this package: +// - It's likely that many methods within this package can panic if not properly utilized. +// - The package is likely at this stage to be changed abruptly from version to version in a breaking way. +// - The package will likely have breaking changes at any minor version bump well into the future (breaking changes to +// this package as a result of changing internal packages will not be a consideration that will slow development). +package embed diff --git a/experimental/embed/embed.go b/experimental/embed/embed.go new file mode 100644 index 000000000..0a2d91168 --- /dev/null +++ b/experimental/embed/embed.go @@ -0,0 +1,7 @@ +package embed + +func ProvidersStartupCheck(ctx Context, log bool) (err error) { + providers := ctx.GetProviders() + + return providers.StartupChecks(ctx, log) +} diff --git a/experimental/embed/embed_test.go b/experimental/embed/embed_test.go new file mode 100644 index 000000000..c20e2cb77 --- /dev/null +++ b/experimental/embed/embed_test.go @@ -0,0 +1,19 @@ +package embed + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestShouldPanicNilCtx(t *testing.T) { + assert.Panics(t, func() { + _ = ProvidersStartupCheck(nil, false) + }) + + ctx := &ctxEmbed{} + + assert.Panics(t, func() { + _ = ProvidersStartupCheck(ctx, false) + }) +} diff --git a/experimental/embed/provider/authentication.go b/experimental/embed/provider/authentication.go new file mode 100644 index 000000000..3903e6c1c --- /dev/null +++ b/experimental/embed/provider/authentication.go @@ -0,0 +1,22 @@ +package provider + +import ( + "crypto/x509" + + "github.com/authelia/authelia/v4/internal/authentication" + "github.com/authelia/authelia/v4/internal/configuration/schema" +) + +// NewAuthenticationFile directly instantiates a new authentication.UserProvider using a *authentication.FileUserProvider. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewAuthenticationFile(config *schema.Configuration) authentication.UserProvider { + return authentication.NewFileUserProvider(config.AuthenticationBackend.File) +} + +// NewAuthenticationLDAP directly instantiates a new authentication.UserProvider using a *authentication.LDAPUserProvider. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewAuthenticationLDAP(config *schema.Configuration, caCertPool *x509.CertPool) authentication.UserProvider { + return authentication.NewLDAPUserProvider(config.AuthenticationBackend, caCertPool) +} diff --git a/experimental/embed/provider/general.go b/experimental/embed/provider/general.go new file mode 100644 index 000000000..95e5d04a7 --- /dev/null +++ b/experimental/embed/provider/general.go @@ -0,0 +1,113 @@ +package provider + +import ( + "crypto/x509" + + "github.com/authelia/authelia/v4/internal/authorization" + "github.com/authelia/authelia/v4/internal/clock" + "github.com/authelia/authelia/v4/internal/configuration/schema" + "github.com/authelia/authelia/v4/internal/expression" + "github.com/authelia/authelia/v4/internal/metrics" + "github.com/authelia/authelia/v4/internal/middlewares" + "github.com/authelia/authelia/v4/internal/ntp" + "github.com/authelia/authelia/v4/internal/oidc" + "github.com/authelia/authelia/v4/internal/random" + "github.com/authelia/authelia/v4/internal/regulation" + "github.com/authelia/authelia/v4/internal/session" + "github.com/authelia/authelia/v4/internal/storage" + "github.com/authelia/authelia/v4/internal/templates" + "github.com/authelia/authelia/v4/internal/totp" + "github.com/authelia/authelia/v4/internal/webauthn" +) + +// New returns a completely new set of providers using the internal API. It is expected you'll check the errs return +// value for any errors, and handle any warnings in a graceful way. If errors are returned the providers should not be +// utilized to run anything. +func New(config *schema.Configuration, caCertPool *x509.CertPool) (providers middlewares.Providers, warns []error, errs []error) { + return middlewares.NewProviders(config, caCertPool) +} + +// NewClock creates a new clock provider. +func NewClock() clock.Provider { + return clock.New() +} + +// NewAuthorizer creates a new *authorization.Authorizer. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewAuthorizer(config *schema.Configuration) *authorization.Authorizer { + return authorization.NewAuthorizer(config) +} + +// NewSession creates a new *session.Provider given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewSession(config *schema.Configuration, caCertPool *x509.CertPool) *session.Provider { + return session.NewProvider(config.Session, caCertPool) +} + +// NewRegulator creates a new *regulation.Regulator given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewRegulator(config *schema.Configuration, storage storage.RegulatorProvider, clock clock.Provider) *regulation.Regulator { + return regulation.NewRegulator(config.Regulation, storage, clock) +} + +// NewMetrics creates a new metrics.Provider. +func NewMetrics() metrics.Provider { + return metrics.NewPrometheus() +} + +// NewNTP creates a new *ntp.Provider given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewNTP(config *schema.Configuration) *ntp.Provider { + return ntp.NewProvider(&config.NTP) +} + +// NewOpenIDConnect creates a new *oidc.OpenIDConnectProvider given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewOpenIDConnect(config *schema.Configuration, storage storage.Provider, templates *templates.Provider) *oidc.OpenIDConnectProvider { + return oidc.NewOpenIDConnectProvider(config, storage, templates) +} + +// NewTemplates creates a new *templates.Provider given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewTemplates(config *schema.Configuration) (provider *templates.Provider, err error) { + return templates.New(templates.Config{EmailTemplatesPath: config.Notifier.TemplatePath}) +} + +// NewTOTP creates a new totp.Provider given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewTOTP(config *schema.Configuration) totp.Provider { + return totp.NewTimeBasedProvider(config.TOTP) +} + +// NewPasswordPolicy creates a new middlewares.PasswordPolicyProvider given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewPasswordPolicy(config *schema.Configuration) middlewares.PasswordPolicyProvider { + return middlewares.NewPasswordPolicyProvider(config.PasswordPolicy) +} + +// NewRandom creates a new random.Provider given a valid configuration. This uses the rand/crypto package. +func NewRandom() random.Provider { + return &random.Cryptographical{} +} + +// NewUserAttributeResolver creates a new expression.UserAttributeResolver given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewUserAttributeResolver(config *schema.Configuration) expression.UserAttributeResolver { + return expression.NewUserAttributes(config) +} + +// NewMetaDataService creates a new webauthn.MetaDataProvider given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewMetaDataService(config *schema.Configuration, store storage.CachedDataProvider) (provider webauthn.MetaDataProvider, err error) { + return webauthn.NewMetaDataProvider(config, store) +} diff --git a/experimental/embed/provider/notification.go b/experimental/embed/provider/notification.go new file mode 100644 index 000000000..a566cd20d --- /dev/null +++ b/experimental/embed/provider/notification.go @@ -0,0 +1,24 @@ +package provider + +import ( + "crypto/x509" + + "github.com/authelia/authelia/v4/internal/configuration/schema" + "github.com/authelia/authelia/v4/internal/notification" +) + +// NewNotificationSMTP creates a new notification.Notifier using the *notification.SMTPNotifier given a valid +// configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewNotificationSMTP(config *schema.Configuration, caCertPool *x509.CertPool) notification.Notifier { + return notification.NewSMTPNotifier(config.Notifier.SMTP, caCertPool) +} + +// NewNotificationFile creates a new notification.Notifier using the *notification.FileNotifier given a valid +// configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewNotificationFile(config *schema.Configuration, caCertPool *x509.CertPool) notification.Notifier { + return notification.NewSMTPNotifier(config.Notifier.SMTP, caCertPool) +} diff --git a/experimental/embed/provider/storage.go b/experimental/embed/provider/storage.go new file mode 100644 index 000000000..42c40aefd --- /dev/null +++ b/experimental/embed/provider/storage.go @@ -0,0 +1,29 @@ +package provider + +import ( + "crypto/x509" + + "github.com/authelia/authelia/v4/internal/configuration/schema" + "github.com/authelia/authelia/v4/internal/storage" +) + +// NewStoragePostgreSQL creates a new storage.Provider using the *storage.PostgreSQLProvider given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewStoragePostgreSQL(config *schema.Configuration, caCertPool *x509.CertPool) storage.Provider { + return storage.NewPostgreSQLProvider(config, caCertPool) +} + +// NewStorageMySQL creates a new storage.Provider using the *storage.MySQLProvider given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewStorageMySQL(config *schema.Configuration, caCertPool *x509.CertPool) storage.Provider { + return storage.NewMySQLProvider(config, caCertPool) +} + +// NewStorageSQLite creates a new storage.Provider using the *storage.SQLiteProvider given a valid configuration. +// +// Warning: This method may panic if the provided configuration isn't validated. +func NewStorageSQLite(config *schema.Configuration) storage.Provider { + return storage.NewSQLiteProvider(config) +} diff --git a/experimental/embed/types.go b/experimental/embed/types.go new file mode 100644 index 000000000..bd048206e --- /dev/null +++ b/experimental/embed/types.go @@ -0,0 +1,24 @@ +package embed + +import ( + "github.com/authelia/authelia/v4/internal/configuration/schema" + "github.com/authelia/authelia/v4/internal/middlewares" +) + +// Configuration is a type alias for the internal schema.Configuration type. It allows manually configuring Authelia +// and transitioning to the internal implementation. +type Configuration schema.Configuration + +// ToInternal converts this Configuration struct into a *schema.Configuration struct using a type cast. +func (c *Configuration) ToInternal() *schema.Configuration { + return (*schema.Configuration)(c) +} + +// Providers is a type alias for the internal middlewares.Providers type. It allows manually performing setup of the +// various Authelia providers and transitioning to the internal implementation. +type Providers middlewares.Providers + +// ToInternal converts this Providers struct into a middlewares.Providers struct using a type cast. +func (p Providers) ToInternal() middlewares.Providers { + return middlewares.Providers(p) +} diff --git a/experimental/embed/types_test.go b/experimental/embed/types_test.go new file mode 100644 index 000000000..3a93ce183 --- /dev/null +++ b/experimental/embed/types_test.go @@ -0,0 +1,15 @@ +package embed + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTypeBasics(t *testing.T) { + c := &Configuration{} + assert.NotNil(t, c.ToInternal()) + + p := &Providers{} + assert.NotNil(t, p.ToInternal()) +} |
