2019-04-24 21:52:08 +00:00
|
|
|
package handlers
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2022-01-20 23:46:13 +00:00
|
|
|
"time"
|
2019-04-24 21:52:08 +00:00
|
|
|
|
2021-08-11 01:04:35 +00:00
|
|
|
"github.com/authelia/authelia/v4/internal/middlewares"
|
|
|
|
"github.com/authelia/authelia/v4/internal/session"
|
2019-04-24 21:52:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func identityRetrieverFromStorage(ctx *middlewares.AutheliaCtx) (*session.Identity, error) {
|
|
|
|
var requestBody resetPasswordStep1RequestBody
|
|
|
|
err := json.Unmarshal(ctx.PostBody(), &requestBody)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
details, err := ctx.Providers.UserProvider.GetDetails(requestBody.Username)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(details.Emails) == 0 {
|
2021-09-17 05:53:40 +00:00
|
|
|
return nil, fmt.Errorf("user %s has no email address configured", requestBody.Username)
|
2019-04-24 21:52:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &session.Identity{
|
2022-04-03 12:24:51 +00:00
|
|
|
Username: requestBody.Username,
|
|
|
|
DisplayName: details.DisplayName,
|
2022-12-26 23:54:58 +00:00
|
|
|
Email: details.Emails[0],
|
2019-04-24 21:52:08 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ResetPasswordIdentityStart the handler for initiating the identity validation for resetting a password.
|
2020-01-21 00:10:00 +00:00
|
|
|
// We need to ensure the attacker cannot perform user enumeration by always replying with 200 whatever what happens in backend.
|
2019-04-24 21:52:08 +00:00
|
|
|
var ResetPasswordIdentityStart = middlewares.IdentityVerificationStart(middlewares.IdentityVerificationStartArgs{
|
|
|
|
MailTitle: "Reset your password",
|
|
|
|
MailButtonContent: "Reset",
|
2019-11-18 23:37:36 +00:00
|
|
|
TargetEndpoint: "/reset-password/step2",
|
2021-07-22 03:52:37 +00:00
|
|
|
ActionClaim: ActionResetPassword,
|
2019-04-24 21:52:08 +00:00
|
|
|
IdentityRetrieverFunc: identityRetrieverFromStorage,
|
2023-03-01 23:38:56 +00:00
|
|
|
}, middlewares.NewTimingAttackDelayer("password reset", time.Millisecond*500, time.Millisecond*250, time.Millisecond*85, 10))
|
2019-04-24 21:52:08 +00:00
|
|
|
|
|
|
|
func resetPasswordIdentityFinish(ctx *middlewares.AutheliaCtx, username string) {
|
2023-01-25 09:36:40 +00:00
|
|
|
var (
|
|
|
|
userSession session.UserSession
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
|
|
|
|
if userSession, err = ctx.GetSession(); err != nil {
|
|
|
|
ctx.Logger.Errorf("Unable to get session to clear password reset flag in session for user %s: %s", userSession.Username, err)
|
|
|
|
}
|
|
|
|
|
2019-04-24 21:52:08 +00:00
|
|
|
// TODO(c.michaud): use JWT tokens to expire the request in only few seconds for better security.
|
|
|
|
userSession.PasswordResetUsername = &username
|
2020-12-16 01:47:31 +00:00
|
|
|
|
2023-01-25 09:36:40 +00:00
|
|
|
if err = ctx.SaveSession(userSession); err != nil {
|
2020-12-16 01:47:31 +00:00
|
|
|
ctx.Logger.Errorf("Unable to clear password reset flag in session for user %s: %s", userSession.Username, err)
|
|
|
|
}
|
2019-04-24 21:52:08 +00:00
|
|
|
|
2022-04-03 11:58:27 +00:00
|
|
|
ctx.ReplyOK()
|
2019-04-24 21:52:08 +00:00
|
|
|
}
|
|
|
|
|
2020-01-21 00:10:00 +00:00
|
|
|
// ResetPasswordIdentityFinish the handler for finishing the identity validation.
|
2019-04-24 21:52:08 +00:00
|
|
|
var ResetPasswordIdentityFinish = middlewares.IdentityVerificationFinish(
|
2021-07-22 03:52:37 +00:00
|
|
|
middlewares.IdentityVerificationFinishArgs{ActionClaim: ActionResetPassword}, resetPasswordIdentityFinish)
|