Verify password for local-account activation (#13631)

* Verify passwords for activation

This is to prevent 3rd party activation

* Fix function comment

* only veify password on local-account aktivation

* fix lint

* Update templates/user/auth/activate.tmpl

Co-authored-by: silverwind <me@silverwind.io>

Co-authored-by: Andreas Shimokawa <shimokawa@fsfe.org>
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
6543 2020-11-28 23:41:06 +01:00 committed by GitHub
parent e82150d41b
commit 0f14f69e60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 34 deletions

View file

@ -1203,6 +1203,8 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo
// Activate render activate user page // Activate render activate user page
func Activate(ctx *context.Context) { func Activate(ctx *context.Context) {
code := ctx.Query("code") code := ctx.Query("code")
password := ctx.Query("password")
if len(code) == 0 { if len(code) == 0 {
ctx.Data["IsActivatePage"] = true ctx.Data["IsActivatePage"] = true
if ctx.User.IsActive { if ctx.User.IsActive {
@ -1228,42 +1230,58 @@ func Activate(ctx *context.Context) {
return return
} }
// Verify code. user := models.VerifyUserActiveCode(code)
if user := models.VerifyUserActiveCode(code); user != nil { // if code is wrong
user.IsActive = true if user == nil {
var err error ctx.Data["IsActivateFailed"] = true
if user.Rands, err = models.GetUserSalt(); err != nil { ctx.HTML(200, TplActivate)
ctx.ServerError("UpdateUser", err)
return
}
if err := models.UpdateUserCols(user, "is_active", "rands"); err != nil {
if models.IsErrUserNotExist(err) {
ctx.Error(404)
} else {
ctx.ServerError("UpdateUser", err)
}
return
}
log.Trace("User activated: %s", user.Name)
if err := ctx.Session.Set("uid", user.ID); err != nil {
log.Error(fmt.Sprintf("Error setting uid in session: %v", err))
}
if err := ctx.Session.Set("uname", user.Name); err != nil {
log.Error(fmt.Sprintf("Error setting uname in session: %v", err))
}
if err := ctx.Session.Release(); err != nil {
log.Error("Error storing session: %v", err)
}
ctx.Flash.Success(ctx.Tr("auth.account_activated"))
ctx.Redirect(setting.AppSubURL + "/")
return return
} }
ctx.Data["IsActivateFailed"] = true // if account is local account, verify password
ctx.HTML(200, TplActivate) if user.LoginSource == 0 {
if len(password) == 0 {
ctx.Data["Code"] = code
ctx.Data["NeedsPassword"] = true
ctx.HTML(200, TplActivate)
return
}
if !user.ValidatePassword(password) {
ctx.Data["IsActivateFailed"] = true
ctx.HTML(200, TplActivate)
return
}
}
user.IsActive = true
var err error
if user.Rands, err = models.GetUserSalt(); err != nil {
ctx.ServerError("UpdateUser", err)
return
}
if err := models.UpdateUserCols(user, "is_active", "rands"); err != nil {
if models.IsErrUserNotExist(err) {
ctx.Error(404)
} else {
ctx.ServerError("UpdateUser", err)
}
return
}
log.Trace("User activated: %s", user.Name)
if err := ctx.Session.Set("uid", user.ID); err != nil {
log.Error(fmt.Sprintf("Error setting uid in session: %v", err))
}
if err := ctx.Session.Set("uname", user.Name); err != nil {
log.Error(fmt.Sprintf("Error setting uname in session: %v", err))
}
if err := ctx.Session.Release(); err != nil {
log.Error("Error storing session: %v", err)
}
ctx.Flash.Success(ctx.Tr("auth.account_activated"))
ctx.Redirect(setting.AppSubURL + "/")
} }
// ActivateEmail render the activate email page // ActivateEmail render the activate email page

View file

@ -18,7 +18,19 @@
<p>{{.i18n.Tr "auth.confirmation_mail_sent_prompt" (.SignedUser.Email|Escape) .ActiveCodeLives | Str2html}}</p> <p>{{.i18n.Tr "auth.confirmation_mail_sent_prompt" (.SignedUser.Email|Escape) .ActiveCodeLives | Str2html}}</p>
{{end}} {{end}}
{{else}} {{else}}
{{if .IsSendRegisterMail}} {{if .NeedsPassword}}
<form class="ui form" action="/user/activate" method="post">
<div class="required inline field">
<label for="password">{{.i18n.Tr "password"}}</label>
<input id="password" name="password" type="password" autocomplete="off" required>
</div>
<div class="inline field">
<label></label>
<button class="ui green button">{{.i18n.Tr "install.confirm_password"}}</button>
</div>
<input id="code" name="code" type="hidden" value="{{.Code}}">
</form>
{{else if .IsSendRegisterMail}}
<p>{{.i18n.Tr "auth.confirmation_mail_sent_prompt" (.Email|Escape) .ActiveCodeLives | Str2html}}</p> <p>{{.i18n.Tr "auth.confirmation_mail_sent_prompt" (.Email|Escape) .ActiveCodeLives | Str2html}}</p>
{{else if .IsActivateFailed}} {{else if .IsActivateFailed}}
<p>{{.i18n.Tr "auth.invalid_code"}}</p> <p>{{.i18n.Tr "auth.invalid_code"}}</p>