forked from authentricity/authentricity
72 lines
1.7 KiB
Go
72 lines
1.7 KiB
Go
package webui
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/GehirnInc/crypt/sha512_crypt"
|
|
"go.e43.eu/authentricity/internal/models"
|
|
"go.e43.eu/authentricity/internal/store"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func (s *Service) actionChangePassword(
|
|
w http.ResponseWriter,
|
|
r *http.Request,
|
|
ent models.Entity,
|
|
md store.EntryMetadata,
|
|
) {
|
|
user, ok := ent.(*models.UserRecord)
|
|
if !ok {
|
|
s.renderBadRequest(w, r)
|
|
return
|
|
}
|
|
|
|
if !s.canEditEntity(r.Context(), user.UUID) {
|
|
s.renderForbidden(w, r)
|
|
return
|
|
}
|
|
|
|
tok := getUserToken(r.Context())
|
|
isYou := user.UUID.String() == tok.Subject()
|
|
|
|
priv := user.EnsurePrivileged()
|
|
oldPW := r.PostForm.Get("old_password")
|
|
newPW := r.PostForm.Get("new_password")
|
|
confirmPW := r.PostForm.Get("confirm_password")
|
|
|
|
switch {
|
|
case newPW == "":
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
s.renderEntity(w, r, ent, "New password must not be blank")
|
|
return
|
|
case newPW != confirmPW:
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
s.renderEntity(w, r, ent, "Passwords do not match")
|
|
return
|
|
|
|
// Admins skip old password check, except for when changing their own password
|
|
case isYou && !priv.CheckPassword(oldPW):
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
s.renderEntity(w, r, ent, "Old password incorrect")
|
|
return
|
|
}
|
|
|
|
// TODO: This should probably be customizable!
|
|
c := sha512_crypt.New()
|
|
hash, err := c.Generate([]byte(newPW), nil)
|
|
if err != nil {
|
|
zap.L().Error("Error computing password hash", zap.Error(err))
|
|
s.renderError(w)
|
|
return
|
|
}
|
|
|
|
priv.HashedPassword = []string{hash}
|
|
|
|
if err := s.store.UpdateEntitySimple(r.Context(), user, md); err != nil {
|
|
zap.L().Error("Error updating user", zap.Error(err))
|
|
s.renderError(w)
|
|
} else {
|
|
s.renderEntity(w, r, ent, "Password changed")
|
|
}
|
|
}
|