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