diff --git a/handlers/user-init-password-change.go b/handlers/user-init-password-change.go index e86a179..f2dd596 100644 --- a/handlers/user-init-password-change.go +++ b/handlers/user-init-password-change.go @@ -5,6 +5,7 @@ package handlers import ( "context" + "errors" "net/http" moduser "git.dotya.ml/mirre-mt/pcmt/modules/user" @@ -70,6 +71,24 @@ func InitialPasswordChange() echo.HandlerFunc { if err != nil { c.Logger().Errorf("error changing initial user password: %q", err) + switch { + case errors.Is(err, moduser.ErrPasswordEmpty): + return renderErrorPage( + c, + http.StatusBadRequest, + http.StatusText(http.StatusBadRequest), + err.Error(), + ) + + case errors.Is(err, moduser.ErrNewPasswordCannotEqual): + return renderErrorPage( + c, + http.StatusBadRequest, + http.StatusText(http.StatusBadRequest)+" - the new password needs to be different from the original", + err.Error(), + ) + } + return renderErrorPage( c, http.StatusInternalServerError, diff --git a/modules/user/error.go b/modules/user/error.go index 2df3fc9..d811f81 100644 --- a/modules/user/error.go +++ b/modules/user/error.go @@ -6,8 +6,10 @@ package user import "errors" var ( - ErrUsersAlreadyPresent = errors.New("don't call CreateFirst when there already are another users") - ErrUserNotFound = errors.New("user not found") - ErrFailedToQueryUser = errors.New("failed to query user") - ErrBadUUID = errors.New("invalid uuid") + ErrUsersAlreadyPresent = errors.New("don't call CreateFirst when there already are another users") + ErrUserNotFound = errors.New("user not found") + ErrFailedToQueryUser = errors.New("failed to query user") + ErrBadUUID = errors.New("invalid uuid") + ErrPasswordEmpty = errors.New("password was empty") + ErrNewPasswordCannotEqual = errors.New("the new password cannot be the same as the old one") ) diff --git a/modules/user/user.go b/modules/user/user.go index 47eaf60..f314cef 100644 --- a/modules/user/user.go +++ b/modules/user/user.go @@ -120,6 +120,19 @@ func QueryUserByID(ctx context.Context, client *ent.Client, strID string) (*ent. return nil, ErrBadUUID } + return QueryUserByUUID(ctx, client, id) +} + +// QueryUserByUUID returns user for the provided ID, and nil if err == nil, nil +// and err otherwise. +func QueryUserByUUID(ctx context.Context, client *ent.Client, id uuid.UUID) (*ent.User, error) { + slogger := ctx.Value(CtxKey{}).(*slogging.Slogger) + log := *slogger + + log.Logger = log.Logger.With( + slog.Group("pcmt extra", slog.String("module", "modules/user")), + ) + u, err := client.User. Query(). Where(user.IDEQ(id)). @@ -171,6 +184,22 @@ func ChangePassFirstLogin(ctx context.Context, client *ent.Client, id uuid.UUID, return nil } + if password == "" { + return ErrPasswordEmpty + } + + { + u, err := QueryUserByUUID(ctx, client, id) + if err != nil { + return err + } + + equal := passwd.Compare(u.Password, password) + if equal { + return ErrNewPasswordCannotEqual + } + } + var digest []byte digest, err = passwd.GetHash(password)