Merge branch 'develop'

This commit is contained in:
Lars Hoogestraat 2021-08-27 00:02:06 +02:00
commit 82a94386fd
6 changed files with 47 additions and 49 deletions

View File

@ -229,9 +229,9 @@ func ResetPasswordHandler(ctx *middleware.AppContext, w http.ResponseWriter, r *
// ResetPasswordPostHandler handles a password reset
func ResetPasswordPostHandler(ctx *middleware.AppContext, w http.ResponseWriter, r *http.Request) *middleware.Template {
hash := getVar(r, "hash")
password := r.FormValue("password")
password2 := r.FormValue("password_repeat")
hash := getVar(r, "hash")
t, err := ctx.TokenService.Get(hash, models.PasswordReset, time.Duration(1)*time.Hour)
@ -277,6 +277,15 @@ func ResetPasswordPostHandler(ctx *middleware.AppContext, w http.ResponseWriter,
ctx.Mailer.SendPasswordChangeConfirmation(u)
if !u.Active {
logger.Log.Warnf("password reset for user '%s' was successful, but user is deactivated", u.Email)
return &middleware.Template{
Name: tplAdminResetPassword,
WarnMsg: "Your password reset was successful, but your account is deactivated.",
}
}
return &middleware.Template{
RedirectPath: "admin",
SuccessMsg: "Your password reset was successful.",
@ -297,11 +306,14 @@ func ForgotPasswordPostHandler(ctx *middleware.AppContext, w http.ResponseWriter
u, err := ctx.UserService.GetByMail(email)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
logger.Log.Error(err)
return &middleware.Template{
RedirectPath: "admin",
SuccessMsg: "An email with password reset instructions is on the way.",
var e *httperror.Error
if errors.As(err, &e) {
if errors.Is(e.Err, sql.ErrNoRows) {
logger.Log.Error(err)
return &middleware.Template{
Name: tplAdminForgotPassword,
SuccessMsg: fmt.Sprintf("An email to '%s' with password reset instructions is on the way.", email),
}
}
} else {
return &middleware.Template{
@ -316,31 +328,16 @@ func ForgotPasswordPostHandler(ctx *middleware.AppContext, w http.ResponseWriter
}
}
if !u.Active {
return &middleware.Template{
Name: tplAdminForgotPassword,
Err: httperror.New(http.StatusUnauthorized, "Your account is deactivated.", err),
Data: map[string]interface{}{
"user": models.User{
Email: email,
},
},
}
}
t := &models.Token{
Author: u,
Type: models.PasswordReset,
}
err = ctx.TokenService.RateLimit(u.ID, models.PasswordReset)
if err != nil {
if err = ctx.TokenService.RateLimit(u.ID, models.PasswordReset); err != nil {
logger.Log.Error(err)
}
err = ctx.TokenService.Create(t)
if err != nil {
if err = ctx.TokenService.Create(t); err != nil {
return &middleware.Template{
Name: tplAdminForgotPassword,
Err: err,
@ -350,7 +347,7 @@ func ForgotPasswordPostHandler(ctx *middleware.AppContext, w http.ResponseWriter
ctx.Mailer.SendPasswordResetLink(u, t)
return &middleware.Template{
RedirectPath: "admin",
SuccessMsg: "An email with password reset instructions is on the way.",
Name: tplAdminForgotPassword,
SuccessMsg: fmt.Sprintf("An email to '%s' with password reset instructions is on the way.", email),
}
}

View File

@ -16,7 +16,7 @@ import (
)
// GetArticleHandler returns a specific article
// Parameters are in the form /year/month/slug e.g. 2016/3/my-headline
// URL Parameters are in the form /year/month/slug e.g. 2016/3/my-
func GetArticleHandler(ctx *middleware.AppContext, w http.ResponseWriter, r *http.Request) *middleware.Template {
year := getVar(r, "year")
month := getVar(r, "month")

View File

@ -87,3 +87,7 @@ func ValueRequired(param string) *Error {
func (e Error) Error() string {
return fmt.Sprintf("code=[%d], error=[%s], displayMsg=[%s]", e.HTTPStatus, e.Err.Error(), e.DisplayMsg)
}
func (e *Error) Unwrap() error {
return e.Err
}

View File

@ -144,7 +144,7 @@ func (s Service) Send(m Mail) error {
}
}
var buffer = make(chan Mail, 10)
var buffer = make(chan Mail, 5)
func (s Service) readBuffer() {
for {

View File

@ -33,50 +33,47 @@ type TemplateHandler struct {
type Handler func(*AppContext, http.ResponseWriter, *http.Request) *Template
func (fn TemplateHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
var errorMsg, warnMsg, successMsg string
code := http.StatusOK
ip := getIP(r)
en := logger.Log.WithField("ip", ip)
t := fn.Handler(fn.AppCtx, rw, r)
if t.Data == nil {
t.Data = make(map[string]interface{})
}
user, err := User(r)
if err == nil {
t.Data["currentUser"] = user
}
var errorMsg, warnMsg, successMsg string
successMsg = t.SuccessMsg
warnMsg = t.WarnMsg
code := http.StatusOK
logWithIP := logger.Log.WithField("ip", getIP(r))
t.Data["CSRFToken"] = csrf.Token(r)
if t.Err != nil {
switch e := t.Err.(type) {
case *httperror.Error:
code = e.HTTPStatus
en.Error(e)
logWithIP.Error(e)
errorMsg = e.DisplayMsg
default:
en.Error(e)
logWithIP.Error(e)
errorMsg = "Sorry, an internal server error occurred"
}
t.Data["ErrorMsg"] = errorMsg
}
if user, err := User(r); err == nil {
t.Data["currentUser"] = user
}
if len(t.RedirectPath) == 0 {
t.Data["SuccessMsg"] = successMsg
t.Data["WarnsMsg"] = warnMsg
fl, err := getFlash(rw, r, "SuccessMsg")
if err != nil {
logger.Log.Error(err)
logWithIP.Error(err)
} else if len(fl) > 0 {
t.Data["SuccessMsg"] = fl
}
@ -84,7 +81,7 @@ func (fn TemplateHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
fl, err = getFlash(rw, r, "ErrorMsg")
if err != nil {
en.Error(err)
logWithIP.Error(err)
} else if len(fl) > 0 {
t.Data["ErrorMsg"] = fl
}
@ -92,7 +89,7 @@ func (fn TemplateHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
fl, err = getFlash(rw, r, "WarnMsg")
if err != nil {
en.Error(err)
logWithIP.Error(err)
} else if len(fl) > 0 {
t.Data["WarnMsg"] = fl
}
@ -103,7 +100,7 @@ func (fn TemplateHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
rw.WriteHeader(code)
if err := fn.AppCtx.Templates.ExecuteTemplate(rw, t.Name, t.Data); err != nil {
en.Error(err)
logWithIP.Error(err)
http.Error(rw, err.Error(), http.StatusInternalServerError)
}
} else {
@ -177,7 +174,7 @@ func (ctx AppContext) AuthHandler(handler http.Handler) http.Handler {
return http.HandlerFunc(fn)
}
// RequireAdmin ensures that the user is an admin; if not next handler in chain is not called
// RequireAdmin ensures that the user is an admin; if not next handler in chain is not called.
func (ctx AppContext) RequireAdmin(handler http.Handler) http.Handler {
fn := func(rw http.ResponseWriter, r *http.Request) {
u, err := User(r)

View File

@ -43,7 +43,7 @@ type TokenType int
// Scan implements the Scanner interface.
func (tt *TokenType) Scan(value interface{}) error {
for k, t := range types {
if t == string(value.([]byte)) {
if t == (value.(string)) {
tts := TokenType(k)
tt = &tts
return nil