2019-04-24 21:52:08 +00:00
package handlers
import (
"fmt"
2019-12-24 02:14:52 +00:00
"github.com/authelia/authelia/internal/authentication"
"github.com/authelia/authelia/internal/middlewares"
2019-04-24 21:52:08 +00:00
)
// SecondFactorTOTPPost validate the TOTP passcode provided by the user.
2020-02-01 12:54:50 +00:00
func SecondFactorTOTPPost ( totpVerifier TOTPVerifier ) middlewares . RequestHandler {
return func ( ctx * middlewares . AutheliaCtx ) {
2021-05-04 22:06:05 +00:00
requestBody := signTOTPRequestBody { }
err := ctx . ParseBody ( & requestBody )
2019-04-24 21:52:08 +00:00
2020-02-01 12:54:50 +00:00
if err != nil {
2020-05-05 21:27:38 +00:00
handleAuthenticationUnauthorized ( ctx , err , mfaValidationFailedMessage )
2020-02-01 12:54:50 +00:00
return
}
2019-04-24 21:52:08 +00:00
2020-02-01 12:54:50 +00:00
userSession := ctx . GetSession ( )
2020-05-05 19:35:32 +00:00
2020-02-01 12:54:50 +00:00
secret , err := ctx . Providers . StorageProvider . LoadTOTPSecret ( userSession . Username )
if err != nil {
2020-05-05 21:27:38 +00:00
handleAuthenticationUnauthorized ( ctx , fmt . Errorf ( "Unable to load TOTP secret: %s" , err ) , mfaValidationFailedMessage )
2020-02-01 12:54:50 +00:00
return
}
2019-04-24 21:52:08 +00:00
2021-05-04 22:06:05 +00:00
isValid , err := totpVerifier . Verify ( requestBody . Token , secret )
2020-03-25 01:48:20 +00:00
if err != nil {
2020-05-05 21:27:38 +00:00
handleAuthenticationUnauthorized ( ctx , fmt . Errorf ( "Error occurred during OTP validation for user %s: %s" , userSession . Username , err ) , mfaValidationFailedMessage )
2020-03-25 01:48:20 +00:00
return
}
2019-04-24 21:52:08 +00:00
2020-02-01 12:54:50 +00:00
if ! isValid {
2020-05-05 21:27:38 +00:00
handleAuthenticationUnauthorized ( ctx , fmt . Errorf ( "Wrong passcode during TOTP validation for user %s" , userSession . Username ) , mfaValidationFailedMessage )
2020-02-01 12:54:50 +00:00
return
}
2019-04-24 21:52:08 +00:00
2020-02-29 23:13:33 +00:00
err = ctx . Providers . SessionProvider . RegenerateSession ( ctx . RequestCtx )
if err != nil {
2020-05-05 21:27:38 +00:00
handleAuthenticationUnauthorized ( ctx , fmt . Errorf ( "Unable to regenerate session for user %s: %s" , userSession . Username , err ) , mfaValidationFailedMessage )
2020-02-29 23:13:33 +00:00
return
}
2020-02-01 12:54:50 +00:00
userSession . AuthenticationLevel = authentication . TwoFactor
err = ctx . SaveSession ( userSession )
2019-04-24 21:52:08 +00:00
if err != nil {
2020-05-05 21:27:38 +00:00
handleAuthenticationUnauthorized ( ctx , fmt . Errorf ( "Unable to update the authentication level with TOTP: %s" , err ) , mfaValidationFailedMessage )
2019-04-24 21:52:08 +00:00
return
}
2021-05-04 22:06:05 +00:00
if userSession . OIDCWorkflowSession != nil {
HandleOIDCWorkflowResponse ( ctx )
} else {
Handle2FAResponse ( ctx , requestBody . TargetURL )
}
2019-04-24 21:52:08 +00:00
}
}