summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorJames Elliott <james-d-elliott@users.noreply.github.com>2023-11-30 19:45:24 +1100
committerJames Elliott <james-d-elliott@users.noreply.github.com>2024-03-04 20:29:12 +1100
commite4e878f05f8ae1e1784b3ac190459b2d506f796c (patch)
treeed8f5b927156300dddff33f3e14bc732803ea405 /internal
parent61c30b373f8c5ee14321e82c8d7210aae7d260c3 (diff)
build(deps): use go.uber.org/mock
Use the new go.uber.org/mock which is currently maintained. Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
Diffstat (limited to 'internal')
-rw-r--r--internal/authentication/file_user_provider_database_mock_test.go2
-rw-r--r--internal/authentication/file_user_provider_hash_mock_test.go2
-rw-r--r--internal/authentication/file_user_provider_test.go2
-rw-r--r--internal/authentication/ldap_client_factory_mock_test.go2
-rw-r--r--internal/authentication/ldap_client_mock_test.go2
-rw-r--r--internal/authentication/ldap_user_provider_test.go2
-rw-r--r--internal/handlers/const.go34
-rw-r--r--internal/handlers/func_test.go51
-rw-r--r--internal/handlers/handler_authz_impl_legacy_test.go2
-rw-r--r--internal/handlers/handler_authz_test.go2
-rw-r--r--internal/handlers/handler_firstfactor_test.go26
-rw-r--r--internal/handlers/handler_register_duo_device_test.go2
-rw-r--r--internal/handlers/handler_register_totp.go138
-rw-r--r--internal/handlers/handler_register_totp_test.go121
-rw-r--r--internal/handlers/handler_register_webauthn.go32
-rw-r--r--internal/handlers/handler_register_webauthn_test.go12
-rwxr-xr-xinternal/handlers/handler_session_elevation.go36
-rw-r--r--internal/handlers/handler_session_elevation_test.go20
-rw-r--r--internal/handlers/handler_sign_duo_test.go2
-rw-r--r--internal/handlers/handler_sign_totp.go128
-rw-r--r--internal/handlers/handler_sign_totp_test.go572
-rw-r--r--internal/handlers/handler_sign_webauthn.go43
-rw-r--r--internal/handlers/handler_sign_webauthn_test.go22
-rw-r--r--internal/handlers/handler_user_info_test.go2
-rw-r--r--internal/handlers/handler_webauthn_credentials.go81
-rw-r--r--internal/handlers/handler_webauthn_credentials_test.go161
-rw-r--r--internal/handlers/webauthn_test.go2
-rw-r--r--internal/middlewares/authelia_context_test.go2
-rw-r--r--internal/middlewares/identity_verification_test.go2
-rw-r--r--internal/mocks/authelia_ctx.go20
-rw-r--r--internal/mocks/duo_api.go14
-rw-r--r--internal/mocks/fosite_access_requester.go26
-rw-r--r--internal/mocks/fosite_access_token_strategy.go14
-rw-r--r--internal/mocks/fosite_client_credentials_grant_storage.go14
-rw-r--r--internal/mocks/fosite_pkce_request_storage.go14
-rw-r--r--internal/mocks/fosite_storage.go14
-rw-r--r--internal/mocks/fosite_token_introspector.go10
-rw-r--r--internal/mocks/fosite_token_revocation_storage.go26
-rw-r--r--internal/mocks/fosite_transactional.go14
-rw-r--r--internal/mocks/notifier.go12
-rw-r--r--internal/mocks/random.go28
-rw-r--r--internal/mocks/storage.go175
-rw-r--r--internal/mocks/totp.go21
-rw-r--r--internal/mocks/user_provider.go14
-rw-r--r--internal/model/oidc_test.go2
-rw-r--r--internal/model/totp_configuration.go15
-rw-r--r--internal/oidc/client_credentials_test.go2
-rw-r--r--internal/oidc/flow_client_credentials_test.go2
-rw-r--r--internal/oidc/flow_refresh_test.go2
-rw-r--r--internal/oidc/handler_introspection_test.go2
-rw-r--r--internal/oidc/store_test.go2
-rw-r--r--internal/regulation/regulator_test.go2
-rw-r--r--internal/storage/const.go1
-rw-r--r--internal/storage/migrations/mysql/V0013.OneTimeCode.up.sql3
-rw-r--r--internal/storage/migrations/mysql/V0015.TOTPEnhance.down.sql1
-rw-r--r--internal/storage/migrations/mysql/V0015.TOTPEnhance.up.sql8
-rw-r--r--internal/storage/migrations/postgres/V0013.OneTimeCode.up.sql1
-rw-r--r--internal/storage/migrations/postgres/V0015.TOTPEnhance.down.sql1
-rw-r--r--internal/storage/migrations/postgres/V0015.TOTPEnhance.up.sql8
-rw-r--r--internal/storage/migrations/sqlite/V0013.OneTimeCode.up.sql1
-rw-r--r--internal/storage/migrations/sqlite/V0015.TOTPEnhance.down.sql1
-rw-r--r--internal/storage/migrations/sqlite/V0015.TOTPEnhance.up.sql8
-rw-r--r--internal/storage/migrations_test.go2
-rw-r--r--internal/storage/provider.go10
-rw-r--r--internal/storage/sql_provider.go32
-rw-r--r--internal/storage/sql_provider_backend_postgres.go3
-rw-r--r--internal/storage/sql_provider_queries.go11
-rw-r--r--internal/suites/action_totp.go4
-rw-r--r--internal/suites/suites_credentials.go2
-rw-r--r--internal/totp/helpers.go2
-rw-r--r--internal/totp/helpers_test.go2
-rw-r--r--internal/totp/provider.go2
-rw-r--r--internal/totp/totp.go12
73 files changed, 1447 insertions, 618 deletions
diff --git a/internal/authentication/file_user_provider_database_mock_test.go b/internal/authentication/file_user_provider_database_mock_test.go
index fde875135..dfdda0c63 100644
--- a/internal/authentication/file_user_provider_database_mock_test.go
+++ b/internal/authentication/file_user_provider_database_mock_test.go
@@ -7,7 +7,7 @@ package authentication
import (
reflect "reflect"
- gomock "github.com/golang/mock/gomock"
+ gomock "go.uber.org/mock/gomock"
)
// MockFileUserDatabase is a mock of FileUserProviderDatabase interface.
diff --git a/internal/authentication/file_user_provider_hash_mock_test.go b/internal/authentication/file_user_provider_hash_mock_test.go
index fb78a32c4..915cf3cf7 100644
--- a/internal/authentication/file_user_provider_hash_mock_test.go
+++ b/internal/authentication/file_user_provider_hash_mock_test.go
@@ -8,7 +8,7 @@ import (
reflect "reflect"
algorithm "github.com/go-crypt/crypt/algorithm"
- gomock "github.com/golang/mock/gomock"
+ gomock "go.uber.org/mock/gomock"
)
// MockHash is a mock of Hash interface.
diff --git a/internal/authentication/file_user_provider_test.go b/internal/authentication/file_user_provider_test.go
index 0e8d1f8e9..f91501719 100644
--- a/internal/authentication/file_user_provider_test.go
+++ b/internal/authentication/file_user_provider_test.go
@@ -14,9 +14,9 @@ import (
"github.com/go-crypt/crypt/algorithm/bcrypt"
"github.com/go-crypt/crypt/algorithm/pbkdf2"
"github.com/go-crypt/crypt/algorithm/scrypt"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/configuration/schema"
)
diff --git a/internal/authentication/ldap_client_factory_mock_test.go b/internal/authentication/ldap_client_factory_mock_test.go
index d6cb41226..48fb070af 100644
--- a/internal/authentication/ldap_client_factory_mock_test.go
+++ b/internal/authentication/ldap_client_factory_mock_test.go
@@ -8,7 +8,7 @@ import (
reflect "reflect"
v3 "github.com/go-ldap/ldap/v3"
- gomock "github.com/golang/mock/gomock"
+ gomock "go.uber.org/mock/gomock"
)
// MockLDAPClientFactory is a mock of LDAPClientFactory interface.
diff --git a/internal/authentication/ldap_client_mock_test.go b/internal/authentication/ldap_client_mock_test.go
index 5c996114d..6c8346f73 100644
--- a/internal/authentication/ldap_client_mock_test.go
+++ b/internal/authentication/ldap_client_mock_test.go
@@ -10,7 +10,7 @@ import (
time "time"
ldap "github.com/go-ldap/ldap/v3"
- gomock "github.com/golang/mock/gomock"
+ gomock "go.uber.org/mock/gomock"
)
// MockLDAPClient is a mock of LDAPClient interface.
diff --git a/internal/authentication/ldap_user_provider_test.go b/internal/authentication/ldap_user_provider_test.go
index 96c06b31f..0918aee5a 100644
--- a/internal/authentication/ldap_user_provider_test.go
+++ b/internal/authentication/ldap_user_provider_test.go
@@ -7,9 +7,9 @@ import (
"time"
"github.com/go-ldap/ldap/v3"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "go.uber.org/mock/gomock"
"golang.org/x/text/encoding/unicode"
"github.com/authelia/authelia/v4/internal/clock"
diff --git a/internal/handlers/const.go b/internal/handlers/const.go
index 75e6066a5..c6725fc14 100644
--- a/internal/handlers/const.go
+++ b/internal/handlers/const.go
@@ -1,6 +1,8 @@
package handlers
import (
+ "errors"
+
"github.com/valyala/fasthttp"
)
@@ -58,15 +60,17 @@ var (
)
const (
- messageOperationFailed = "Operation failed."
- messageAuthenticationFailed = "Authentication failed. Check your credentials."
- messageUnableToRegisterOneTimePassword = "Unable to set up one-time password." //nolint:gosec
- messageUnableToDeleteOneTimePassword = "Unable to delete one-time password." //nolint:gosec
- messageUnableToRegisterSecurityKey = "Unable to register your security key."
- messageSecurityKeyDuplicateName = "Another one of your security keys is already registered with that display name."
- messageUnableToResetPassword = "Unable to reset your password."
- messageMFAValidationFailed = "Authentication failed, please retry later."
- messagePasswordWeak = "Your supplied password does not meet the password policy requirements"
+ messageOperationFailed = "Operation failed."
+ messageAuthenticationFailed = "Authentication failed. Check your credentials."
+ messageUnableToOptionsOneTimePassword = "Unable to retrieve TOTP registration options." //nolint:gosec
+ messageUnableToRegisterOneTimePassword = "Unable to set up one-time password." //nolint:gosec
+ messageUnableToDeleteRegisterOneTimePassword = "Unable to delete one-time password registration session." //nolint:gosec
+ messageUnableToDeleteOneTimePassword = "Unable to delete one-time password."
+ messageUnableToRegisterSecurityKey = "Unable to register your security key."
+ messageSecurityKeyDuplicateName = "Another one of your security keys is already registered with that display name."
+ messageUnableToResetPassword = "Unable to reset your password."
+ messageMFAValidationFailed = "Authentication failed, please retry later."
+ messagePasswordWeak = "Your supplied password does not meet the password policy requirements"
)
const (
@@ -78,7 +82,6 @@ const (
logFmtActionRegistration = "registration"
logFmtErrParseRequestBody = "Failed to parse %s request body"
- logFmtErrWriteResponseBody = "Failed to write %s response body for user '%s'"
logFmtErrRegulationFail = "Failed to perform %s authentication regulation for user '%s'"
logFmtErrSessionRegenerate = "Could not regenerate session during %s authentication for user '%s'"
logFmtErrSessionReset = "Could not reset session during %s authentication for user '%s'"
@@ -139,3 +142,14 @@ var ldapPasswordComplexityErrors = []string{
"LDAP Result Code 19 \"Constraint Violation\": Password fails quality checking policy",
"LDAP Result Code 19 \"Constraint Violation\": Password is too young to change",
}
+
+const (
+ errStrReqBodyParse = "error parsing the request body"
+ errStrRespBody = "error occurred writing the response body"
+ errStrUserSessionData = "error occurred retrieving the user session data"
+ errStrUserSessionDataSave = "error occurred saving the user session data"
+)
+
+var (
+ errUserAnonymous = errors.New("user is anonymous")
+)
diff --git a/internal/handlers/func_test.go b/internal/handlers/func_test.go
new file mode 100644
index 000000000..9aa8a24de
--- /dev/null
+++ b/internal/handlers/func_test.go
@@ -0,0 +1,51 @@
+package handlers
+
+import (
+ "testing"
+
+ "github.com/sirupsen/logrus"
+ "github.com/sirupsen/logrus/hooks/test"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/authelia/authelia/v4/internal/middlewares"
+)
+
+func AssertLogEntryMessageAndError(t *testing.T, entry *logrus.Entry, message, err string) {
+ require.NotNil(t, entry)
+
+ assert.Equal(t, message, entry.Message)
+
+ v, ok := entry.Data["error"]
+
+ if err == "" {
+ assert.False(t, ok)
+ assert.Nil(t, v)
+ } else {
+ assert.True(t, ok)
+ require.NotNil(t, v)
+
+ theErr, ok := v.(error)
+ assert.True(t, ok)
+ require.NotNil(t, theErr)
+
+ assert.EqualError(t, theErr, err)
+ }
+}
+
+func MustGetLogLastSeq(t *testing.T, hook *test.Hook, seq int) *logrus.Entry {
+ require.Greater(t, len(hook.Entries), seq)
+
+ return &hook.Entries[len(hook.Entries)-1-seq]
+}
+
+//nolint:unparam
+func getStepTOTP(ctx *middlewares.AutheliaCtx, period int) uint64 {
+ step := ctx.Clock.Now().Unix()
+
+ if period < 0 {
+ period = ctx.Configuration.TOTP.DefaultPeriod
+ }
+
+ return uint64(int(step) / period)
+}
diff --git a/internal/handlers/handler_authz_impl_legacy_test.go b/internal/handlers/handler_authz_impl_legacy_test.go
index 30949e387..f7adfbff7 100644
--- a/internal/handlers/handler_authz_impl_legacy_test.go
+++ b/internal/handlers/handler_authz_impl_legacy_test.go
@@ -7,10 +7,10 @@ import (
"strings"
"testing"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/authorization"
diff --git a/internal/handlers/handler_authz_test.go b/internal/handlers/handler_authz_test.go
index 19d670400..368091977 100644
--- a/internal/handlers/handler_authz_test.go
+++ b/internal/handlers/handler_authz_test.go
@@ -6,10 +6,10 @@ import (
"testing"
"time"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/configuration/schema"
diff --git a/internal/handlers/handler_firstfactor_test.go b/internal/handlers/handler_firstfactor_test.go
index 3c046ea4a..6d17a71b9 100644
--- a/internal/handlers/handler_firstfactor_test.go
+++ b/internal/handlers/handler_firstfactor_test.go
@@ -5,12 +5,10 @@ import (
"net/url"
"testing"
- "github.com/golang/mock/gomock"
- "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/authorization"
@@ -464,25 +462,3 @@ func TestFirstFactorSuite(t *testing.T) {
suite.Run(t, new(FirstFactorSuite))
suite.Run(t, new(FirstFactorRedirectionSuite))
}
-
-func AssertLogEntryMessageAndError(t *testing.T, entry *logrus.Entry, message, err string) {
- require.NotNil(t, entry)
-
- assert.Equal(t, message, entry.Message)
-
- v, ok := entry.Data["error"]
-
- if err == "" {
- assert.False(t, ok)
- assert.Nil(t, v)
- } else {
- assert.True(t, ok)
- require.NotNil(t, v)
-
- theErr, ok := v.(error)
- assert.True(t, ok)
- require.NotNil(t, theErr)
-
- assert.EqualError(t, theErr, err)
- }
-}
diff --git a/internal/handlers/handler_register_duo_device_test.go b/internal/handlers/handler_register_duo_device_test.go
index 84988c602..ee26511df 100644
--- a/internal/handlers/handler_register_duo_device_test.go
+++ b/internal/handlers/handler_register_duo_device_test.go
@@ -5,11 +5,11 @@ import (
"net/url"
"testing"
- "github.com/golang/mock/gomock"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/duo"
"github.com/authelia/authelia/v4/internal/mocks"
diff --git a/internal/handlers/handler_register_totp.go b/internal/handlers/handler_register_totp.go
index 9eee6b219..d5830e010 100644
--- a/internal/handlers/handler_register_totp.go
+++ b/internal/handlers/handler_register_totp.go
@@ -2,6 +2,7 @@ package handlers
import (
"encoding/json"
+ "fmt"
"time"
"github.com/valyala/fasthttp"
@@ -15,8 +16,34 @@ import (
// TOTPRegisterGET returns the registration specific options.
func TOTPRegisterGET(ctx *middlewares.AutheliaCtx) {
- if err := ctx.SetJSONBody(ctx.Providers.TOTP.Options()); err != nil {
- ctx.Logger.Errorf("Unable to set TOTP options response in body: %s", err)
+ var (
+ userSession session.UserSession
+ err error
+ )
+
+ if userSession, err = ctx.GetSession(); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred retrieving TOTP registration options: %s", errStrUserSessionData)
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToOptionsOneTimePassword)
+
+ return
+ }
+
+ if userSession.IsAnonymous() {
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred retrieving TOTP registration options")
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToOptionsOneTimePassword)
+
+ return
+ }
+
+ if err = ctx.SetJSONBody(ctx.Providers.TOTP.Options()); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred retrieving TOTP registration options for user '%s': %s", userSession.Username, errStrRespBody)
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToOptionsOneTimePassword)
}
}
@@ -29,28 +56,28 @@ func TOTPRegisterPUT(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred retrieving session for %s registration", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a TOTP registration session: %s", errStrUserSessionData)
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
}
if userSession.IsAnonymous() {
- ctx.Logger.Errorf("Error occurred handling request: anonymous user attempted %s registration", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred generating a TOTP registration session")
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
}
if err = json.Unmarshal(ctx.PostBody(), &bodyJSON); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred unmarshaling body %s registration", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a TOTP registration session for user '%s': %s", userSession.Username, errStrReqBodyParse)
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusBadRequest)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
}
@@ -60,10 +87,10 @@ func TOTPRegisterPUT(ctx *middlewares.AutheliaCtx) {
if !utils.IsStringInSlice(bodyJSON.Algorithm, opts.Algorithms) ||
!utils.IsIntegerInSlice(bodyJSON.Period, opts.Periods) ||
!utils.IsIntegerInSlice(bodyJSON.Length, opts.Lengths) {
- ctx.Logger.Errorf("Validation failed for %s registration because the input options were not permitted by the configuration", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(fmt.Errorf("the algorithm '%s', period '%d', or length '%d' was not permitted by configured policy", bodyJSON.Algorithm, bodyJSON.Period, bodyJSON.Length)).Errorf("Error occurred generating a TOTP registration session for user '%s': error occurred validating registration options selection", userSession.Username)
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusBadRequest)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
}
@@ -71,8 +98,9 @@ func TOTPRegisterPUT(ctx *middlewares.AutheliaCtx) {
var config *model.TOTPConfiguration
if config, err = ctx.Providers.TOTP.GenerateCustom(userSession.Username, bodyJSON.Algorithm, "", uint(bodyJSON.Length), uint(bodyJSON.Period), 0); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred generating TOTP configuration")
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a TOTP registration session for user '%s': error generating TOTP configuration", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
@@ -88,8 +116,9 @@ func TOTPRegisterPUT(ctx *middlewares.AutheliaCtx) {
}
if err = ctx.SaveSession(userSession); err != nil {
- ctx.Logger.WithError(err).Errorf(logFmtErrSessionSave, "pending TOTP configuration", regulation.AuthTypeTOTP, logFmtActionRegistration, userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a TOTP registration session for user '%s': %s", userSession.Username, errStrUserSessionDataSave)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
@@ -101,7 +130,10 @@ func TOTPRegisterPUT(ctx *middlewares.AutheliaCtx) {
}
if err = ctx.SetJSONBody(response); err != nil {
- ctx.Logger.WithError(err).Errorf("Unable to set TOTP key response in body")
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a TOTP registration session for user '%s': %s", userSession.Username, errStrRespBody)
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
}
}
@@ -111,50 +143,51 @@ func TOTPRegisterPOST(ctx *middlewares.AutheliaCtx) {
userSession session.UserSession
bodyJSON bodyRegisterFinishTOTP
valid bool
+ step uint64
err error
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred retrieving session for %s registration", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP registration session: %s", errStrUserSessionData)
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
}
if userSession.IsAnonymous() {
- ctx.Logger.Errorf("Error occurred handling request: anonymous user attempted %s registration", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred validating a TOTP registration session")
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
}
- if userSession.TOTP == nil {
- ctx.Logger.Errorf("Error occurred during %s registration: the user did not initiate a registration on their current session", regulation.AuthTypeTOTP)
+ if err = json.Unmarshal(ctx.PostBody(), &bodyJSON); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP registration session for user '%s': %s", userSession.Username, errStrReqBodyParse)
+ ctx.SetStatusCode(fasthttp.StatusBadRequest)
ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
- ctx.SetStatusCode(fasthttp.StatusForbidden)
return
}
- if ctx.Clock.Now().After(userSession.TOTP.Expires) {
- ctx.Logger.Errorf("Error occurred during %s registration: the registration is expired", regulation.AuthTypeTOTP)
+ if userSession.TOTP == nil {
+ ctx.Logger.Errorf("Error occurred validating a TOTP registration session for user '%s': the user did not initiate a registration session on their current session", userSession.Username)
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
}
- if err = json.Unmarshal(ctx.PostBody(), &bodyJSON); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred unmarshaling body %s registration", regulation.AuthTypeTOTP)
+ if ctx.Clock.Now().After(userSession.TOTP.Expires) {
+ ctx.Logger.WithError(fmt.Errorf("the registration session is expired")).Errorf("Error occurred validating a TOTP registration session for user '%s': error occurred validating the session", userSession.Username)
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
}
@@ -169,25 +202,37 @@ func TOTPRegisterPOST(ctx *middlewares.AutheliaCtx) {
Secret: []byte(userSession.TOTP.Secret),
}
- if valid, err = ctx.Providers.TOTP.Validate(bodyJSON.Token, &config); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred validating %s registration", regulation.AuthTypeTOTP)
+ if valid, step, err = ctx.Providers.TOTP.Validate(bodyJSON.Token, &config); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP registration session for user '%s': error occurred validating the user input against the session", userSession.Username)
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
- } else if !valid {
- ctx.Logger.Errorf("Error occurred validating %s registration", regulation.AuthTypeTOTP)
+ }
+
+ if !valid {
+ ctx.Logger.WithError(fmt.Errorf("user input did not match any expected value")).Errorf("Error occurred validating a TOTP registration session for user '%s'", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
+
+ return
+ }
+
+ if err = ctx.Providers.StorageProvider.SaveTOTPHistory(ctx, userSession.Username, step*uint64(config.Period)); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP registration session for user '%s': error occurred saving the TOTP history to the storage backend", userSession.Username)
+
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
}
if err = ctx.Providers.StorageProvider.SaveTOTPConfiguration(ctx, config); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred saving %s registration", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP registration session for user '%s': error occurred saving the TOTP configuration to the storage backend", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
@@ -196,8 +241,9 @@ func TOTPRegisterPOST(ctx *middlewares.AutheliaCtx) {
userSession.TOTP = nil
if err = ctx.SaveSession(userSession); err != nil {
- ctx.Logger.WithError(err).Errorf(logFmtErrSessionSave, "completed TOTP configuration", regulation.AuthTypeTOTP, logFmtActionRegistration, userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP registration session for user '%s': %s", userSession.Username, errStrUserSessionDataSave)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
return
@@ -216,19 +262,19 @@ func TOTPRegisterDELETE(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred retrieving session for %s registration cancel", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(err).Errorf("Error occurred deleting a TOTP registration session: %s", errStrUserSessionData)
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToDeleteRegisterOneTimePassword)
return
}
if userSession.IsAnonymous() {
- ctx.Logger.Errorf("Error occurred handling request: anonymous user attempted %s registration", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred deleting a TOTP registration session")
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToDeleteRegisterOneTimePassword)
return
}
@@ -244,7 +290,8 @@ func TOTPRegisterDELETE(ctx *middlewares.AutheliaCtx) {
if err = ctx.SaveSession(userSession); err != nil {
ctx.Logger.WithError(err).Errorf(logFmtErrSessionSave, "deleted pending TOTP configuration", regulation.AuthTypeTOTP, logFmtActionRegistration, userSession.Username)
- ctx.SetJSONError(messageUnableToRegisterOneTimePassword)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToDeleteRegisterOneTimePassword)
return
}
@@ -260,35 +307,36 @@ func TOTPConfigurationDELETE(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred retrieving session for %s configuration delete operation", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(err).Errorf("Error occurred deleting a TOTP configuration: %s", errStrUserSessionData)
- ctx.SetJSONError(messageUnableToDeleteOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToDeleteOneTimePassword)
return
}
if userSession.IsAnonymous() {
- ctx.Logger.Errorf("Error occurred handling request: anonymous user attempted %s removal", regulation.AuthTypeTOTP)
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred deleting a TOTP configuration")
- ctx.SetJSONError(messageUnableToDeleteOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToDeleteOneTimePassword)
return
}
if _, err = ctx.Providers.StorageProvider.LoadTOTPConfiguration(ctx, userSession.Username); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred loading from storage for %s configuration delete operation for user '%s'", regulation.AuthTypeTOTP, userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred deleting a TOTP configuration for user '%s': error occurred loading configuration from the storage backend", userSession.Username)
- ctx.SetJSONError(messageUnableToDeleteOneTimePassword)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageUnableToDeleteOneTimePassword)
return
}
if err = ctx.Providers.StorageProvider.DeleteTOTPConfiguration(ctx, userSession.Username); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred deleting from storage for %s configuration delete operation for user '%s'", regulation.AuthTypeTOTP, userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred deleting a TOTP configuration for user '%s': error occurred deleting configuration from the storage backend", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToDeleteOneTimePassword)
return
diff --git a/internal/handlers/handler_register_totp_test.go b/internal/handlers/handler_register_totp_test.go
index ffd7d1c79..c5ec482ac 100644
--- a/internal/handlers/handler_register_totp_test.go
+++ b/internal/handlers/handler_register_totp_test.go
@@ -6,10 +6,10 @@ import (
"testing"
"time"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/configuration/schema"
@@ -23,20 +23,58 @@ func TestShouldReturnTOTPRegisterOptions(t *testing.T) {
testCases := []struct {
name string
config schema.TOTP
+ setup func(t *testing.T, mock *mocks.MockAutheliaCtx)
expected string
expectedStatus int
+ expectedf func(t *testing.T, mock *mocks.MockAutheliaCtx)
}{
{
"ShouldHandleDefaults",
schema.DefaultTOTPConfiguration,
- "{\"status\":\"OK\",\"data\":{\"algorithm\":\"SHA1\",\"algorithms\":[\"SHA1\"],\"length\":6,\"lengths\":[6],\"period\":30,\"periods\":[30]}}",
+ func(t *testing.T, mock *mocks.MockAutheliaCtx) {
+ us, err := mock.Ctx.GetSession()
+
+ require.NoError(t, err)
+
+ us.Username = testUsername
+ us.AuthenticationLevel = authentication.OneFactor
+
+ require.NoError(t, mock.Ctx.SaveSession(us))
+
+ mock.TOTPMock.EXPECT().Options().Return(*totp.NewTOTPOptionsFromSchema(mock.Ctx.Configuration.TOTP))
+ },
+ `{"status":"OK","data":{"algorithm":"SHA1","algorithms":["SHA1"],"length":6,"lengths":[6],"period":30,"periods":[30]}}`,
fasthttp.StatusOK,
+ nil,
},
{
"ShouldHandleCustom",
schema.TOTP{DefaultAlgorithm: "SHA256", AllowedAlgorithms: []string{"SHA1", "SHA256"}, DefaultDigits: 6, AllowedDigits: []int{6, 8}, DefaultPeriod: 30, AllowedPeriods: []int{30, 60, 90}},
- "{\"status\":\"OK\",\"data\":{\"algorithm\":\"SHA256\",\"algorithms\":[\"SHA1\",\"SHA256\"],\"length\":6,\"lengths\":[6,8],\"period\":30,\"periods\":[30,60,90]}}",
+ func(t *testing.T, mock *mocks.MockAutheliaCtx) {
+ us, err := mock.Ctx.GetSession()
+
+ require.NoError(t, err)
+
+ us.Username = testUsername
+ us.AuthenticationLevel = authentication.OneFactor
+
+ require.NoError(t, mock.Ctx.SaveSession(us))
+
+ mock.TOTPMock.EXPECT().Options().Return(*totp.NewTOTPOptionsFromSchema(mock.Ctx.Configuration.TOTP))
+ },
+ `{"status":"OK","data":{"algorithm":"SHA256","algorithms":["SHA1","SHA256"],"length":6,"lengths":[6,8],"period":30,"periods":[30,60,90]}}`,
fasthttp.StatusOK,
+ nil,
+ },
+ {
+ "ShouldHandleAnonymous",
+ schema.TOTP{DefaultAlgorithm: "SHA256", AllowedAlgorithms: []string{"SHA1", "SHA256"}, DefaultDigits: 6, AllowedDigits: []int{6, 8}, DefaultPeriod: 30, AllowedPeriods: []int{30, 60, 90}},
+ nil,
+ `{"status":"KO","message":"Unable to retrieve TOTP registration options."}`,
+ fasthttp.StatusForbidden,
+ func(t *testing.T, mock *mocks.MockAutheliaCtx) {
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred retrieving TOTP registration options", "user is anonymous")
+ },
},
}
@@ -48,12 +86,18 @@ func TestShouldReturnTOTPRegisterOptions(t *testing.T) {
mock.Ctx.Configuration.TOTP = tc.config
- mock.TOTPMock.EXPECT().Options().Return(*totp.NewTOTPOptionsFromSchema(mock.Ctx.Configuration.TOTP))
+ if tc.setup != nil {
+ tc.setup(t, mock)
+ }
TOTPRegisterGET(mock.Ctx)
assert.Equal(t, tc.expectedStatus, mock.Ctx.Response.StatusCode())
assert.Equal(t, tc.expected, string(mock.Ctx.Response.Body()))
+
+ if tc.expectedf != nil {
+ tc.expectedf(t, mock)
+ }
})
}
}
@@ -114,7 +158,7 @@ func TestTOTPRegisterPUT(t *testing.T) {
`{"status":"KO","message":"Unable to set up one-time password."}`,
fasthttp.StatusBadRequest,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Validation failed for TOTP registration because the input options were not permitted by the configuration", "")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating a TOTP registration session for user 'john': error occurred validating registration options selection", "the algorithm 'SHA1', period '30', or length '20' was not permitted by configured policy")
},
},
{
@@ -125,7 +169,7 @@ func TestTOTPRegisterPUT(t *testing.T) {
`{"status":"KO","message":"Unable to set up one-time password."}`,
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred handling request: anonymous user attempted TOTP registration", "")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating a TOTP registration session", "user is anonymous")
},
},
{
@@ -145,7 +189,7 @@ func TestTOTPRegisterPUT(t *testing.T) {
`{"status":"KO","message":"Unable to set up one-time password."}`,
fasthttp.StatusBadRequest,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred unmarshaling body TOTP registration", "invalid character 'S' after object key")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating a TOTP registration session for user 'john': error parsing the request body", "invalid character 'S' after object key")
},
},
{
@@ -179,9 +223,9 @@ func TestTOTPRegisterPUT(t *testing.T) {
)
},
`{"status":"KO","message":"Unable to set up one-time password."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating TOTP configuration", "no issuer")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating a TOTP registration session for user 'john': error generating TOTP configuration", "no issuer")
},
},
}
@@ -222,7 +266,7 @@ func TestTOTPRegisterDELETE(t *testing.T) {
{
"ShouldFailAnonymous",
nil,
- `{"status":"KO","message":"Unable to set up one-time password."}`,
+ `{"status":"KO","message":"Unable to delete one-time password registration session."}`,
fasthttp.StatusForbidden,
nil,
},
@@ -317,7 +361,7 @@ func TestTOTPRegisterPOST(t *testing.T) {
`{"status":"KO","message":"Unable to set up one-time password."}`,
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred during TOTP registration: the user did not initiate a registration on their current session", "")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a TOTP registration session for user 'john': the user did not initiate a registration session on their current session", "")
},
},
{
@@ -343,9 +387,9 @@ func TestTOTPRegisterPOST(t *testing.T) {
require.NoError(t, mock.Ctx.SaveSession(us))
},
`{"status":"KO","message":"Unable to set up one-time password."}`,
- fasthttp.StatusForbidden,
+ fasthttp.StatusBadRequest,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred unmarshaling body TOTP registration", "invalid character '1' after object key:value pair")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a TOTP registration session for user 'john': error parsing the request body", "invalid character '1' after object key:value pair")
},
},
{
@@ -373,7 +417,7 @@ func TestTOTPRegisterPOST(t *testing.T) {
`{"status":"KO","message":"Unable to set up one-time password."}`,
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred during TOTP registration: the registration is expired", "")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a TOTP registration session for user 'john': error occurred validating the session", "the registration session is expired")
},
},
{
@@ -399,7 +443,7 @@ func TestTOTPRegisterPOST(t *testing.T) {
`{"status":"KO","message":"Unable to set up one-time password."}`,
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred handling request: anonymous user attempted TOTP registration", "")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a TOTP registration session", "user is anonymous")
},
},
{
@@ -429,13 +473,13 @@ func TestTOTPRegisterPOST(t *testing.T) {
Validate(
"012345",
&model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)},
- ).Return(false, nil),
+ ).Return(false, uint64(0), nil),
)
},
`{"status":"KO","message":"Unable to set up one-time password."}`,
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating TOTP registration", "")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a TOTP registration session for user 'john'", "user input did not match any expected value")
},
},
{
@@ -465,13 +509,13 @@ func TestTOTPRegisterPOST(t *testing.T) {
Validate(
"012345",
&model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)},
- ).Return(false, fmt.Errorf("pink staple")),
+ ).Return(false, uint64(0), fmt.Errorf("pink staple")),
)
},
`{"status":"KO","message":"Unable to set up one-time password."}`,
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating TOTP registration", "pink staple")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a TOTP registration session for user 'john': error occurred validating the user input against the session", "pink staple")
},
},
{
@@ -501,7 +545,11 @@ func TestTOTPRegisterPOST(t *testing.T) {
Validate(
"012345",
&model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)},
- ).Return(true, nil),
+ ).Return(true, getStepTOTP(mock.Ctx, -1), nil),
+ mock.StorageMock.
+ EXPECT().
+ SaveTOTPHistory(mock.Ctx, "john", uint64(1701295890)).
+ Return(nil),
mock.StorageMock.EXPECT().
SaveTOTPConfiguration(mock.Ctx, model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)}).Return(nil),
mock.UserProviderMock.EXPECT().GetDetails(testUsername).Return(&authentication.UserDetails{Username: testUsername, DisplayName: testDisplayName, Emails: []string{"john@example.com"}}, nil),
@@ -539,7 +587,8 @@ func TestTOTPRegisterPOST(t *testing.T) {
Validate(
"012345",
&model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)},
- ).Return(true, nil),
+ ).Return(true, getStepTOTP(mock.Ctx, -1), nil),
+ mock.StorageMock.EXPECT().SaveTOTPHistory(mock.Ctx, "john", uint64(1701295890)).Return(nil),
mock.StorageMock.EXPECT().
SaveTOTPConfiguration(mock.Ctx, model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)}).Return(nil),
mock.UserProviderMock.EXPECT().GetDetails(testUsername).Return(&authentication.UserDetails{Username: testUsername, DisplayName: testDisplayName, Emails: []string{"john@example.com"}}, nil),
@@ -578,8 +627,9 @@ func TestTOTPRegisterPOST(t *testing.T) {
mock.TOTPMock.EXPECT().
Validate(
"012345",
- &model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)},
- ).Return(true, nil),
+ &model.TOTPConfiguration{CreatedAt: mock.Ctx.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)},
+ ).Return(true, getStepTOTP(mock.Ctx, -1), nil),
+ mock.StorageMock.EXPECT().SaveTOTPHistory(mock.Ctx, "john", uint64(1701295890)).Return(nil),
mock.StorageMock.EXPECT().
SaveTOTPConfiguration(mock.Ctx, model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)}).Return(nil),
mock.UserProviderMock.EXPECT().GetDetails(testUsername).Return(&authentication.UserDetails{Username: testUsername, DisplayName: testDisplayName}, nil),
@@ -617,8 +667,9 @@ func TestTOTPRegisterPOST(t *testing.T) {
mock.TOTPMock.EXPECT().
Validate(
"012345",
- &model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)},
- ).Return(true, nil),
+ &model.TOTPConfiguration{CreatedAt: mock.Ctx.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)},
+ ).Return(true, getStepTOTP(mock.Ctx, -1), nil),
+ mock.StorageMock.EXPECT().SaveTOTPHistory(mock.Ctx, "john", uint64(1701295890)).Return(nil),
mock.StorageMock.EXPECT().
SaveTOTPConfiguration(mock.Ctx, model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)}).Return(nil),
mock.UserProviderMock.EXPECT().GetDetails(testUsername).Return(nil, fmt.Errorf("lookup failure")),
@@ -657,15 +708,16 @@ func TestTOTPRegisterPOST(t *testing.T) {
Validate(
"012345",
&model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)},
- ).Return(true, nil),
+ ).Return(true, getStepTOTP(mock.Ctx, -1), nil),
+ mock.StorageMock.EXPECT().SaveTOTPHistory(mock.Ctx, "john", uint64(1701295890)).Return(nil),
mock.StorageMock.EXPECT().
SaveTOTPConfiguration(mock.Ctx, model.TOTPConfiguration{CreatedAt: mock.Clock.Now(), Username: testUsername, Issuer: "abc", Algorithm: "SHA1", Period: 30, Digits: 6, Secret: []byte(testBASE32TOTPSecret)}).Return(fmt.Errorf("failed to connect")),
)
},
`{"status":"KO","message":"Unable to set up one-time password."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred saving TOTP registration", "failed to connect")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a TOTP registration session for user 'john': error occurred saving the TOTP configuration to the storage backend", "failed to connect")
},
},
}
@@ -678,7 +730,7 @@ func TestTOTPRegisterPOST(t *testing.T) {
mock.Ctx.Configuration.TOTP = tc.config
mock.Ctx.Request.SetBodyString(tc.have)
- mock.Clock.Set(time.Unix(0, 0))
+ mock.Clock.Set(time.Unix(1701295903, 0))
mock.Ctx.Clock = &mock.Clock
if tc.setup != nil {
@@ -814,9 +866,9 @@ func TestTOTPConfigurationDELETE(t *testing.T) {
)
},
`{"status":"KO","message":"Unable to delete one-time password."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred deleting from storage for TOTP configuration delete operation for user 'john'", "not a sql")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred deleting a TOTP configuration for user 'john': error occurred deleting configuration from the storage backend", "not a sql")
},
},
{
@@ -835,13 +887,16 @@ func TestTOTPConfigurationDELETE(t *testing.T) {
require.NoError(t, mock.Ctx.SaveSession(us))
gomock.InOrder(
- mock.StorageMock.EXPECT().LoadTOTPConfiguration(mock.Ctx, testUsername).Return(nil, fmt.Errorf("not found")),
+ mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(mock.Ctx, testUsername).
+ Return(nil, fmt.Errorf("not found")),
)
},
`{"status":"KO","message":"Unable to delete one-time password."}`,
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred loading from storage for TOTP configuration delete operation for user 'john'", "not found")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred deleting a TOTP configuration for user 'john': error occurred loading configuration from the storage backend", "not found")
},
},
}
diff --git a/internal/handlers/handler_register_webauthn.go b/internal/handlers/handler_register_webauthn.go
index 21c94090d..84c187384 100644
--- a/internal/handlers/handler_register_webauthn.go
+++ b/internal/handlers/handler_register_webauthn.go
@@ -27,7 +27,7 @@ func WebAuthnRegistrationPUT(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred generating a WebAuthn registration challenge: error occurred retrieving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn registration challenge: %s", errStrUserSessionData)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -36,7 +36,7 @@ func WebAuthnRegistrationPUT(ctx *middlewares.AutheliaCtx) {
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Error("Error occurred generating a WebAuthn registration challenge")
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred generating a WebAuthn registration challenge")
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -45,7 +45,7 @@ func WebAuthnRegistrationPUT(ctx *middlewares.AutheliaCtx) {
}
if err = json.Unmarshal(ctx.PostBody(), &bodyJSON); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn registration challenge for user '%s': error parsing the request body", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn registration challenge for user '%s': %s", userSession.Username, errStrReqBodyParse)
ctx.SetStatusCode(fasthttp.StatusBadRequest)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -72,7 +72,7 @@ func WebAuthnRegistrationPUT(ctx *middlewares.AutheliaCtx) {
}
if user, err = handleGetWebAuthnUserByRPID(ctx, userSession.Username, userSession.DisplayName, w.Config.RPID); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn registration challenge for user '%s': error occurred retrieving the WebAuthn user configuration from storage", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn registration challenge for user '%s': error occurred retrieving the WebAuthn user configuration from the storage backend", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -117,7 +117,7 @@ func WebAuthnRegistrationPUT(ctx *middlewares.AutheliaCtx) {
userSession.WebAuthn = &data
if err = ctx.SaveSession(userSession); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred generating a WebAuthn registration challenge: error occurred saving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn registration challenge for user '%s': %s", userSession.Username, errStrUserSessionDataSave)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -126,7 +126,7 @@ func WebAuthnRegistrationPUT(ctx *middlewares.AutheliaCtx) {
}
if err = ctx.SetJSONBody(creation); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn registration challenge for user '%s': error occurred writing the response body", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn registration challenge for user '%s': %s", userSession.Username, errStrRespBody)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -150,7 +150,7 @@ func WebAuthnRegistrationPOST(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred validating a WebAuthn registration challenge: error occurred retrieving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn registration challenge: %s", errStrUserSessionData)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -159,7 +159,7 @@ func WebAuthnRegistrationPOST(ctx *middlewares.AutheliaCtx) {
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Error("Error occurred validating a WebAuthn registration challenge")
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred validating a WebAuthn registration challenge")
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -180,7 +180,7 @@ func WebAuthnRegistrationPOST(ctx *middlewares.AutheliaCtx) {
userSession.WebAuthn = nil
if err = ctx.SaveSession(userSession); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn registration challenge for user '%s': error occurred saving the user session data", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn registration challenge for user '%s': %s", userSession.Username, errStrUserSessionDataSave)
}
}()
@@ -189,9 +189,9 @@ func WebAuthnRegistrationPOST(ctx *middlewares.AutheliaCtx) {
switch {
case errors.As(err, &e):
- ctx.Logger.WithError(fmt.Errorf("%w: %s", e, e.DevInfo)).Errorf("Error occurred validating a WebAuthn registration challenge for user '%s': error parsing the request body", userSession.Username)
+ ctx.Logger.WithError(fmt.Errorf("%w: %s", e, e.DevInfo)).Errorf("Error occurred validating a WebAuthn registration challenge for user '%s': %s", userSession.Username, errStrReqBodyParse)
default:
- ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn registration challenge for user '%s': error parsing the request body", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn registration challenge for user '%s': %s", userSession.Username, errStrReqBodyParse)
}
ctx.SetStatusCode(fasthttp.StatusBadRequest)
@@ -210,7 +210,7 @@ func WebAuthnRegistrationPOST(ctx *middlewares.AutheliaCtx) {
}
if user, err = handleGetWebAuthnUserByRPID(ctx, userSession.Username, userSession.DisplayName, w.Config.RPID); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn registration challenge for user '%s': error occurred retrieving the WebAuthn user configuration from storage", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn registration challenge for user '%s': error occurred retrieving the WebAuthn user configuration from the storage backend", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusBadRequest)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -239,7 +239,7 @@ func WebAuthnRegistrationPOST(ctx *middlewares.AutheliaCtx) {
credential.Discoverable = handleWebAuthnCredentialCreationIsDiscoverable(ctx, response)
if err = ctx.Providers.StorageProvider.SaveWebAuthnCredential(ctx, credential); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn registration challenge for user '%s': error occurred saving the registration to storage", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn registration challenge for user '%s': error occurred saving the credential to the storage backend", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -261,7 +261,7 @@ func WebAuthnRegistrationDELETE(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred deleting a WebAuthn registration challenge: error occurred retrieving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred deleting a WebAuthn registration challenge: %s", errStrUserSessionData)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
@@ -270,7 +270,7 @@ func WebAuthnRegistrationDELETE(ctx *middlewares.AutheliaCtx) {
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Error("Error occurred deleting a WebAuthn registration challenge")
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred deleting a WebAuthn registration challenge")
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
@@ -282,7 +282,7 @@ func WebAuthnRegistrationDELETE(ctx *middlewares.AutheliaCtx) {
userSession.WebAuthn = nil
if err = ctx.SaveSession(userSession); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred deleting a WebAuthn registration challenge: error occurred saving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred deleting a WebAuthn registration challenge for user '%s': %s", userSession.Username, errStrUserSessionDataSave)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
diff --git a/internal/handlers/handler_register_webauthn_test.go b/internal/handlers/handler_register_webauthn_test.go
index e29432497..0ceb796d5 100644
--- a/internal/handlers/handler_register_webauthn_test.go
+++ b/internal/handlers/handler_register_webauthn_test.go
@@ -10,10 +10,10 @@ import (
"time"
"github.com/go-webauthn/webauthn/webauthn"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/configuration/schema"
@@ -162,7 +162,7 @@ func TestWebAuthnRegistrationPUT(t *testing.T) {
regexp.MustCompile(`^\{"status":"KO","message":"Unable to register your security key."}$`),
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating a WebAuthn registration challenge for user 'john': error occurred retrieving the WebAuthn user configuration from storage", "database closed")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating a WebAuthn registration challenge for user 'john': error occurred retrieving the WebAuthn user configuration from the storage backend", "database closed")
},
},
{
@@ -189,7 +189,7 @@ func TestWebAuthnRegistrationPUT(t *testing.T) {
regexp.MustCompile(`^\{"status":"KO","message":"Unable to register your security key."}$`),
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating a WebAuthn registration challenge for user 'john': error occurred retrieving the WebAuthn user configuration from storage", "no user x")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating a WebAuthn registration challenge for user 'john': error occurred retrieving the WebAuthn user configuration from the storage backend", "no user x")
},
},
{
@@ -574,7 +574,7 @@ func TestWebAuthnRegistrationPOST(t *testing.T) {
assert.Nil(t, us.WebAuthn)
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn registration challenge for user 'john': error occurred saving the registration to storage", "disk full")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn registration challenge for user 'john': error occurred saving the credential to the storage backend", "disk full")
},
},
{
@@ -620,7 +620,7 @@ func TestWebAuthnRegistrationPOST(t *testing.T) {
assert.Nil(t, us.WebAuthn)
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn registration challenge for user 'john': error occurred retrieving the WebAuthn user configuration from storage", "no dice")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn registration challenge for user 'john': error occurred retrieving the WebAuthn user configuration from the storage backend", "no dice")
},
},
{
@@ -662,7 +662,7 @@ func TestWebAuthnRegistrationPOST(t *testing.T) {
assert.Nil(t, us.WebAuthn)
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn registration challenge for user 'john': error occurred retrieving the WebAuthn user configuration from storage", "not enough cowbell")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn registration challenge for user 'john': error occurred retrieving the WebAuthn user configuration from the storage backend", "not enough cowbell")
},
},
{
diff --git a/internal/handlers/handler_session_elevation.go b/internal/handlers/handler_session_elevation.go
index 63b2dd5ad..e58338167 100755
--- a/internal/handlers/handler_session_elevation.go
+++ b/internal/handlers/handler_session_elevation.go
@@ -29,7 +29,7 @@ func UserSessionElevationGET(ctx *middlewares.AutheliaCtx) {
response := &bodyGETUserSessionElevate{}
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred retrieving user session elevation state: error occurred retrieving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred retrieving user session elevation state: %s", errStrUserSessionData)
ctx.SetJSONError(messageOperationFailed)
ctx.SetStatusCode(fasthttp.StatusForbidden)
@@ -38,7 +38,7 @@ func UserSessionElevationGET(ctx *middlewares.AutheliaCtx) {
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Error("Error occurred retrieving user session elevation state")
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred retrieving user session elevation state")
ctx.SetJSONError(messageOperationFailed)
ctx.SetStatusCode(fasthttp.StatusForbidden)
@@ -105,7 +105,7 @@ func UserSessionElevationGET(ctx *middlewares.AutheliaCtx) {
}
if err = ctx.ReplyJSON(middlewares.OKResponse{Status: "OK", Data: response}, fasthttp.StatusOK); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred retrieving the user session elevation state: error occurred writing the response body")
+ ctx.Logger.WithError(err).Errorf("Error occurred retrieving the user session elevation state for user '%s': %s", userSession.Username, errStrRespBody)
ctx.SetJSONError(messageOperationFailed)
@@ -123,7 +123,7 @@ func UserSessionElevationPOST(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred creating user session elevation One-Time Code challenge: error occurred retrieving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred creating user session elevation One-Time Code challenge: %s", errStrUserSessionData)
ctx.SetJSONError(messageOperationFailed)
ctx.SetStatusCode(fasthttp.StatusForbidden)
@@ -132,7 +132,7 @@ func UserSessionElevationPOST(ctx *middlewares.AutheliaCtx) {
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Error("Error occurred creating user session elevation One-Time Code challenge")
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred creating user session elevation One-Time Code challenge")
ctx.SetJSONError(messageOperationFailed)
ctx.SetStatusCode(fasthttp.StatusForbidden)
@@ -156,7 +156,7 @@ func UserSessionElevationPOST(ctx *middlewares.AutheliaCtx) {
var signature string
if signature, err = ctx.Providers.StorageProvider.SaveOneTimeCode(ctx, *otp); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred creating user session elevation One-Time Code challenge for user '%s': error occurred saving the challenge to storage", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred creating user session elevation One-Time Code challenge for user '%s': error occurred saving the challenge to the storage backend", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
@@ -201,7 +201,7 @@ func UserSessionElevationPOST(ctx *middlewares.AutheliaCtx) {
if err = ctx.SetJSONBody(&bodyPOSTUserSessionElevate{
DeleteID: deleteID,
}); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred creating user session elevation One-Time Code challenge: error occurred writing the response body")
+ ctx.Logger.WithError(err).Errorf("Error occurred creating user session elevation One-Time Code challenge for user '%s': %s", userSession.Username, errStrRespBody)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
@@ -221,7 +221,7 @@ func UserSessionElevationPUT(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred validating user session elevation One-Time Code challenge: error occurred retrieving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred validating user session elevation One-Time Code challenge: %s", errStrUserSessionData)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
@@ -230,7 +230,7 @@ func UserSessionElevationPUT(ctx *middlewares.AutheliaCtx) {
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Error("Error occurred validating user session elevation One-Time Code challenge")
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred validating user session elevation One-Time Code challenge")
ctx.SetJSONError(messageOperationFailed)
ctx.SetStatusCode(fasthttp.StatusForbidden)
@@ -239,7 +239,7 @@ func UserSessionElevationPUT(ctx *middlewares.AutheliaCtx) {
}
if err = ctx.ParseBody(&bodyJSON); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred validating user session elevation One-Time Code challenge: error parsing the request body")
+ ctx.Logger.WithError(err).Errorf("Error occurred validating user session elevation One-Time Code challenge for user '%s': %s", userSession.Username, errStrReqBodyParse)
ctx.SetStatusCode(fasthttp.StatusBadRequest)
ctx.SetJSONError(messageOperationFailed)
@@ -251,7 +251,7 @@ func UserSessionElevationPUT(ctx *middlewares.AutheliaCtx) {
if code, err = ctx.Providers.StorageProvider.LoadOneTimeCode(ctx, userSession.Username, model.OTCIntentUserSessionElevation, bodyJSON.OneTimeCode); err != nil {
ctx.Logger.WithError(err).
- Errorf("Error occurred validating user session elevation One-Time Code challenge for user '%s': error occurred retrieving the code challenge from storage", userSession.Username)
+ Errorf("Error occurred validating user session elevation One-Time Code challenge for user '%s': error occurred retrieving the code challenge from the storage backend", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
@@ -259,7 +259,7 @@ func UserSessionElevationPUT(ctx *middlewares.AutheliaCtx) {
return
} else if code == nil {
ctx.Logger.WithError(fmt.Errorf("the code didn't match any recorded code challenges")).
- Errorf("Error occurred validating user session elevation One-Time Code challenge for user '%s': error occurred retrieving the code challenge from storage", userSession.Username)
+ Errorf("Error occurred validating user session elevation One-Time Code challenge for user '%s': error occurred retrieving the code challenge from the storage backend", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
@@ -330,7 +330,7 @@ func UserSessionElevationPUT(ctx *middlewares.AutheliaCtx) {
}
if err = ctx.SaveSession(userSession); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred validating user session elevation One-Time Code challenge: error occurred saving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred validating user session elevation One-Time Code challenge for user '%s': %s", userSession.Username, errStrUserSessionDataSave)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
@@ -373,7 +373,7 @@ func UserSessionElevateDELETE(ctx *middlewares.AutheliaCtx) {
if code, err = ctx.Providers.StorageProvider.LoadOneTimeCodeByPublicID(ctx, id); err != nil {
ctx.Logger.WithError(err).
- Error("Error occurred revoking user session elevation One-Time Code challenge: error occurred retrieving the code challenge from storage")
+ Error("Error occurred revoking user session elevation One-Time Code challenge: error occurred retrieving the code challenge from the storage backend")
ctx.SetJSONError(messageOperationFailed)
@@ -381,7 +381,7 @@ func UserSessionElevateDELETE(ctx *middlewares.AutheliaCtx) {
}
if code.RevokedAt.Valid {
- ctx.Logger.WithError(fmt.Errorf("the code challenge has already been revoked")).Errorf("Error occurred validating user session elevation One-Time Code challenge")
+ ctx.Logger.WithError(fmt.Errorf("the code challenge has already been revoked")).Errorf("Error occurred revoking user session elevation One-Time Code challenge")
ctx.SetJSONError(messageOperationFailed)
@@ -389,7 +389,7 @@ func UserSessionElevateDELETE(ctx *middlewares.AutheliaCtx) {
}
if code.ConsumedAt.Valid {
- ctx.Logger.WithError(fmt.Errorf("the code challenge has already been consumed")).Errorf("Error occurred validating user session elevation One-Time Code challenge")
+ ctx.Logger.WithError(fmt.Errorf("the code challenge has already been consumed")).Errorf("Error occurred revoking user session elevation One-Time Code challenge")
ctx.SetJSONError(messageOperationFailed)
@@ -397,7 +397,7 @@ func UserSessionElevateDELETE(ctx *middlewares.AutheliaCtx) {
}
if code.Intent != model.OTCIntentUserSessionElevation {
- ctx.Logger.WithError(fmt.Errorf("the code challenge has the '%s' intent but the '%s' intent is required", code.Intent, model.OTCIntentUserSessionElevation)).Errorf("Error occurred revoking user session elevation One-Time Code challenge for user")
+ ctx.Logger.WithError(fmt.Errorf("the code challenge has the '%s' intent but the '%s' intent is required", code.Intent, model.OTCIntentUserSessionElevation)).Errorf("Error occurred revoking user session elevation One-Time Code challenge")
ctx.SetJSONError(messageOperationFailed)
@@ -405,7 +405,7 @@ func UserSessionElevateDELETE(ctx *middlewares.AutheliaCtx) {
}
if err = ctx.Providers.StorageProvider.RevokeOneTimeCode(ctx, id, model.NewIP(ctx.RemoteIP())); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred revoking user session elevation One-Time Code challenge: error occurred saving the revocation of the code being saved to storage")
+ ctx.Logger.WithError(err).Errorf("Error occurred revoking user session elevation One-Time Code challenge: error occurred saving the revocation to the storage backend")
ctx.SetJSONError(messageOperationFailed)
diff --git a/internal/handlers/handler_session_elevation_test.go b/internal/handlers/handler_session_elevation_test.go
index 0b256b7b1..3cb2e5a4c 100644
--- a/internal/handlers/handler_session_elevation_test.go
+++ b/internal/handlers/handler_session_elevation_test.go
@@ -9,11 +9,11 @@ import (
"testing"
"time"
- "github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/mocks"
@@ -449,7 +449,7 @@ func TestUserSessionElevationPOST(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred creating user session elevation One-Time Code challenge for user 'john': error occurred saving the challenge to storage", "failed to insert")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred creating user session elevation One-Time Code challenge for user 'john': error occurred saving the challenge to the storage backend", "failed to insert")
},
},
{
@@ -670,7 +670,7 @@ func TestUserSessionElevationPUT(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusBadRequest,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating user session elevation One-Time Code challenge: error parsing the request body", "unable to parse body: invalid character 'A' looking for beginning of value")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating user session elevation One-Time Code challenge for user 'john': error parsing the request body", "unable to parse body: invalid character 'A' looking for beginning of value")
},
},
{
@@ -905,7 +905,7 @@ func TestUserSessionElevationPUT(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating user session elevation One-Time Code challenge for user 'john': error occurred retrieving the code challenge from storage", "the code didn't match any recorded code challenges")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating user session elevation One-Time Code challenge for user 'john': error occurred retrieving the code challenge from the storage backend", "the code didn't match any recorded code challenges")
},
},
{
@@ -934,7 +934,7 @@ func TestUserSessionElevationPUT(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating user session elevation One-Time Code challenge for user 'john': error occurred retrieving the code challenge from storage", "not found")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating user session elevation One-Time Code challenge for user 'john': error occurred retrieving the code challenge from the storage backend", "not found")
},
},
}
@@ -1068,7 +1068,7 @@ func TestUserSessionElevationDELETE(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusOK,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred revoking user session elevation One-Time Code challenge: error occurred saving the revocation of the code being saved to storage", "failed to update")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred revoking user session elevation One-Time Code challenge: error occurred saving the revocation to the storage backend", "failed to update")
},
},
{
@@ -1108,7 +1108,7 @@ func TestUserSessionElevationDELETE(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusOK,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred revoking user session elevation One-Time Code challenge for user", "the code challenge has the 'abc' intent but the 'use' intent is required")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred revoking user session elevation One-Time Code challenge", "the code challenge has the 'abc' intent but the 'use' intent is required")
},
},
{
@@ -1149,7 +1149,7 @@ func TestUserSessionElevationDELETE(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusOK,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating user session elevation One-Time Code challenge", "the code challenge has already been consumed")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred revoking user session elevation One-Time Code challenge", "the code challenge has already been consumed")
},
},
{
@@ -1190,7 +1190,7 @@ func TestUserSessionElevationDELETE(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusOK,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating user session elevation One-Time Code challenge", "the code challenge has already been revoked")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred revoking user session elevation One-Time Code challenge", "the code challenge has already been revoked")
},
},
{
@@ -1219,7 +1219,7 @@ func TestUserSessionElevationDELETE(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusOK,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred revoking user session elevation One-Time Code challenge: error occurred retrieving the code challenge from storage", "invalid user")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred revoking user session elevation One-Time Code challenge: error occurred retrieving the code challenge from the storage backend", "invalid user")
},
},
{
diff --git a/internal/handlers/handler_sign_duo_test.go b/internal/handlers/handler_sign_duo_test.go
index bd68d93ba..bc2130561 100644
--- a/internal/handlers/handler_sign_duo_test.go
+++ b/internal/handlers/handler_sign_duo_test.go
@@ -8,10 +8,10 @@ import (
"regexp"
"testing"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/duo"
diff --git a/internal/handlers/handler_sign_totp.go b/internal/handlers/handler_sign_totp.go
index e6a95ec5e..a4416e532 100644
--- a/internal/handlers/handler_sign_totp.go
+++ b/internal/handlers/handler_sign_totp.go
@@ -2,6 +2,7 @@ package handlers
import (
"errors"
+ "fmt"
"github.com/valyala/fasthttp"
@@ -20,9 +21,19 @@ func TimeBasedOneTimePasswordGET(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred retrieving user session")
+ ctx.Logger.WithError(err).Errorf("Error occurred retrieving TOTP configuration: %s", errStrUserSessionData)
- ctx.ReplyForbidden()
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
+
+ return
+ }
+
+ if userSession.IsAnonymous() {
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred retrieving TOTP configuration")
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
return
}
@@ -30,24 +41,27 @@ func TimeBasedOneTimePasswordGET(ctx *middlewares.AutheliaCtx) {
var config *model.TOTPConfiguration
if config, err = ctx.Providers.StorageProvider.LoadTOTPConfiguration(ctx, userSession.Username); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred retrieving TOTP configuration for user '%s': error occurred retrieving the configuration from the storage backend", userSession.Username)
+
if errors.Is(err, storage.ErrNoTOTPConfiguration) {
ctx.SetStatusCode(fasthttp.StatusNotFound)
ctx.SetJSONError("Could not find TOTP Configuration for user.")
- ctx.Logger.WithError(err).Errorf("Failed to lookup TOTP configuration for user '%s'", userSession.Username)
} else {
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
ctx.SetJSONError("Could not find TOTP Configuration for user.")
- ctx.Logger.WithError(err).Errorf("Failed to lookup TOTP configuration for user '%s' with unknown error", userSession.Username)
}
return
}
if err = ctx.SetJSONBody(config); err != nil {
- ctx.Logger.Errorf("Unable to perform TOTP configuration response: %s", err)
- }
+ ctx.Logger.WithError(err).Errorf("Error occurred retrieving TOTP configuration for user '%s': %s", userSession.Username, errStrRespBody)
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
- ctx.SetStatusCode(fasthttp.StatusOK)
+ return
+ }
}
// TimeBasedOneTimePasswordPOST validate the TOTP passcode provided by the user.
@@ -55,60 +69,108 @@ func TimeBasedOneTimePasswordPOST(ctx *middlewares.AutheliaCtx) {
bodyJSON := bodySignTOTPRequest{}
var (
- userSession session.UserSession
- err error
+ userSession session.UserSession
+ config *model.TOTPConfiguration
+ valid, exists bool
+ step uint64
+ err error
)
- if err = ctx.ParseBody(&bodyJSON); err != nil {
- ctx.Logger.WithError(err).Errorf(logFmtErrParseRequestBody, regulation.AuthTypeTOTP)
+ if userSession, err = ctx.GetSession(); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP authentication: %s", errStrUserSessionData)
- respondUnauthorized(ctx, messageMFAValidationFailed)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
return
}
- if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred retrieving user session")
+ if userSession.IsAnonymous() {
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred validating a TOTP authentication")
- respondUnauthorized(ctx, messageMFAValidationFailed)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
return
}
- config, err := ctx.Providers.StorageProvider.LoadTOTPConfiguration(ctx, userSession.Username)
- if err != nil {
- ctx.Logger.WithError(err).Errorf("Failed to load TOTP configuration")
+ if err = ctx.ParseBody(&bodyJSON); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP authentication for user '%s': %s", userSession.Username, errStrReqBodyParse)
- respondUnauthorized(ctx, messageMFAValidationFailed)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
return
}
- var valid bool
+ if config, err = ctx.Providers.StorageProvider.LoadTOTPConfiguration(ctx, userSession.Username); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP authentication for user '%s': error occurred retreiving the configuration from the storage backend", userSession.Username)
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
+
+ return
+ }
- if valid, err = ctx.Providers.TOTP.Validate(bodyJSON.Token, config); err != nil {
- ctx.Logger.WithError(err).Errorf("Failed to perform TOTP verification")
+ if valid, step, err = ctx.Providers.TOTP.Validate(bodyJSON.Token, config); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP authentication for user '%s': error occurred validating the user input", userSession.Username)
- respondUnauthorized(ctx, messageMFAValidationFailed)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
return
- } else if !valid {
+ }
+
+ if !valid {
+ ctx.Logger.WithError(fmt.Errorf("the user input wasn't valid")).Errorf("Error occurred validating a TOTP authentication for user '%s': error occurred validating the user input", userSession.Username)
+
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeTOTP, nil)
- respondUnauthorized(ctx, messageMFAValidationFailed)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
+
+ return
+ }
+
+ if exists, err = ctx.Providers.StorageProvider.ExistsTOTPHistory(ctx, userSession.Username, step*uint64(config.Period), config.HistorySince(ctx.GetClock().Now(), ctx.Configuration.TOTP.Skew)); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP authentication for user '%s': error occurred checking the TOTP history", userSession.Username)
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
+
+ return
+ }
+
+ if exists {
+ ctx.Logger.WithError(fmt.Errorf("the user has already used this code recently and will not be permitted to reuse it")).Errorf("Error occurred validating a TOTP authentication for user '%s': error occurred satisfying security policies", userSession.Username)
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
+
+ return
+ }
+
+ if err = ctx.Providers.StorageProvider.SaveTOTPHistory(ctx, userSession.Username, step*uint64(config.Period)); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP authentication for user '%s': error occurred saving the TOTP history to the storage backend", userSession.Username)
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
return
}
if err = markAuthenticationAttempt(ctx, true, nil, userSession.Username, regulation.AuthTypeTOTP, nil); err != nil {
- respondUnauthorized(ctx, messageMFAValidationFailed)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
+
return
}
if err = ctx.RegenerateSession(); err != nil {
- ctx.Logger.WithError(err).Errorf(logFmtErrSessionRegenerate, regulation.AuthTypeTOTP, userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP authentication for user '%s': error regenerating the user session", userSession.Username)
- respondUnauthorized(ctx, messageMFAValidationFailed)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
return
}
@@ -116,9 +178,10 @@ func TimeBasedOneTimePasswordPOST(ctx *middlewares.AutheliaCtx) {
config.UpdateSignInInfo(ctx.Clock.Now())
if err = ctx.Providers.StorageProvider.UpdateTOTPConfigurationSignIn(ctx, config.ID, config.LastUsedAt); err != nil {
- ctx.Logger.WithError(err).Errorf("Unable to save %s device sign in metadata for user '%s'", regulation.AuthTypeTOTP, userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP authentication for user '%s': error occurred saving the credential sign-in information to the storage backend", userSession.Username)
- respondUnauthorized(ctx, messageMFAValidationFailed)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
return
}
@@ -126,9 +189,10 @@ func TimeBasedOneTimePasswordPOST(ctx *middlewares.AutheliaCtx) {
userSession.SetTwoFactorTOTP(ctx.Clock.Now())
if err = ctx.SaveSession(userSession); err != nil {
- ctx.Logger.WithError(err).Errorf(logFmtErrSessionSave, "authentication time", regulation.AuthTypeTOTP, logFmtActionAuthentication, userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a TOTP authentication for user '%s': %s", userSession.Username, errStrUserSessionDataSave)
- respondUnauthorized(ctx, messageMFAValidationFailed)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
return
}
diff --git a/internal/handlers/handler_sign_totp_test.go b/internal/handlers/handler_sign_totp_test.go
index 9e57951c1..aa73c190e 100644
--- a/internal/handlers/handler_sign_totp_test.go
+++ b/internal/handlers/handler_sign_totp_test.go
@@ -6,14 +6,17 @@ import (
"fmt"
"regexp"
"testing"
+ "time"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/suite"
+ "go.uber.org/mock/gomock"
+ "github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"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/storage"
)
type HandlerSignTOTPSuite struct {
@@ -28,6 +31,12 @@ func (s *HandlerSignTOTPSuite) SetupTest() {
s.Assert().NoError(err)
userSession.Username = testUsername
+ userSession.AuthenticationLevel = authentication.OneFactor
+
+ s.mock.Clock.Set(time.Unix(1701295903, 0))
+ s.mock.Ctx.Clock = &s.mock.Clock
+ s.mock.Ctx.Configuration.TOTP = schema.DefaultTOTPConfiguration
+
s.Assert().NoError(s.mock.Ctx.SaveSession(userSession))
}
@@ -35,29 +44,46 @@ func (s *HandlerSignTOTPSuite) TearDownTest() {
s.mock.Close()
}
-func (s *HandlerSignTOTPSuite) TestShouldRedirectUserToDefaultURL() {
- config := model.TOTPConfiguration{ID: 1, Username: "john", Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
-
- s.mock.StorageMock.EXPECT().
- LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
- Return(&config, nil)
-
- s.mock.StorageMock.
- EXPECT().
- AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
- Username: "john",
- Successful: true,
- Banned: false,
- Time: s.mock.Clock.Now(),
- Type: regulation.AuthTypeTOTP,
- RemoteIP: model.NewNullIPFromString("0.0.0.0"),
- }))
+func (s *HandlerSignTOTPSuite) AssertLastLogMessage(message string, err string) {
+ AssertLogEntryMessageAndError(s.T(), s.mock.Hook.LastEntry(), message, err)
+}
- s.mock.TOTPMock.EXPECT().Validate(gomock.Eq("abc"), gomock.Eq(&config)).Return(true, nil)
+func (s *HandlerSignTOTPSuite) TestShouldRedirectUserToDefaultURL() {
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
- s.mock.StorageMock.
- EXPECT().
- UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any())
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
+ Return(&config, nil),
+ s.mock.TOTPMock.
+ EXPECT().
+ Validate(gomock.Eq("abc"), gomock.Eq(&config)).
+ Return(true, getStepTOTP(s.mock.Ctx, -1), nil),
+ s.mock.StorageMock.
+ EXPECT().
+ ExistsTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890), config.HistorySince(s.mock.Clock.Now(), s.mock.Ctx.Configuration.TOTP.Skew)).
+ Return(false, nil),
+ s.mock.StorageMock.
+ EXPECT().
+ SaveTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890)).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
+ Username: testUsername,
+ Successful: true,
+ Banned: false,
+ Time: s.mock.Clock.Now(),
+ Type: regulation.AuthTypeTOTP,
+ RemoteIP: model.NewNullIPFromString("0.0.0.0"),
+ })).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any()).
+ Return(nil),
+ )
s.mock.Ctx.Configuration.Session.Cookies[0].DefaultRedirectionURL = testRedirectionURL
@@ -74,28 +100,40 @@ func (s *HandlerSignTOTPSuite) TestShouldRedirectUserToDefaultURL() {
}
func (s *HandlerSignTOTPSuite) TestShouldFailWhenTOTPSignInInfoFailsToUpdate() {
- config := model.TOTPConfiguration{ID: 1, Username: "john", Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
-
- s.mock.StorageMock.EXPECT().
- LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
- Return(&config, nil)
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
- s.mock.StorageMock.
- EXPECT().
- AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
- Username: "john",
- Successful: true,
- Banned: false,
- Time: s.mock.Clock.Now(),
- Type: regulation.AuthTypeTOTP,
- RemoteIP: model.NewNullIPFromString("0.0.0.0"),
- }))
-
- s.mock.TOTPMock.EXPECT().Validate(gomock.Eq("abc"), gomock.Eq(&config)).Return(true, nil)
-
- s.mock.StorageMock.
- EXPECT().
- UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any()).Return(errors.New("failed to perform update"))
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
+ Return(&config, nil),
+ s.mock.TOTPMock.
+ EXPECT().
+ Validate(gomock.Eq("abc"), gomock.Eq(&config)).
+ Return(true, getStepTOTP(s.mock.Ctx, -1), nil),
+ s.mock.StorageMock.
+ EXPECT().
+ ExistsTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890), config.HistorySince(s.mock.Clock.Now(), s.mock.Ctx.Configuration.TOTP.Skew)).
+ Return(false, nil),
+ s.mock.StorageMock.
+ EXPECT().
+ SaveTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890)).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
+ Username: testUsername,
+ Successful: true,
+ Banned: false,
+ Time: s.mock.Clock.Now(),
+ Type: regulation.AuthTypeTOTP,
+ RemoteIP: model.NewNullIPFromString("0.0.0.0"),
+ })),
+ s.mock.StorageMock.
+ EXPECT().
+ UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any()).
+ Return(errors.New("failed to perform update")),
+ )
s.mock.Ctx.Configuration.Session.Cookies[0].DefaultRedirectionURL = testRedirectionURL
@@ -106,32 +144,45 @@ func (s *HandlerSignTOTPSuite) TestShouldFailWhenTOTPSignInInfoFailsToUpdate() {
s.mock.Ctx.Request.SetBody(bodyBytes)
TimeBasedOneTimePasswordPOST(s.mock.Ctx)
- s.mock.Assert401KO(s.T(), "Authentication failed, please retry later.")
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
}
func (s *HandlerSignTOTPSuite) TestShouldNotReturnRedirectURL() {
- config := model.TOTPConfiguration{ID: 1, Username: "john", Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
-
- s.mock.StorageMock.EXPECT().
- LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
- Return(&config, nil)
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
- s.mock.StorageMock.
- EXPECT().
- AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
- Username: "john",
- Successful: true,
- Banned: false,
- Time: s.mock.Clock.Now(),
- Type: regulation.AuthTypeTOTP,
- RemoteIP: model.NewNullIPFromString("0.0.0.0"),
- }))
-
- s.mock.TOTPMock.EXPECT().Validate(gomock.Eq("abc"), gomock.Eq(&config)).Return(true, nil)
-
- s.mock.StorageMock.
- EXPECT().
- UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any())
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
+ Return(&config, nil),
+ s.mock.TOTPMock.
+ EXPECT().
+ Validate(gomock.Eq("abc"), gomock.Eq(&config)).
+ Return(true, getStepTOTP(s.mock.Ctx, -1), nil),
+ s.mock.StorageMock.
+ EXPECT().
+ ExistsTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890), config.HistorySince(s.mock.Clock.Now(), s.mock.Ctx.Configuration.TOTP.Skew)).
+ Return(false, nil),
+ s.mock.StorageMock.
+ EXPECT().
+ SaveTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890)).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
+ Username: testUsername,
+ Successful: true,
+ Banned: false,
+ Time: s.mock.Clock.Now(),
+ Type: regulation.AuthTypeTOTP,
+ RemoteIP: model.NewNullIPFromString("0.0.0.0"),
+ })).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any()).
+ Return(nil),
+ )
bodyBytes, err := json.Marshal(bodySignTOTPRequest{
Token: "abc",
@@ -144,7 +195,7 @@ func (s *HandlerSignTOTPSuite) TestShouldNotReturnRedirectURL() {
}
func (s *HandlerSignTOTPSuite) TestShouldRedirectUserToSafeTargetURL() {
- config := model.TOTPConfiguration{ID: 1, Username: "john", Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
s.mock.Ctx.Configuration.Session.Cookies = []schema.SessionCookie{
{
Domain: "example.com",
@@ -154,26 +205,39 @@ func (s *HandlerSignTOTPSuite) TestShouldRedirectUserToSafeTargetURL() {
},
}
- s.mock.StorageMock.EXPECT().
- LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
- Return(&config, nil)
-
- s.mock.StorageMock.
- EXPECT().
- AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
- Username: "john",
- Successful: true,
- Banned: false,
- Time: s.mock.Clock.Now(),
- Type: regulation.AuthTypeTOTP,
- RemoteIP: model.NewNullIPFromString("0.0.0.0"),
- }))
-
- s.mock.TOTPMock.EXPECT().Validate(gomock.Eq("abc"), gomock.Eq(&config)).Return(true, nil)
-
- s.mock.StorageMock.
- EXPECT().
- UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any())
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
+ Return(&config, nil),
+ s.mock.TOTPMock.
+ EXPECT().
+ Validate(gomock.Eq("abc"), gomock.Eq(&config)).
+ Return(true, getStepTOTP(s.mock.Ctx, -1), nil),
+ s.mock.StorageMock.
+ EXPECT().
+ ExistsTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890), config.HistorySince(s.mock.Clock.Now(), s.mock.Ctx.Configuration.TOTP.Skew)).
+ Return(false, nil),
+ s.mock.StorageMock.
+ EXPECT().
+ SaveTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890)).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
+ Username: testUsername,
+ Successful: true,
+ Banned: false,
+ Time: s.mock.Clock.Now(),
+ Type: regulation.AuthTypeTOTP,
+ RemoteIP: model.NewNullIPFromString("0.0.0.0"),
+ })).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any()).
+ Return(nil),
+ )
bodyBytes, err := json.Marshal(bodySignTOTPRequest{
Token: "abc",
@@ -190,28 +254,38 @@ func (s *HandlerSignTOTPSuite) TestShouldRedirectUserToSafeTargetURL() {
}
func (s *HandlerSignTOTPSuite) TestShouldNotRedirectToUnsafeURL() {
- s.mock.StorageMock.EXPECT().
- LoadTOTPConfiguration(s.mock.Ctx, "john").
- Return(&model.TOTPConfiguration{Secret: []byte("secret")}, nil)
-
- s.mock.StorageMock.
- EXPECT().
- AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
- Username: "john",
- Successful: true,
- Banned: false,
- Time: s.mock.Clock.Now(),
- Type: regulation.AuthTypeTOTP,
- RemoteIP: model.NewNullIPFromString("0.0.0.0"),
- }))
-
- s.mock.StorageMock.
- EXPECT().
- UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any())
-
- s.mock.TOTPMock.EXPECT().
- Validate(gomock.Eq("abc"), gomock.Eq(&model.TOTPConfiguration{Secret: []byte("secret")})).
- Return(true, nil)
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, testUsername).
+ Return(&model.TOTPConfiguration{Secret: []byte("secret"), Period: 30}, nil),
+ s.mock.TOTPMock.EXPECT().
+ Validate(gomock.Eq("abc"), gomock.Eq(&model.TOTPConfiguration{Secret: []byte("secret"), Period: 30})).
+ Return(true, getStepTOTP(s.mock.Ctx, -1), nil),
+ s.mock.StorageMock.
+ EXPECT().
+ ExistsTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890), gomock.Any()).
+ Return(false, nil),
+ s.mock.StorageMock.
+ EXPECT().
+ SaveTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890)).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
+ Username: testUsername,
+ Successful: true,
+ Banned: false,
+ Time: s.mock.Clock.Now(),
+ Type: regulation.AuthTypeTOTP,
+ RemoteIP: model.NewNullIPFromString("0.0.0.0"),
+ })).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any()).
+ Return(nil),
+ )
bodyBytes, err := json.Marshal(bodySignTOTPRequest{
Token: "abc",
@@ -226,30 +300,41 @@ func (s *HandlerSignTOTPSuite) TestShouldNotRedirectToUnsafeURL() {
}
func (s *HandlerSignTOTPSuite) TestShouldRegenerateSessionForPreventingSessionFixation() {
- config := model.TOTPConfiguration{ID: 1, Username: "john", Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
-
- s.mock.StorageMock.EXPECT().
- LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
- Return(&config, nil)
-
- s.mock.StorageMock.
- EXPECT().
- AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
- Username: "john",
- Successful: true,
- Banned: false,
- Time: s.mock.Clock.Now(),
- Type: regulation.AuthTypeTOTP,
- RemoteIP: model.NewNullIPFromString("0.0.0.0"),
- }))
-
- s.mock.TOTPMock.EXPECT().
- Validate(gomock.Eq("abc"), gomock.Eq(&config)).
- Return(true, nil)
-
- s.mock.StorageMock.
- EXPECT().
- UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any())
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
+
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
+ Return(&config, nil),
+ s.mock.TOTPMock.
+ EXPECT().
+ Validate(gomock.Eq("abc"), gomock.Eq(&config)).
+ Return(true, getStepTOTP(s.mock.Ctx, -1), nil),
+ s.mock.StorageMock.
+ EXPECT().
+ ExistsTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890), config.HistorySince(s.mock.Clock.Now(), s.mock.Ctx.Configuration.TOTP.Skew)).
+ Return(false, nil),
+ s.mock.StorageMock.
+ EXPECT().
+ SaveTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890)).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
+ Username: testUsername,
+ Successful: true,
+ Banned: false,
+ Time: s.mock.Clock.Now(),
+ Type: regulation.AuthTypeTOTP,
+ RemoteIP: model.NewNullIPFromString("0.0.0.0"),
+ })).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ UpdateTOTPConfigurationSignIn(s.mock.Ctx, gomock.Any(), gomock.Any()).
+ Return(nil),
+ )
bodyBytes, err := json.Marshal(bodySignTOTPRequest{
Token: "abc",
@@ -268,8 +353,168 @@ func (s *HandlerSignTOTPSuite) TestShouldRegenerateSessionForPreventingSessionFi
string(s.mock.Ctx.Request.Header.Cookie("authelia_session")))
}
+func (s *HandlerSignTOTPSuite) TestShouldHandleErrorSaveHistory() {
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
+
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
+ Return(&config, nil),
+ s.mock.TOTPMock.
+ EXPECT().
+ Validate(gomock.Eq("abc"), gomock.Eq(&config)).
+ Return(true, getStepTOTP(s.mock.Ctx, -1), nil),
+ s.mock.StorageMock.
+ EXPECT().
+ ExistsTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890), config.HistorySince(s.mock.Clock.Now(), s.mock.Ctx.Configuration.TOTP.Skew)).
+ Return(false, nil),
+ s.mock.StorageMock.
+ EXPECT().
+ SaveTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890)).
+ Return(fmt.Errorf("bad stuff")),
+ )
+
+ bodyBytes, err := json.Marshal(bodySignTOTPRequest{
+ Token: "abc",
+ })
+ s.Require().NoError(err)
+ s.mock.Ctx.Request.SetBody(bodyBytes)
+
+ TimeBasedOneTimePasswordPOST(s.mock.Ctx)
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
+
+ s.AssertLastLogMessage("Error occurred validating a TOTP authentication for user 'john': error occurred saving the TOTP history to the storage backend", "bad stuff")
+}
+
+func (s *HandlerSignTOTPSuite) TestShouldHandleErrorExistsHistory() {
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
+
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
+ Return(&config, nil),
+ s.mock.TOTPMock.
+ EXPECT().
+ Validate(gomock.Eq("abc"), gomock.Eq(&config)).
+ Return(true, getStepTOTP(s.mock.Ctx, -1), nil),
+ s.mock.StorageMock.
+ EXPECT().
+ ExistsTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890), config.HistorySince(s.mock.Clock.Now(), s.mock.Ctx.Configuration.TOTP.Skew)).
+ Return(false, fmt.Errorf("oh my")),
+ )
+
+ bodyBytes, err := json.Marshal(bodySignTOTPRequest{
+ Token: "abc",
+ })
+ s.Require().NoError(err)
+ s.mock.Ctx.Request.SetBody(bodyBytes)
+
+ TimeBasedOneTimePasswordPOST(s.mock.Ctx)
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
+
+ s.AssertLastLogMessage("Error occurred validating a TOTP authentication for user 'john': error occurred checking the TOTP history", "oh my")
+}
+
+func (s *HandlerSignTOTPSuite) TestShouldHandleExistsHistory() {
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
+
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
+ Return(&config, nil),
+ s.mock.TOTPMock.
+ EXPECT().
+ Validate(gomock.Eq("abc"), gomock.Eq(&config)).
+ Return(true, getStepTOTP(s.mock.Ctx, -1), nil),
+ s.mock.StorageMock.
+ EXPECT().
+ ExistsTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890), config.HistorySince(s.mock.Clock.Now(), s.mock.Ctx.Configuration.TOTP.Skew)).
+ Return(true, nil),
+ )
+
+ bodyBytes, err := json.Marshal(bodySignTOTPRequest{
+ Token: "abc",
+ })
+ s.Require().NoError(err)
+ s.mock.Ctx.Request.SetBody(bodyBytes)
+
+ TimeBasedOneTimePasswordPOST(s.mock.Ctx)
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
+
+ s.AssertLastLogMessage("Error occurred validating a TOTP authentication for user 'john': error occurred satisfying security policies", "the user has already used this code recently and will not be permitted to reuse it")
+}
+
+func (s *HandlerSignTOTPSuite) TestShouldHandleAnonymous() {
+ us, err := s.mock.Ctx.GetSession()
+
+ s.Require().NoError(err)
+
+ us.Username = ""
+ us.AuthenticationLevel = authentication.NotAuthenticated
+
+ s.Require().NoError(s.mock.Ctx.SaveSession(us))
+
+ bodyBytes, err := json.Marshal(bodySignTOTPRequest{
+ Token: "abc",
+ })
+ s.Require().NoError(err)
+ s.mock.Ctx.Request.SetBody(bodyBytes)
+
+ TimeBasedOneTimePasswordPOST(s.mock.Ctx)
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
+
+ s.AssertLastLogMessage("Error occurred validating a TOTP authentication", "user is anonymous")
+}
+
+func (s *HandlerSignTOTPSuite) TestShouldHandleGETAnonymous() {
+ us, err := s.mock.Ctx.GetSession()
+
+ s.Require().NoError(err)
+
+ us.Username = ""
+ us.AuthenticationLevel = authentication.NotAuthenticated
+
+ s.Require().NoError(s.mock.Ctx.SaveSession(us))
+
+ TimeBasedOneTimePasswordGET(s.mock.Ctx)
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
+
+ s.AssertLastLogMessage("Error occurred retrieving TOTP configuration", "user is anonymous")
+}
+
+func (s *HandlerSignTOTPSuite) TestShouldHandleGETErrorLoadConfiguration() {
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, testUsername).
+ Return(nil, fmt.Errorf("nah")),
+ )
+
+ TimeBasedOneTimePasswordGET(s.mock.Ctx)
+ s.mock.Assert500KO(s.T(), "Could not find TOTP Configuration for user.")
+
+ s.AssertLastLogMessage("Error occurred retrieving TOTP configuration for user 'john': error occurred retrieving the configuration from the storage backend", "nah")
+}
+
+func (s *HandlerSignTOTPSuite) TestShouldHandleGETErrorLoadConfigurationNotFound() {
+ gomock.InOrder(
+ s.mock.StorageMock.
+ EXPECT().
+ LoadTOTPConfiguration(s.mock.Ctx, testUsername).
+ Return(nil, storage.ErrNoTOTPConfiguration),
+ )
+
+ TimeBasedOneTimePasswordGET(s.mock.Ctx)
+ s.mock.Assert404KO(s.T(), "Could not find TOTP Configuration for user.")
+
+ s.AssertLastLogMessage("Error occurred retrieving TOTP configuration for user 'john': error occurred retrieving the configuration from the storage backend", "no TOTP configuration for user")
+}
+
func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidValue() {
- config := model.TOTPConfiguration{ID: 1, Username: "john", Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
gomock.InOrder(
s.mock.StorageMock.EXPECT().
@@ -277,7 +522,7 @@ func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidValue() {
Return(&config, nil),
s.mock.TOTPMock.EXPECT().
Validate(gomock.Eq("abc"), gomock.Eq(&config)).
- Return(false, fmt.Errorf("invalid")),
+ Return(false, uint64(0), fmt.Errorf("invalid")),
)
bodyBytes, err := json.Marshal(bodySignTOTPRequest{
@@ -290,35 +535,38 @@ func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidValue() {
res := r.FindAllStringSubmatch(string(s.mock.Ctx.Response.Header.PeekCookie("authelia_session")), -1)
TimeBasedOneTimePasswordPOST(s.mock.Ctx)
- s.mock.Assert401KO(s.T(), "Authentication failed, please retry later.")
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
s.NotEqual(
res[0][1],
string(s.mock.Ctx.Request.Header.Cookie("authelia_session")))
- AssertLogEntryMessageAndError(s.T(), s.mock.Hook.LastEntry(), "Failed to perform TOTP verification", "invalid")
+ AssertLogEntryMessageAndError(s.T(), s.mock.Hook.LastEntry(), "Error occurred validating a TOTP authentication for user 'john': error occurred validating the user input", "invalid")
}
func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidBoolean() {
- config := model.TOTPConfiguration{ID: 1, Username: "john", Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
gomock.InOrder(
- s.mock.StorageMock.EXPECT().
+ s.mock.StorageMock.
+ EXPECT().
LoadTOTPConfiguration(s.mock.Ctx, gomock.Any()).
Return(&config, nil),
- s.mock.TOTPMock.EXPECT().
+ s.mock.TOTPMock.
+ EXPECT().
Validate(gomock.Eq("abc"), gomock.Eq(&config)).
- Return(false, nil),
+ Return(false, uint64(0), nil),
s.mock.StorageMock.
EXPECT().
AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
- Username: "john",
+ Username: testUsername,
Successful: false,
Banned: false,
Time: s.mock.Clock.Now(),
Type: regulation.AuthTypeTOTP,
RemoteIP: model.NewNullIPFromString("0.0.0.0"),
- })),
+ })).
+ Return(nil),
)
bodyBytes, err := json.Marshal(bodySignTOTPRequest{
@@ -331,17 +579,17 @@ func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidBoolean() {
res := r.FindAllStringSubmatch(string(s.mock.Ctx.Response.Header.PeekCookie("authelia_session")), -1)
TimeBasedOneTimePasswordPOST(s.mock.Ctx)
- s.mock.Assert401KO(s.T(), "Authentication failed, please retry later.")
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
s.NotEqual(
res[0][1],
string(s.mock.Ctx.Request.Header.Cookie("authelia_session")))
- AssertLogEntryMessageAndError(s.T(), s.mock.Hook.LastEntry(), "Unsuccessful TOTP authentication attempt by user 'john'", "")
+ AssertLogEntryMessageAndError(s.T(), MustGetLogLastSeq(s.T(), s.mock.Hook, 1), "Error occurred validating a TOTP authentication for user 'john': error occurred validating the user input", "the user input wasn't valid")
}
func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidBooleanMarkErr() {
- config := model.TOTPConfiguration{ID: 1, Username: "john", Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
gomock.InOrder(
s.mock.StorageMock.EXPECT().
@@ -349,11 +597,11 @@ func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidBooleanMarkErr() {
Return(&config, nil),
s.mock.TOTPMock.EXPECT().
Validate(gomock.Eq("abc"), gomock.Eq(&config)).
- Return(false, nil),
+ Return(false, uint64(0), nil),
s.mock.StorageMock.
EXPECT().
AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
- Username: "john",
+ Username: testUsername,
Successful: false,
Banned: false,
Time: s.mock.Clock.Now(),
@@ -372,7 +620,7 @@ func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidBooleanMarkErr() {
res := r.FindAllStringSubmatch(string(s.mock.Ctx.Response.Header.PeekCookie("authelia_session")), -1)
TimeBasedOneTimePasswordPOST(s.mock.Ctx)
- s.mock.Assert401KO(s.T(), "Authentication failed, please retry later.")
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
s.NotEqual(
res[0][1],
@@ -388,17 +636,17 @@ func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidJSON() {
res := r.FindAllStringSubmatch(string(s.mock.Ctx.Response.Header.PeekCookie("authelia_session")), -1)
TimeBasedOneTimePasswordPOST(s.mock.Ctx)
- s.mock.Assert401KO(s.T(), "Authentication failed, please retry later.")
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
s.NotEqual(
res[0][1],
string(s.mock.Ctx.Request.Header.Cookie("authelia_session")))
- AssertLogEntryMessageAndError(s.T(), s.mock.Hook.LastEntry(), "Failed to parse TOTP request body", "unable to parse body: invalid character '1' after object key")
+ AssertLogEntryMessageAndError(s.T(), s.mock.Hook.LastEntry(), "Error occurred validating a TOTP authentication for user 'john': error parsing the request body", "unable to parse body: invalid character '1' after object key")
}
func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidBooleanMarkErrSuccess() {
- config := model.TOTPConfiguration{ID: 1, Username: "john", Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
+ config := model.TOTPConfiguration{ID: 1, Username: testUsername, Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"}
gomock.InOrder(
s.mock.StorageMock.EXPECT().
@@ -406,17 +654,25 @@ func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidBooleanMarkErrSucce
Return(&config, nil),
s.mock.TOTPMock.EXPECT().
Validate(gomock.Eq("abc"), gomock.Eq(&config)).
- Return(true, nil),
+ Return(true, getStepTOTP(s.mock.Ctx, -1), nil),
s.mock.StorageMock.
EXPECT().
- AppendAuthenticationLog(s.mock.Ctx, gomock.Eq(model.AuthenticationAttempt{
- Username: "john",
+ ExistsTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890), config.HistorySince(s.mock.Clock.Now(), s.mock.Ctx.Configuration.TOTP.Skew)).
+ Return(false, nil),
+ s.mock.StorageMock.
+ EXPECT().
+ SaveTOTPHistory(s.mock.Ctx, testUsername, uint64(1701295890)).
+ Return(nil),
+ s.mock.StorageMock.
+ EXPECT().
+ AppendAuthenticationLog(s.mock.Ctx, model.AuthenticationAttempt{
+ Username: testUsername,
Successful: true,
Banned: false,
Time: s.mock.Clock.Now(),
Type: regulation.AuthTypeTOTP,
RemoteIP: model.NewNullIPFromString("0.0.0.0"),
- })).
+ }).
Return(fmt.Errorf("failed to insert")),
)
@@ -430,7 +686,7 @@ func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidBooleanMarkErrSucce
res := r.FindAllStringSubmatch(string(s.mock.Ctx.Response.Header.PeekCookie("authelia_session")), -1)
TimeBasedOneTimePasswordPOST(s.mock.Ctx)
- s.mock.Assert401KO(s.T(), "Authentication failed, please retry later.")
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
s.NotEqual(
res[0][1],
@@ -456,13 +712,13 @@ func (s *HandlerSignTOTPSuite) TestShouldReturnErrorOnInvalidConfig() {
res := r.FindAllStringSubmatch(string(s.mock.Ctx.Response.Header.PeekCookie("authelia_session")), -1)
TimeBasedOneTimePasswordPOST(s.mock.Ctx)
- s.mock.Assert401KO(s.T(), "Authentication failed, please retry later.")
+ s.mock.Assert403KO(s.T(), "Authentication failed, please retry later.")
s.NotEqual(
res[0][1],
string(s.mock.Ctx.Request.Header.Cookie("authelia_session")))
- AssertLogEntryMessageAndError(s.T(), s.mock.Hook.LastEntry(), "Failed to load TOTP configuration", "not found")
+ AssertLogEntryMessageAndError(s.T(), s.mock.Hook.LastEntry(), "Error occurred validating a TOTP authentication for user 'john': error occurred retreiving the configuration from the storage backend", "not found")
}
func TestRunHandlerSignTOTPSuite(t *testing.T) {
diff --git a/internal/handlers/handler_sign_webauthn.go b/internal/handlers/handler_sign_webauthn.go
index e8c8bd387..dfa21eb59 100644
--- a/internal/handlers/handler_sign_webauthn.go
+++ b/internal/handlers/handler_sign_webauthn.go
@@ -24,7 +24,7 @@ func WebAuthnAssertionGET(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred generating a WebAuthn authentication challenge: error occurred retrieving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn authentication challenge: %s", errStrUserSessionData)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -33,7 +33,7 @@ func WebAuthnAssertionGET(ctx *middlewares.AutheliaCtx) {
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Error("Error occurred generating a WebAuthn authentication challenge")
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred generating a WebAuthn authentication challenge")
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -51,7 +51,7 @@ func WebAuthnAssertionGET(ctx *middlewares.AutheliaCtx) {
}
if user, err = handleGetWebAuthnUserByRPID(ctx, userSession.Username, userSession.DisplayName, w.Config.RPID); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn authentication challenge for user '%s': error occurred retrieving the WebAuthn user configuration from storage", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn authentication challenge for user '%s': error occurred retrieving the WebAuthn user configuration from the storage backend", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -90,7 +90,7 @@ func WebAuthnAssertionGET(ctx *middlewares.AutheliaCtx) {
userSession.WebAuthn = &data
if err = ctx.SaveSession(userSession); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred generating a WebAuthn authentication challenge: error occurred saving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn authentication challenge for user '%s': %s", userSession.Username, errStrUserSessionDataSave)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -99,7 +99,7 @@ func WebAuthnAssertionGET(ctx *middlewares.AutheliaCtx) {
}
if err = ctx.SetJSONBody(assertion); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn authentication challenge for user '%s': error occurred writing the response body", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred generating a WebAuthn authentication challenge for user '%s': %s", userSession.Username, errStrRespBody)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageUnableToRegisterSecurityKey)
@@ -127,7 +127,7 @@ func WebAuthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred validating a WebAuthn authentication challenge: error occurred retrieving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge: %s", errStrUserSessionData)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -136,7 +136,7 @@ func WebAuthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Error("Error occurred validating a WebAuthn authentication challenge")
+ ctx.Logger.WithError(errUserAnonymous).Error("Error occurred validating a WebAuthn authentication challenge")
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -144,26 +144,26 @@ func WebAuthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
return
}
- if userSession.WebAuthn == nil || userSession.WebAuthn.SessionData == nil {
- ctx.Logger.WithError(fmt.Errorf("challenge session data is not present")).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': error occurred retrieving the user session data", userSession.Username)
+ if err = ctx.ParseBody(&bodyJSON); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': %s", userSession.Username, errStrReqBodyParse)
- ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetStatusCode(fasthttp.StatusBadRequest)
ctx.SetJSONError(messageMFAValidationFailed)
return
}
- if err = ctx.ParseBody(&bodyJSON); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': error parsing the request body", userSession.Username)
+ if assertionResponse, err = protocol.ParseCredentialRequestResponseBody(bytes.NewReader(bodyJSON.Response)); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': %s", userSession.Username, errStrReqBodyParse)
- ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetStatusCode(fasthttp.StatusBadRequest)
ctx.SetJSONError(messageMFAValidationFailed)
return
}
- if assertionResponse, err = protocol.ParseCredentialRequestResponseBody(bytes.NewReader(bodyJSON.Response)); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': error parsing the request body", userSession.Username)
+ if userSession.WebAuthn == nil || userSession.WebAuthn.SessionData == nil {
+ ctx.Logger.WithError(fmt.Errorf("challenge session data is not present")).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': %s", userSession.Username, errStrUserSessionData)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -181,7 +181,7 @@ func WebAuthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
}
if user, err = handleGetWebAuthnUserByRPID(ctx, userSession.Username, userSession.DisplayName, w.Config.RPID); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': error occurred retrieving the WebAuthn user configuration from storage", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': error occurred retrieving the WebAuthn user configuration from the storage backend", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -193,6 +193,7 @@ func WebAuthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeWebAuthn, err)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageMFAValidationFailed)
return
}
@@ -201,7 +202,7 @@ func WebAuthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
userSession.WebAuthn = nil
if err = ctx.SaveSession(userSession); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred validating a WebAuthn authentication challenge: error occurred saving the user session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': %s", userSession.Username, errStrUserSessionDataSave)
}
}()
@@ -214,7 +215,7 @@ func WebAuthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
found = true
if err = ctx.Providers.StorageProvider.UpdateWebAuthnCredentialSignIn(ctx, credential); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': error occurred saving the credential sign-in information to storage", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': error occurred saving the credential sign-in information to the storage backend", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -236,7 +237,7 @@ func WebAuthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
}
if c.Authenticator.CloneWarning {
- ctx.Logger.WithError(fmt.Errorf("authenticator sign count indicates that it is cloned")).Error("Error occurred validating a WebAuthn authentication challenge: error occurred validating the authenticator response")
+ ctx.Logger.WithError(fmt.Errorf("authenticator sign count indicates that it is cloned")).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': error occurred validating the authenticator response", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -245,7 +246,7 @@ func WebAuthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
}
if err = ctx.RegenerateSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred validating a WebAuthn authentication challenge: error occurred regenerating the user session cookie value")
+ ctx.Logger.WithError(err).Errorf("Error occurred validating a WebAuthn authentication challenge for user '%s': error regenerating the user session", userSession.Username)
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
@@ -254,8 +255,6 @@ func WebAuthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
}
if err = markAuthenticationAttempt(ctx, true, nil, userSession.Username, regulation.AuthTypeWebAuthn, nil); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred validating a WebAuthn authentication challenge: error occurred recording the authentication result")
-
ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageMFAValidationFailed)
diff --git a/internal/handlers/handler_sign_webauthn_test.go b/internal/handlers/handler_sign_webauthn_test.go
index bc9f452ab..c87ad079b 100644
--- a/internal/handlers/handler_sign_webauthn_test.go
+++ b/internal/handlers/handler_sign_webauthn_test.go
@@ -9,11 +9,11 @@ import (
"time"
"github.com/go-webauthn/webauthn/webauthn"
- "github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/configuration/schema"
@@ -133,7 +133,7 @@ func TestWebAuthnAssertionGET(t *testing.T) {
assert.Nil(t, us.WebAuthn)
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating a WebAuthn authentication challenge for user 'john': error occurred retrieving the WebAuthn user configuration from storage", "failed")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred generating a WebAuthn authentication challenge for user 'john': error occurred retrieving the WebAuthn user configuration from the storage backend", "failed")
},
},
{
@@ -379,7 +379,7 @@ func TestWebAuthnAssertionPOST(t *testing.T) {
assert.Nil(t, us.WebAuthn)
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge: error occurred validating the authenticator response", "authenticator sign count indicates that it is cloned")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge for user 'john': error occurred validating the authenticator response", "authenticator sign count indicates that it is cloned")
},
},
{
@@ -450,7 +450,7 @@ func TestWebAuthnAssertionPOST(t *testing.T) {
assert.Nil(t, us.WebAuthn)
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge for user 'john': error occurred saving the credential sign-in information to storage", "failed to update")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge for user 'john': error occurred saving the credential sign-in information to the storage backend", "failed to update")
},
},
{
@@ -521,7 +521,7 @@ func TestWebAuthnAssertionPOST(t *testing.T) {
"",
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge: error occurred recording the authentication result", "bad record")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Unable to mark WebAuthn authentication attempt by user 'john'", "bad record")
},
},
{
@@ -616,7 +616,7 @@ func TestWebAuthnAssertionPOST(t *testing.T) {
},
`{"response":{"id":true,"rawId":"rwOwV8WCh1hrE0M6mvaoRGpGHidqK6IlhkDJ2xERhPU","response":{"authenticatorData":"DGygg5w6VoNVeDP2GKJVZmXfKgiJZHh9U4ULStTTvtwFAAAAAw","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiaW4xY0wtb1dmU2pTZDd1dXdVdnYybmRPQW1SWGIwY09BYlVvVHRBcXZHRSIsIm9yaWdpbiI6Imh0dHBzOi8vbG9naW4uZXhhbXBsZS5jb206ODA4MCIsImNyb3NzT3JpZ2luIjpmYWxzZSwib3RoZXJfa2V5c19jYW5fYmVfYWRkZWRfaGVyZSI6ImRvIG5vdCBjb21wYXJlIGNsaWVudERhdGFKU09OIGFnYWluc3QgYSB0ZW1wbGF0ZS4gU2VlIGh0dHBzOi8vZ29vLmdsL3lhYlBleCJ9","signature":"MEQCIBlJ2Fxf6ZwLNTCQglz0AW0pD4HlU8W5Yk696jjfxVxhAiAhAMkLh8iKyhW6zSmzwfQDjMF2nKjVHzEs7jLHRPDZ2A"},"type":"public-key","clientExtensionResults":{},"authenticatorAttachment":"cross-platform"},"targetURL":null}`,
"",
- fasthttp.StatusForbidden,
+ fasthttp.StatusBadRequest,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge for user 'john': error parsing the request body", "Parse error for Assertion")
},
@@ -646,7 +646,7 @@ func TestWebAuthnAssertionPOST(t *testing.T) {
},
`{"response:{"id":true,"rawId":"rwOwV8WCh1hrE0M6mvaoRGpGHidqK6IlhkDJ2xERhPU","response":{"authenticatorData":"DGygg5w6VoNVeDP2GKJVZmXfKgiJZHh9U4ULStTTvtwFAAAAAw","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiaW4xY0wtb1dmU2pTZDd1dXdVdnYybmRPQW1SWGIwY09BYlVvVHRBcXZHRSIsIm9yaWdpbiI6Imh0dHBzOi8vbG9naW4uZXhhbXBsZS5jb206ODA4MCIsImNyb3NzT3JpZ2luIjpmYWxzZSwib3RoZXJfa2V5c19jYW5fYmVfYWRkZWRfaGVyZSI6ImRvIG5vdCBjb21wYXJlIGNsaWVudERhdGFKU09OIGFnYWluc3QgYSB0ZW1wbGF0ZS4gU2VlIGh0dHBzOi8vZ29vLmdsL3lhYlBleCJ9","signature":"MEQCIBlJ2Fxf6ZwLNTCQglz0AW0pD4HlU8W5Yk696jjfxVxhAiAhAMkLh8iKyhW6zSmzwfQDjMF2nKjVHzEs7jLHRPDZ2A"},"type":"public-key","clientExtensionResults":{},"authenticatorAttachment":"cross-platform"},"targetURL":null}`,
"",
- fasthttp.StatusForbidden,
+ fasthttp.StatusBadRequest,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge for user 'john': error parsing the request body", "unable to parse body: invalid character 'i' after object key")
},
@@ -696,7 +696,7 @@ func TestWebAuthnAssertionPOST(t *testing.T) {
require.NoError(t, mock.Ctx.SaveSession(us))
},
- `{"response:{"id":true,"rawId":"rwOwV8WCh1hrE0M6mvaoRGpGHidqK6IlhkDJ2xERhPU","response":{"authenticatorData":"DGygg5w6VoNVeDP2GKJVZmXfKgiJZHh9U4ULStTTvtwFAAAAAw","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiaW4xY0wtb1dmU2pTZDd1dXdVdnYybmRPQW1SWGIwY09BYlVvVHRBcXZHRSIsIm9yaWdpbiI6Imh0dHBzOi8vbG9naW4uZXhhbXBsZS5jb206ODA4MCIsImNyb3NzT3JpZ2luIjpmYWxzZSwib3RoZXJfa2V5c19jYW5fYmVfYWRkZWRfaGVyZSI6ImRvIG5vdCBjb21wYXJlIGNsaWVudERhdGFKU09OIGFnYWluc3QgYSB0ZW1wbGF0ZS4gU2VlIGh0dHBzOi8vZ29vLmdsL3lhYlBleCJ9","signature":"MEQCIBlJ2Fxf6ZwLNTCQglz0AW0pD4HlU8W5Yk696jjfxVxhAiAhAMkLh8iKyhW6zSmzwfQDjMF2nKjVHzEs7jLHRPDZ2A"},"type":"public-key","clientExtensionResults":{},"authenticatorAttachment":"cross-platform"},"targetURL":null}`,
+ dataReqGood,
"",
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
@@ -715,7 +715,7 @@ func TestWebAuthnAssertionPOST(t *testing.T) {
},
},
{
- "ShouldFailUpdateAuthLog",
+ "ShouldFailLoadWebAuthnUser",
&schema.DefaultWebAuthnConfiguration,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
us, err := mock.Ctx.GetSession()
@@ -750,7 +750,7 @@ func TestWebAuthnAssertionPOST(t *testing.T) {
"",
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge for user 'john': error occurred retrieving the WebAuthn user configuration from storage", "failed to load credentials")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge for user 'john': error occurred retrieving the WebAuthn user configuration from the storage backend", "failed to load credentials")
},
},
{
@@ -785,7 +785,7 @@ func TestWebAuthnAssertionPOST(t *testing.T) {
"",
fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge for user 'john': error occurred retrieving the WebAuthn user configuration from storage", "failed load user")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred validating a WebAuthn authentication challenge for user 'john': error occurred retrieving the WebAuthn user configuration from the storage backend", "failed load user")
},
},
}
diff --git a/internal/handlers/handler_user_info_test.go b/internal/handlers/handler_user_info_test.go
index dc10ad861..64f86d6af 100644
--- a/internal/handlers/handler_user_info_test.go
+++ b/internal/handlers/handler_user_info_test.go
@@ -6,11 +6,11 @@ import (
"fmt"
"testing"
- "github.com/golang/mock/gomock"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/mocks"
diff --git a/internal/handlers/handler_webauthn_credentials.go b/internal/handlers/handler_webauthn_credentials.go
index 52e0b9e36..7e4f6d391 100644
--- a/internal/handlers/handler_webauthn_credentials.go
+++ b/internal/handlers/handler_webauthn_credentials.go
@@ -42,7 +42,7 @@ func WebAuthnCredentialsGET(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred loading WebAuthn credentials: error occurred loading session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred loading WebAuthn credentials: %s", errStrUserSessionData)
ctx.SetJSONError(messageOperationFailed)
ctx.SetStatusCode(fasthttp.StatusForbidden)
@@ -51,7 +51,7 @@ func WebAuthnCredentialsGET(ctx *middlewares.AutheliaCtx) {
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Errorf("Error occurred loading WebAuthn credentials")
+ ctx.Logger.WithError(errUserAnonymous).Errorf("Error occurred loading WebAuthn credentials")
ctx.SetJSONError(messageOperationFailed)
@@ -69,7 +69,7 @@ func WebAuthnCredentialsGET(ctx *middlewares.AutheliaCtx) {
var credentials []model.WebAuthnCredential
if credentials, err = ctx.Providers.StorageProvider.LoadWebAuthnCredentialsByUsername(ctx, origin.Hostname(), userSession.Username); err != nil && err != storage.ErrNoWebAuthnCredential {
- ctx.Logger.WithError(err).Errorf("Error occurred loading WebAuthn credentials for user '%s'", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred loading WebAuthn credentials for user '%s': error occurred loading credentials from the storage backend", userSession.Username)
ctx.SetJSONError(messageOperationFailed)
@@ -77,7 +77,7 @@ func WebAuthnCredentialsGET(ctx *middlewares.AutheliaCtx) {
}
if err = ctx.SetJSONBody(credentials); err != nil {
- ctx.Logger.WithError(err).Errorf("Error ccurred loading WebAuthn credentials for user '%s': error occurred attempting to write the response body", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error ccurred loading WebAuthn credentials for user '%s': %s", userSession.Username, errStrRespBody)
}
}
@@ -90,31 +90,35 @@ func WebAuthnCredentialPUT(ctx *middlewares.AutheliaCtx) {
credential *model.WebAuthnCredential
userSession session.UserSession
+ origin *url.URL
+ credentials []model.WebAuthnCredential
+
err error
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred modifying WebAuthn credential: error occurred loading session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred modifying WebAuthn credential: %s", errStrUserSessionData)
- ctx.SetJSONError(messageOperationFailed)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageOperationFailed)
return
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Errorf("Error occurred modifying WebAuthn credential")
+ ctx.Logger.WithError(errUserAnonymous).Errorf("Error occurred modifying WebAuthn credential")
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
return
}
if err = json.Unmarshal(ctx.PostBody(), &bodyJSON); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred modifying WebAuthn credential: error occurred parsing the form data")
+ ctx.Logger.WithError(err).Errorf("Error occurred modifying WebAuthn credential for user '%s': %s", userSession.Username, errStrReqBodyParse)
- ctx.SetJSONError(messageOperationFailed)
ctx.SetStatusCode(fasthttp.StatusBadRequest)
+ ctx.SetJSONError(messageOperationFailed)
return
}
@@ -122,6 +126,7 @@ func WebAuthnCredentialPUT(ctx *middlewares.AutheliaCtx) {
if id, err = getWebAuthnCredentialIDFromContext(ctx); err != nil {
ctx.Logger.WithError(err).Errorf("Error occurred modifying WebAuthn credential for user '%s': error occurred trying to determine the credential ID", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusBadRequest)
ctx.SetJSONError(messageOperationFailed)
return
@@ -130,14 +135,16 @@ func WebAuthnCredentialPUT(ctx *middlewares.AutheliaCtx) {
if len(bodyJSON.Description) == 0 {
ctx.Logger.WithError(fmt.Errorf("description is empty")).Errorf("Error occurred modifying WebAuthn credential for user '%s", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
return
}
if credential, err = ctx.Providers.StorageProvider.LoadWebAuthnCredentialByID(ctx, id); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred modifying WebAuthn credential for user '%s': error occurred trying to load the credential", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred modifying WebAuthn credential for user '%s': error occurred loading the credential from the storage backend", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
return
@@ -146,14 +153,49 @@ func WebAuthnCredentialPUT(ctx *middlewares.AutheliaCtx) {
if credential.Username != userSession.Username {
ctx.Logger.WithError(fmt.Errorf("user '%s' owns the credential with id '%d'", credential.Username, credential.ID)).Errorf("Error occurred modifying WebAuthn credential for user '%s'", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageOperationFailed)
+
+ return
+ }
+
+ if origin, err = ctx.GetOrigin(); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred modifying WebAuthn credential for user '%s': error occurred determining the origin for the request", userSession.Username)
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
return
}
+ if credentials, err = ctx.Providers.StorageProvider.LoadWebAuthnCredentialsByUsername(ctx, origin.Hostname(), userSession.Username); err != nil {
+ ctx.Logger.WithError(err).Errorf("Error occurred modifying WebAuthn credential for user '%s': error occurred looking up existing credentials", userSession.Username)
+
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageOperationFailed)
+
+ return
+ }
+
+ for _, c := range credentials {
+ if c.ID == id {
+ continue
+ }
+
+ if c.Description == bodyJSON.Description {
+ ctx.Logger.WithError(fmt.Errorf("credential with id '%d' also has the description '%s'", c.ID, bodyJSON.Description)).Errorf("Error occurred modifying WebAuthn credential for user '%s': error occurred ensuring the credentials had unique descriptions", userSession.Username)
+
+ ctx.SetStatusCode(fasthttp.StatusConflict)
+ ctx.SetJSONError(messageOperationFailed)
+
+ return
+ }
+ }
+
if err = ctx.Providers.StorageProvider.UpdateWebAuthnCredentialDescription(ctx, userSession.Username, id, bodyJSON.Description); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred modifying WebAuthn credential for user '%s': error occurred while attempting to save the modified credential in storage", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred modifying WebAuthn credential for user '%s': error occurred while attempting to update the modified credential in the storage backend", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
return
@@ -172,33 +214,36 @@ func WebAuthnCredentialDELETE(ctx *middlewares.AutheliaCtx) {
)
if userSession, err = ctx.GetSession(); err != nil {
- ctx.Logger.WithError(err).Error("Error occurred deleting WebAuthn credential: error occurred loading session data")
+ ctx.Logger.WithError(err).Errorf("Error occurred deleting WebAuthn credential: %s", errStrUserSessionData)
- ctx.SetJSONError(messageOperationFailed)
ctx.SetStatusCode(fasthttp.StatusForbidden)
+ ctx.SetJSONError(messageOperationFailed)
return
}
if userSession.IsAnonymous() {
- ctx.Logger.WithError(fmt.Errorf("user is anonymous")).Errorf("Error occurred modifying WebAuthn credential")
+ ctx.Logger.WithError(errUserAnonymous).Errorf("Error occurred modifying WebAuthn credential")
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
return
}
if id, err = getWebAuthnCredentialIDFromContext(ctx); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred deleting WebAuthn credential: error occurred trying to determine the credential ID")
+ ctx.Logger.WithError(err).Errorf("Error occurred deleting WebAuthn credential for user '%s': error occurred trying to determine the credential ID", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusBadRequest)
ctx.SetJSONError(messageOperationFailed)
return
}
if credential, err = ctx.Providers.StorageProvider.LoadWebAuthnCredentialByID(ctx, id); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred deleting WebAuthn credential for user '%s': error occurred trying to load the credential", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred deleting WebAuthn credential for user '%s': error occurred trying to load the credential from the storage backend", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
return
@@ -207,14 +252,16 @@ func WebAuthnCredentialDELETE(ctx *middlewares.AutheliaCtx) {
if credential.Username != userSession.Username {
ctx.Logger.WithError(fmt.Errorf("user '%s' owns the credential with id '%d'", credential.Username, credential.ID)).Errorf("Error occurred deleting WebAuthn credential for user '%s'", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
return
}
if err = ctx.Providers.StorageProvider.DeleteWebAuthnCredential(ctx, credential.KID.String()); err != nil {
- ctx.Logger.WithError(err).Errorf("Error occurred delete WebAuthn credential for user '%s': error occurred while attempting to delete the credential from storage", userSession.Username)
+ ctx.Logger.WithError(err).Errorf("Error occurred delete WebAuthn credential for user '%s': error occurred while attempting to delete the credential from the storage backend", userSession.Username)
+ ctx.SetStatusCode(fasthttp.StatusForbidden)
ctx.SetJSONError(messageOperationFailed)
return
diff --git a/internal/handlers/handler_webauthn_credentials_test.go b/internal/handlers/handler_webauthn_credentials_test.go
index d95195f48..374088693 100644
--- a/internal/handlers/handler_webauthn_credentials_test.go
+++ b/internal/handlers/handler_webauthn_credentials_test.go
@@ -5,10 +5,10 @@ import (
"net/mail"
"testing"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/mocks"
@@ -138,7 +138,7 @@ func TestWebAuthnCredentialsGET(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusOK,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred loading WebAuthn credentials for user 'john'", "bad block")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred loading WebAuthn credentials for user 'john': error occurred loading credentials from the storage backend", "bad block")
},
},
{
@@ -204,8 +204,20 @@ func TestWebAuthnCredentialsPUT(t *testing.T) {
require.NoError(t, mock.Ctx.SaveSession(us))
- mock.StorageMock.EXPECT().LoadWebAuthnCredentialByID(mock.Ctx, 1).Return(&model.WebAuthnCredential{ID: 1, Username: testUsername}, nil)
- mock.StorageMock.EXPECT().UpdateWebAuthnCredentialDescription(mock.Ctx, testUsername, 1, "abc").Return(nil)
+ gomock.InOrder(
+ mock.StorageMock.
+ EXPECT().
+ LoadWebAuthnCredentialByID(mock.Ctx, 1).
+ Return(&model.WebAuthnCredential{ID: 1, Username: testUsername}, nil),
+ mock.StorageMock.
+ EXPECT().
+ LoadWebAuthnCredentialsByUsername(mock.Ctx, exampleDotCom, testUsername).
+ Return([]model.WebAuthnCredential{{ID: 1, Username: testUsername}}, nil),
+ mock.StorageMock.
+ EXPECT().
+ UpdateWebAuthnCredentialDescription(mock.Ctx, testUsername, 1, "abc").
+ Return(nil),
+ )
},
`{"description":"abc"}`,
`{"status":"OK"}`,
@@ -213,6 +225,94 @@ func TestWebAuthnCredentialsPUT(t *testing.T) {
nil,
},
{
+ "ShouldHandleDuplicateNames",
+ func(t *testing.T, mock *mocks.MockAutheliaCtx) {
+ us, err := mock.Ctx.GetSession()
+
+ require.NoError(t, err)
+
+ us.Username = testUsername
+ us.AuthenticationLevel = authentication.OneFactor
+
+ require.NoError(t, mock.Ctx.SaveSession(us))
+
+ gomock.InOrder(
+ mock.StorageMock.
+ EXPECT().
+ LoadWebAuthnCredentialByID(mock.Ctx, 1).
+ Return(&model.WebAuthnCredential{ID: 1, Username: testUsername}, nil),
+ mock.StorageMock.
+ EXPECT().
+ LoadWebAuthnCredentialsByUsername(mock.Ctx, exampleDotCom, testUsername).
+ Return([]model.WebAuthnCredential{{ID: 1, Username: testUsername}, {ID: 2, Description: "abc", Username: testUsername}}, nil),
+ )
+ },
+ `{"description":"abc"}`,
+ `{"status":"KO","message":"Operation failed."}`,
+ fasthttp.StatusConflict,
+ func(t *testing.T, mock *mocks.MockAutheliaCtx) {
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential for user 'john': error occurred ensuring the credentials had unique descriptions", "credential with id '2' also has the description 'abc'")
+ },
+ },
+ {
+ "ShouldHandleDuplicateFail",
+ func(t *testing.T, mock *mocks.MockAutheliaCtx) {
+ us, err := mock.Ctx.GetSession()
+
+ require.NoError(t, err)
+
+ us.Username = testUsername
+ us.AuthenticationLevel = authentication.OneFactor
+
+ require.NoError(t, mock.Ctx.SaveSession(us))
+
+ gomock.InOrder(
+ mock.StorageMock.
+ EXPECT().
+ LoadWebAuthnCredentialByID(mock.Ctx, 1).
+ Return(&model.WebAuthnCredential{ID: 1, Username: testUsername}, nil),
+ mock.StorageMock.
+ EXPECT().
+ LoadWebAuthnCredentialsByUsername(mock.Ctx, exampleDotCom, testUsername).
+ Return(nil, fmt.Errorf("oops")),
+ )
+ },
+ `{"description":"abc"}`,
+ `{"status":"KO","message":"Operation failed."}`,
+ fasthttp.StatusForbidden,
+ func(t *testing.T, mock *mocks.MockAutheliaCtx) {
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential for user 'john': error occurred looking up existing credentials", "oops")
+ },
+ },
+ {
+ "ShouldHandleBadOrigin",
+ func(t *testing.T, mock *mocks.MockAutheliaCtx) {
+ us, err := mock.Ctx.GetSession()
+
+ require.NoError(t, err)
+
+ us.Username = testUsername
+ us.AuthenticationLevel = authentication.OneFactor
+
+ require.NoError(t, mock.Ctx.SaveSession(us))
+
+ gomock.InOrder(
+ mock.StorageMock.
+ EXPECT().
+ LoadWebAuthnCredentialByID(mock.Ctx, 1).
+ Return(&model.WebAuthnCredential{ID: 1, Username: testUsername}, nil),
+ )
+
+ mock.Ctx.Request.Header.Set("X-Original-URL", "##!@#!@")
+ },
+ `{"description":"abc"}`,
+ `{"status":"KO","message":"Operation failed."}`,
+ fasthttp.StatusForbidden,
+ func(t *testing.T, mock *mocks.MockAutheliaCtx) {
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential for user 'john': error occurred determining the origin for the request", "failed to parse X-Original-URL header: parse \"##!@#!@\": invalid URI for request")
+ },
+ },
+ {
"ShouldHandleAnotherUser",
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
us, err := mock.Ctx.GetSession()
@@ -224,11 +324,16 @@ func TestWebAuthnCredentialsPUT(t *testing.T) {
require.NoError(t, mock.Ctx.SaveSession(us))
- mock.StorageMock.EXPECT().LoadWebAuthnCredentialByID(mock.Ctx, 1).Return(&model.WebAuthnCredential{ID: 1, Username: "anotheruser"}, nil)
+ gomock.InOrder(
+ mock.StorageMock.
+ EXPECT().
+ LoadWebAuthnCredentialByID(mock.Ctx, 1).
+ Return(&model.WebAuthnCredential{ID: 1, Username: "anotheruser"}, nil),
+ )
},
`{"description":"abc"}`,
`{"status":"KO","message":"Operation failed."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential for user 'john'", "user 'anotheruser' owns the credential with id '1'")
},
@@ -245,14 +350,26 @@ func TestWebAuthnCredentialsPUT(t *testing.T) {
require.NoError(t, mock.Ctx.SaveSession(us))
- mock.StorageMock.EXPECT().LoadWebAuthnCredentialByID(mock.Ctx, 1).Return(&model.WebAuthnCredential{ID: 1, Username: testUsername}, nil)
- mock.StorageMock.EXPECT().UpdateWebAuthnCredentialDescription(mock.Ctx, testUsername, 1, "abc").Return(fmt.Errorf("gremlin"))
+ gomock.InOrder(
+ mock.StorageMock.
+ EXPECT().
+ LoadWebAuthnCredentialByID(mock.Ctx, 1).
+ Return(&model.WebAuthnCredential{ID: 1, Username: testUsername}, nil),
+ mock.StorageMock.
+ EXPECT().
+ LoadWebAuthnCredentialsByUsername(mock.Ctx, exampleDotCom, testUsername).
+ Return([]model.WebAuthnCredential{{ID: 1, Username: testUsername}}, nil),
+ mock.StorageMock.
+ EXPECT().
+ UpdateWebAuthnCredentialDescription(mock.Ctx, testUsername, 1, "abc").
+ Return(fmt.Errorf("gremlin")),
+ )
},
`{"description":"abc"}`,
`{"status":"KO","message":"Operation failed."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential for user 'john': error occurred while attempting to save the modified credential in storage", "gremlin")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential for user 'john': error occurred while attempting to update the modified credential in the storage backend", "gremlin")
},
},
{
@@ -271,9 +388,9 @@ func TestWebAuthnCredentialsPUT(t *testing.T) {
},
`{"description":"abc"}`,
`{"status":"KO","message":"Operation failed."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential for user 'john': error occurred trying to load the credential", "deleted")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential for user 'john': error occurred loading the credential from the storage backend", "deleted")
},
},
{
@@ -292,7 +409,7 @@ func TestWebAuthnCredentialsPUT(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusBadRequest,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential: error occurred parsing the form data", "invalid character 'a' after object key")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential for user 'john': error parsing the request body", "invalid character 'a' after object key")
},
},
{
@@ -309,7 +426,7 @@ func TestWebAuthnCredentialsPUT(t *testing.T) {
},
`{"description":""}`,
`{"status":"KO","message":"Operation failed."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential for user 'john", "description is empty")
},
@@ -319,7 +436,7 @@ func TestWebAuthnCredentialsPUT(t *testing.T) {
nil,
`{"description":"abc"}`,
`{"status":"KO","message":"Operation failed."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential", "user is anonymous")
},
@@ -496,9 +613,9 @@ func TestWebAuthnCredentialsDELETE(t *testing.T) {
)
},
`{"status":"KO","message":"Operation failed."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred delete WebAuthn credential for user 'john': error occurred while attempting to delete the credential from storage", "bad pipe")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred delete WebAuthn credential for user 'john': error occurred while attempting to delete the credential from the storage backend", "bad pipe")
},
},
{
@@ -520,9 +637,9 @@ func TestWebAuthnCredentialsDELETE(t *testing.T) {
)
},
`{"status":"KO","message":"Operation failed."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred deleting WebAuthn credential for user 'john': error occurred trying to load the credential", "bad sql password")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred deleting WebAuthn credential for user 'john': error occurred trying to load the credential from the storage backend", "bad sql password")
},
},
{
@@ -544,7 +661,7 @@ func TestWebAuthnCredentialsDELETE(t *testing.T) {
)
},
`{"status":"KO","message":"Operation failed."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred deleting WebAuthn credential for user 'john'", "user 'baduser' owns the credential with id '1'")
},
@@ -566,14 +683,14 @@ func TestWebAuthnCredentialsDELETE(t *testing.T) {
`{"status":"KO","message":"Operation failed."}`,
fasthttp.StatusBadRequest,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
- AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred deleting WebAuthn credential: error occurred trying to determine the credential ID", "strconv.Atoi: parsing \"a\": invalid syntax")
+ AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred deleting WebAuthn credential for user 'john': error occurred trying to determine the credential ID", "strconv.Atoi: parsing \"a\": invalid syntax")
},
},
{
"ShouldHandleAnonymous",
nil,
`{"status":"KO","message":"Operation failed."}`,
- fasthttp.StatusOK,
+ fasthttp.StatusForbidden,
func(t *testing.T, mock *mocks.MockAutheliaCtx) {
AssertLogEntryMessageAndError(t, mock.Hook.LastEntry(), "Error occurred modifying WebAuthn credential", "user is anonymous")
},
diff --git a/internal/handlers/webauthn_test.go b/internal/handlers/webauthn_test.go
index 100db5ab8..480affd34 100644
--- a/internal/handlers/webauthn_test.go
+++ b/internal/handlers/webauthn_test.go
@@ -6,10 +6,10 @@ import (
"testing"
"github.com/go-webauthn/webauthn/protocol"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/mocks"
"github.com/authelia/authelia/v4/internal/model"
diff --git a/internal/middlewares/authelia_context_test.go b/internal/middlewares/authelia_context_test.go
index 2430d846c..c20b9df88 100644
--- a/internal/middlewares/authelia_context_test.go
+++ b/internal/middlewares/authelia_context_test.go
@@ -5,10 +5,10 @@ import (
"net/url"
"testing"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/middlewares"
diff --git a/internal/middlewares/identity_verification_test.go b/internal/middlewares/identity_verification_test.go
index 011eb3274..54e81bb5d 100644
--- a/internal/middlewares/identity_verification_test.go
+++ b/internal/middlewares/identity_verification_test.go
@@ -7,11 +7,11 @@ import (
"time"
"github.com/golang-jwt/jwt/v5"
- "github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/middlewares"
"github.com/authelia/authelia/v4/internal/mocks"
diff --git a/internal/mocks/authelia_ctx.go b/internal/mocks/authelia_ctx.go
index 906a3a72c..b51207112 100644
--- a/internal/mocks/authelia_ctx.go
+++ b/internal/mocks/authelia_ctx.go
@@ -7,12 +7,12 @@ import (
"testing"
"time"
- "github.com/golang/mock/gomock"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/authorization"
"github.com/authelia/authelia/v4/internal/clock"
@@ -263,6 +263,24 @@ func (m *MockAutheliaCtx) Assert401KO(t *testing.T, message string) {
assert.Equal(t, fmt.Sprintf("{\"status\":\"KO\",\"message\":\"%s\"}", message), string(m.Ctx.Response.Body()))
}
+// Assert403KO assert an error response from the service.
+func (m *MockAutheliaCtx) Assert403KO(t *testing.T, message string) {
+ assert.Equal(t, fasthttp.StatusForbidden, m.Ctx.Response.StatusCode())
+ assert.Equal(t, fmt.Sprintf("{\"status\":\"KO\",\"message\":\"%s\"}", message), string(m.Ctx.Response.Body()))
+}
+
+// Assert404KO assert an error response from the service.
+func (m *MockAutheliaCtx) Assert404KO(t *testing.T, message string) {
+ assert.Equal(t, fasthttp.StatusNotFound, m.Ctx.Response.StatusCode())
+ assert.Equal(t, fmt.Sprintf("{\"status\":\"KO\",\"message\":\"%s\"}", message), string(m.Ctx.Response.Body()))
+}
+
+// Assert500KO assert an error response from the service.
+func (m *MockAutheliaCtx) Assert500KO(t *testing.T, message string) {
+ assert.Equal(t, fasthttp.StatusInternalServerError, m.Ctx.Response.StatusCode())
+ assert.Equal(t, fmt.Sprintf("{\"status\":\"KO\",\"message\":\"%s\"}", message), string(m.Ctx.Response.Body()))
+}
+
// Assert200KO assert an error response from the service.
func (m *MockAutheliaCtx) Assert200KO(t *testing.T, message string) {
assert.Equal(t, fasthttp.StatusOK, m.Ctx.Response.StatusCode())
diff --git a/internal/mocks/duo_api.go b/internal/mocks/duo_api.go
index d358f9c74..655dc331b 100644
--- a/internal/mocks/duo_api.go
+++ b/internal/mocks/duo_api.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/authelia/authelia/v4/internal/duo (interfaces: API)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination duo_api.go -mock_names API=MockAPI github.com/authelia/authelia/v4/internal/duo API
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -11,7 +15,7 @@ import (
duo "github.com/authelia/authelia/v4/internal/duo"
middlewares "github.com/authelia/authelia/v4/internal/middlewares"
session "github.com/authelia/authelia/v4/internal/session"
- gomock "github.com/golang/mock/gomock"
+ gomock "go.uber.org/mock/gomock"
)
// MockAPI is a mock of API interface.
@@ -47,7 +51,7 @@ func (m *MockAPI) AuthCall(arg0 *middlewares.AutheliaCtx, arg1 *session.UserSess
}
// AuthCall indicates an expected call of AuthCall.
-func (mr *MockAPIMockRecorder) AuthCall(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockAPIMockRecorder) AuthCall(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthCall", reflect.TypeOf((*MockAPI)(nil).AuthCall), arg0, arg1, arg2)
}
@@ -62,7 +66,7 @@ func (m *MockAPI) Call(arg0 *middlewares.AutheliaCtx, arg1 *session.UserSession,
}
// Call indicates an expected call of Call.
-func (mr *MockAPIMockRecorder) Call(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
+func (mr *MockAPIMockRecorder) Call(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Call", reflect.TypeOf((*MockAPI)(nil).Call), arg0, arg1, arg2, arg3, arg4)
}
@@ -77,7 +81,7 @@ func (m *MockAPI) PreAuthCall(arg0 *middlewares.AutheliaCtx, arg1 *session.UserS
}
// PreAuthCall indicates an expected call of PreAuthCall.
-func (mr *MockAPIMockRecorder) PreAuthCall(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockAPIMockRecorder) PreAuthCall(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PreAuthCall", reflect.TypeOf((*MockAPI)(nil).PreAuthCall), arg0, arg1, arg2)
}
diff --git a/internal/mocks/fosite_access_requester.go b/internal/mocks/fosite_access_requester.go
index 91ffa6a8a..cea0a3a64 100644
--- a/internal/mocks/fosite_access_requester.go
+++ b/internal/mocks/fosite_access_requester.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ory/fosite (interfaces: AccessRequester)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination fosite_access_requester.go -mock_names Provider=MockAccessRequester github.com/ory/fosite AccessRequester
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -9,8 +13,8 @@ import (
reflect "reflect"
time "time"
- gomock "github.com/golang/mock/gomock"
fosite "github.com/ory/fosite"
+ gomock "go.uber.org/mock/gomock"
)
// MockAccessRequester is a mock of AccessRequester interface.
@@ -43,7 +47,7 @@ func (m *MockAccessRequester) AppendRequestedScope(arg0 string) {
}
// AppendRequestedScope indicates an expected call of AppendRequestedScope.
-func (mr *MockAccessRequesterMockRecorder) AppendRequestedScope(arg0 interface{}) *gomock.Call {
+func (mr *MockAccessRequesterMockRecorder) AppendRequestedScope(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendRequestedScope", reflect.TypeOf((*MockAccessRequester)(nil).AppendRequestedScope), arg0)
}
@@ -195,7 +199,7 @@ func (m *MockAccessRequester) GrantAudience(arg0 string) {
}
// GrantAudience indicates an expected call of GrantAudience.
-func (mr *MockAccessRequesterMockRecorder) GrantAudience(arg0 interface{}) *gomock.Call {
+func (mr *MockAccessRequesterMockRecorder) GrantAudience(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GrantAudience", reflect.TypeOf((*MockAccessRequester)(nil).GrantAudience), arg0)
}
@@ -207,7 +211,7 @@ func (m *MockAccessRequester) GrantScope(arg0 string) {
}
// GrantScope indicates an expected call of GrantScope.
-func (mr *MockAccessRequesterMockRecorder) GrantScope(arg0 interface{}) *gomock.Call {
+func (mr *MockAccessRequesterMockRecorder) GrantScope(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GrantScope", reflect.TypeOf((*MockAccessRequester)(nil).GrantScope), arg0)
}
@@ -219,7 +223,7 @@ func (m *MockAccessRequester) Merge(arg0 fosite.Requester) {
}
// Merge indicates an expected call of Merge.
-func (mr *MockAccessRequesterMockRecorder) Merge(arg0 interface{}) *gomock.Call {
+func (mr *MockAccessRequesterMockRecorder) Merge(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Merge", reflect.TypeOf((*MockAccessRequester)(nil).Merge), arg0)
}
@@ -233,7 +237,7 @@ func (m *MockAccessRequester) Sanitize(arg0 []string) fosite.Requester {
}
// Sanitize indicates an expected call of Sanitize.
-func (mr *MockAccessRequesterMockRecorder) Sanitize(arg0 interface{}) *gomock.Call {
+func (mr *MockAccessRequesterMockRecorder) Sanitize(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sanitize", reflect.TypeOf((*MockAccessRequester)(nil).Sanitize), arg0)
}
@@ -245,7 +249,7 @@ func (m *MockAccessRequester) SetID(arg0 string) {
}
// SetID indicates an expected call of SetID.
-func (mr *MockAccessRequesterMockRecorder) SetID(arg0 interface{}) *gomock.Call {
+func (mr *MockAccessRequesterMockRecorder) SetID(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetID", reflect.TypeOf((*MockAccessRequester)(nil).SetID), arg0)
}
@@ -257,7 +261,7 @@ func (m *MockAccessRequester) SetRequestedAudience(arg0 fosite.Arguments) {
}
// SetRequestedAudience indicates an expected call of SetRequestedAudience.
-func (mr *MockAccessRequesterMockRecorder) SetRequestedAudience(arg0 interface{}) *gomock.Call {
+func (mr *MockAccessRequesterMockRecorder) SetRequestedAudience(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetRequestedAudience", reflect.TypeOf((*MockAccessRequester)(nil).SetRequestedAudience), arg0)
}
@@ -269,7 +273,7 @@ func (m *MockAccessRequester) SetRequestedScopes(arg0 fosite.Arguments) {
}
// SetRequestedScopes indicates an expected call of SetRequestedScopes.
-func (mr *MockAccessRequesterMockRecorder) SetRequestedScopes(arg0 interface{}) *gomock.Call {
+func (mr *MockAccessRequesterMockRecorder) SetRequestedScopes(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetRequestedScopes", reflect.TypeOf((*MockAccessRequester)(nil).SetRequestedScopes), arg0)
}
@@ -281,7 +285,7 @@ func (m *MockAccessRequester) SetSession(arg0 fosite.Session) {
}
// SetSession indicates an expected call of SetSession.
-func (mr *MockAccessRequesterMockRecorder) SetSession(arg0 interface{}) *gomock.Call {
+func (mr *MockAccessRequesterMockRecorder) SetSession(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSession", reflect.TypeOf((*MockAccessRequester)(nil).SetSession), arg0)
}
diff --git a/internal/mocks/fosite_access_token_strategy.go b/internal/mocks/fosite_access_token_strategy.go
index 0e3baa1c6..319c5fd6c 100644
--- a/internal/mocks/fosite_access_token_strategy.go
+++ b/internal/mocks/fosite_access_token_strategy.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ory/fosite/handler/oauth2 (interfaces: AccessTokenStrategy)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination fosite_access_token_strategy.go -mock_names Provider=MockAccessTokenStrategy github.com/ory/fosite/handler/oauth2 AccessTokenStrategy
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -8,8 +12,8 @@ import (
context "context"
reflect "reflect"
- gomock "github.com/golang/mock/gomock"
fosite "github.com/ory/fosite"
+ gomock "go.uber.org/mock/gomock"
)
// MockAccessTokenStrategy is a mock of AccessTokenStrategy interface.
@@ -44,7 +48,7 @@ func (m *MockAccessTokenStrategy) AccessTokenSignature(arg0 context.Context, arg
}
// AccessTokenSignature indicates an expected call of AccessTokenSignature.
-func (mr *MockAccessTokenStrategyMockRecorder) AccessTokenSignature(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockAccessTokenStrategyMockRecorder) AccessTokenSignature(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccessTokenSignature", reflect.TypeOf((*MockAccessTokenStrategy)(nil).AccessTokenSignature), arg0, arg1)
}
@@ -60,7 +64,7 @@ func (m *MockAccessTokenStrategy) GenerateAccessToken(arg0 context.Context, arg1
}
// GenerateAccessToken indicates an expected call of GenerateAccessToken.
-func (mr *MockAccessTokenStrategyMockRecorder) GenerateAccessToken(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockAccessTokenStrategyMockRecorder) GenerateAccessToken(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenerateAccessToken", reflect.TypeOf((*MockAccessTokenStrategy)(nil).GenerateAccessToken), arg0, arg1)
}
@@ -74,7 +78,7 @@ func (m *MockAccessTokenStrategy) ValidateAccessToken(arg0 context.Context, arg1
}
// ValidateAccessToken indicates an expected call of ValidateAccessToken.
-func (mr *MockAccessTokenStrategyMockRecorder) ValidateAccessToken(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockAccessTokenStrategyMockRecorder) ValidateAccessToken(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateAccessToken", reflect.TypeOf((*MockAccessTokenStrategy)(nil).ValidateAccessToken), arg0, arg1, arg2)
}
diff --git a/internal/mocks/fosite_client_credentials_grant_storage.go b/internal/mocks/fosite_client_credentials_grant_storage.go
index 077712a7d..a35d2bc52 100644
--- a/internal/mocks/fosite_client_credentials_grant_storage.go
+++ b/internal/mocks/fosite_client_credentials_grant_storage.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ory/fosite/handler/oauth2 (interfaces: ClientCredentialsGrantStorage)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination fosite_client_credentials_grant_storage.go -mock_names Provider=MockClientCredentialsGrantStorage github.com/ory/fosite/handler/oauth2 ClientCredentialsGrantStorage
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -8,8 +12,8 @@ import (
context "context"
reflect "reflect"
- gomock "github.com/golang/mock/gomock"
fosite "github.com/ory/fosite"
+ gomock "go.uber.org/mock/gomock"
)
// MockClientCredentialsGrantStorage is a mock of ClientCredentialsGrantStorage interface.
@@ -44,7 +48,7 @@ func (m *MockClientCredentialsGrantStorage) CreateAccessTokenSession(arg0 contex
}
// CreateAccessTokenSession indicates an expected call of CreateAccessTokenSession.
-func (mr *MockClientCredentialsGrantStorageMockRecorder) CreateAccessTokenSession(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockClientCredentialsGrantStorageMockRecorder) CreateAccessTokenSession(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAccessTokenSession", reflect.TypeOf((*MockClientCredentialsGrantStorage)(nil).CreateAccessTokenSession), arg0, arg1, arg2)
}
@@ -58,7 +62,7 @@ func (m *MockClientCredentialsGrantStorage) DeleteAccessTokenSession(arg0 contex
}
// DeleteAccessTokenSession indicates an expected call of DeleteAccessTokenSession.
-func (mr *MockClientCredentialsGrantStorageMockRecorder) DeleteAccessTokenSession(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockClientCredentialsGrantStorageMockRecorder) DeleteAccessTokenSession(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAccessTokenSession", reflect.TypeOf((*MockClientCredentialsGrantStorage)(nil).DeleteAccessTokenSession), arg0, arg1)
}
@@ -73,7 +77,7 @@ func (m *MockClientCredentialsGrantStorage) GetAccessTokenSession(arg0 context.C
}
// GetAccessTokenSession indicates an expected call of GetAccessTokenSession.
-func (mr *MockClientCredentialsGrantStorageMockRecorder) GetAccessTokenSession(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockClientCredentialsGrantStorageMockRecorder) GetAccessTokenSession(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccessTokenSession", reflect.TypeOf((*MockClientCredentialsGrantStorage)(nil).GetAccessTokenSession), arg0, arg1, arg2)
}
diff --git a/internal/mocks/fosite_pkce_request_storage.go b/internal/mocks/fosite_pkce_request_storage.go
index be8191bc0..1ada6e2d5 100644
--- a/internal/mocks/fosite_pkce_request_storage.go
+++ b/internal/mocks/fosite_pkce_request_storage.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ory/fosite/handler/pkce (interfaces: PKCERequestStorage)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination fosite_pkce_request_storage.go -mock_names Provider=MockPKCERequestStorage github.com/ory/fosite/handler/pkce PKCERequestStorage
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -8,8 +12,8 @@ import (
context "context"
reflect "reflect"
- gomock "github.com/golang/mock/gomock"
fosite "github.com/ory/fosite"
+ gomock "go.uber.org/mock/gomock"
)
// MockPKCERequestStorage is a mock of PKCERequestStorage interface.
@@ -44,7 +48,7 @@ func (m *MockPKCERequestStorage) CreatePKCERequestSession(arg0 context.Context,
}
// CreatePKCERequestSession indicates an expected call of CreatePKCERequestSession.
-func (mr *MockPKCERequestStorageMockRecorder) CreatePKCERequestSession(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockPKCERequestStorageMockRecorder) CreatePKCERequestSession(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreatePKCERequestSession", reflect.TypeOf((*MockPKCERequestStorage)(nil).CreatePKCERequestSession), arg0, arg1, arg2)
}
@@ -58,7 +62,7 @@ func (m *MockPKCERequestStorage) DeletePKCERequestSession(arg0 context.Context,
}
// DeletePKCERequestSession indicates an expected call of DeletePKCERequestSession.
-func (mr *MockPKCERequestStorageMockRecorder) DeletePKCERequestSession(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockPKCERequestStorageMockRecorder) DeletePKCERequestSession(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePKCERequestSession", reflect.TypeOf((*MockPKCERequestStorage)(nil).DeletePKCERequestSession), arg0, arg1)
}
@@ -73,7 +77,7 @@ func (m *MockPKCERequestStorage) GetPKCERequestSession(arg0 context.Context, arg
}
// GetPKCERequestSession indicates an expected call of GetPKCERequestSession.
-func (mr *MockPKCERequestStorageMockRecorder) GetPKCERequestSession(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockPKCERequestStorageMockRecorder) GetPKCERequestSession(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPKCERequestSession", reflect.TypeOf((*MockPKCERequestStorage)(nil).GetPKCERequestSession), arg0, arg1, arg2)
}
diff --git a/internal/mocks/fosite_storage.go b/internal/mocks/fosite_storage.go
index aea59a69d..e7b99271b 100644
--- a/internal/mocks/fosite_storage.go
+++ b/internal/mocks/fosite_storage.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ory/fosite (interfaces: Storage)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination fosite_storage.go -mock_names Storage=MockFositeStorage github.com/ory/fosite Storage
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -9,8 +13,8 @@ import (
reflect "reflect"
time "time"
- gomock "github.com/golang/mock/gomock"
fosite "github.com/ory/fosite"
+ gomock "go.uber.org/mock/gomock"
)
// MockFositeStorage is a mock of Storage interface.
@@ -45,7 +49,7 @@ func (m *MockFositeStorage) ClientAssertionJWTValid(arg0 context.Context, arg1 s
}
// ClientAssertionJWTValid indicates an expected call of ClientAssertionJWTValid.
-func (mr *MockFositeStorageMockRecorder) ClientAssertionJWTValid(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockFositeStorageMockRecorder) ClientAssertionJWTValid(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientAssertionJWTValid", reflect.TypeOf((*MockFositeStorage)(nil).ClientAssertionJWTValid), arg0, arg1)
}
@@ -60,7 +64,7 @@ func (m *MockFositeStorage) GetClient(arg0 context.Context, arg1 string) (fosite
}
// GetClient indicates an expected call of GetClient.
-func (mr *MockFositeStorageMockRecorder) GetClient(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockFositeStorageMockRecorder) GetClient(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClient", reflect.TypeOf((*MockFositeStorage)(nil).GetClient), arg0, arg1)
}
@@ -74,7 +78,7 @@ func (m *MockFositeStorage) SetClientAssertionJWT(arg0 context.Context, arg1 str
}
// SetClientAssertionJWT indicates an expected call of SetClientAssertionJWT.
-func (mr *MockFositeStorageMockRecorder) SetClientAssertionJWT(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockFositeStorageMockRecorder) SetClientAssertionJWT(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClientAssertionJWT", reflect.TypeOf((*MockFositeStorage)(nil).SetClientAssertionJWT), arg0, arg1, arg2)
}
diff --git a/internal/mocks/fosite_token_introspector.go b/internal/mocks/fosite_token_introspector.go
index 0dd8ebd66..52760ea76 100644
--- a/internal/mocks/fosite_token_introspector.go
+++ b/internal/mocks/fosite_token_introspector.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ory/fosite (interfaces: TokenIntrospector)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination fosite_token_introspector.go -mock_names TokenIntrospector=MockTokenIntrospector github.com/ory/fosite TokenIntrospector
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -8,8 +12,8 @@ import (
context "context"
reflect "reflect"
- gomock "github.com/golang/mock/gomock"
fosite "github.com/ory/fosite"
+ gomock "go.uber.org/mock/gomock"
)
// MockTokenIntrospector is a mock of TokenIntrospector interface.
@@ -45,7 +49,7 @@ func (m *MockTokenIntrospector) IntrospectToken(arg0 context.Context, arg1 strin
}
// IntrospectToken indicates an expected call of IntrospectToken.
-func (mr *MockTokenIntrospectorMockRecorder) IntrospectToken(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
+func (mr *MockTokenIntrospectorMockRecorder) IntrospectToken(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IntrospectToken", reflect.TypeOf((*MockTokenIntrospector)(nil).IntrospectToken), arg0, arg1, arg2, arg3, arg4)
}
diff --git a/internal/mocks/fosite_token_revocation_storage.go b/internal/mocks/fosite_token_revocation_storage.go
index b47d9aef6..d9836c373 100644
--- a/internal/mocks/fosite_token_revocation_storage.go
+++ b/internal/mocks/fosite_token_revocation_storage.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ory/fosite/handler/oauth2 (interfaces: TokenRevocationStorage)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination fosite_token_revocation_storage.go -mock_names Provider=MockTokenRevocationStorage github.com/ory/fosite/handler/oauth2 TokenRevocationStorage
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -8,8 +12,8 @@ import (
context "context"
reflect "reflect"
- gomock "github.com/golang/mock/gomock"
fosite "github.com/ory/fosite"
+ gomock "go.uber.org/mock/gomock"
)
// MockTokenRevocationStorage is a mock of TokenRevocationStorage interface.
@@ -44,7 +48,7 @@ func (m *MockTokenRevocationStorage) CreateAccessTokenSession(arg0 context.Conte
}
// CreateAccessTokenSession indicates an expected call of CreateAccessTokenSession.
-func (mr *MockTokenRevocationStorageMockRecorder) CreateAccessTokenSession(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockTokenRevocationStorageMockRecorder) CreateAccessTokenSession(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAccessTokenSession", reflect.TypeOf((*MockTokenRevocationStorage)(nil).CreateAccessTokenSession), arg0, arg1, arg2)
}
@@ -58,7 +62,7 @@ func (m *MockTokenRevocationStorage) CreateRefreshTokenSession(arg0 context.Cont
}
// CreateRefreshTokenSession indicates an expected call of CreateRefreshTokenSession.
-func (mr *MockTokenRevocationStorageMockRecorder) CreateRefreshTokenSession(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockTokenRevocationStorageMockRecorder) CreateRefreshTokenSession(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRefreshTokenSession", reflect.TypeOf((*MockTokenRevocationStorage)(nil).CreateRefreshTokenSession), arg0, arg1, arg2)
}
@@ -72,7 +76,7 @@ func (m *MockTokenRevocationStorage) DeleteAccessTokenSession(arg0 context.Conte
}
// DeleteAccessTokenSession indicates an expected call of DeleteAccessTokenSession.
-func (mr *MockTokenRevocationStorageMockRecorder) DeleteAccessTokenSession(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockTokenRevocationStorageMockRecorder) DeleteAccessTokenSession(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAccessTokenSession", reflect.TypeOf((*MockTokenRevocationStorage)(nil).DeleteAccessTokenSession), arg0, arg1)
}
@@ -86,7 +90,7 @@ func (m *MockTokenRevocationStorage) DeleteRefreshTokenSession(arg0 context.Cont
}
// DeleteRefreshTokenSession indicates an expected call of DeleteRefreshTokenSession.
-func (mr *MockTokenRevocationStorageMockRecorder) DeleteRefreshTokenSession(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockTokenRevocationStorageMockRecorder) DeleteRefreshTokenSession(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRefreshTokenSession", reflect.TypeOf((*MockTokenRevocationStorage)(nil).DeleteRefreshTokenSession), arg0, arg1)
}
@@ -101,7 +105,7 @@ func (m *MockTokenRevocationStorage) GetAccessTokenSession(arg0 context.Context,
}
// GetAccessTokenSession indicates an expected call of GetAccessTokenSession.
-func (mr *MockTokenRevocationStorageMockRecorder) GetAccessTokenSession(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockTokenRevocationStorageMockRecorder) GetAccessTokenSession(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccessTokenSession", reflect.TypeOf((*MockTokenRevocationStorage)(nil).GetAccessTokenSession), arg0, arg1, arg2)
}
@@ -116,7 +120,7 @@ func (m *MockTokenRevocationStorage) GetRefreshTokenSession(arg0 context.Context
}
// GetRefreshTokenSession indicates an expected call of GetRefreshTokenSession.
-func (mr *MockTokenRevocationStorageMockRecorder) GetRefreshTokenSession(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockTokenRevocationStorageMockRecorder) GetRefreshTokenSession(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRefreshTokenSession", reflect.TypeOf((*MockTokenRevocationStorage)(nil).GetRefreshTokenSession), arg0, arg1, arg2)
}
@@ -130,7 +134,7 @@ func (m *MockTokenRevocationStorage) RevokeAccessToken(arg0 context.Context, arg
}
// RevokeAccessToken indicates an expected call of RevokeAccessToken.
-func (mr *MockTokenRevocationStorageMockRecorder) RevokeAccessToken(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockTokenRevocationStorageMockRecorder) RevokeAccessToken(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevokeAccessToken", reflect.TypeOf((*MockTokenRevocationStorage)(nil).RevokeAccessToken), arg0, arg1)
}
@@ -144,7 +148,7 @@ func (m *MockTokenRevocationStorage) RevokeRefreshToken(arg0 context.Context, ar
}
// RevokeRefreshToken indicates an expected call of RevokeRefreshToken.
-func (mr *MockTokenRevocationStorageMockRecorder) RevokeRefreshToken(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockTokenRevocationStorageMockRecorder) RevokeRefreshToken(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevokeRefreshToken", reflect.TypeOf((*MockTokenRevocationStorage)(nil).RevokeRefreshToken), arg0, arg1)
}
@@ -158,7 +162,7 @@ func (m *MockTokenRevocationStorage) RevokeRefreshTokenMaybeGracePeriod(arg0 con
}
// RevokeRefreshTokenMaybeGracePeriod indicates an expected call of RevokeRefreshTokenMaybeGracePeriod.
-func (mr *MockTokenRevocationStorageMockRecorder) RevokeRefreshTokenMaybeGracePeriod(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockTokenRevocationStorageMockRecorder) RevokeRefreshTokenMaybeGracePeriod(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevokeRefreshTokenMaybeGracePeriod", reflect.TypeOf((*MockTokenRevocationStorage)(nil).RevokeRefreshTokenMaybeGracePeriod), arg0, arg1, arg2)
}
diff --git a/internal/mocks/fosite_transactional.go b/internal/mocks/fosite_transactional.go
index 817bef67b..3ff7a11aa 100644
--- a/internal/mocks/fosite_transactional.go
+++ b/internal/mocks/fosite_transactional.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ory/fosite/storage (interfaces: Transactional)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination fosite_transactional.go -mock_names Provider=MockTransactional github.com/ory/fosite/storage Transactional
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -8,7 +12,7 @@ import (
context "context"
reflect "reflect"
- gomock "github.com/golang/mock/gomock"
+ gomock "go.uber.org/mock/gomock"
)
// MockTransactional is a mock of Transactional interface.
@@ -44,7 +48,7 @@ func (m *MockTransactional) BeginTX(arg0 context.Context) (context.Context, erro
}
// BeginTX indicates an expected call of BeginTX.
-func (mr *MockTransactionalMockRecorder) BeginTX(arg0 interface{}) *gomock.Call {
+func (mr *MockTransactionalMockRecorder) BeginTX(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginTX", reflect.TypeOf((*MockTransactional)(nil).BeginTX), arg0)
}
@@ -58,7 +62,7 @@ func (m *MockTransactional) Commit(arg0 context.Context) error {
}
// Commit indicates an expected call of Commit.
-func (mr *MockTransactionalMockRecorder) Commit(arg0 interface{}) *gomock.Call {
+func (mr *MockTransactionalMockRecorder) Commit(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockTransactional)(nil).Commit), arg0)
}
@@ -72,7 +76,7 @@ func (m *MockTransactional) Rollback(arg0 context.Context) error {
}
// Rollback indicates an expected call of Rollback.
-func (mr *MockTransactionalMockRecorder) Rollback(arg0 interface{}) *gomock.Call {
+func (mr *MockTransactionalMockRecorder) Rollback(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Rollback", reflect.TypeOf((*MockTransactional)(nil).Rollback), arg0)
}
diff --git a/internal/mocks/notifier.go b/internal/mocks/notifier.go
index b568e808c..6f31b8e7a 100644
--- a/internal/mocks/notifier.go
+++ b/internal/mocks/notifier.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/authelia/authelia/v4/internal/notification (interfaces: Notifier)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination notifier.go -mock_names Notifier=MockNotifier github.com/authelia/authelia/v4/internal/notification Notifier
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -10,7 +14,7 @@ import (
reflect "reflect"
templates "github.com/authelia/authelia/v4/internal/templates"
- gomock "github.com/golang/mock/gomock"
+ gomock "go.uber.org/mock/gomock"
)
// MockNotifier is a mock of Notifier interface.
@@ -37,7 +41,7 @@ func (m *MockNotifier) EXPECT() *MockNotifierMockRecorder {
}
// Send mocks base method.
-func (m *MockNotifier) Send(arg0 context.Context, arg1 mail.Address, arg2 string, arg3 *templates.EmailTemplate, arg4 interface{}) error {
+func (m *MockNotifier) Send(arg0 context.Context, arg1 mail.Address, arg2 string, arg3 *templates.EmailTemplate, arg4 any) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Send", arg0, arg1, arg2, arg3, arg4)
ret0, _ := ret[0].(error)
@@ -45,7 +49,7 @@ func (m *MockNotifier) Send(arg0 context.Context, arg1 mail.Address, arg2 string
}
// Send indicates an expected call of Send.
-func (mr *MockNotifierMockRecorder) Send(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
+func (mr *MockNotifierMockRecorder) Send(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockNotifier)(nil).Send), arg0, arg1, arg2, arg3, arg4)
}
diff --git a/internal/mocks/random.go b/internal/mocks/random.go
index 497bc4d1e..f566c59a1 100644
--- a/internal/mocks/random.go
+++ b/internal/mocks/random.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/authelia/authelia/v4/internal/random (interfaces: Provider)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination random.go -mock_names Provider=MockRandom github.com/authelia/authelia/v4/internal/random Provider
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -8,7 +12,7 @@ import (
big "math/big"
reflect "reflect"
- gomock "github.com/golang/mock/gomock"
+ gomock "go.uber.org/mock/gomock"
)
// MockRandom is a mock of Provider interface.
@@ -57,7 +61,7 @@ func (m *MockRandom) BytesCustom(arg0 int, arg1 []byte) []byte {
}
// BytesCustom indicates an expected call of BytesCustom.
-func (mr *MockRandomMockRecorder) BytesCustom(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockRandomMockRecorder) BytesCustom(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BytesCustom", reflect.TypeOf((*MockRandom)(nil).BytesCustom), arg0, arg1)
}
@@ -72,7 +76,7 @@ func (m *MockRandom) BytesCustomErr(arg0 int, arg1 []byte) ([]byte, error) {
}
// BytesCustomErr indicates an expected call of BytesCustomErr.
-func (mr *MockRandomMockRecorder) BytesCustomErr(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockRandomMockRecorder) BytesCustomErr(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BytesCustomErr", reflect.TypeOf((*MockRandom)(nil).BytesCustomErr), arg0, arg1)
}
@@ -101,7 +105,7 @@ func (m *MockRandom) Int(arg0 *big.Int) *big.Int {
}
// Int indicates an expected call of Int.
-func (mr *MockRandomMockRecorder) Int(arg0 interface{}) *gomock.Call {
+func (mr *MockRandomMockRecorder) Int(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Int", reflect.TypeOf((*MockRandom)(nil).Int), arg0)
}
@@ -116,7 +120,7 @@ func (m *MockRandom) IntErr(arg0 *big.Int) (*big.Int, error) {
}
// IntErr indicates an expected call of IntErr.
-func (mr *MockRandomMockRecorder) IntErr(arg0 interface{}) *gomock.Call {
+func (mr *MockRandomMockRecorder) IntErr(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IntErr", reflect.TypeOf((*MockRandom)(nil).IntErr), arg0)
}
@@ -130,7 +134,7 @@ func (m *MockRandom) Intn(arg0 int) int {
}
// Intn indicates an expected call of Intn.
-func (mr *MockRandomMockRecorder) Intn(arg0 interface{}) *gomock.Call {
+func (mr *MockRandomMockRecorder) Intn(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Intn", reflect.TypeOf((*MockRandom)(nil).Intn), arg0)
}
@@ -145,7 +149,7 @@ func (m *MockRandom) IntnErr(arg0 int) (int, error) {
}
// IntnErr indicates an expected call of IntnErr.
-func (mr *MockRandomMockRecorder) IntnErr(arg0 interface{}) *gomock.Call {
+func (mr *MockRandomMockRecorder) IntnErr(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IntnErr", reflect.TypeOf((*MockRandom)(nil).IntnErr), arg0)
}
@@ -160,7 +164,7 @@ func (m *MockRandom) Prime(arg0 int) (*big.Int, error) {
}
// Prime indicates an expected call of Prime.
-func (mr *MockRandomMockRecorder) Prime(arg0 interface{}) *gomock.Call {
+func (mr *MockRandomMockRecorder) Prime(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Prime", reflect.TypeOf((*MockRandom)(nil).Prime), arg0)
}
@@ -175,7 +179,7 @@ func (m *MockRandom) Read(arg0 []byte) (int, error) {
}
// Read indicates an expected call of Read.
-func (mr *MockRandomMockRecorder) Read(arg0 interface{}) *gomock.Call {
+func (mr *MockRandomMockRecorder) Read(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockRandom)(nil).Read), arg0)
}
@@ -189,7 +193,7 @@ func (m *MockRandom) StringCustom(arg0 int, arg1 string) string {
}
// StringCustom indicates an expected call of StringCustom.
-func (mr *MockRandomMockRecorder) StringCustom(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockRandomMockRecorder) StringCustom(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StringCustom", reflect.TypeOf((*MockRandom)(nil).StringCustom), arg0, arg1)
}
@@ -204,7 +208,7 @@ func (m *MockRandom) StringCustomErr(arg0 int, arg1 string) (string, error) {
}
// StringCustomErr indicates an expected call of StringCustomErr.
-func (mr *MockRandomMockRecorder) StringCustomErr(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockRandomMockRecorder) StringCustomErr(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StringCustomErr", reflect.TypeOf((*MockRandom)(nil).StringCustomErr), arg0, arg1)
}
diff --git a/internal/mocks/storage.go b/internal/mocks/storage.go
index 26110b898..993a11737 100644
--- a/internal/mocks/storage.go
+++ b/internal/mocks/storage.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/authelia/authelia/v4/internal/storage (interfaces: Provider)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination storage.go -mock_names Provider=MockStorage github.com/authelia/authelia/v4/internal/storage Provider
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -12,8 +16,8 @@ import (
model "github.com/authelia/authelia/v4/internal/model"
storage "github.com/authelia/authelia/v4/internal/storage"
- gomock "github.com/golang/mock/gomock"
uuid "github.com/google/uuid"
+ gomock "go.uber.org/mock/gomock"
)
// MockStorage is a mock of Provider interface.
@@ -48,7 +52,7 @@ func (m *MockStorage) AppendAuthenticationLog(arg0 context.Context, arg1 model.A
}
// AppendAuthenticationLog indicates an expected call of AppendAuthenticationLog.
-func (mr *MockStorageMockRecorder) AppendAuthenticationLog(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) AppendAuthenticationLog(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendAuthenticationLog", reflect.TypeOf((*MockStorage)(nil).AppendAuthenticationLog), arg0, arg1)
}
@@ -63,7 +67,7 @@ func (m *MockStorage) BeginTX(arg0 context.Context) (context.Context, error) {
}
// BeginTX indicates an expected call of BeginTX.
-func (mr *MockStorageMockRecorder) BeginTX(arg0 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) BeginTX(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginTX", reflect.TypeOf((*MockStorage)(nil).BeginTX), arg0)
}
@@ -91,7 +95,7 @@ func (m *MockStorage) Commit(arg0 context.Context) error {
}
// Commit indicates an expected call of Commit.
-func (mr *MockStorageMockRecorder) Commit(arg0 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) Commit(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockStorage)(nil).Commit), arg0)
}
@@ -105,7 +109,7 @@ func (m *MockStorage) ConsumeIdentityVerification(arg0 context.Context, arg1 str
}
// ConsumeIdentityVerification indicates an expected call of ConsumeIdentityVerification.
-func (mr *MockStorageMockRecorder) ConsumeIdentityVerification(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) ConsumeIdentityVerification(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConsumeIdentityVerification", reflect.TypeOf((*MockStorage)(nil).ConsumeIdentityVerification), arg0, arg1, arg2)
}
@@ -119,7 +123,7 @@ func (m *MockStorage) ConsumeOneTimeCode(arg0 context.Context, arg1 *model.OneTi
}
// ConsumeOneTimeCode indicates an expected call of ConsumeOneTimeCode.
-func (mr *MockStorageMockRecorder) ConsumeOneTimeCode(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) ConsumeOneTimeCode(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConsumeOneTimeCode", reflect.TypeOf((*MockStorage)(nil).ConsumeOneTimeCode), arg0, arg1)
}
@@ -133,7 +137,7 @@ func (m *MockStorage) DeactivateOAuth2Session(arg0 context.Context, arg1 storage
}
// DeactivateOAuth2Session indicates an expected call of DeactivateOAuth2Session.
-func (mr *MockStorageMockRecorder) DeactivateOAuth2Session(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) DeactivateOAuth2Session(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeactivateOAuth2Session", reflect.TypeOf((*MockStorage)(nil).DeactivateOAuth2Session), arg0, arg1, arg2)
}
@@ -147,7 +151,7 @@ func (m *MockStorage) DeactivateOAuth2SessionByRequestID(arg0 context.Context, a
}
// DeactivateOAuth2SessionByRequestID indicates an expected call of DeactivateOAuth2SessionByRequestID.
-func (mr *MockStorageMockRecorder) DeactivateOAuth2SessionByRequestID(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) DeactivateOAuth2SessionByRequestID(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeactivateOAuth2SessionByRequestID", reflect.TypeOf((*MockStorage)(nil).DeactivateOAuth2SessionByRequestID), arg0, arg1, arg2)
}
@@ -161,7 +165,7 @@ func (m *MockStorage) DeletePreferredDuoDevice(arg0 context.Context, arg1 string
}
// DeletePreferredDuoDevice indicates an expected call of DeletePreferredDuoDevice.
-func (mr *MockStorageMockRecorder) DeletePreferredDuoDevice(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) DeletePreferredDuoDevice(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePreferredDuoDevice", reflect.TypeOf((*MockStorage)(nil).DeletePreferredDuoDevice), arg0, arg1)
}
@@ -175,7 +179,7 @@ func (m *MockStorage) DeleteTOTPConfiguration(arg0 context.Context, arg1 string)
}
// DeleteTOTPConfiguration indicates an expected call of DeleteTOTPConfiguration.
-func (mr *MockStorageMockRecorder) DeleteTOTPConfiguration(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) DeleteTOTPConfiguration(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTOTPConfiguration", reflect.TypeOf((*MockStorage)(nil).DeleteTOTPConfiguration), arg0, arg1)
}
@@ -189,7 +193,7 @@ func (m *MockStorage) DeleteWebAuthnCredential(arg0 context.Context, arg1 string
}
// DeleteWebAuthnCredential indicates an expected call of DeleteWebAuthnCredential.
-func (mr *MockStorageMockRecorder) DeleteWebAuthnCredential(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) DeleteWebAuthnCredential(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWebAuthnCredential", reflect.TypeOf((*MockStorage)(nil).DeleteWebAuthnCredential), arg0, arg1)
}
@@ -203,11 +207,26 @@ func (m *MockStorage) DeleteWebAuthnCredentialByUsername(arg0 context.Context, a
}
// DeleteWebAuthnCredentialByUsername indicates an expected call of DeleteWebAuthnCredentialByUsername.
-func (mr *MockStorageMockRecorder) DeleteWebAuthnCredentialByUsername(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) DeleteWebAuthnCredentialByUsername(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWebAuthnCredentialByUsername", reflect.TypeOf((*MockStorage)(nil).DeleteWebAuthnCredentialByUsername), arg0, arg1, arg2)
}
+// ExistsTOTPHistory mocks base method.
+func (m *MockStorage) ExistsTOTPHistory(arg0 context.Context, arg1 string, arg2 uint64, arg3 time.Time) (bool, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "ExistsTOTPHistory", arg0, arg1, arg2, arg3)
+ ret0, _ := ret[0].(bool)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// ExistsTOTPHistory indicates an expected call of ExistsTOTPHistory.
+func (mr *MockStorageMockRecorder) ExistsTOTPHistory(arg0, arg1, arg2, arg3 any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExistsTOTPHistory", reflect.TypeOf((*MockStorage)(nil).ExistsTOTPHistory), arg0, arg1, arg2, arg3)
+}
+
// FindIdentityVerification mocks base method.
func (m *MockStorage) FindIdentityVerification(arg0 context.Context, arg1 string) (bool, error) {
m.ctrl.T.Helper()
@@ -218,7 +237,7 @@ func (m *MockStorage) FindIdentityVerification(arg0 context.Context, arg1 string
}
// FindIdentityVerification indicates an expected call of FindIdentityVerification.
-func (mr *MockStorageMockRecorder) FindIdentityVerification(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) FindIdentityVerification(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindIdentityVerification", reflect.TypeOf((*MockStorage)(nil).FindIdentityVerification), arg0, arg1)
}
@@ -233,7 +252,7 @@ func (m *MockStorage) LoadAuthenticationLogs(arg0 context.Context, arg1 string,
}
// LoadAuthenticationLogs indicates an expected call of LoadAuthenticationLogs.
-func (mr *MockStorageMockRecorder) LoadAuthenticationLogs(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadAuthenticationLogs(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadAuthenticationLogs", reflect.TypeOf((*MockStorage)(nil).LoadAuthenticationLogs), arg0, arg1, arg2, arg3, arg4)
}
@@ -248,7 +267,7 @@ func (m *MockStorage) LoadIdentityVerification(arg0 context.Context, arg1 string
}
// LoadIdentityVerification indicates an expected call of LoadIdentityVerification.
-func (mr *MockStorageMockRecorder) LoadIdentityVerification(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadIdentityVerification(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadIdentityVerification", reflect.TypeOf((*MockStorage)(nil).LoadIdentityVerification), arg0, arg1)
}
@@ -263,7 +282,7 @@ func (m *MockStorage) LoadOAuth2BlacklistedJTI(arg0 context.Context, arg1 string
}
// LoadOAuth2BlacklistedJTI indicates an expected call of LoadOAuth2BlacklistedJTI.
-func (mr *MockStorageMockRecorder) LoadOAuth2BlacklistedJTI(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadOAuth2BlacklistedJTI(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadOAuth2BlacklistedJTI", reflect.TypeOf((*MockStorage)(nil).LoadOAuth2BlacklistedJTI), arg0, arg1)
}
@@ -278,7 +297,7 @@ func (m *MockStorage) LoadOAuth2ConsentPreConfigurations(arg0 context.Context, a
}
// LoadOAuth2ConsentPreConfigurations indicates an expected call of LoadOAuth2ConsentPreConfigurations.
-func (mr *MockStorageMockRecorder) LoadOAuth2ConsentPreConfigurations(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadOAuth2ConsentPreConfigurations(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadOAuth2ConsentPreConfigurations", reflect.TypeOf((*MockStorage)(nil).LoadOAuth2ConsentPreConfigurations), arg0, arg1, arg2)
}
@@ -293,7 +312,7 @@ func (m *MockStorage) LoadOAuth2ConsentSessionByChallengeID(arg0 context.Context
}
// LoadOAuth2ConsentSessionByChallengeID indicates an expected call of LoadOAuth2ConsentSessionByChallengeID.
-func (mr *MockStorageMockRecorder) LoadOAuth2ConsentSessionByChallengeID(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadOAuth2ConsentSessionByChallengeID(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadOAuth2ConsentSessionByChallengeID", reflect.TypeOf((*MockStorage)(nil).LoadOAuth2ConsentSessionByChallengeID), arg0, arg1)
}
@@ -308,7 +327,7 @@ func (m *MockStorage) LoadOAuth2PARContext(arg0 context.Context, arg1 string) (*
}
// LoadOAuth2PARContext indicates an expected call of LoadOAuth2PARContext.
-func (mr *MockStorageMockRecorder) LoadOAuth2PARContext(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadOAuth2PARContext(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadOAuth2PARContext", reflect.TypeOf((*MockStorage)(nil).LoadOAuth2PARContext), arg0, arg1)
}
@@ -323,7 +342,7 @@ func (m *MockStorage) LoadOAuth2Session(arg0 context.Context, arg1 storage.OAuth
}
// LoadOAuth2Session indicates an expected call of LoadOAuth2Session.
-func (mr *MockStorageMockRecorder) LoadOAuth2Session(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadOAuth2Session(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadOAuth2Session", reflect.TypeOf((*MockStorage)(nil).LoadOAuth2Session), arg0, arg1, arg2)
}
@@ -338,7 +357,7 @@ func (m *MockStorage) LoadOneTimeCode(arg0 context.Context, arg1, arg2, arg3 str
}
// LoadOneTimeCode indicates an expected call of LoadOneTimeCode.
-func (mr *MockStorageMockRecorder) LoadOneTimeCode(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadOneTimeCode(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadOneTimeCode", reflect.TypeOf((*MockStorage)(nil).LoadOneTimeCode), arg0, arg1, arg2, arg3)
}
@@ -353,7 +372,7 @@ func (m *MockStorage) LoadOneTimeCodeByID(arg0 context.Context, arg1 int) (*mode
}
// LoadOneTimeCodeByID indicates an expected call of LoadOneTimeCodeByID.
-func (mr *MockStorageMockRecorder) LoadOneTimeCodeByID(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadOneTimeCodeByID(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadOneTimeCodeByID", reflect.TypeOf((*MockStorage)(nil).LoadOneTimeCodeByID), arg0, arg1)
}
@@ -368,7 +387,7 @@ func (m *MockStorage) LoadOneTimeCodeByPublicID(arg0 context.Context, arg1 uuid.
}
// LoadOneTimeCodeByPublicID indicates an expected call of LoadOneTimeCodeByPublicID.
-func (mr *MockStorageMockRecorder) LoadOneTimeCodeByPublicID(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadOneTimeCodeByPublicID(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadOneTimeCodeByPublicID", reflect.TypeOf((*MockStorage)(nil).LoadOneTimeCodeByPublicID), arg0, arg1)
}
@@ -383,7 +402,7 @@ func (m *MockStorage) LoadOneTimeCodeBySignature(arg0 context.Context, arg1 stri
}
// LoadOneTimeCodeBySignature indicates an expected call of LoadOneTimeCodeBySignature.
-func (mr *MockStorageMockRecorder) LoadOneTimeCodeBySignature(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadOneTimeCodeBySignature(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadOneTimeCodeBySignature", reflect.TypeOf((*MockStorage)(nil).LoadOneTimeCodeBySignature), arg0, arg1)
}
@@ -398,7 +417,7 @@ func (m *MockStorage) LoadPreferred2FAMethod(arg0 context.Context, arg1 string)
}
// LoadPreferred2FAMethod indicates an expected call of LoadPreferred2FAMethod.
-func (mr *MockStorageMockRecorder) LoadPreferred2FAMethod(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadPreferred2FAMethod(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadPreferred2FAMethod", reflect.TypeOf((*MockStorage)(nil).LoadPreferred2FAMethod), arg0, arg1)
}
@@ -413,7 +432,7 @@ func (m *MockStorage) LoadPreferredDuoDevice(arg0 context.Context, arg1 string)
}
// LoadPreferredDuoDevice indicates an expected call of LoadPreferredDuoDevice.
-func (mr *MockStorageMockRecorder) LoadPreferredDuoDevice(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadPreferredDuoDevice(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadPreferredDuoDevice", reflect.TypeOf((*MockStorage)(nil).LoadPreferredDuoDevice), arg0, arg1)
}
@@ -428,7 +447,7 @@ func (m *MockStorage) LoadTOTPConfiguration(arg0 context.Context, arg1 string) (
}
// LoadTOTPConfiguration indicates an expected call of LoadTOTPConfiguration.
-func (mr *MockStorageMockRecorder) LoadTOTPConfiguration(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadTOTPConfiguration(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadTOTPConfiguration", reflect.TypeOf((*MockStorage)(nil).LoadTOTPConfiguration), arg0, arg1)
}
@@ -443,7 +462,7 @@ func (m *MockStorage) LoadTOTPConfigurations(arg0 context.Context, arg1, arg2 in
}
// LoadTOTPConfigurations indicates an expected call of LoadTOTPConfigurations.
-func (mr *MockStorageMockRecorder) LoadTOTPConfigurations(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadTOTPConfigurations(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadTOTPConfigurations", reflect.TypeOf((*MockStorage)(nil).LoadTOTPConfigurations), arg0, arg1, arg2)
}
@@ -458,7 +477,7 @@ func (m *MockStorage) LoadUserInfo(arg0 context.Context, arg1 string) (model.Use
}
// LoadUserInfo indicates an expected call of LoadUserInfo.
-func (mr *MockStorageMockRecorder) LoadUserInfo(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadUserInfo(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadUserInfo", reflect.TypeOf((*MockStorage)(nil).LoadUserInfo), arg0, arg1)
}
@@ -473,7 +492,7 @@ func (m *MockStorage) LoadUserOpaqueIdentifier(arg0 context.Context, arg1 uuid.U
}
// LoadUserOpaqueIdentifier indicates an expected call of LoadUserOpaqueIdentifier.
-func (mr *MockStorageMockRecorder) LoadUserOpaqueIdentifier(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadUserOpaqueIdentifier(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadUserOpaqueIdentifier", reflect.TypeOf((*MockStorage)(nil).LoadUserOpaqueIdentifier), arg0, arg1)
}
@@ -488,7 +507,7 @@ func (m *MockStorage) LoadUserOpaqueIdentifierBySignature(arg0 context.Context,
}
// LoadUserOpaqueIdentifierBySignature indicates an expected call of LoadUserOpaqueIdentifierBySignature.
-func (mr *MockStorageMockRecorder) LoadUserOpaqueIdentifierBySignature(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadUserOpaqueIdentifierBySignature(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadUserOpaqueIdentifierBySignature", reflect.TypeOf((*MockStorage)(nil).LoadUserOpaqueIdentifierBySignature), arg0, arg1, arg2, arg3)
}
@@ -503,7 +522,7 @@ func (m *MockStorage) LoadUserOpaqueIdentifiers(arg0 context.Context) ([]model.U
}
// LoadUserOpaqueIdentifiers indicates an expected call of LoadUserOpaqueIdentifiers.
-func (mr *MockStorageMockRecorder) LoadUserOpaqueIdentifiers(arg0 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadUserOpaqueIdentifiers(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadUserOpaqueIdentifiers", reflect.TypeOf((*MockStorage)(nil).LoadUserOpaqueIdentifiers), arg0)
}
@@ -518,7 +537,7 @@ func (m *MockStorage) LoadWebAuthnCredentialByID(arg0 context.Context, arg1 int)
}
// LoadWebAuthnCredentialByID indicates an expected call of LoadWebAuthnCredentialByID.
-func (mr *MockStorageMockRecorder) LoadWebAuthnCredentialByID(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadWebAuthnCredentialByID(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadWebAuthnCredentialByID", reflect.TypeOf((*MockStorage)(nil).LoadWebAuthnCredentialByID), arg0, arg1)
}
@@ -533,7 +552,7 @@ func (m *MockStorage) LoadWebAuthnCredentials(arg0 context.Context, arg1, arg2 i
}
// LoadWebAuthnCredentials indicates an expected call of LoadWebAuthnCredentials.
-func (mr *MockStorageMockRecorder) LoadWebAuthnCredentials(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadWebAuthnCredentials(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadWebAuthnCredentials", reflect.TypeOf((*MockStorage)(nil).LoadWebAuthnCredentials), arg0, arg1, arg2)
}
@@ -548,7 +567,7 @@ func (m *MockStorage) LoadWebAuthnCredentialsByUsername(arg0 context.Context, ar
}
// LoadWebAuthnCredentialsByUsername indicates an expected call of LoadWebAuthnCredentialsByUsername.
-func (mr *MockStorageMockRecorder) LoadWebAuthnCredentialsByUsername(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadWebAuthnCredentialsByUsername(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadWebAuthnCredentialsByUsername", reflect.TypeOf((*MockStorage)(nil).LoadWebAuthnCredentialsByUsername), arg0, arg1, arg2)
}
@@ -563,7 +582,7 @@ func (m *MockStorage) LoadWebAuthnUser(arg0 context.Context, arg1, arg2 string)
}
// LoadWebAuthnUser indicates an expected call of LoadWebAuthnUser.
-func (mr *MockStorageMockRecorder) LoadWebAuthnUser(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) LoadWebAuthnUser(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadWebAuthnUser", reflect.TypeOf((*MockStorage)(nil).LoadWebAuthnUser), arg0, arg1, arg2)
}
@@ -577,7 +596,7 @@ func (m *MockStorage) RevokeIdentityVerification(arg0 context.Context, arg1 stri
}
// RevokeIdentityVerification indicates an expected call of RevokeIdentityVerification.
-func (mr *MockStorageMockRecorder) RevokeIdentityVerification(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) RevokeIdentityVerification(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevokeIdentityVerification", reflect.TypeOf((*MockStorage)(nil).RevokeIdentityVerification), arg0, arg1, arg2)
}
@@ -591,7 +610,7 @@ func (m *MockStorage) RevokeOAuth2PARContext(arg0 context.Context, arg1 string)
}
// RevokeOAuth2PARContext indicates an expected call of RevokeOAuth2PARContext.
-func (mr *MockStorageMockRecorder) RevokeOAuth2PARContext(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) RevokeOAuth2PARContext(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevokeOAuth2PARContext", reflect.TypeOf((*MockStorage)(nil).RevokeOAuth2PARContext), arg0, arg1)
}
@@ -605,7 +624,7 @@ func (m *MockStorage) RevokeOAuth2Session(arg0 context.Context, arg1 storage.OAu
}
// RevokeOAuth2Session indicates an expected call of RevokeOAuth2Session.
-func (mr *MockStorageMockRecorder) RevokeOAuth2Session(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) RevokeOAuth2Session(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevokeOAuth2Session", reflect.TypeOf((*MockStorage)(nil).RevokeOAuth2Session), arg0, arg1, arg2)
}
@@ -619,7 +638,7 @@ func (m *MockStorage) RevokeOAuth2SessionByRequestID(arg0 context.Context, arg1
}
// RevokeOAuth2SessionByRequestID indicates an expected call of RevokeOAuth2SessionByRequestID.
-func (mr *MockStorageMockRecorder) RevokeOAuth2SessionByRequestID(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) RevokeOAuth2SessionByRequestID(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevokeOAuth2SessionByRequestID", reflect.TypeOf((*MockStorage)(nil).RevokeOAuth2SessionByRequestID), arg0, arg1, arg2)
}
@@ -633,7 +652,7 @@ func (m *MockStorage) RevokeOneTimeCode(arg0 context.Context, arg1 uuid.UUID, ar
}
// RevokeOneTimeCode indicates an expected call of RevokeOneTimeCode.
-func (mr *MockStorageMockRecorder) RevokeOneTimeCode(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) RevokeOneTimeCode(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevokeOneTimeCode", reflect.TypeOf((*MockStorage)(nil).RevokeOneTimeCode), arg0, arg1, arg2)
}
@@ -647,7 +666,7 @@ func (m *MockStorage) Rollback(arg0 context.Context) error {
}
// Rollback indicates an expected call of Rollback.
-func (mr *MockStorageMockRecorder) Rollback(arg0 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) Rollback(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Rollback", reflect.TypeOf((*MockStorage)(nil).Rollback), arg0)
}
@@ -661,7 +680,7 @@ func (m *MockStorage) SaveIdentityVerification(arg0 context.Context, arg1 model.
}
// SaveIdentityVerification indicates an expected call of SaveIdentityVerification.
-func (mr *MockStorageMockRecorder) SaveIdentityVerification(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveIdentityVerification(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveIdentityVerification", reflect.TypeOf((*MockStorage)(nil).SaveIdentityVerification), arg0, arg1)
}
@@ -675,7 +694,7 @@ func (m *MockStorage) SaveOAuth2BlacklistedJTI(arg0 context.Context, arg1 model.
}
// SaveOAuth2BlacklistedJTI indicates an expected call of SaveOAuth2BlacklistedJTI.
-func (mr *MockStorageMockRecorder) SaveOAuth2BlacklistedJTI(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveOAuth2BlacklistedJTI(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveOAuth2BlacklistedJTI", reflect.TypeOf((*MockStorage)(nil).SaveOAuth2BlacklistedJTI), arg0, arg1)
}
@@ -690,7 +709,7 @@ func (m *MockStorage) SaveOAuth2ConsentPreConfiguration(arg0 context.Context, ar
}
// SaveOAuth2ConsentPreConfiguration indicates an expected call of SaveOAuth2ConsentPreConfiguration.
-func (mr *MockStorageMockRecorder) SaveOAuth2ConsentPreConfiguration(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveOAuth2ConsentPreConfiguration(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveOAuth2ConsentPreConfiguration", reflect.TypeOf((*MockStorage)(nil).SaveOAuth2ConsentPreConfiguration), arg0, arg1)
}
@@ -704,7 +723,7 @@ func (m *MockStorage) SaveOAuth2ConsentSession(arg0 context.Context, arg1 model.
}
// SaveOAuth2ConsentSession indicates an expected call of SaveOAuth2ConsentSession.
-func (mr *MockStorageMockRecorder) SaveOAuth2ConsentSession(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveOAuth2ConsentSession(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveOAuth2ConsentSession", reflect.TypeOf((*MockStorage)(nil).SaveOAuth2ConsentSession), arg0, arg1)
}
@@ -718,7 +737,7 @@ func (m *MockStorage) SaveOAuth2ConsentSessionGranted(arg0 context.Context, arg1
}
// SaveOAuth2ConsentSessionGranted indicates an expected call of SaveOAuth2ConsentSessionGranted.
-func (mr *MockStorageMockRecorder) SaveOAuth2ConsentSessionGranted(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveOAuth2ConsentSessionGranted(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveOAuth2ConsentSessionGranted", reflect.TypeOf((*MockStorage)(nil).SaveOAuth2ConsentSessionGranted), arg0, arg1)
}
@@ -732,7 +751,7 @@ func (m *MockStorage) SaveOAuth2ConsentSessionResponse(arg0 context.Context, arg
}
// SaveOAuth2ConsentSessionResponse indicates an expected call of SaveOAuth2ConsentSessionResponse.
-func (mr *MockStorageMockRecorder) SaveOAuth2ConsentSessionResponse(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveOAuth2ConsentSessionResponse(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveOAuth2ConsentSessionResponse", reflect.TypeOf((*MockStorage)(nil).SaveOAuth2ConsentSessionResponse), arg0, arg1, arg2)
}
@@ -746,7 +765,7 @@ func (m *MockStorage) SaveOAuth2ConsentSessionSubject(arg0 context.Context, arg1
}
// SaveOAuth2ConsentSessionSubject indicates an expected call of SaveOAuth2ConsentSessionSubject.
-func (mr *MockStorageMockRecorder) SaveOAuth2ConsentSessionSubject(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveOAuth2ConsentSessionSubject(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveOAuth2ConsentSessionSubject", reflect.TypeOf((*MockStorage)(nil).SaveOAuth2ConsentSessionSubject), arg0, arg1)
}
@@ -760,7 +779,7 @@ func (m *MockStorage) SaveOAuth2PARContext(arg0 context.Context, arg1 model.OAut
}
// SaveOAuth2PARContext indicates an expected call of SaveOAuth2PARContext.
-func (mr *MockStorageMockRecorder) SaveOAuth2PARContext(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveOAuth2PARContext(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveOAuth2PARContext", reflect.TypeOf((*MockStorage)(nil).SaveOAuth2PARContext), arg0, arg1)
}
@@ -774,7 +793,7 @@ func (m *MockStorage) SaveOAuth2Session(arg0 context.Context, arg1 storage.OAuth
}
// SaveOAuth2Session indicates an expected call of SaveOAuth2Session.
-func (mr *MockStorageMockRecorder) SaveOAuth2Session(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveOAuth2Session(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveOAuth2Session", reflect.TypeOf((*MockStorage)(nil).SaveOAuth2Session), arg0, arg1, arg2)
}
@@ -789,7 +808,7 @@ func (m *MockStorage) SaveOneTimeCode(arg0 context.Context, arg1 model.OneTimeCo
}
// SaveOneTimeCode indicates an expected call of SaveOneTimeCode.
-func (mr *MockStorageMockRecorder) SaveOneTimeCode(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveOneTimeCode(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveOneTimeCode", reflect.TypeOf((*MockStorage)(nil).SaveOneTimeCode), arg0, arg1)
}
@@ -803,7 +822,7 @@ func (m *MockStorage) SavePreferred2FAMethod(arg0 context.Context, arg1, arg2 st
}
// SavePreferred2FAMethod indicates an expected call of SavePreferred2FAMethod.
-func (mr *MockStorageMockRecorder) SavePreferred2FAMethod(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SavePreferred2FAMethod(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SavePreferred2FAMethod", reflect.TypeOf((*MockStorage)(nil).SavePreferred2FAMethod), arg0, arg1, arg2)
}
@@ -817,7 +836,7 @@ func (m *MockStorage) SavePreferredDuoDevice(arg0 context.Context, arg1 model.Du
}
// SavePreferredDuoDevice indicates an expected call of SavePreferredDuoDevice.
-func (mr *MockStorageMockRecorder) SavePreferredDuoDevice(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SavePreferredDuoDevice(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SavePreferredDuoDevice", reflect.TypeOf((*MockStorage)(nil).SavePreferredDuoDevice), arg0, arg1)
}
@@ -831,11 +850,25 @@ func (m *MockStorage) SaveTOTPConfiguration(arg0 context.Context, arg1 model.TOT
}
// SaveTOTPConfiguration indicates an expected call of SaveTOTPConfiguration.
-func (mr *MockStorageMockRecorder) SaveTOTPConfiguration(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveTOTPConfiguration(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveTOTPConfiguration", reflect.TypeOf((*MockStorage)(nil).SaveTOTPConfiguration), arg0, arg1)
}
+// SaveTOTPHistory mocks base method.
+func (m *MockStorage) SaveTOTPHistory(arg0 context.Context, arg1 string, arg2 uint64) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SaveTOTPHistory", arg0, arg1, arg2)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SaveTOTPHistory indicates an expected call of SaveTOTPHistory.
+func (mr *MockStorageMockRecorder) SaveTOTPHistory(arg0, arg1, arg2 any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveTOTPHistory", reflect.TypeOf((*MockStorage)(nil).SaveTOTPHistory), arg0, arg1, arg2)
+}
+
// SaveUserOpaqueIdentifier mocks base method.
func (m *MockStorage) SaveUserOpaqueIdentifier(arg0 context.Context, arg1 model.UserOpaqueIdentifier) error {
m.ctrl.T.Helper()
@@ -845,7 +878,7 @@ func (m *MockStorage) SaveUserOpaqueIdentifier(arg0 context.Context, arg1 model.
}
// SaveUserOpaqueIdentifier indicates an expected call of SaveUserOpaqueIdentifier.
-func (mr *MockStorageMockRecorder) SaveUserOpaqueIdentifier(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveUserOpaqueIdentifier(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveUserOpaqueIdentifier", reflect.TypeOf((*MockStorage)(nil).SaveUserOpaqueIdentifier), arg0, arg1)
}
@@ -859,7 +892,7 @@ func (m *MockStorage) SaveWebAuthnCredential(arg0 context.Context, arg1 model.We
}
// SaveWebAuthnCredential indicates an expected call of SaveWebAuthnCredential.
-func (mr *MockStorageMockRecorder) SaveWebAuthnCredential(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveWebAuthnCredential(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveWebAuthnCredential", reflect.TypeOf((*MockStorage)(nil).SaveWebAuthnCredential), arg0, arg1)
}
@@ -873,7 +906,7 @@ func (m *MockStorage) SaveWebAuthnUser(arg0 context.Context, arg1 model.WebAuthn
}
// SaveWebAuthnUser indicates an expected call of SaveWebAuthnUser.
-func (mr *MockStorageMockRecorder) SaveWebAuthnUser(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SaveWebAuthnUser(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveWebAuthnUser", reflect.TypeOf((*MockStorage)(nil).SaveWebAuthnUser), arg0, arg1)
}
@@ -887,7 +920,7 @@ func (m *MockStorage) SchemaEncryptionChangeKey(arg0 context.Context, arg1 strin
}
// SchemaEncryptionChangeKey indicates an expected call of SchemaEncryptionChangeKey.
-func (mr *MockStorageMockRecorder) SchemaEncryptionChangeKey(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SchemaEncryptionChangeKey(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchemaEncryptionChangeKey", reflect.TypeOf((*MockStorage)(nil).SchemaEncryptionChangeKey), arg0, arg1)
}
@@ -902,7 +935,7 @@ func (m *MockStorage) SchemaEncryptionCheckKey(arg0 context.Context, arg1 bool)
}
// SchemaEncryptionCheckKey indicates an expected call of SchemaEncryptionCheckKey.
-func (mr *MockStorageMockRecorder) SchemaEncryptionCheckKey(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SchemaEncryptionCheckKey(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchemaEncryptionCheckKey", reflect.TypeOf((*MockStorage)(nil).SchemaEncryptionCheckKey), arg0, arg1)
}
@@ -931,7 +964,7 @@ func (m *MockStorage) SchemaMigrate(arg0 context.Context, arg1 bool, arg2 int) e
}
// SchemaMigrate indicates an expected call of SchemaMigrate.
-func (mr *MockStorageMockRecorder) SchemaMigrate(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SchemaMigrate(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchemaMigrate", reflect.TypeOf((*MockStorage)(nil).SchemaMigrate), arg0, arg1, arg2)
}
@@ -946,7 +979,7 @@ func (m *MockStorage) SchemaMigrationHistory(arg0 context.Context) ([]model.Migr
}
// SchemaMigrationHistory indicates an expected call of SchemaMigrationHistory.
-func (mr *MockStorageMockRecorder) SchemaMigrationHistory(arg0 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SchemaMigrationHistory(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchemaMigrationHistory", reflect.TypeOf((*MockStorage)(nil).SchemaMigrationHistory), arg0)
}
@@ -961,7 +994,7 @@ func (m *MockStorage) SchemaMigrationsDown(arg0 context.Context, arg1 int) ([]mo
}
// SchemaMigrationsDown indicates an expected call of SchemaMigrationsDown.
-func (mr *MockStorageMockRecorder) SchemaMigrationsDown(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SchemaMigrationsDown(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchemaMigrationsDown", reflect.TypeOf((*MockStorage)(nil).SchemaMigrationsDown), arg0, arg1)
}
@@ -976,7 +1009,7 @@ func (m *MockStorage) SchemaMigrationsUp(arg0 context.Context, arg1 int) ([]mode
}
// SchemaMigrationsUp indicates an expected call of SchemaMigrationsUp.
-func (mr *MockStorageMockRecorder) SchemaMigrationsUp(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SchemaMigrationsUp(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchemaMigrationsUp", reflect.TypeOf((*MockStorage)(nil).SchemaMigrationsUp), arg0, arg1)
}
@@ -991,7 +1024,7 @@ func (m *MockStorage) SchemaTables(arg0 context.Context) ([]string, error) {
}
// SchemaTables indicates an expected call of SchemaTables.
-func (mr *MockStorageMockRecorder) SchemaTables(arg0 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SchemaTables(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchemaTables", reflect.TypeOf((*MockStorage)(nil).SchemaTables), arg0)
}
@@ -1006,7 +1039,7 @@ func (m *MockStorage) SchemaVersion(arg0 context.Context) (int, error) {
}
// SchemaVersion indicates an expected call of SchemaVersion.
-func (mr *MockStorageMockRecorder) SchemaVersion(arg0 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) SchemaVersion(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchemaVersion", reflect.TypeOf((*MockStorage)(nil).SchemaVersion), arg0)
}
@@ -1034,7 +1067,7 @@ func (m *MockStorage) UpdateOAuth2PARContext(arg0 context.Context, arg1 model.OA
}
// UpdateOAuth2PARContext indicates an expected call of UpdateOAuth2PARContext.
-func (mr *MockStorageMockRecorder) UpdateOAuth2PARContext(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) UpdateOAuth2PARContext(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateOAuth2PARContext", reflect.TypeOf((*MockStorage)(nil).UpdateOAuth2PARContext), arg0, arg1)
}
@@ -1048,7 +1081,7 @@ func (m *MockStorage) UpdateTOTPConfigurationSignIn(arg0 context.Context, arg1 i
}
// UpdateTOTPConfigurationSignIn indicates an expected call of UpdateTOTPConfigurationSignIn.
-func (mr *MockStorageMockRecorder) UpdateTOTPConfigurationSignIn(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) UpdateTOTPConfigurationSignIn(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTOTPConfigurationSignIn", reflect.TypeOf((*MockStorage)(nil).UpdateTOTPConfigurationSignIn), arg0, arg1, arg2)
}
@@ -1062,7 +1095,7 @@ func (m *MockStorage) UpdateWebAuthnCredentialDescription(arg0 context.Context,
}
// UpdateWebAuthnCredentialDescription indicates an expected call of UpdateWebAuthnCredentialDescription.
-func (mr *MockStorageMockRecorder) UpdateWebAuthnCredentialDescription(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) UpdateWebAuthnCredentialDescription(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWebAuthnCredentialDescription", reflect.TypeOf((*MockStorage)(nil).UpdateWebAuthnCredentialDescription), arg0, arg1, arg2, arg3)
}
@@ -1076,7 +1109,7 @@ func (m *MockStorage) UpdateWebAuthnCredentialSignIn(arg0 context.Context, arg1
}
// UpdateWebAuthnCredentialSignIn indicates an expected call of UpdateWebAuthnCredentialSignIn.
-func (mr *MockStorageMockRecorder) UpdateWebAuthnCredentialSignIn(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockStorageMockRecorder) UpdateWebAuthnCredentialSignIn(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWebAuthnCredentialSignIn", reflect.TypeOf((*MockStorage)(nil).UpdateWebAuthnCredentialSignIn), arg0, arg1)
}
diff --git a/internal/mocks/totp.go b/internal/mocks/totp.go
index ab61dfe30..87738aac0 100644
--- a/internal/mocks/totp.go
+++ b/internal/mocks/totp.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/authelia/authelia/v4/internal/totp (interfaces: Provider)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination totp.go -mock_names Provider=MockTOTP github.com/authelia/authelia/v4/internal/totp Provider
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -8,7 +12,7 @@ import (
reflect "reflect"
model "github.com/authelia/authelia/v4/internal/model"
- gomock "github.com/golang/mock/gomock"
+ gomock "go.uber.org/mock/gomock"
)
// MockTOTP is a mock of Provider interface.
@@ -44,7 +48,7 @@ func (m *MockTOTP) Generate(arg0 string) (*model.TOTPConfiguration, error) {
}
// Generate indicates an expected call of Generate.
-func (mr *MockTOTPMockRecorder) Generate(arg0 interface{}) *gomock.Call {
+func (mr *MockTOTPMockRecorder) Generate(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Generate", reflect.TypeOf((*MockTOTP)(nil).Generate), arg0)
}
@@ -59,7 +63,7 @@ func (m *MockTOTP) GenerateCustom(arg0, arg1, arg2 string, arg3, arg4, arg5 uint
}
// GenerateCustom indicates an expected call of GenerateCustom.
-func (mr *MockTOTPMockRecorder) GenerateCustom(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
+func (mr *MockTOTPMockRecorder) GenerateCustom(arg0, arg1, arg2, arg3, arg4, arg5 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenerateCustom", reflect.TypeOf((*MockTOTP)(nil).GenerateCustom), arg0, arg1, arg2, arg3, arg4, arg5)
}
@@ -79,16 +83,17 @@ func (mr *MockTOTPMockRecorder) Options() *gomock.Call {
}
// Validate mocks base method.
-func (m *MockTOTP) Validate(arg0 string, arg1 *model.TOTPConfiguration) (bool, error) {
+func (m *MockTOTP) Validate(arg0 string, arg1 *model.TOTPConfiguration) (bool, uint64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Validate", arg0, arg1)
ret0, _ := ret[0].(bool)
- ret1, _ := ret[1].(error)
- return ret0, ret1
+ ret1, _ := ret[1].(uint64)
+ ret2, _ := ret[2].(error)
+ return ret0, ret1, ret2
}
// Validate indicates an expected call of Validate.
-func (mr *MockTOTPMockRecorder) Validate(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockTOTPMockRecorder) Validate(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validate", reflect.TypeOf((*MockTOTP)(nil).Validate), arg0, arg1)
}
diff --git a/internal/mocks/user_provider.go b/internal/mocks/user_provider.go
index 4cc592dc9..54e3e478a 100644
--- a/internal/mocks/user_provider.go
+++ b/internal/mocks/user_provider.go
@@ -1,6 +1,10 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/authelia/authelia/v4/internal/authentication (interfaces: UserProvider)
-
+//
+// Generated by this command:
+//
+// mockgen -package mocks -destination user_provider.go -mock_names UserProvider=MockUserProvider github.com/authelia/authelia/v4/internal/authentication UserProvider
+//
// Package mocks is a generated GoMock package.
package mocks
@@ -8,7 +12,7 @@ import (
reflect "reflect"
authentication "github.com/authelia/authelia/v4/internal/authentication"
- gomock "github.com/golang/mock/gomock"
+ gomock "go.uber.org/mock/gomock"
)
// MockUserProvider is a mock of UserProvider interface.
@@ -44,7 +48,7 @@ func (m *MockUserProvider) CheckUserPassword(arg0, arg1 string) (bool, error) {
}
// CheckUserPassword indicates an expected call of CheckUserPassword.
-func (mr *MockUserProviderMockRecorder) CheckUserPassword(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockUserProviderMockRecorder) CheckUserPassword(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckUserPassword", reflect.TypeOf((*MockUserProvider)(nil).CheckUserPassword), arg0, arg1)
}
@@ -59,7 +63,7 @@ func (m *MockUserProvider) GetDetails(arg0 string) (*authentication.UserDetails,
}
// GetDetails indicates an expected call of GetDetails.
-func (mr *MockUserProviderMockRecorder) GetDetails(arg0 interface{}) *gomock.Call {
+func (mr *MockUserProviderMockRecorder) GetDetails(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDetails", reflect.TypeOf((*MockUserProvider)(nil).GetDetails), arg0)
}
@@ -87,7 +91,7 @@ func (m *MockUserProvider) UpdatePassword(arg0, arg1 string) error {
}
// UpdatePassword indicates an expected call of UpdatePassword.
-func (mr *MockUserProviderMockRecorder) UpdatePassword(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockUserProviderMockRecorder) UpdatePassword(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatePassword", reflect.TypeOf((*MockUserProvider)(nil).UpdatePassword), arg0, arg1)
}
diff --git a/internal/model/oidc_test.go b/internal/model/oidc_test.go
index bcde86833..fde5d7f2c 100644
--- a/internal/model/oidc_test.go
+++ b/internal/model/oidc_test.go
@@ -9,12 +9,12 @@ import (
"testing"
"time"
- "github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/ory/fosite"
"github.com/ory/fosite/handler/openid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/mocks"
"github.com/authelia/authelia/v4/internal/model"
diff --git a/internal/model/totp_configuration.go b/internal/model/totp_configuration.go
index 67fc492b7..275afc67c 100644
--- a/internal/model/totp_configuration.go
+++ b/internal/model/totp_configuration.go
@@ -9,7 +9,7 @@ import (
"strconv"
"time"
- "github.com/pquerna/otp"
+ "github.com/authelia/otp"
"gopkg.in/yaml.v3"
)
@@ -64,6 +64,19 @@ func (c TOTPConfiguration) MarshalJSON() (data []byte, err error) {
return json.Marshal(o)
}
+// HistorySince provides a reasonably accurate window for previously successful attempts to check for history.
+func (c *TOTPConfiguration) HistorySince(now time.Time, skew *int) time.Time {
+ var s int
+
+ if skew == nil {
+ s = 2
+ } else {
+ s = *skew + 2
+ }
+
+ return now.Add(-time.Second * time.Duration(c.Period) * time.Duration(s))
+}
+
// LastUsed provides LastUsedAt as a *time.Time instead of sql.NullTime.
func (c *TOTPConfiguration) LastUsed() *time.Time {
if c.LastUsedAt.Valid {
diff --git a/internal/oidc/client_credentials_test.go b/internal/oidc/client_credentials_test.go
index d9642b180..9fbc6df22 100644
--- a/internal/oidc/client_credentials_test.go
+++ b/internal/oidc/client_credentials_test.go
@@ -15,7 +15,6 @@ import (
"time"
"github.com/golang-jwt/jwt/v5"
- "github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/ory/fosite"
"github.com/ory/fosite/storage"
@@ -23,6 +22,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"gopkg.in/square/go-jose.v2"
"github.com/authelia/authelia/v4/internal/authorization"
diff --git a/internal/oidc/flow_client_credentials_test.go b/internal/oidc/flow_client_credentials_test.go
index 82c5e5b54..0e1b0ef50 100644
--- a/internal/oidc/flow_client_credentials_test.go
+++ b/internal/oidc/flow_client_credentials_test.go
@@ -6,10 +6,10 @@ import (
"testing"
"time"
- "github.com/golang/mock/gomock"
"github.com/ory/fosite"
"github.com/ory/fosite/handler/oauth2"
"github.com/stretchr/testify/assert"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/mocks"
"github.com/authelia/authelia/v4/internal/oidc"
diff --git a/internal/oidc/flow_refresh_test.go b/internal/oidc/flow_refresh_test.go
index 7efc4be9f..3d6add0d8 100644
--- a/internal/oidc/flow_refresh_test.go
+++ b/internal/oidc/flow_refresh_test.go
@@ -8,13 +8,13 @@ import (
"testing"
"time"
- "github.com/golang/mock/gomock"
"github.com/ory/fosite"
"github.com/ory/fosite/handler/oauth2"
"github.com/ory/fosite/storage"
"github.com/ory/fosite/token/hmac"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/mocks"
"github.com/authelia/authelia/v4/internal/oidc"
diff --git a/internal/oidc/handler_introspection_test.go b/internal/oidc/handler_introspection_test.go
index 74e79e75e..adf7afa3a 100644
--- a/internal/oidc/handler_introspection_test.go
+++ b/internal/oidc/handler_introspection_test.go
@@ -8,11 +8,11 @@ import (
"net/url"
"testing"
- "github.com/golang/mock/gomock"
"github.com/ory/fosite"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/mocks"
diff --git a/internal/oidc/store_test.go b/internal/oidc/store_test.go
index 544f93b74..f5057b42d 100644
--- a/internal/oidc/store_test.go
+++ b/internal/oidc/store_test.go
@@ -8,11 +8,11 @@ import (
"testing"
"time"
- "github.com/golang/mock/gomock"
"github.com/ory/fosite"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/authorization"
"github.com/authelia/authelia/v4/internal/configuration/schema"
diff --git a/internal/regulation/regulator_test.go b/internal/regulation/regulator_test.go
index 536d674ae..55b783889 100644
--- a/internal/regulation/regulator_test.go
+++ b/internal/regulation/regulator_test.go
@@ -6,10 +6,10 @@ import (
"testing"
"time"
- "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/valyala/fasthttp"
+ "go.uber.org/mock/gomock"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/mocks"
diff --git a/internal/storage/const.go b/internal/storage/const.go
index c00a957d7..907842b89 100644
--- a/internal/storage/const.go
+++ b/internal/storage/const.go
@@ -10,6 +10,7 @@ const (
tableIdentityVerification = "identity_verification"
tableOneTimeCode = "one_time_code"
tableTOTPConfigurations = "totp_configurations"
+ tableTOTPHistory = "totp_history"
tableUserOpaqueIdentifier = "user_opaque_identifier"
tableUserPreferences = "user_preferences"
tableWebAuthnCredentials = "webauthn_credentials" //nolint:gosec // This is a table name, not a credential.
diff --git a/internal/storage/migrations/mysql/V0013.OneTimeCode.up.sql b/internal/storage/migrations/mysql/V0013.OneTimeCode.up.sql
index a27f6c709..8edd66979 100644
--- a/internal/storage/migrations/mysql/V0013.OneTimeCode.up.sql
+++ b/internal/storage/migrations/mysql/V0013.OneTimeCode.up.sql
@@ -14,5 +14,4 @@ CREATE TABLE IF NOT EXISTS one_time_code (
code BLOB NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
-CREATE UNIQUE INDEX one_time_code_signature ON one_time_code (signature);
-CREATE INDEX one_time_code_lookup ON one_time_code (signature, username);
+CREATE UNIQUE INDEX one_time_code_signature ON one_time_code (signature, username);
diff --git a/internal/storage/migrations/mysql/V0015.TOTPEnhance.down.sql b/internal/storage/migrations/mysql/V0015.TOTPEnhance.down.sql
new file mode 100644
index 000000000..53d9ae5ab
--- /dev/null
+++ b/internal/storage/migrations/mysql/V0015.TOTPEnhance.down.sql
@@ -0,0 +1 @@
+DROP TABLE IF EXISTS totp_history;
diff --git a/internal/storage/migrations/mysql/V0015.TOTPEnhance.up.sql b/internal/storage/migrations/mysql/V0015.TOTPEnhance.up.sql
new file mode 100644
index 000000000..e74462ffd
--- /dev/null
+++ b/internal/storage/migrations/mysql/V0015.TOTPEnhance.up.sql
@@ -0,0 +1,8 @@
+CREATE TABLE IF NOT EXISTS totp_history (
+ id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ username VARCHAR(100) NOT NULL,
+ step CHAR(128) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
+
+CREATE UNIQUE INDEX totp_history_lookup_key ON totp_history (username, step);
diff --git a/internal/storage/migrations/postgres/V0013.OneTimeCode.up.sql b/internal/storage/migrations/postgres/V0013.OneTimeCode.up.sql
index 434068170..77016c801 100644
--- a/internal/storage/migrations/postgres/V0013.OneTimeCode.up.sql
+++ b/internal/storage/migrations/postgres/V0013.OneTimeCode.up.sql
@@ -15,4 +15,3 @@ CREATE TABLE IF NOT EXISTS one_time_code (
);
CREATE UNIQUE INDEX one_time_code_lookup_key ON one_time_code (signature, username);
-CREATE INDEX one_time_code_lookup ON one_time_code (signature, username);
diff --git a/internal/storage/migrations/postgres/V0015.TOTPEnhance.down.sql b/internal/storage/migrations/postgres/V0015.TOTPEnhance.down.sql
new file mode 100644
index 000000000..53d9ae5ab
--- /dev/null
+++ b/internal/storage/migrations/postgres/V0015.TOTPEnhance.down.sql
@@ -0,0 +1 @@
+DROP TABLE IF EXISTS totp_history;
diff --git a/internal/storage/migrations/postgres/V0015.TOTPEnhance.up.sql b/internal/storage/migrations/postgres/V0015.TOTPEnhance.up.sql
new file mode 100644
index 000000000..22c6e23c1
--- /dev/null
+++ b/internal/storage/migrations/postgres/V0015.TOTPEnhance.up.sql
@@ -0,0 +1,8 @@
+CREATE TABLE IF NOT EXISTS totp_history (
+ id SERIAL CONSTRAINT one_time_code_pkey PRIMARY KEY,
+ created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ username VARCHAR(100) NOT NULL,
+ step CHAR(128) NOT NULL
+);
+
+CREATE UNIQUE INDEX totp_history_lookup_key ON totp_history (username, step);
diff --git a/internal/storage/migrations/sqlite/V0013.OneTimeCode.up.sql b/internal/storage/migrations/sqlite/V0013.OneTimeCode.up.sql
index f7e2ab0f7..6fc19d524 100644
--- a/internal/storage/migrations/sqlite/V0013.OneTimeCode.up.sql
+++ b/internal/storage/migrations/sqlite/V0013.OneTimeCode.up.sql
@@ -15,4 +15,3 @@ CREATE TABLE IF NOT EXISTS one_time_code (
);
CREATE UNIQUE INDEX one_time_code_lookup_key ON one_time_code (signature, username);
-CREATE INDEX one_time_code_lookup ON one_time_code (signature, username);
diff --git a/internal/storage/migrations/sqlite/V0015.TOTPEnhance.down.sql b/internal/storage/migrations/sqlite/V0015.TOTPEnhance.down.sql
new file mode 100644
index 000000000..53d9ae5ab
--- /dev/null
+++ b/internal/storage/migrations/sqlite/V0015.TOTPEnhance.down.sql
@@ -0,0 +1 @@
+DROP TABLE IF EXISTS totp_history;
diff --git a/internal/storage/migrations/sqlite/V0015.TOTPEnhance.up.sql b/internal/storage/migrations/sqlite/V0015.TOTPEnhance.up.sql
new file mode 100644
index 000000000..21a3c5667
--- /dev/null
+++ b/internal/storage/migrations/sqlite/V0015.TOTPEnhance.up.sql
@@ -0,0 +1,8 @@
+CREATE TABLE IF NOT EXISTS totp_history (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ username VARCHAR(100) NOT NULL,
+ step CHAR(128) NOT NULL
+);
+
+CREATE UNIQUE INDEX totp_history_lookup_key ON totp_history (username, step);
diff --git a/internal/storage/migrations_test.go b/internal/storage/migrations_test.go
index 5ebf686e2..7cfedace2 100644
--- a/internal/storage/migrations_test.go
+++ b/internal/storage/migrations_test.go
@@ -11,7 +11,7 @@ import (
const (
// This is the latest schema version for the purpose of tests.
- LatestVersion = 14
+ LatestVersion = 15
)
func TestShouldObtainCorrectMigrations(t *testing.T) {
diff --git a/internal/storage/provider.go b/internal/storage/provider.go
index a0f23627d..e53cf7ed1 100644
--- a/internal/storage/provider.go
+++ b/internal/storage/provider.go
@@ -71,6 +71,16 @@ type Provider interface {
LoadTOTPConfigurations(ctx context.Context, limit, page int) (configs []model.TOTPConfiguration, err error)
/*
+ Implementation for User TOTP History.
+ */
+
+ // SaveTOTPHistory saves a TOTP history item in the storage provider.
+ SaveTOTPHistory(ctx context.Context, username string, step uint64) (err error)
+
+ // ExistsTOTPHistory checks if a TOTP history item exists in the storage provider.
+ ExistsTOTPHistory(ctx context.Context, username string, step uint64, since time.Time) (exists bool, err error)
+
+ /*
Implementation for User WebAuthn Information.
*/
diff --git a/internal/storage/sql_provider.go b/internal/storage/sql_provider.go
index 66f8a7795..cb86e137c 100644
--- a/internal/storage/sql_provider.go
+++ b/internal/storage/sql_provider.go
@@ -6,6 +6,7 @@ import (
"database/sql"
"errors"
"fmt"
+ "strconv"
"strings"
"time"
@@ -59,6 +60,9 @@ func NewSQLProvider(config *schema.Configuration, name, driverName, dataSourceNa
sqlUpdateTOTPConfigRecordSignIn: fmt.Sprintf(queryFmtUpdateTOTPConfigRecordSignIn, tableTOTPConfigurations),
sqlUpdateTOTPConfigRecordSignInByUsername: fmt.Sprintf(queryFmtUpdateTOTPConfigRecordSignInByUsername, tableTOTPConfigurations),
+ sqlInsertTOTPHistory: fmt.Sprintf(queryFmtInsertTOTPHistory, tableTOTPHistory),
+ sqlSelectTOTPHistory: fmt.Sprintf(queryFmtSelectTOTPHistory, tableTOTPHistory),
+
sqlInsertWebAuthnUser: fmt.Sprintf(queryFmtInsertWebAuthnUser, tableWebAuthnUsers),
sqlSelectWebAuthnUser: fmt.Sprintf(queryFmtSelectWebAuthnUser, tableWebAuthnUsers),
@@ -193,6 +197,10 @@ type SQLProvider struct {
sqlUpdateTOTPConfigRecordSignIn string
sqlUpdateTOTPConfigRecordSignInByUsername string
+ // Table: totp_history.
+ sqlInsertTOTPHistory string
+ sqlSelectTOTPHistory string
+
// Table: webauthn_users.
sqlInsertWebAuthnUser string
sqlSelectWebAuthnUser string
@@ -546,6 +554,30 @@ func (p *SQLProvider) LoadTOTPConfiguration(ctx context.Context, username string
return config, nil
}
+// SaveTOTPHistory saves a TOTP history item in the storage provider.
+func (p *SQLProvider) SaveTOTPHistory(ctx context.Context, username string, step uint64) (err error) {
+ signature := p.hmacSignature([]byte(strconv.Itoa(int(step))), []byte(username))
+
+ if _, err = p.db.ExecContext(ctx, p.sqlInsertTOTPHistory, username, signature); err != nil {
+ return fmt.Errorf("error inserting TOTP history for user '%s': %w", username, err)
+ }
+
+ return nil
+}
+
+// ExistsTOTPHistory checks if a TOTP history item exists in the storage provider.
+func (p *SQLProvider) ExistsTOTPHistory(ctx context.Context, username string, step uint64, since time.Time) (exists bool, err error) {
+ var count int
+
+ signature := p.hmacSignature([]byte(strconv.Itoa(int(step))), []byte(username))
+
+ if err = p.db.SelectContext(ctx, &count, p.sqlSelectTOTPHistory, username, signature, since); err != nil {
+ return false, fmt.Errorf("error checking if TOTP history exists: %w", err)
+ }
+
+ return count != 0, nil
+}
+
// LoadTOTPConfigurations load a set of TOTP configurations from the storage provider.
func (p *SQLProvider) LoadTOTPConfigurations(ctx context.Context, limit, page int) (configs []model.TOTPConfiguration, err error) {
configs = make([]model.TOTPConfiguration, 0, limit)
diff --git a/internal/storage/sql_provider_backend_postgres.go b/internal/storage/sql_provider_backend_postgres.go
index 4a049cffd..ee6aa434b 100644
--- a/internal/storage/sql_provider_backend_postgres.go
+++ b/internal/storage/sql_provider_backend_postgres.go
@@ -66,6 +66,9 @@ func NewPostgreSQLProvider(config *schema.Configuration, caCertPool *x509.CertPo
provider.sqlDeleteTOTPConfig = provider.db.Rebind(provider.sqlDeleteTOTPConfig)
provider.sqlSelectTOTPConfigs = provider.db.Rebind(provider.sqlSelectTOTPConfigs)
+ provider.sqlInsertTOTPHistory = provider.db.Rebind(provider.sqlInsertTOTPHistory)
+ provider.sqlSelectTOTPHistory = provider.db.Rebind(provider.sqlSelectTOTPHistory)
+
provider.sqlInsertWebAuthnUser = provider.db.Rebind(provider.sqlInsertWebAuthnUser)
provider.sqlSelectWebAuthnUser = provider.db.Rebind(provider.sqlSelectWebAuthnUser)
diff --git a/internal/storage/sql_provider_queries.go b/internal/storage/sql_provider_queries.go
index bff832dbd..48be6d2af 100644
--- a/internal/storage/sql_provider_queries.go
+++ b/internal/storage/sql_provider_queries.go
@@ -167,6 +167,17 @@ const (
WHERE id = ?;`
)
+const (
+ queryFmtInsertTOTPHistory = `
+ INSERT INTO %s (username, step)
+ VALUES (?, ?);`
+
+ queryFmtSelectTOTPHistory = `
+ SELECT COUNT(id)
+ FROM %s
+ WHERE username = ? AND step = ?;`
+)
+
//nolint:gosec // The following queries are not hard coded credentials.
const (
queryFmtSelectWebAuthnCredentials = `
diff --git a/internal/suites/action_totp.go b/internal/suites/action_totp.go
index fd75f7e8c..3f4f9f77f 100644
--- a/internal/suites/action_totp.go
+++ b/internal/suites/action_totp.go
@@ -7,10 +7,10 @@ import (
"testing"
"time"
+ "github.com/authelia/otp"
+ "github.com/authelia/otp/totp"
"github.com/go-rod/rod"
"github.com/go-rod/rod/lib/input"
- "github.com/pquerna/otp"
- "github.com/pquerna/otp/totp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
diff --git a/internal/suites/suites_credentials.go b/internal/suites/suites_credentials.go
index d59007144..ac9a1861c 100644
--- a/internal/suites/suites_credentials.go
+++ b/internal/suites/suites_credentials.go
@@ -4,7 +4,7 @@ import (
"sync"
"time"
- "github.com/pquerna/otp/totp"
+ "github.com/authelia/otp/totp"
)
func NewRodSuiteCredentials() *RodSuiteCredentials {
diff --git a/internal/totp/helpers.go b/internal/totp/helpers.go
index e464c1d72..1f56ed832 100644
--- a/internal/totp/helpers.go
+++ b/internal/totp/helpers.go
@@ -1,7 +1,7 @@
package totp
import (
- "github.com/pquerna/otp"
+ "github.com/authelia/otp"
"github.com/authelia/authelia/v4/internal/configuration/schema"
)
diff --git a/internal/totp/helpers_test.go b/internal/totp/helpers_test.go
index 19c551cbf..060c775de 100644
--- a/internal/totp/helpers_test.go
+++ b/internal/totp/helpers_test.go
@@ -3,7 +3,7 @@ package totp
import (
"testing"
- "github.com/pquerna/otp"
+ "github.com/authelia/otp"
"github.com/stretchr/testify/assert"
)
diff --git a/internal/totp/provider.go b/internal/totp/provider.go
index 91ed49a10..6686ec904 100644
--- a/internal/totp/provider.go
+++ b/internal/totp/provider.go
@@ -8,6 +8,6 @@ import (
type Provider interface {
Generate(username string) (config *model.TOTPConfiguration, err error)
GenerateCustom(username string, algorithm, secret string, digits, period, secretSize uint) (config *model.TOTPConfiguration, err error)
- Validate(token string, config *model.TOTPConfiguration) (valid bool, err error)
+ Validate(token string, config *model.TOTPConfiguration) (valid bool, step uint64, err error)
Options() model.TOTPOptions
}
diff --git a/internal/totp/totp.go b/internal/totp/totp.go
index d1659a5d9..986626d6f 100644
--- a/internal/totp/totp.go
+++ b/internal/totp/totp.go
@@ -5,8 +5,8 @@ import (
"fmt"
"time"
- "github.com/pquerna/otp"
- "github.com/pquerna/otp/totp"
+ "github.com/authelia/otp"
+ "github.com/authelia/otp/totp"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/model"
@@ -104,7 +104,7 @@ func (p TimeBased) Generate(username string) (config *model.TOTPConfiguration, e
}
// Validate the token against the given configuration.
-func (p TimeBased) Validate(token string, config *model.TOTPConfiguration) (valid bool, err error) {
+func (p TimeBased) Validate(token string, config *model.TOTPConfiguration) (valid bool, step uint64, err error) {
opts := totp.ValidateOpts{
Period: config.Period,
Skew: p.skew,
@@ -112,10 +112,14 @@ func (p TimeBased) Validate(token string, config *model.TOTPConfiguration) (vali
Algorithm: otpStringToAlgo(config.Algorithm),
}
- return totp.ValidateCustom(token, string(config.Secret), time.Now().UTC(), opts)
+ return totp.ValidateCustomStep(token, string(config.Secret), time.Now().UTC(), opts)
}
// Options returns the configured options for this provider.
func (p TimeBased) Options() model.TOTPOptions {
return *p.opts
}
+
+var (
+ _ Provider = (*TimeBased)(nil)
+)