summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/content/en/reference/guides/ldap.md43
-rw-r--r--internal/authentication/const.go13
-rw-r--r--internal/authentication/ldap_user_provider.go40
-rw-r--r--internal/authentication/ldap_user_provider_startup.go12
-rw-r--r--internal/authentication/ldap_user_provider_test.go334
-rw-r--r--internal/configuration/schema/authentication.go4
-rw-r--r--internal/handlers/handler_verify_test.go16
-rw-r--r--internal/mocks/authelia_ctx.go25
-rw-r--r--internal/regulation/regulator_test.go3
-rw-r--r--internal/utils/clock.go20
-rw-r--r--internal/utils/const.go31
-rw-r--r--internal/utils/const_test.go5
-rw-r--r--internal/utils/time.go5
-rw-r--r--internal/utils/time_test.go8
14 files changed, 315 insertions, 244 deletions
diff --git a/docs/content/en/reference/guides/ldap.md b/docs/content/en/reference/guides/ldap.md
index 523cc258e..0d38b709d 100644
--- a/docs/content/en/reference/guides/ldap.md
+++ b/docs/content/en/reference/guides/ldap.md
@@ -60,12 +60,15 @@ search.
#### Users filter replacements
-| Placeholder | Phase | Replacement |
-|:------------------------:|:-------:|:-------------------------------------:|
-| {username_attribute} | startup | The configured username attribute |
-| {mail_attribute} | startup | The configured mail attribute |
-| {display_name_attribute} | startup | The configured display name attribute |
-| {input} | search | The input into the username field |
+| Placeholder | Phase | Replacement |
+|:-------------------------:|:-------:|:--------------------------------------------------------------------------------------------------------------:|
+| {username_attribute} | startup | The configured username attribute |
+| {mail_attribute} | startup | The configured mail attribute |
+| {display_name_attribute} | startup | The configured display name attribute |
+| {input} | search | The input into the username field |
+| {date-time:generalized} | search | The current UTC time formatted as a LDAP generalized time in the format of `20060102150405.0Z` |
+| {date-time:unix-epoch} | search | The current time formatted as a Unix epoch |
+| {date-time:msft-nt-epoch} | search | The current time formatted as a Microsoft NT epoch which is used by some Microsoft Active Directory attributes |
#### Groups filter replacements
@@ -92,16 +95,24 @@ Username column.
#### Filter defaults
-The filters are probably the most important part to get correct when setting up LDAP. You want to exclude disabled
-accounts. The active directory example has two attribute filters that accomplish this as an example (more examples would
-be appreciated). The userAccountControl filter checks that the account is not disabled and the pwdLastSet makes sure that
-value is not 0 which means the password requires changing at the next login.
-
-| Implementation | Users Filter | Groups Filter |
-|:---------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------:|
-| custom | N/A | N/A |
-| activedirectory | (&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))) | (&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912))) |
-| freeipa | (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)(!(nsAccountLock=TRUE))) | (&(member={dn})(objectClass=groupOfNames)) |
+The filters are probably the most important part to get correct when setting up LDAP. You want to exclude accounts under
+the following conditions:
+
+- The account is disabled or locked:
+ - The Active Directory implementation achieves this via the `(!(userAccountControl:1.2.840.113556.1.4.803:=2))` filter.
+ - The FreeIPA implementation achieves this via the `(!(nsAccountLock=TRUE))` filter.
+- Their password is expired:
+ - The Active Directory implementation achieves this via the `(!(pwdLastSet=0))` filter.
+ - The FreeIPA implementation achieves this via the `(krbPasswordExpiration>={date-time:generalized})` filter.
+- Their account is expired:
+ - The Active Directory implementation achieves this via the `(|(!(accountExpires=*))(accountExpires=0)(accountExpires>={date-time:msft-nt-epoch}))` filter.
+ - The FreeIPA implementation achieves this via the `(|(!(krbPrincipalExpiration=*))(krbPrincipalExpiration>={date-time:generalized}))` filter.
+
+| Implementation | Users Filter | Groups Filter |
+|:---------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------:|
+| custom | N/A | N/A |
+| activedirectory | (&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))(|(!(accountExpires=*))(accountExpires=0)(accountExpires>={date-time:msft-nt-epoch}))) | (&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912))) |
+| freeipa | (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)(!(nsAccountLock=TRUE))(krbPasswordExpiration>={date-time:generalized})(|(!(krbPrincipalExpiration=*))(krbPrincipalExpiration>={date-time:generalized}))) | (&(member={dn})(objectClass=groupOfNames)) |
##### Microsoft Active Directory sAMAccountType
diff --git a/internal/authentication/const.go b/internal/authentication/const.go
index 48d31c186..4bf9e3cdb 100644
--- a/internal/authentication/const.go
+++ b/internal/authentication/const.go
@@ -70,9 +70,16 @@ const (
)
const (
- ldapPlaceholderInput = "{input}"
- ldapPlaceholderDistinguishedName = "{dn}"
- ldapPlaceholderUsername = "{username}"
+ ldapPlaceholderInput = "{input}"
+ ldapPlaceholderDistinguishedName = "{dn}"
+ ldapPlaceholderUsername = "{username}"
+ ldapPlaceholderDateTimeGeneralized = "{date-time:generalized}"
+ ldapPlaceholderDateTimeMicrosoftNTTimeEpoch = "{date-time:msft-nt-epoch}"
+ ldapPlaceholderDateTimeUnixEpoch = "{date-time:unix-epoch}"
+)
+
+const (
+ ldapGeneralizedTimeDateTimeFormat = "20060102150405.0Z"
)
const (
diff --git a/internal/authentication/ldap_user_provider.go b/internal/authentication/ldap_user_provider.go
index 65f635bf7..56ad08c6f 100644
--- a/internal/authentication/ldap_user_provider.go
+++ b/internal/authentication/ldap_user_provider.go
@@ -5,6 +5,7 @@ import (
"crypto/x509"
"fmt"
"net"
+ "strconv"
"strings"
"github.com/go-ldap/ldap/v3"
@@ -23,15 +24,20 @@ type LDAPUserProvider struct {
log *logrus.Logger
factory LDAPClientFactory
+ clock utils.Clock
+
disableResetPassword bool
// Automatically detected LDAP features.
features LDAPSupportedFeatures
// Dynamically generated users values.
- usersBaseDN string
- usersAttributes []string
- usersFilterReplacementInput bool
+ usersBaseDN string
+ usersAttributes []string
+ usersFilterReplacementInput bool
+ usersFilterReplacementDateTimeGeneralized bool
+ usersFilterReplacementDateTimeUnixEpoch bool
+ usersFilterReplacementDateTimeMicrosoftNTTimeEpoch bool
// Dynamically generated groups values.
groupsBaseDN string
@@ -41,14 +47,15 @@ type LDAPUserProvider struct {
groupsFilterReplacementDN bool
}
-// NewLDAPUserProvider creates a new instance of LDAPUserProvider.
+// NewLDAPUserProvider creates a new instance of LDAPUserProvider with the ProductionLDAPClientFactory.
func NewLDAPUserProvider(config schema.AuthenticationBackend, certPool *x509.CertPool) (provider *LDAPUserProvider) {
- provider = newLDAPUserProvider(*config.LDAP, config.PasswordReset.Disable, certPool, nil)
+ provider = NewLDAPUserProviderWithFactory(*config.LDAP, config.PasswordReset.Disable, certPool, NewProductionLDAPClientFactory())
return provider
}
-func newLDAPUserProvider(config schema.LDAPAuthenticationBackend, disableResetPassword bool, certPool *x509.CertPool, factory LDAPClientFactory) (provider *LDAPUserProvider) {
+// NewLDAPUserProviderWithFactory creates a new instance of LDAPUserProvider with the specified LDAPClientFactory.
+func NewLDAPUserProviderWithFactory(config schema.LDAPAuthenticationBackend, disableResetPassword bool, certPool *x509.CertPool, factory LDAPClientFactory) (provider *LDAPUserProvider) {
if config.TLS == nil {
config.TLS = schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom.TLS
}
@@ -74,6 +81,7 @@ func newLDAPUserProvider(config schema.LDAPAuthenticationBackend, disableResetPa
log: logging.Logger(),
factory: factory,
disableResetPassword: disableResetPassword,
+ clock: &utils.RealClock{},
}
provider.parseDynamicUsersConfiguration()
@@ -394,12 +402,24 @@ func (p *LDAPUserProvider) getUserProfile(client LDAPClient, username string) (p
return &userProfile, nil
}
-func (p *LDAPUserProvider) resolveUsersFilter(username string) (filter string) {
+func (p *LDAPUserProvider) resolveUsersFilter(input string) (filter string) {
filter = p.config.UsersFilter
if p.usersFilterReplacementInput {
// The {input} placeholder is replaced by the username input.
- filter = strings.ReplaceAll(filter, ldapPlaceholderInput, ldapEscape(username))
+ filter = strings.ReplaceAll(filter, ldapPlaceholderInput, ldapEscape(input))
+ }
+
+ if p.usersFilterReplacementDateTimeGeneralized {
+ filter = strings.ReplaceAll(filter, ldapPlaceholderDateTimeGeneralized, p.clock.Now().UTC().Format(ldapGeneralizedTimeDateTimeFormat))
+ }
+
+ if p.usersFilterReplacementDateTimeUnixEpoch {
+ filter = strings.ReplaceAll(filter, ldapPlaceholderDateTimeUnixEpoch, strconv.Itoa(int(p.clock.Now().Unix())))
+ }
+
+ if p.usersFilterReplacementDateTimeMicrosoftNTTimeEpoch {
+ filter = strings.ReplaceAll(filter, ldapPlaceholderDateTimeMicrosoftNTTimeEpoch, strconv.Itoa(int(utils.UnixNanoTimeToMicrosoftNTEpoch(p.clock.Now().UnixNano()))))
}
p.log.Tracef("Detected user filter is %s", filter)
@@ -407,12 +427,12 @@ func (p *LDAPUserProvider) resolveUsersFilter(username string) (filter string) {
return filter
}
-func (p *LDAPUserProvider) resolveGroupsFilter(username string, profile *ldapUserProfile) (filter string) {
+func (p *LDAPUserProvider) resolveGroupsFilter(input string, profile *ldapUserProfile) (filter string) {
filter = p.config.GroupsFilter
if p.groupsFilterReplacementInput {
// The {input} placeholder is replaced by the users username input.
- filter = strings.ReplaceAll(p.config.GroupsFilter, ldapPlaceholderInput, ldapEscape(username))
+ filter = strings.ReplaceAll(p.config.GroupsFilter, ldapPlaceholderInput, ldapEscape(input))
}
if profile != nil {
diff --git a/internal/authentication/ldap_user_provider_startup.go b/internal/authentication/ldap_user_provider_startup.go
index a3a2e760a..edf668587 100644
--- a/internal/authentication/ldap_user_provider_startup.go
+++ b/internal/authentication/ldap_user_provider_startup.go
@@ -120,6 +120,18 @@ func (p *LDAPUserProvider) parseDynamicUsersConfiguration() {
p.usersFilterReplacementInput = true
}
+ if strings.Contains(p.config.UsersFilter, ldapPlaceholderDateTimeGeneralized) {
+ p.usersFilterReplacementDateTimeGeneralized = true
+ }
+
+ if strings.Contains(p.config.UsersFilter, ldapPlaceholderDateTimeUnixEpoch) {
+ p.usersFilterReplacementDateTimeUnixEpoch = true
+ }
+
+ if strings.Contains(p.config.UsersFilter, ldapPlaceholderDateTimeMicrosoftNTTimeEpoch) {
+ p.usersFilterReplacementDateTimeMicrosoftNTTimeEpoch = true
+ }
+
p.log.Tracef("Detected user filter replacements that need to be resolved per lookup are: %s=%v",
ldapPlaceholderInput, p.usersFilterReplacementInput)
}
diff --git a/internal/authentication/ldap_user_provider_test.go b/internal/authentication/ldap_user_provider_test.go
index d28d05e9c..2b929683e 100644
--- a/internal/authentication/ldap_user_provider_test.go
+++ b/internal/authentication/ldap_user_provider_test.go
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"testing"
+ "time"
"github.com/go-ldap/ldap/v3"
"github.com/golang/mock/gomock"
@@ -22,7 +23,7 @@ func TestShouldCreateRawConnectionWhenSchemeIsLDAP(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -42,7 +43,7 @@ func TestShouldCreateRawConnectionWhenSchemeIsLDAP(t *testing.T) {
gomock.InOrder(dialURL, connBind)
- _, err := ldapClient.connect()
+ _, err := provider.connect()
require.NoError(t, err)
}
@@ -54,7 +55,7 @@ func TestShouldCreateTLSConnectionWhenSchemeIsLDAPS(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldaps://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -74,7 +75,7 @@ func TestShouldCreateTLSConnectionWhenSchemeIsLDAPS(t *testing.T) {
gomock.InOrder(dialURL, connBind)
- _, err := ldapClient.connect()
+ _, err := provider.connect()
require.NoError(t, err)
}
@@ -104,7 +105,7 @@ func TestEscapeSpecialCharsInGroupsFilter(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldaps://127.0.0.1:389",
GroupsFilter: "(|(member={dn})(uid={username})(uid={input}))",
@@ -120,10 +121,10 @@ func TestEscapeSpecialCharsInGroupsFilter(t *testing.T) {
Emails: []string{"john.doe@authelia.com"},
}
- filter := ldapClient.resolveGroupsFilter("john", &profile)
+ filter := provider.resolveGroupsFilter("john", &profile)
assert.Equal(t, "(|(member=cn=john \\28external\\29,dc=example,dc=com)(uid=john)(uid=john))", filter)
- filter = ldapClient.resolveGroupsFilter("john#=(abc,def)", &profile)
+ filter = provider.resolveGroupsFilter("john#=(abc,def)", &profile)
assert.Equal(t, "(|(member=cn=john \\28external\\29,dc=example,dc=com)(uid=john)(uid=john\\#\\=\\28abc\\,def\\29))", filter)
}
@@ -162,7 +163,7 @@ func TestShouldCheckLDAPServerExtensions(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -210,14 +211,14 @@ func TestShouldCheckLDAPServerExtensions(t *testing.T) {
gomock.InOrder(dialURL, connBind, searchOIDs, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
assert.NoError(t, err)
- assert.True(t, ldapClient.features.Extensions.PwdModifyExOp)
- assert.True(t, ldapClient.features.Extensions.TLS)
+ assert.True(t, provider.features.Extensions.PwdModifyExOp)
+ assert.True(t, provider.features.Extensions.TLS)
- assert.False(t, ldapClient.features.ControlTypes.MsftPwdPolHints)
- assert.False(t, ldapClient.features.ControlTypes.MsftPwdPolHintsDeprecated)
+ assert.False(t, provider.features.ControlTypes.MsftPwdPolHints)
+ assert.False(t, provider.features.ControlTypes.MsftPwdPolHintsDeprecated)
}
func TestShouldNotCheckLDAPServerExtensionsWhenRootDSEReturnsMoreThanOneEntry(t *testing.T) {
@@ -227,7 +228,7 @@ func TestShouldNotCheckLDAPServerExtensionsWhenRootDSEReturnsMoreThanOneEntry(t
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -276,14 +277,14 @@ func TestShouldNotCheckLDAPServerExtensionsWhenRootDSEReturnsMoreThanOneEntry(t
gomock.InOrder(dialURL, connBind, searchOIDs, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
assert.NoError(t, err)
- assert.False(t, ldapClient.features.Extensions.PwdModifyExOp)
- assert.False(t, ldapClient.features.Extensions.TLS)
+ assert.False(t, provider.features.Extensions.PwdModifyExOp)
+ assert.False(t, provider.features.Extensions.TLS)
- assert.False(t, ldapClient.features.ControlTypes.MsftPwdPolHints)
- assert.False(t, ldapClient.features.ControlTypes.MsftPwdPolHintsDeprecated)
+ assert.False(t, provider.features.ControlTypes.MsftPwdPolHints)
+ assert.False(t, provider.features.ControlTypes.MsftPwdPolHintsDeprecated)
}
func TestShouldCheckLDAPServerControlTypes(t *testing.T) {
@@ -293,7 +294,7 @@ func TestShouldCheckLDAPServerControlTypes(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -341,14 +342,14 @@ func TestShouldCheckLDAPServerControlTypes(t *testing.T) {
gomock.InOrder(dialURL, connBind, searchOIDs, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
assert.NoError(t, err)
- assert.False(t, ldapClient.features.Extensions.PwdModifyExOp)
- assert.False(t, ldapClient.features.Extensions.TLS)
+ assert.False(t, provider.features.Extensions.PwdModifyExOp)
+ assert.False(t, provider.features.Extensions.TLS)
- assert.True(t, ldapClient.features.ControlTypes.MsftPwdPolHints)
- assert.True(t, ldapClient.features.ControlTypes.MsftPwdPolHintsDeprecated)
+ assert.True(t, provider.features.ControlTypes.MsftPwdPolHints)
+ assert.True(t, provider.features.ControlTypes.MsftPwdPolHintsDeprecated)
}
func TestShouldNotEnablePasswdModifyExtensionOrControlTypes(t *testing.T) {
@@ -358,7 +359,7 @@ func TestShouldNotEnablePasswdModifyExtensionOrControlTypes(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -406,14 +407,14 @@ func TestShouldNotEnablePasswdModifyExtensionOrControlTypes(t *testing.T) {
gomock.InOrder(dialURL, connBind, searchOIDs, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
assert.NoError(t, err)
- assert.False(t, ldapClient.features.Extensions.PwdModifyExOp)
- assert.False(t, ldapClient.features.Extensions.TLS)
+ assert.False(t, provider.features.Extensions.PwdModifyExOp)
+ assert.False(t, provider.features.Extensions.TLS)
- assert.False(t, ldapClient.features.ControlTypes.MsftPwdPolHints)
- assert.False(t, ldapClient.features.ControlTypes.MsftPwdPolHintsDeprecated)
+ assert.False(t, provider.features.ControlTypes.MsftPwdPolHints)
+ assert.False(t, provider.features.ControlTypes.MsftPwdPolHintsDeprecated)
}
func TestShouldReturnCheckServerConnectError(t *testing.T) {
@@ -423,7 +424,7 @@ func TestShouldReturnCheckServerConnectError(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -443,10 +444,10 @@ func TestShouldReturnCheckServerConnectError(t *testing.T) {
DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
Return(mockClient, errors.New("could not connect"))
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
assert.EqualError(t, err, "dial failed with error: could not connect")
- assert.False(t, ldapClient.features.Extensions.PwdModifyExOp)
+ assert.False(t, provider.features.Extensions.PwdModifyExOp)
}
func TestShouldReturnCheckServerSearchError(t *testing.T) {
@@ -456,7 +457,7 @@ func TestShouldReturnCheckServerSearchError(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -488,10 +489,10 @@ func TestShouldReturnCheckServerSearchError(t *testing.T) {
gomock.InOrder(dialURL, connBind, searchOIDs, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
assert.EqualError(t, err, "error occurred during RootDSE search: could not perform the search")
- assert.False(t, ldapClient.features.Extensions.PwdModifyExOp)
+ assert.False(t, provider.features.Extensions.PwdModifyExOp)
}
type SearchRequestMatcher struct {
@@ -518,7 +519,7 @@ func TestShouldEscapeUserInput(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -540,7 +541,7 @@ func TestShouldEscapeUserInput(t *testing.T) {
Search(NewSearchRequestMatcher("(|(uid=john\\=abc)(mail=john\\=abc))")).
Return(&ldap.SearchResult{}, nil)
- _, err := ldapClient.getUserProfile(mockClient, "john=abc")
+ _, err := provider.getUserProfile(mockClient, "john=abc")
require.Error(t, err)
assert.EqualError(t, err, "user not found")
}
@@ -552,7 +553,7 @@ func TestShouldReturnEmailWhenAttributeSameAsUsername(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -568,7 +569,7 @@ func TestShouldReturnEmailWhenAttributeSameAsUsername(t *testing.T) {
nil,
mockFactory)
- assert.Equal(t, []string{"mail", "displayName"}, ldapClient.usersAttributes)
+ assert.Equal(t, []string{"mail", "displayName"}, provider.usersAttributes)
dialURL := mockFactory.EXPECT().
DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
@@ -600,10 +601,10 @@ func TestShouldReturnEmailWhenAttributeSameAsUsername(t *testing.T) {
gomock.InOrder(dialURL, bind, search)
- client, err := ldapClient.connect()
+ client, err := provider.connect()
assert.NoError(t, err)
- profile, err := ldapClient.getUserProfile(client, "john@example.com")
+ profile, err := provider.getUserProfile(client, "john@example.com")
assert.NoError(t, err)
require.NotNil(t, profile)
@@ -623,7 +624,7 @@ func TestShouldReturnUsernameAndBlankDisplayNameWhenAttributesTheSame(t *testing
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -639,7 +640,7 @@ func TestShouldReturnUsernameAndBlankDisplayNameWhenAttributesTheSame(t *testing
nil,
mockFactory)
- assert.Equal(t, []string{"uid", "mail"}, ldapClient.usersAttributes)
+ assert.Equal(t, []string{"uid", "mail"}, provider.usersAttributes)
dialURL := mockFactory.EXPECT().
DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
@@ -671,10 +672,10 @@ func TestShouldReturnUsernameAndBlankDisplayNameWhenAttributesTheSame(t *testing
gomock.InOrder(dialURL, bind, search)
- client, err := ldapClient.connect()
+ client, err := provider.connect()
assert.NoError(t, err)
- profile, err := ldapClient.getUserProfile(client, "john@example.com")
+ profile, err := provider.getUserProfile(client, "john@example.com")
assert.NoError(t, err)
require.NotNil(t, profile)
@@ -694,7 +695,7 @@ func TestShouldReturnBlankEmailAndDisplayNameWhenAttrsLenZero(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -710,7 +711,7 @@ func TestShouldReturnBlankEmailAndDisplayNameWhenAttrsLenZero(t *testing.T) {
nil,
mockFactory)
- assert.Equal(t, []string{"uid", "mail", "displayName"}, ldapClient.usersAttributes)
+ assert.Equal(t, []string{"uid", "mail", "displayName"}, provider.usersAttributes)
dialURL := mockFactory.EXPECT().
DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
@@ -746,10 +747,10 @@ func TestShouldReturnBlankEmailAndDisplayNameWhenAttrsLenZero(t *testing.T) {
gomock.InOrder(dialURL, bind, search)
- client, err := ldapClient.connect()
+ client, err := provider.connect()
assert.NoError(t, err)
- profile, err := ldapClient.getUserProfile(client, "john@example.com")
+ profile, err := provider.getUserProfile(client, "john@example.com")
assert.NoError(t, err)
require.NotNil(t, profile)
@@ -768,7 +769,7 @@ func TestShouldCombineUsernameFilterAndUsersFilter(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -785,15 +786,15 @@ func TestShouldCombineUsernameFilterAndUsersFilter(t *testing.T) {
nil,
mockFactory)
- assert.Equal(t, []string{"uid", "mail", "displayName"}, ldapClient.usersAttributes)
+ assert.Equal(t, []string{"uid", "mail", "displayName"}, provider.usersAttributes)
- assert.True(t, ldapClient.usersFilterReplacementInput)
+ assert.True(t, provider.usersFilterReplacementInput)
mockClient.EXPECT().
Search(NewSearchRequestMatcher("(&(uid=john)(&(objectCategory=person)(objectClass=user)))")).
Return(&ldap.SearchResult{}, nil)
- _, err := ldapClient.getUserProfile(mockClient, "john")
+ _, err := provider.getUserProfile(mockClient, "john")
require.Error(t, err)
assert.EqualError(t, err, "user not found")
}
@@ -819,7 +820,7 @@ func TestShouldNotCrashWhenGroupsAreNotRetrievedFromLDAP(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -876,7 +877,7 @@ func TestShouldNotCrashWhenGroupsAreNotRetrievedFromLDAP(t *testing.T) {
gomock.InOrder(dialURL, connBind, searchProfile, searchGroups, connClose)
- details, err := ldapClient.GetDetails("john")
+ details, err := provider.GetDetails("john")
require.NoError(t, err)
assert.ElementsMatch(t, details.Groups, []string{})
@@ -892,7 +893,7 @@ func TestShouldNotCrashWhenEmailsAreNotRetrievedFromLDAP(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -938,7 +939,7 @@ func TestShouldNotCrashWhenEmailsAreNotRetrievedFromLDAP(t *testing.T) {
gomock.InOrder(dialURL, connBind, searchProfile, searchGroups, connClose)
- details, err := ldapClient.GetDetails("john")
+ details, err := provider.GetDetails("john")
require.NoError(t, err)
assert.ElementsMatch(t, details.Groups, []string{"group1", "group2"})
@@ -953,7 +954,7 @@ func TestShouldReturnUsernameFromLDAP(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -1009,7 +1010,7 @@ func TestShouldReturnUsernameFromLDAP(t *testing.T) {
gomock.InOrder(dialURL, connBind, searchProfile, searchGroups, connClose)
- details, err := ldapClient.GetDetails("john")
+ details, err := provider.GetDetails("john")
require.NoError(t, err)
assert.ElementsMatch(t, details.Groups, []string{"group1", "group2"})
@@ -1026,7 +1027,7 @@ func TestShouldReturnUsernameFromLDAPWithReferrals(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl)
mockClientReferral := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -1100,7 +1101,7 @@ func TestShouldReturnUsernameFromLDAPWithReferrals(t *testing.T) {
gomock.InOrder(dialURL, connBind, searchProfile, dialURLReferral, connBindReferral, searchProfileReferral, connCloseReferral, searchGroups, connClose)
- details, err := ldapClient.GetDetails("john")
+ details, err := provider.GetDetails("john")
require.NoError(t, err)
assert.ElementsMatch(t, details.Groups, []string{"group1", "group2"})
@@ -1118,7 +1119,7 @@ func TestShouldReturnUsernameFromLDAPWithReferralsInErrorAndResult(t *testing.T)
mockClientReferral := NewMockLDAPClient(ctrl)
mockClientReferralAlt := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -1226,7 +1227,7 @@ func TestShouldReturnUsernameFromLDAPWithReferralsInErrorAndResult(t *testing.T)
gomock.InOrder(dialURL, connBind, searchProfile, dialURLReferral, connBindReferral, searchProfileReferral, connCloseReferral, dialURLReferralAlt, connBindReferralAlt, searchProfileReferralAlt, connCloseReferralAlt, searchGroups, connClose)
- details, err := ldapClient.GetDetails("john")
+ details, err := provider.GetDetails("john")
require.NoError(t, err)
assert.ElementsMatch(t, details.Groups, []string{"group1", "group2"})
@@ -1243,7 +1244,7 @@ func TestShouldReturnUsernameFromLDAPWithReferralsErr(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl)
mockClientReferral := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -1314,7 +1315,7 @@ func TestShouldReturnUsernameFromLDAPWithReferralsErr(t *testing.T) {
gomock.InOrder(dialURL, connBind, searchProfile, dialURLReferral, connBindReferral, searchProfileReferral, connCloseReferral, searchGroups, connClose)
- details, err := ldapClient.GetDetails("john")
+ details, err := provider.GetDetails("john")
require.NoError(t, err)
assert.ElementsMatch(t, details.Groups, []string{"group1", "group2"})
@@ -1330,7 +1331,7 @@ func TestShouldNotUpdateUserPasswordConnect(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -1383,10 +1384,10 @@ func TestShouldNotUpdateUserPasswordConnect(t *testing.T) {
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
assert.EqualError(t, err, "unable to update password. Cause: dial failed with error: tcp timeout")
}
@@ -1397,7 +1398,7 @@ func TestShouldNotUpdateUserPasswordGetDetails(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -1460,10 +1461,10 @@ func TestShouldNotUpdateUserPasswordGetDetails(t *testing.T) {
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
assert.EqualError(t, err, "unable to update password. Cause: cannot find user DN of user 'john'. Cause: LDAP Result Code 2 \"Protocol Error\": permission error")
}
@@ -1474,7 +1475,7 @@ func TestShouldUpdateUserPassword(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -1567,10 +1568,10 @@ func TestShouldUpdateUserPassword(t *testing.T) {
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, modify, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
require.NoError(t, err)
}
@@ -1581,7 +1582,7 @@ func TestShouldUpdateUserPasswordMSAD(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
Implementation: "activedirectory",
URL: "ldap://127.0.0.1:389",
@@ -1676,10 +1677,10 @@ func TestShouldUpdateUserPasswordMSAD(t *testing.T) {
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, modify, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
require.NoError(t, err)
}
@@ -1691,7 +1692,7 @@ func TestShouldUpdateUserPasswordMSADWithReferrals(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl)
mockClientReferral := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
Implementation: "activedirectory",
URL: "ldap://127.0.0.1:389",
@@ -1805,10 +1806,10 @@ func TestShouldUpdateUserPasswordMSADWithReferrals(t *testing.T) {
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, modify, dialURLReferral, connBindReferral, modifyReferral, connCloseReferral, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
require.NoError(t, err)
}
@@ -1819,7 +1820,7 @@ func TestShouldUpdateUserPasswordMSADWithReferralsWithReferralConnectErr(t *test
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
Implementation: "activedirectory",
URL: "ldap://127.0.0.1:389",
@@ -1923,10 +1924,10 @@ func TestShouldUpdateUserPasswordMSADWithReferralsWithReferralConnectErr(t *test
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, modify, dialURLReferral, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
assert.EqualError(t, err, "unable to update password. Cause: error occurred connecting to referred LDAP server 'ldap://192.168.0.1': dial failed with error: tcp timeout. Original Error: LDAP Result Code 10 \"Referral\": error occurred")
}
@@ -1938,7 +1939,7 @@ func TestShouldUpdateUserPasswordMSADWithReferralsWithReferralModifyErr(t *testi
mockClient := NewMockLDAPClient(ctrl)
mockClientReferral := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
Implementation: "activedirectory",
URL: "ldap://127.0.0.1:389",
@@ -2056,10 +2057,10 @@ func TestShouldUpdateUserPasswordMSADWithReferralsWithReferralModifyErr(t *testi
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, modify, dialURLReferral, connBindReferral, modifyReferral, connCloseReferral, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
assert.EqualError(t, err, "unable to update password. Cause: error occurred performing modify on referred LDAP server 'ldap://192.168.0.1': LDAP Result Code 51 \"Busy\": error occurred. Original Error: LDAP Result Code 10 \"Referral\": error occurred")
}
@@ -2070,7 +2071,7 @@ func TestShouldUpdateUserPasswordMSADWithoutReferrals(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
Implementation: "activedirectory",
URL: "ldap://127.0.0.1:389",
@@ -2170,10 +2171,10 @@ func TestShouldUpdateUserPasswordMSADWithoutReferrals(t *testing.T) {
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, modify, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
assert.EqualError(t, err, "unable to update password. Cause: LDAP Result Code 10 \"Referral\": error occurred")
}
@@ -2184,7 +2185,7 @@ func TestShouldUpdateUserPasswordPasswdModifyExtension(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -2276,10 +2277,10 @@ func TestShouldUpdateUserPasswordPasswdModifyExtension(t *testing.T) {
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, passwdModify, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
require.NoError(t, err)
}
@@ -2291,7 +2292,7 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferrals(t *testing.T
mockClient := NewMockLDAPClient(ctrl)
mockClientReferral := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -2404,10 +2405,10 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferrals(t *testing.T
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, passwdModify, dialURLReferral, connBindReferral, passwdModifyReferral, connCloseReferral, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
require.NoError(t, err)
}
@@ -2418,7 +2419,7 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithoutReferrals(t *testin
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -2517,10 +2518,10 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithoutReferrals(t *testin
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, passwdModify, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
assert.EqualError(t, err, "unable to update password. Cause: LDAP Result Code 10 \"Referral\": error occurred")
}
@@ -2531,7 +2532,7 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferralsReferralConne
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -2634,10 +2635,10 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferralsReferralConne
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, passwdModify, dialURLReferral, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
assert.EqualError(t, err, "unable to update password. Cause: error occurred connecting to referred LDAP server 'ldap://192.168.0.1': dial failed with error: tcp timeout. Original Error: LDAP Result Code 10 \"Referral\": error occurred")
}
@@ -2649,7 +2650,7 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferralsReferralPassw
mockClient := NewMockLDAPClient(ctrl)
mockClientReferral := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -2766,10 +2767,10 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferralsReferralPassw
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, passwdModify, dialURLReferral, connBindReferral, passwdModifyReferral, connCloseReferral, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
assert.EqualError(t, err, "unable to update password. Cause: error occurred performing password modify on referred LDAP server 'ldap://192.168.0.1': LDAP Result Code 51 \"Busy\": too busy. Original Error: LDAP Result Code 10 \"Referral\": error occurred")
}
@@ -2780,7 +2781,7 @@ func TestShouldUpdateUserPasswordActiveDirectoryWithServerPolicyHints(t *testing
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
Implementation: "activedirectory",
URL: "ldap://127.0.0.1:389",
@@ -2877,10 +2878,10 @@ func TestShouldUpdateUserPasswordActiveDirectoryWithServerPolicyHints(t *testing
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, passwdModify, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
assert.NoError(t, err)
}
@@ -2891,7 +2892,7 @@ func TestShouldUpdateUserPasswordActiveDirectoryWithServerPolicyHintsDeprecated(
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
Implementation: "activedirectory",
URL: "ldap://127.0.0.1:389",
@@ -2988,10 +2989,10 @@ func TestShouldUpdateUserPasswordActiveDirectoryWithServerPolicyHintsDeprecated(
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, passwdModify, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
require.NoError(t, err)
}
@@ -3002,7 +3003,7 @@ func TestShouldUpdateUserPasswordActiveDirectory(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
Implementation: "activedirectory",
URL: "ldap://127.0.0.1:389",
@@ -3099,10 +3100,10 @@ func TestShouldUpdateUserPasswordActiveDirectory(t *testing.T) {
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, passwdModify, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
require.NoError(t, err)
}
@@ -3113,7 +3114,7 @@ func TestShouldUpdateUserPasswordBasic(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
Implementation: "custom",
URL: "ldap://127.0.0.1:389",
@@ -3207,10 +3208,10 @@ func TestShouldUpdateUserPasswordBasic(t *testing.T) {
gomock.InOrder(dialURLOIDs, connBindOIDs, searchOIDs, connCloseOIDs, dialURL, connBind, searchProfile, passwdModify, connClose)
- err := ldapClient.StartupCheck()
+ err := provider.StartupCheck()
require.NoError(t, err)
- err = ldapClient.UpdatePassword("john", "password")
+ err = provider.UpdatePassword("john", "password")
require.NoError(t, err)
}
@@ -3221,7 +3222,7 @@ func TestShouldReturnErrorWhenMultipleUsernameAttributes(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3271,10 +3272,10 @@ func TestShouldReturnErrorWhenMultipleUsernameAttributes(t *testing.T) {
gomock.InOrder(dialURL, bind, search)
- client, err := ldapClient.connect()
+ client, err := provider.connect()
assert.NoError(t, err)
- profile, err := ldapClient.getUserProfile(client, "john")
+ profile, err := provider.getUserProfile(client, "john")
assert.Nil(t, profile)
assert.EqualError(t, err, "user 'john' has 2 values for for attribute 'uid' but the attribute must be a single value attribute")
@@ -3287,7 +3288,7 @@ func TestShouldReturnErrorWhenZeroUsernameAttributes(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3337,10 +3338,10 @@ func TestShouldReturnErrorWhenZeroUsernameAttributes(t *testing.T) {
gomock.InOrder(dialURL, bind, search)
- client, err := ldapClient.connect()
+ client, err := provider.connect()
assert.NoError(t, err)
- profile, err := ldapClient.getUserProfile(client, "john")
+ profile, err := provider.getUserProfile(client, "john")
assert.Nil(t, profile)
assert.EqualError(t, err, "user 'john' must have value for attribute 'uid'")
@@ -3353,7 +3354,7 @@ func TestShouldReturnErrorWhenUsernameAttributeNotReturned(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3399,10 +3400,10 @@ func TestShouldReturnErrorWhenUsernameAttributeNotReturned(t *testing.T) {
gomock.InOrder(dialURL, bind, search)
- client, err := ldapClient.connect()
+ client, err := provider.connect()
assert.NoError(t, err)
- profile, err := ldapClient.getUserProfile(client, "john")
+ profile, err := provider.getUserProfile(client, "john")
assert.Nil(t, profile)
assert.EqualError(t, err, "user 'john' must have value for attribute 'uid'")
@@ -3415,7 +3416,7 @@ func TestShouldReturnErrorWhenMultipleUsersFound(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3482,10 +3483,10 @@ func TestShouldReturnErrorWhenMultipleUsersFound(t *testing.T) {
gomock.InOrder(dialURL, bind, search)
- client, err := ldapClient.connect()
+ client, err := provider.connect()
assert.NoError(t, err)
- profile, err := ldapClient.getUserProfile(client, "john")
+ profile, err := provider.getUserProfile(client, "john")
assert.Nil(t, profile)
assert.EqualError(t, err, "there were 2 users found when searching for 'john' but there should only be 1")
@@ -3498,7 +3499,7 @@ func TestShouldReturnErrorWhenNoDN(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3548,10 +3549,10 @@ func TestShouldReturnErrorWhenNoDN(t *testing.T) {
gomock.InOrder(dialURL, bind, search)
- client, err := ldapClient.connect()
+ client, err := provider.connect()
assert.NoError(t, err)
- profile, err := ldapClient.getUserProfile(client, "john")
+ profile, err := provider.getUserProfile(client, "john")
assert.Nil(t, profile)
assert.EqualError(t, err, "user 'john' must have a distinguished name but the result returned an empty distinguished name")
@@ -3564,7 +3565,7 @@ func TestShouldCheckValidUserPassword(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3619,7 +3620,7 @@ func TestShouldCheckValidUserPassword(t *testing.T) {
mockClient.EXPECT().Close().Times(2),
)
- valid, err := ldapClient.CheckUserPassword("john", "password")
+ valid, err := provider.CheckUserPassword("john", "password")
assert.True(t, valid)
require.NoError(t, err)
@@ -3632,7 +3633,7 @@ func TestShouldNotCheckValidUserPasswordWithConnectError(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3658,7 +3659,7 @@ func TestShouldNotCheckValidUserPasswordWithConnectError(t *testing.T) {
gomock.InOrder(dialURL, bind, mockClient.EXPECT().Close())
- valid, err := ldapClient.CheckUserPassword("john", "password")
+ valid, err := provider.CheckUserPassword("john", "password")
assert.False(t, valid)
assert.EqualError(t, err, "bind failed with error: LDAP Result Code 49 \"Invalid Credentials\": invalid username or password")
@@ -3671,7 +3672,7 @@ func TestShouldCheckInvalidUserPassword(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3726,7 +3727,7 @@ func TestShouldCheckInvalidUserPassword(t *testing.T) {
mockClient.EXPECT().Close().Times(2),
)
- valid, err := ldapClient.CheckUserPassword("john", "password")
+ valid, err := provider.CheckUserPassword("john", "password")
assert.False(t, valid)
require.EqualError(t, err, "authentication failed. Cause: bind failed with error: invalid username or password")
@@ -3739,7 +3740,7 @@ func TestShouldCallStartTLSWhenEnabled(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3765,7 +3766,7 @@ func TestShouldCallStartTLSWhenEnabled(t *testing.T) {
Return(nil)
connStartTLS := mockClient.EXPECT().
- StartTLS(ldapClient.tlsConfig)
+ StartTLS(provider.tlsConfig)
connClose := mockClient.EXPECT().Close()
@@ -3799,7 +3800,7 @@ func TestShouldCallStartTLSWhenEnabled(t *testing.T) {
gomock.InOrder(dialURL, connStartTLS, connBind, searchProfile, searchGroups, connClose)
- details, err := ldapClient.GetDetails("john")
+ details, err := provider.GetDetails("john")
require.NoError(t, err)
assert.ElementsMatch(t, details.Groups, []string{})
@@ -3814,7 +3815,7 @@ func TestShouldParseDynamicConfiguration(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3822,7 +3823,7 @@ func TestShouldParseDynamicConfiguration(t *testing.T) {
UsernameAttribute: "uid",
MailAttribute: "mail",
DisplayNameAttribute: "displayName",
- UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input})({display_name_attribute}={input}))(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)(!pwdLastSet=0))",
+ UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))(|(!(accountExpires=*))(accountExpires=0)(accountExpires>={date-time:msft-nt-epoch})(accountExpires>={date-time:generalized})))",
GroupsFilter: "(&(|(member={dn})(member={input})(member={username}))(objectClass=group))",
AdditionalUsersDN: "ou=users",
AdditionalGroupsDN: "ou=groups",
@@ -3833,16 +3834,27 @@ func TestShouldParseDynamicConfiguration(t *testing.T) {
nil,
mockFactory)
- assert.True(t, ldapClient.groupsFilterReplacementInput)
- assert.True(t, ldapClient.groupsFilterReplacementUsername)
- assert.True(t, ldapClient.groupsFilterReplacementDN)
+ clock := &utils.TestingClock{}
- assert.True(t, ldapClient.usersFilterReplacementInput)
+ provider.clock = clock
- assert.Equal(t, "(&(|(uid={input})(mail={input})(displayName={input}))(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)(!pwdLastSet=0))", ldapClient.config.UsersFilter)
- assert.Equal(t, "(&(|(member={dn})(member={input})(member={username}))(objectClass=group))", ldapClient.config.GroupsFilter)
- assert.Equal(t, "ou=users,dc=example,dc=com", ldapClient.usersBaseDN)
- assert.Equal(t, "ou=groups,dc=example,dc=com", ldapClient.groupsBaseDN)
+ clock.Set(time.Unix(1670250519, 0))
+
+ assert.True(t, provider.groupsFilterReplacementInput)
+ assert.True(t, provider.groupsFilterReplacementUsername)
+ assert.True(t, provider.groupsFilterReplacementDN)
+
+ assert.True(t, provider.usersFilterReplacementInput)
+ assert.True(t, provider.usersFilterReplacementDateTimeGeneralized)
+ assert.True(t, provider.usersFilterReplacementDateTimeMicrosoftNTTimeEpoch)
+
+ assert.Equal(t, "(&(|(uid={input})(mail={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))(|(!(accountExpires=*))(accountExpires=0)(accountExpires>={date-time:msft-nt-epoch})(accountExpires>={date-time:generalized})))", provider.config.UsersFilter)
+ assert.Equal(t, "(&(|(member={dn})(member={input})(member={username}))(objectClass=group))", provider.config.GroupsFilter)
+ assert.Equal(t, "ou=users,dc=example,dc=com", provider.usersBaseDN)
+ assert.Equal(t, "ou=groups,dc=example,dc=com", provider.groupsBaseDN)
+
+ assert.Equal(t, "(&(|(uid=test@example.com)(mail=test@example.com))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))(|(!(accountExpires=*))(accountExpires=0)(accountExpires>=133147241190000000)(accountExpires>=20221205142839.0Z)))", provider.resolveUsersFilter("test@example.com"))
+ assert.Equal(t, "(&(|(member=cn=admin,dc=example,dc=com)(member=test@example.com)(member=test))(objectClass=group))", provider.resolveGroupsFilter("test@example.com", &ldapUserProfile{Username: "test", DN: "cn=admin,dc=example,dc=com"}))
}
func TestShouldCallStartTLSWithInsecureSkipVerifyWhenSkipVerifyTrue(t *testing.T) {
@@ -3852,7 +3864,7 @@ func TestShouldCallStartTLSWithInsecureSkipVerifyWhenSkipVerifyTrue(t *testing.T
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldap://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3872,9 +3884,9 @@ func TestShouldCallStartTLSWithInsecureSkipVerifyWhenSkipVerifyTrue(t *testing.T
nil,
mockFactory)
- assert.False(t, ldapClient.groupsFilterReplacementInput)
- assert.False(t, ldapClient.groupsFilterReplacementUsername)
- assert.False(t, ldapClient.groupsFilterReplacementDN)
+ assert.False(t, provider.groupsFilterReplacementInput)
+ assert.False(t, provider.groupsFilterReplacementUsername)
+ assert.False(t, provider.groupsFilterReplacementDN)
dialURL := mockFactory.EXPECT().
DialURL(gomock.Eq("ldap://127.0.0.1:389"), gomock.Any()).
@@ -3885,7 +3897,7 @@ func TestShouldCallStartTLSWithInsecureSkipVerifyWhenSkipVerifyTrue(t *testing.T
Return(nil)
connStartTLS := mockClient.EXPECT().
- StartTLS(ldapClient.tlsConfig)
+ StartTLS(provider.tlsConfig)
connClose := mockClient.EXPECT().Close()
@@ -3919,7 +3931,7 @@ func TestShouldCallStartTLSWithInsecureSkipVerifyWhenSkipVerifyTrue(t *testing.T
gomock.InOrder(dialURL, connStartTLS, connBind, searchProfile, searchGroups, connClose)
- details, err := ldapClient.GetDetails("john")
+ details, err := provider.GetDetails("john")
require.NoError(t, err)
assert.ElementsMatch(t, details.Groups, []string{})
@@ -3935,7 +3947,7 @@ func TestShouldReturnLDAPSAlreadySecuredWhenStartTLSAttempted(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl)
mockClient := NewMockLDAPClient(ctrl)
- ldapClient := newLDAPUserProvider(
+ provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{
URL: "ldaps://127.0.0.1:389",
User: "cn=admin,dc=example,dc=com",
@@ -3960,11 +3972,11 @@ func TestShouldReturnLDAPSAlreadySecuredWhenStartTLSAttempted(t *testing.T) {
Return(mockClient, nil)
connStartTLS := mockClient.EXPECT().
- StartTLS(ldapClient.tlsConfig).
+ StartTLS(provider.tlsConfig).
Return(errors.New("LDAP Result Code 200 \"Network Error\": ldap: already encrypted"))
gomock.InOrder(dialURL, connStartTLS, mockClient.EXPECT().Close())
- _, err := ldapClient.GetDetails("john")
+ _, err := provider.GetDetails("john")
assert.EqualError(t, err, "starttls failed with error: LDAP Result Code 200 \"Network Error\": ldap: already encrypted")
}
diff --git a/internal/configuration/schema/authentication.go b/internal/configuration/schema/authentication.go
index 1d7bf181b..d830071ac 100644
--- a/internal/configuration/schema/authentication.go
+++ b/internal/configuration/schema/authentication.go
@@ -187,7 +187,7 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationCustom = LDAPAuth
// DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory represents the default LDAP config for the LDAPImplementationActiveDirectory Implementation.
var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory = LDAPAuthenticationBackend{
- UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0)))",
+ UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))(|(!(accountExpires=*))(accountExpires=0)(accountExpires>={date-time:msft-nt-epoch})))",
UsernameAttribute: "sAMAccountName",
MailAttribute: ldapAttrMail,
DisplayNameAttribute: ldapAttrDisplayName,
@@ -201,7 +201,7 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory =
// DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA represents the default LDAP config for the LDAPImplementationFreeIPA Implementation.
var DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA = LDAPAuthenticationBackend{
- UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)(!(nsAccountLock=TRUE)))",
+ UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)(!(nsAccountLock=TRUE))(krbPasswordExpiration>={date-time:generalized})(|(!(krbPrincipalExpiration=*))(krbPrincipalExpiration>={date-time:generalized})))",
UsernameAttribute: ldapAttrUserID,
MailAttribute: ldapAttrMail,
DisplayNameAttribute: ldapAttrDisplayName,
diff --git a/internal/handlers/handler_verify_test.go b/internal/handlers/handler_verify_test.go
index a0ef56858..518ac7ec0 100644
--- a/internal/handlers/handler_verify_test.go
+++ b/internal/handlers/handler_verify_test.go
@@ -702,7 +702,7 @@ func TestShouldDestroySessionWhenInactiveForTooLong(t *testing.T) {
mock := mocks.NewMockAutheliaCtx(t)
defer mock.Close()
- clock := mocks.TestingClock{}
+ clock := utils.TestingClock{}
clock.Set(time.Now())
past := clock.Now().Add(-1 * time.Hour)
@@ -736,7 +736,7 @@ func TestShouldDestroySessionWhenInactiveForTooLongUsingDurationNotation(t *test
mock := mocks.NewMockAutheliaCtx(t)
defer mock.Close()
- clock := mocks.TestingClock{}
+ clock := utils.TestingClock{}
clock.Set(time.Now())
mock.Ctx.Configuration.Session.Inactivity = time.Second * 10
@@ -833,7 +833,7 @@ func TestShouldRedirectWhenSessionInactiveForTooLongAndRDParamProvided(t *testin
mock := mocks.NewMockAutheliaCtx(t)
defer mock.Close()
- clock := mocks.TestingClock{}
+ clock := utils.TestingClock{}
clock.Set(time.Now())
mock.Ctx.Configuration.Session.Inactivity = testInactivity
@@ -1055,7 +1055,7 @@ func TestShouldNotRefreshUserGroupsFromBackend(t *testing.T) {
mock.UserProviderMock.EXPECT().GetDetails("john").Times(0)
- clock := mocks.TestingClock{}
+ clock := utils.TestingClock{}
clock.Set(time.Now())
userSession := mock.Ctx.GetSession()
@@ -1115,7 +1115,7 @@ func TestShouldNotRefreshUserGroupsFromBackendWhenDisabled(t *testing.T) {
mock.UserProviderMock.EXPECT().GetDetails("john").Times(0)
- clock := mocks.TestingClock{}
+ clock := utils.TestingClock{}
clock.Set(time.Now())
userSession := mock.Ctx.GetSession()
@@ -1161,7 +1161,7 @@ func TestShouldDestroySessionWhenUserNotExist(t *testing.T) {
mock.UserProviderMock.EXPECT().GetDetails("john").Return(user, nil).Times(1)
- clock := mocks.TestingClock{}
+ clock := utils.TestingClock{}
clock.Set(time.Now())
userSession := mock.Ctx.GetSession()
@@ -1222,7 +1222,7 @@ func TestShouldGetRemovedUserGroupsFromBackend(t *testing.T) {
mock.UserProviderMock.EXPECT().GetDetails("john").Return(user, nil).Times(2)
- clock := mocks.TestingClock{}
+ clock := utils.TestingClock{}
clock.Set(time.Now())
userSession := mock.Ctx.GetSession()
@@ -1431,7 +1431,7 @@ func TestShouldNotRedirectRequestsForBypassACLWhenInactiveForTooLong(t *testing.
mock := mocks.NewMockAutheliaCtx(t)
defer mock.Close()
- clock := mocks.TestingClock{}
+ clock := utils.TestingClock{}
clock.Set(time.Now())
past := clock.Now().Add(-1 * time.Hour)
diff --git a/internal/mocks/authelia_ctx.go b/internal/mocks/authelia_ctx.go
index 22c0f5003..26a4a876f 100644
--- a/internal/mocks/authelia_ctx.go
+++ b/internal/mocks/authelia_ctx.go
@@ -19,6 +19,7 @@ import (
"github.com/authelia/authelia/v4/internal/regulation"
"github.com/authelia/authelia/v4/internal/session"
"github.com/authelia/authelia/v4/internal/templates"
+ "github.com/authelia/authelia/v4/internal/utils"
)
// MockAutheliaCtx a mock of AutheliaCtx.
@@ -36,33 +37,13 @@ type MockAutheliaCtx struct {
UserSession *session.UserSession
- Clock TestingClock
-}
-
-// TestingClock implementation of clock for tests.
-type TestingClock struct {
- now time.Time
-}
-
-// Now return the stored clock.
-func (dc *TestingClock) Now() time.Time {
- return dc.now
-}
-
-// After return a channel receiving the time after duration has elapsed.
-func (dc *TestingClock) After(d time.Duration) <-chan time.Time {
- return time.After(d)
-}
-
-// Set set the time of the clock.
-func (dc *TestingClock) Set(now time.Time) {
- dc.now = now
+ Clock utils.TestingClock
}
// NewMockAutheliaCtx create an instance of AutheliaCtx mock.
func NewMockAutheliaCtx(t *testing.T) *MockAutheliaCtx {
mockAuthelia := new(MockAutheliaCtx)
- mockAuthelia.Clock = TestingClock{}
+ mockAuthelia.Clock = utils.TestingClock{}
datetime, _ := time.Parse("2006-Jan-02", "2013-Feb-03")
mockAuthelia.Clock.Set(datetime)
diff --git a/internal/regulation/regulator_test.go b/internal/regulation/regulator_test.go
index 37f371169..6b61be4da 100644
--- a/internal/regulation/regulator_test.go
+++ b/internal/regulation/regulator_test.go
@@ -13,6 +13,7 @@ import (
"github.com/authelia/authelia/v4/internal/mocks"
"github.com/authelia/authelia/v4/internal/model"
"github.com/authelia/authelia/v4/internal/regulation"
+ "github.com/authelia/authelia/v4/internal/utils"
)
type RegulatorSuite struct {
@@ -22,7 +23,7 @@ type RegulatorSuite struct {
ctrl *gomock.Controller
storageMock *mocks.MockStorage
config schema.RegulationConfiguration
- clock mocks.TestingClock
+ clock utils.TestingClock
}
func (s *RegulatorSuite) SetupTest() {
diff --git a/internal/utils/clock.go b/internal/utils/clock.go
index 388275f3d..9b5cc423f 100644
--- a/internal/utils/clock.go
+++ b/internal/utils/clock.go
@@ -20,3 +20,23 @@ func (RealClock) Now() time.Time {
func (RealClock) After(d time.Duration) <-chan time.Time {
return time.After(d)
}
+
+// TestingClock implementation of clock for tests.
+type TestingClock struct {
+ now time.Time
+}
+
+// Now return the stored clock.
+func (dc *TestingClock) Now() time.Time {
+ return dc.now
+}
+
+// After return a channel receiving the time after duration has elapsed.
+func (dc *TestingClock) After(d time.Duration) <-chan time.Time {
+ return time.After(d)
+}
+
+// Set set the time of the clock.
+func (dc *TestingClock) Set(now time.Time) {
+ dc.now = now
+}
diff --git a/internal/utils/const.go b/internal/utils/const.go
index 1188b5f9c..2e65da318 100644
--- a/internal/utils/const.go
+++ b/internal/utils/const.go
@@ -8,24 +8,9 @@ import (
)
const (
- windows = "windows"
- testStringInput = "abcdefghijkl"
-
// RFC3339Zero is the default value for time.Time.Unix().
RFC3339Zero = int64(-62135596800)
- // TLS13 is the textual representation of TLS 1.3.
- TLS13 = "1.3"
-
- // TLS12 is the textual representation of TLS 1.2.
- TLS12 = "1.2"
-
- // TLS11 is the textual representation of TLS 1.1.
- TLS11 = "1.1"
-
- // TLS10 is the textual representation of TLS 1.0.
- TLS10 = "1.0"
-
clean = "clean"
tagged = "tagged"
unknown = "unknown"
@@ -84,10 +69,6 @@ const (
Month = Year / 12
)
-const (
- errFmtLinuxNotFound = "open %s: no such file or directory"
-)
-
var (
standardDurationUnits = []string{"ns", "us", "µs", "μs", "ms", "s", "m", "h"}
reDurationSeconds = regexp.MustCompile(`^\d+$`)
@@ -111,6 +92,12 @@ const (
)
const (
+ // timeUnixEpochAsMicrosoftNTEpoch represents the unix epoch as a Microsoft NT Epoch.
+ // The Microsoft NT Epoch is ticks since Jan 1, 1601 (1 tick is 100ns).
+ timeUnixEpochAsMicrosoftNTEpoch uint64 = 116444736000000000
+)
+
+const (
// CharSetAlphabeticLower are literally just valid alphabetic lowercase printable ASCII chars.
CharSetAlphabeticLower = "abcdefghijklmnopqrstuvwxyz"
@@ -155,5 +142,7 @@ var htmlEscaper = strings.NewReplacer(
// ErrTimeoutReached error thrown when a timeout is reached.
var ErrTimeoutReached = errors.New("timeout reached")
-// ErrTLSVersionNotSupported returned when an unknown TLS version supplied.
-var ErrTLSVersionNotSupported = errors.New("supplied tls version isn't supported")
+const (
+ windows = "windows"
+ errFmtLinuxNotFound = "open %s: no such file or directory"
+)
diff --git a/internal/utils/const_test.go b/internal/utils/const_test.go
new file mode 100644
index 000000000..879485536
--- /dev/null
+++ b/internal/utils/const_test.go
@@ -0,0 +1,5 @@
+package utils
+
+const (
+ testStringInput = "abcdefghijkl"
+)
diff --git a/internal/utils/time.go b/internal/utils/time.go
index 51952fcdc..4844e108e 100644
--- a/internal/utils/time.go
+++ b/internal/utils/time.go
@@ -67,3 +67,8 @@ func ParseDurationString(input string) (duration time.Duration, err error) {
return time.ParseDuration(out)
}
+
+// UnixNanoTimeToMicrosoftNTEpoch converts a unix timestamp in nanosecond format to win32 epoch format.
+func UnixNanoTimeToMicrosoftNTEpoch(nano int64) (t uint64) {
+ return uint64(nano/100) + timeUnixEpochAsMicrosoftNTEpoch
+}
diff --git a/internal/utils/time_test.go b/internal/utils/time_test.go
index f75871ec8..4cd651c9c 100644
--- a/internal/utils/time_test.go
+++ b/internal/utils/time_test.go
@@ -122,3 +122,11 @@ func TestShouldTimeIntervalsMakeSense(t *testing.T) {
assert.Equal(t, Year, Day*365)
assert.Equal(t, Month, Year/12)
}
+
+func TestShouldConvertKnownUnixNanoTimeToKnownWin32Epoch(t *testing.T) {
+ exampleNanoTime := int64(1626234411 * 1000000000)
+ win32Epoch := uint64(132707080110000000)
+
+ assert.Equal(t, win32Epoch, UnixNanoTimeToMicrosoftNTEpoch(exampleNanoTime))
+ assert.Equal(t, timeUnixEpochAsMicrosoftNTEpoch, UnixNanoTimeToMicrosoftNTEpoch(0))
+}