mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
refactor(web): only fetch totp conf if required (#2663)
Prevents the TOTP user config from being requested when the user has not registered or is already authenticated 2FA.
This commit is contained in:
parent
f0119b5c75
commit
104a61ecd6
2
.github/commit-msg
vendored
2
.github/commit-msg
vendored
|
@ -2,4 +2,4 @@
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
. "$(dirname "$0")/required-apps"
|
. "$(dirname "$0")/required-apps"
|
||||||
|
|
||||||
cd web && ${PMGR} commit
|
cd web && ${PMGR} commitlint --edit "$1"
|
||||||
|
|
|
@ -252,7 +252,7 @@ typically located at `/etc/fail2ban/filter.d`.
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
failregex = ^.*Unsuccessful 1FA authentication attempt by user .*remote_ip="?<HOST>"? stack.*
|
failregex = ^.*Unsuccessful 1FA authentication attempt by user .*remote_ip="?<HOST>"? stack.*
|
||||||
^.*Unsuccessful (TOTP|DUO|U2F) authentication attempt by user .*remote_ip="?<HOST>"? stack.*
|
^.*Unsuccessful (TOTP|Duo|U2F) authentication attempt by user .*remote_ip="?<HOST>"? stack.*
|
||||||
|
|
||||||
ignoreregex = ^.*level=debug.*
|
ignoreregex = ^.*level=debug.*
|
||||||
^.*level=info.*
|
^.*level=info.*
|
||||||
|
|
|
@ -117,7 +117,7 @@ func (p *LDAPUserProvider) CheckUserPassword(inputUsername string, password stri
|
||||||
|
|
||||||
userConn, err := p.connect(profile.DN, password)
|
userConn, err := p.connect(profile.DN, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("Authentication of user %s failed. Cause: %s", inputUsername, err)
|
return false, fmt.Errorf("authentication failed. Cause: %w", err)
|
||||||
}
|
}
|
||||||
defer userConn.Close()
|
defer userConn.Close()
|
||||||
|
|
||||||
|
|
|
@ -1098,14 +1098,14 @@ func TestShouldCheckInvalidUserPassword(t *testing.T) {
|
||||||
Return(mockConn, nil),
|
Return(mockConn, nil),
|
||||||
mockConn.EXPECT().
|
mockConn.EXPECT().
|
||||||
Bind(gomock.Eq("uid=test,dc=example,dc=com"), gomock.Eq("password")).
|
Bind(gomock.Eq("uid=test,dc=example,dc=com"), gomock.Eq("password")).
|
||||||
Return(errors.New("Invalid username or password")),
|
Return(errors.New("invalid username or password")),
|
||||||
mockConn.EXPECT().Close(),
|
mockConn.EXPECT().Close(),
|
||||||
)
|
)
|
||||||
|
|
||||||
valid, err := ldapClient.CheckUserPassword("john", "password")
|
valid, err := ldapClient.CheckUserPassword("john", "password")
|
||||||
|
|
||||||
assert.False(t, valid)
|
assert.False(t, valid)
|
||||||
require.EqualError(t, err, "Authentication of user john failed. Cause: Invalid username or password")
|
require.EqualError(t, err, "authentication failed. Cause: invalid username or password")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldCallStartTLSWhenEnabled(t *testing.T) {
|
func TestShouldCallStartTLSWhenEnabled(t *testing.T) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ func SecondFactorDuoPost(duoAPI duo.API) middlewares.RequestHandler {
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := ctx.ParseBody(&requestBody); err != nil {
|
if err := ctx.ParseBody(&requestBody); err != nil {
|
||||||
ctx.Logger.Errorf(logFmtErrParseRequestBody, regulation.AuthTypeDUO, err)
|
ctx.Logger.Errorf(logFmtErrParseRequestBody, regulation.AuthTypeDuo, err)
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ func SecondFactorDuoPost(duoAPI duo.API) middlewares.RequestHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if authResponse.Result != allow {
|
if authResponse.Result != allow {
|
||||||
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeDUO,
|
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeDuo,
|
||||||
fmt.Errorf("duo auth result: %s, status: %s, message: %s", authResponse.Result, authResponse.Status,
|
fmt.Errorf("duo auth result: %s, status: %s, message: %s", authResponse.Result, authResponse.Status,
|
||||||
authResponse.StatusMessage))
|
authResponse.StatusMessage))
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ func SecondFactorDuoPost(duoAPI duo.API) middlewares.RequestHandler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = markAuthenticationAttempt(ctx, true, nil, userSession.Username, regulation.AuthTypeDUO, nil); err != nil {
|
if err = markAuthenticationAttempt(ctx, true, nil, userSession.Username, regulation.AuthTypeDuo, nil); err != nil {
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ func HandleAllow(ctx *middlewares.AutheliaCtx, targetURL string) {
|
||||||
|
|
||||||
err := ctx.Providers.SessionProvider.RegenerateSession(ctx.RequestCtx)
|
err := ctx.Providers.SessionProvider.RegenerateSession(ctx.RequestCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Logger.Errorf(logFmtErrSessionRegenerate, regulation.AuthTypeDUO, userSession.Username, err)
|
ctx.Logger.Errorf(logFmtErrSessionRegenerate, regulation.AuthTypeDuo, userSession.Username, err)
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ func (s *SecondFactorDuoPostSuite) TestShouldAutoSelect() {
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeDUO,
|
Type: regulation.AuthTypeDuo,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
})).
|
})).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
|
@ -285,7 +285,7 @@ func (s *SecondFactorDuoPostSuite) TestShouldUseInvalidMethodAndAutoSelect() {
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeDUO,
|
Type: regulation.AuthTypeDuo,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
})).
|
})).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
|
@ -413,7 +413,7 @@ func (s *SecondFactorDuoPostSuite) TestShouldCallDuoAPIAndDenyAccess() {
|
||||||
Successful: false,
|
Successful: false,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeDUO,
|
Type: regulation.AuthTypeDuo,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
})).
|
})).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
|
@ -496,7 +496,7 @@ func (s *SecondFactorDuoPostSuite) TestShouldRedirectUserToDefaultURL() {
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeDUO,
|
Type: regulation.AuthTypeDuo,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
})).
|
})).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
|
@ -545,7 +545,7 @@ func (s *SecondFactorDuoPostSuite) TestShouldNotReturnRedirectURL() {
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeDUO,
|
Type: regulation.AuthTypeDuo,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
})).
|
})).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
|
@ -590,7 +590,7 @@ func (s *SecondFactorDuoPostSuite) TestShouldRedirectUserToSafeTargetURL() {
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeDUO,
|
Type: regulation.AuthTypeDuo,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
})).
|
})).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
|
@ -639,7 +639,7 @@ func (s *SecondFactorDuoPostSuite) TestShouldNotRedirectToUnsafeURL() {
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeDUO,
|
Type: regulation.AuthTypeDuo,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
})).
|
})).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
|
@ -686,7 +686,7 @@ func (s *SecondFactorDuoPostSuite) TestShouldRegenerateSessionForPreventingSessi
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeDUO,
|
Type: regulation.AuthTypeDuo,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
})).
|
})).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
|
|
|
@ -33,7 +33,7 @@ func SecondFactorU2FSignGet(ctx *middlewares.AutheliaCtx) {
|
||||||
|
|
||||||
challenge, err := u2f.NewChallenge(appID, trustedFacets)
|
challenge, err := u2f.NewChallenge(appID, trustedFacets)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Logger.Errorf("Unable to create %s challenge for user '%s': %+v", regulation.AuthTypeFIDO, userSession.Username, err)
|
ctx.Logger.Errorf("Unable to create %s challenge for user '%s': %+v", regulation.AuthTypeU2F, userSession.Username, err)
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
|
@ -45,11 +45,11 @@ func SecondFactorU2FSignGet(ctx *middlewares.AutheliaCtx) {
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
if err == storage.ErrNoU2FDeviceHandle {
|
if err == storage.ErrNoU2FDeviceHandle {
|
||||||
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeFIDO, fmt.Errorf("no registered U2F device"))
|
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeU2F, fmt.Errorf("no registered U2F device"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Logger.Errorf("Could not load %s devices for user '%s': %+v", regulation.AuthTypeFIDO, userSession.Username, err)
|
ctx.Logger.Errorf("Could not load %s devices for user '%s': %+v", regulation.AuthTypeU2F, userSession.Username, err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ func SecondFactorU2FSignGet(ctx *middlewares.AutheliaCtx) {
|
||||||
userSession.U2FChallenge = challenge
|
userSession.U2FChallenge = challenge
|
||||||
|
|
||||||
if err = ctx.SaveSession(userSession); err != nil {
|
if err = ctx.SaveSession(userSession); err != nil {
|
||||||
ctx.Logger.Errorf(logFmtErrSessionSave, "challenge and registration", regulation.AuthTypeFIDO, userSession.Username, err)
|
ctx.Logger.Errorf(logFmtErrSessionSave, "challenge and registration", regulation.AuthTypeU2F, userSession.Username, err)
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ func SecondFactorU2FSignGet(ctx *middlewares.AutheliaCtx) {
|
||||||
signRequest := challenge.SignRequest([]u2f.Registration{registration})
|
signRequest := challenge.SignRequest([]u2f.Registration{registration})
|
||||||
|
|
||||||
if err = ctx.SetJSONBody(signRequest); err != nil {
|
if err = ctx.SetJSONBody(signRequest); err != nil {
|
||||||
ctx.Logger.Errorf(logFmtErrWriteResponseBody, regulation.AuthTypeFIDO, userSession.Username, err)
|
ctx.Logger.Errorf(logFmtErrWriteResponseBody, regulation.AuthTypeU2F, userSession.Username, err)
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ func SecondFactorU2FSignPost(u2fVerifier U2FVerifier) middlewares.RequestHandler
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := ctx.ParseBody(&requestBody); err != nil {
|
if err := ctx.ParseBody(&requestBody); err != nil {
|
||||||
ctx.Logger.Errorf(logFmtErrParseRequestBody, regulation.AuthTypeFIDO, err)
|
ctx.Logger.Errorf(logFmtErrParseRequestBody, regulation.AuthTypeU2F, err)
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ func SecondFactorU2FSignPost(u2fVerifier U2FVerifier) middlewares.RequestHandler
|
||||||
|
|
||||||
userSession := ctx.GetSession()
|
userSession := ctx.GetSession()
|
||||||
if userSession.U2FChallenge == nil {
|
if userSession.U2FChallenge == nil {
|
||||||
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeFIDO, errors.New("session did not contain a challenge"))
|
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeU2F, errors.New("session did not contain a challenge"))
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ func SecondFactorU2FSignPost(u2fVerifier U2FVerifier) middlewares.RequestHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
if userSession.U2FRegistration == nil {
|
if userSession.U2FRegistration == nil {
|
||||||
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeFIDO, errors.New("session did not contain a registration"))
|
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeU2F, errors.New("session did not contain a registration"))
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ func SecondFactorU2FSignPost(u2fVerifier U2FVerifier) middlewares.RequestHandler
|
||||||
|
|
||||||
if err = u2fVerifier.Verify(userSession.U2FRegistration.KeyHandle, userSession.U2FRegistration.PublicKey,
|
if err = u2fVerifier.Verify(userSession.U2FRegistration.KeyHandle, userSession.U2FRegistration.PublicKey,
|
||||||
requestBody.SignResponse, *userSession.U2FChallenge); err != nil {
|
requestBody.SignResponse, *userSession.U2FChallenge); err != nil {
|
||||||
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeFIDO, err)
|
_ = markAuthenticationAttempt(ctx, false, nil, userSession.Username, regulation.AuthTypeU2F, err)
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
|
@ -50,14 +50,14 @@ func SecondFactorU2FSignPost(u2fVerifier U2FVerifier) middlewares.RequestHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = ctx.Providers.SessionProvider.RegenerateSession(ctx.RequestCtx); err != nil {
|
if err = ctx.Providers.SessionProvider.RegenerateSession(ctx.RequestCtx); err != nil {
|
||||||
ctx.Logger.Errorf(logFmtErrSessionRegenerate, regulation.AuthTypeFIDO, userSession.Username, err)
|
ctx.Logger.Errorf(logFmtErrSessionRegenerate, regulation.AuthTypeU2F, userSession.Username, err)
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = markAuthenticationAttempt(ctx, true, nil, userSession.Username, regulation.AuthTypeFIDO, nil); err != nil {
|
if err = markAuthenticationAttempt(ctx, true, nil, userSession.Username, regulation.AuthTypeU2F, nil); err != nil {
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ func SecondFactorU2FSignPost(u2fVerifier U2FVerifier) middlewares.RequestHandler
|
||||||
|
|
||||||
err = ctx.SaveSession(userSession)
|
err = ctx.SaveSession(userSession)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Logger.Errorf(logFmtErrSessionSave, "authentication time", regulation.AuthTypeFIDO, userSession.Username, err)
|
ctx.Logger.Errorf(logFmtErrSessionSave, "authentication time", regulation.AuthTypeU2F, userSession.Username, err)
|
||||||
|
|
||||||
respondUnauthorized(ctx, messageMFAValidationFailed)
|
respondUnauthorized(ctx, messageMFAValidationFailed)
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (s *HandlerSignU2FStep2Suite) TestShouldRedirectUserToDefaultURL() {
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeFIDO,
|
Type: regulation.AuthTypeU2F,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ func (s *HandlerSignU2FStep2Suite) TestShouldNotReturnRedirectURL() {
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeFIDO,
|
Type: regulation.AuthTypeU2F,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ func (s *HandlerSignU2FStep2Suite) TestShouldRedirectUserToSafeTargetURL() {
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeFIDO,
|
Type: regulation.AuthTypeU2F,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ func (s *HandlerSignU2FStep2Suite) TestShouldNotRedirectToUnsafeURL() {
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeFIDO,
|
Type: regulation.AuthTypeU2F,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ func (s *HandlerSignU2FStep2Suite) TestShouldRegenerateSessionForPreventingSessi
|
||||||
Successful: true,
|
Successful: true,
|
||||||
Banned: false,
|
Banned: false,
|
||||||
Time: s.mock.Clock.Now(),
|
Time: s.mock.Clock.Now(),
|
||||||
Type: regulation.AuthTypeFIDO,
|
Type: regulation.AuthTypeU2F,
|
||||||
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
RemoteIP: models.NewIPAddressFromString("0.0.0.0"),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,12 @@ func UserTOTPGet(ctx *middlewares.AutheliaCtx) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, storage.ErrNoTOTPConfiguration) {
|
if errors.Is(err, storage.ErrNoTOTPConfiguration) {
|
||||||
ctx.SetStatusCode(fasthttp.StatusNotFound)
|
ctx.SetStatusCode(fasthttp.StatusNotFound)
|
||||||
ctx.Error(err, "No TOTP Configuration.")
|
ctx.SetJSONError("Could not find TOTP Configuration for user.")
|
||||||
|
ctx.Logger.Errorf("Failed to lookup TOTP configuration for user '%s'", userSession.Username)
|
||||||
} else {
|
} else {
|
||||||
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
||||||
ctx.Error(err, "Unknown Error.")
|
ctx.SetJSONError("Could not find TOTP Configuration for user.")
|
||||||
|
ctx.Logger.Errorf("Failed to lookup TOTP configuration for user '%s' with unknown error: %v", userSession.Username, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -95,7 +95,7 @@ func verifyBasicAuth(ctx *middlewares.AutheliaCtx, header, auth []byte) (usernam
|
||||||
authenticated, err := ctx.Providers.UserProvider.CheckUserPassword(username, password)
|
authenticated, err := ctx.Providers.UserProvider.CheckUserPassword(username, password)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", nil, nil, authentication.NotAuthenticated, fmt.Errorf("unable to check credentials extracted from %s header: %s", header, err)
|
return "", "", nil, nil, authentication.NotAuthenticated, fmt.Errorf("unable to check credentials extracted from %s header: %w", header, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the user is not correctly authenticated, send a 401.
|
// If the user is not correctly authenticated, send a 401.
|
||||||
|
|
|
@ -12,12 +12,12 @@ const (
|
||||||
// AuthTypeTOTP is the string representing an auth log for second-factor authentication via TOTP.
|
// AuthTypeTOTP is the string representing an auth log for second-factor authentication via TOTP.
|
||||||
AuthTypeTOTP = "TOTP"
|
AuthTypeTOTP = "TOTP"
|
||||||
|
|
||||||
// AuthTypeFIDO is the string representing an auth log for second-factor authentication via FIDO/CTAP1/U2F.
|
// AuthTypeU2F is the string representing an auth log for second-factor authentication via FIDO/CTAP1/U2F.
|
||||||
AuthTypeFIDO = "FIDO"
|
AuthTypeU2F = "U2F"
|
||||||
|
|
||||||
// AuthTypeFIDO2 is the string representing an auth log for second-factor authentication via FIDO2/CTAP2/Webauthn.
|
// AuthTypeWebAuthn is the string representing an auth log for second-factor authentication via FIDO2/CTAP2/WebAuthn.
|
||||||
// TODO: Add FIDO2.
|
// TODO: Add WebAuthn.
|
||||||
|
|
||||||
// AuthTypeDUO is the string representing an auth log for second-factor authentication via DUO.
|
// AuthTypeDuo is the string representing an auth log for second-factor authentication via DUO.
|
||||||
AuthTypeDUO = "DUO"
|
AuthTypeDuo = "Duo"
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS authentication_logs (
|
||||||
successful BOOLEAN NOT NULL,
|
successful BOOLEAN NOT NULL,
|
||||||
banned BOOLEAN NOT NULL DEFAULT FALSE,
|
banned BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
username VARCHAR(100) NOT NULL,
|
username VARCHAR(100) NOT NULL,
|
||||||
auth_type VARCHAR(5) NOT NULL DEFAULT '1FA',
|
auth_type VARCHAR(8) NOT NULL DEFAULT '1FA',
|
||||||
remote_ip VARCHAR(47) NULL DEFAULT NULL,
|
remote_ip VARCHAR(47) NULL DEFAULT NULL,
|
||||||
request_uri TEXT NOT NULL,
|
request_uri TEXT NOT NULL,
|
||||||
request_method VARCHAR(8) NOT NULL DEFAULT '',
|
request_method VARCHAR(8) NOT NULL DEFAULT '',
|
||||||
|
|
|
@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS authentication_logs (
|
||||||
successful BOOLEAN NOT NULL,
|
successful BOOLEAN NOT NULL,
|
||||||
banned BOOLEAN NOT NULL DEFAULT FALSE,
|
banned BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
username VARCHAR(100) NOT NULL,
|
username VARCHAR(100) NOT NULL,
|
||||||
auth_type VARCHAR(5) NOT NULL DEFAULT '1FA',
|
auth_type VARCHAR(8) NOT NULL DEFAULT '1FA',
|
||||||
remote_ip VARCHAR(47) NULL DEFAULT NULL,
|
remote_ip VARCHAR(47) NULL DEFAULT NULL,
|
||||||
request_uri TEXT,
|
request_uri TEXT,
|
||||||
request_method VARCHAR(8) NOT NULL DEFAULT '',
|
request_method VARCHAR(8) NOT NULL DEFAULT '',
|
||||||
|
|
|
@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS authentication_logs (
|
||||||
successful BOOLEAN NOT NULL,
|
successful BOOLEAN NOT NULL,
|
||||||
banned BOOLEAN NOT NULL DEFAULT FALSE,
|
banned BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
username VARCHAR(100) NOT NULL,
|
username VARCHAR(100) NOT NULL,
|
||||||
auth_type VARCHAR(5) NOT NULL DEFAULT '1FA',
|
auth_type VARCHAR(8) NOT NULL DEFAULT '1FA',
|
||||||
remote_ip VARCHAR(47) NULL DEFAULT NULL,
|
remote_ip VARCHAR(47) NULL DEFAULT NULL,
|
||||||
request_uri TEXT,
|
request_uri TEXT,
|
||||||
request_method VARCHAR(8) NOT NULL DEFAULT '',
|
request_method VARCHAR(8) NOT NULL DEFAULT '',
|
||||||
|
|
|
@ -270,8 +270,6 @@ func (s *CLISuite) TestStorage02ShouldShowSchemaInfo() {
|
||||||
func (s *CLISuite) TestStorage03ShouldExportTOTP() {
|
func (s *CLISuite) TestStorage03ShouldExportTOTP() {
|
||||||
storageProvider := storage.NewSQLiteProvider(&storageLocalTmpConfig)
|
storageProvider := storage.NewSQLiteProvider(&storageLocalTmpConfig)
|
||||||
|
|
||||||
s.Require().NoError(storageProvider.StartupCheck())
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -123,7 +123,6 @@ func (s *StandaloneWebDriverSuite) TestShouldCheckUserIsAskedToRegisterDevice()
|
||||||
// Clean up any TOTP secret already in DB.
|
// Clean up any TOTP secret already in DB.
|
||||||
provider := storage.NewSQLiteProvider(&storageLocalTmpConfig)
|
provider := storage.NewSQLiteProvider(&storageLocalTmpConfig)
|
||||||
|
|
||||||
require.NoError(s.T(), provider.StartupCheck())
|
|
||||||
require.NoError(s.T(), provider.DeleteTOTPConfiguration(ctx, username))
|
require.NoError(s.T(), provider.DeleteTOTPConfiguration(ctx, username))
|
||||||
|
|
||||||
// Login one factor.
|
// Login one factor.
|
||||||
|
|
|
@ -29,8 +29,7 @@
|
||||||
"coverage": "VITE_COVERAGE=true vite build",
|
"coverage": "VITE_COVERAGE=true vite build",
|
||||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
|
"lint": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
|
||||||
"test": "jest --coverage --no-cache",
|
"test": "jest --coverage --no-cache",
|
||||||
"report": "nyc report -r clover -r json -r lcov -r text",
|
"report": "nyc report -r clover -r json -r lcov -r text"
|
||||||
"commit": "commitlint --edit $1"
|
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "react-app"
|
"extends": "react-app"
|
||||||
|
|
|
@ -47,8 +47,10 @@ const OneTimePasswordMethod = function (props: Props) {
|
||||||
}, [onSignInErrorCallback, err]);
|
}, [onSignInErrorCallback, err]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch();
|
if (props.registered && props.authenticationLevel === AuthenticationLevel.OneFactor) {
|
||||||
}, [fetch]);
|
fetch();
|
||||||
|
}
|
||||||
|
}, [fetch, props.authenticationLevel, props.registered]);
|
||||||
|
|
||||||
const signInFunc = useCallback(async () => {
|
const signInFunc = useCallback(async () => {
|
||||||
if (!props.registered || props.authenticationLevel === AuthenticationLevel.TwoFactor) {
|
if (!props.registered || props.authenticationLevel === AuthenticationLevel.TwoFactor) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user