-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Force user to change password #4489
Changes from 7 commits
0bef325
68d57a1
23acb29
ff42bfd
26fccdf
4562460
5a2ea86
3b87fef
7e67ecc
59432fa
741ef66
9b4f70f
845c00b
3b7258e
b6b39d3
4ebdfc1
e0f8fd8
3e5ed18
1a75475
4402c56
f7e1e08
4d96ba5
95f035d
8ea7cdc
0181ebf
d083410
d3febca
dafa9c8
8c6e9c6
454cd3a
d7ee5f8
5441645
98933c6
d2ddc69
4c6658a
e2ef29b
16b5b61
a4152f2
a03c9a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright 2018 The Gitea Authors. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package migrations | ||
|
||
import ( | ||
"github.com/go-xorm/xorm" | ||
) | ||
|
||
func addMustChangePassword(x *xorm.Engine) error { | ||
type User struct { | ||
ID int64 `xorm:"pk autoincr"` | ||
MustChangePassword bool `xorm:"NOT NULL DEFAULT false"` | ||
} | ||
|
||
return x.Sync2(new(User)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ import ( | |
"errors" | ||
"fmt" | ||
"image" | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for newline here |
||
// Needed for jpeg support | ||
_ "image/jpeg" | ||
"image/png" | ||
|
@@ -83,18 +84,23 @@ type User struct { | |
Email string `xorm:"NOT NULL"` | ||
KeepEmailPrivate bool | ||
Passwd string `xorm:"NOT NULL"` | ||
LoginType LoginType | ||
LoginSource int64 `xorm:"NOT NULL DEFAULT 0"` | ||
LoginName string | ||
Type UserType | ||
OwnedOrgs []*User `xorm:"-"` | ||
Orgs []*User `xorm:"-"` | ||
Repos []*Repository `xorm:"-"` | ||
Location string | ||
Website string | ||
Rands string `xorm:"VARCHAR(10)"` | ||
Salt string `xorm:"VARCHAR(10)"` | ||
Language string `xorm:"VARCHAR(5)"` | ||
|
||
// MustChangePassword is an attribute that determines if a user | ||
// is to change his/her password after registration. | ||
MustChangePassword bool `xorm:"NOT NULL DEFAULT false"` | ||
|
||
LoginType LoginType | ||
LoginSource int64 `xorm:"NOT NULL DEFAULT 0"` | ||
LoginName string | ||
Type UserType | ||
OwnedOrgs []*User `xorm:"-"` | ||
Orgs []*User `xorm:"-"` | ||
Repos []*Repository `xorm:"-"` | ||
Location string | ||
Website string | ||
Rands string `xorm:"VARCHAR(10)"` | ||
Salt string `xorm:"VARCHAR(10)"` | ||
Language string `xorm:"VARCHAR(5)"` | ||
|
||
CreatedUnix util.TimeStamp `xorm:"INDEX created"` | ||
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,10 +31,22 @@ func Toggle(options *ToggleOptions) macaron.Handler { | |
} | ||
|
||
// Check prohibit login users. | ||
if ctx.IsSigned && ctx.User.ProhibitLogin { | ||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") | ||
ctx.HTML(200, "user/auth/prohibit_login") | ||
return | ||
if ctx.IsSigned { | ||
|
||
if ctx.User.ProhibitLogin { | ||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") | ||
ctx.HTML(200, "user/auth/prohibit_login") | ||
return | ||
} | ||
|
||
if ctx.Req.URL.Path == "/user/change_password" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will not work if appsuburl is used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @adelowo if gitea is hosted as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lafriks Would it just be safe to use Or what is the potential fix here ? other than giving the url path it's own middleware definition so we can safely handle the scenario without the infinite redirection There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just |
||
return | ||
} else if ctx.User.MustChangePassword { | ||
ctx.Data["Title"] = ctx.Tr("auth.must_change_password") | ||
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password" | ||
ctx.Redirect(setting.AppSubURL + "/user/change_password") | ||
return | ||
} | ||
} | ||
|
||
// Redirect to dashboard if user tries to visit any non-login page. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ import ( | |
) | ||
|
||
const ( | ||
tplMustChangePassword = "user/auth/change_passwd" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: comment would be recommended here like it is for other constants below |
||
// tplSignIn template for sign in page | ||
tplSignIn base.TplName = "user/auth/signin" | ||
// tplSignUp template path for sign up page | ||
|
@@ -1035,7 +1036,7 @@ func Activate(ctx *context.Context) { | |
|
||
ctx.Session.Set("uid", user.ID) | ||
ctx.Session.Set("uname", user.Name) | ||
ctx.Redirect(setting.AppSubURL + "/") | ||
ctx.Redirect(setting.AppSubURL + "/user/login") | ||
return | ||
} | ||
|
||
|
@@ -1185,3 +1186,69 @@ func ResetPasswdPost(ctx *context.Context) { | |
ctx.Data["IsResetFailed"] = true | ||
ctx.HTML(200, tplResetPassword) | ||
} | ||
|
||
// MustChangePassword renders the page to change a user's password | ||
func MustChangePassword(ctx *context.Context) { | ||
ctx.Data["Title"] = ctx.Tr("auth.must_change_password") | ||
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password" | ||
|
||
ctx.HTML(200, tplMustChangePassword) | ||
} | ||
|
||
// MustChangePasswordPost response for updating a user's password after his/her | ||
// account was created by an admin | ||
func MustChangePasswordPost(ctx *context.Context, cpt *captcha.Captcha, form auth.MustChangePasswordForm) { | ||
ctx.Data["Title"] = ctx.Tr("auth.must_change_password") | ||
|
||
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password" | ||
|
||
if ctx.HasError() { | ||
ctx.HTML(200, tplMustChangePassword) | ||
return | ||
} | ||
|
||
u := ctx.User | ||
|
||
// Make sure only requests for users who are eligible to change their password via | ||
// this method passes through | ||
if !u.MustChangePassword { | ||
ctx.ServerError("MustUpdatePassword", errors.New("cannot update password.. Please visit the settings page")) | ||
return | ||
} | ||
|
||
if form.Password != form.Retype { | ||
ctx.Data["Err_Password"] = true | ||
ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplMustChangePassword, &form) | ||
return | ||
} | ||
|
||
if len(form.Password) < setting.MinPasswordLength { | ||
ctx.Data["Err_Password"] = true | ||
ctx.RenderWithErr(ctx.Tr("auth.password_too_short", setting.MinPasswordLength), tplMustChangePassword, &form) | ||
return | ||
} | ||
|
||
var err error | ||
if u.Rands, err = models.GetUserSalt(); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this should be updated when changing password, only if resetting password. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would fix There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
By the way, the above review has been implemented |
||
ctx.ServerError("UpdateUser", err) | ||
return | ||
} | ||
|
||
if u.Salt, err = models.GetUserSalt(); err != nil { | ||
ctx.ServerError("UpdateUser", err) | ||
return | ||
} | ||
|
||
u.HashPassword(form.Password) | ||
u.MustChangePassword = false | ||
|
||
if err := models.UpdateUserCols(u, "must_change_password", "passwd", "rands", "salt"); err != nil { | ||
ctx.ServerError("UpdateUser", err) | ||
return | ||
} | ||
|
||
ctx.Flash.Success(ctx.Tr("settings.change_password_success")) | ||
|
||
log.Trace("User updated password: %s", u.Name) | ||
ctx.Redirect(setting.AppSubURL + "/") | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{{template "base/head" .}} | ||
<div class="user signin{{if .LinkAccountMode}} icon{{end}}"> | ||
<div class="ui container"> | ||
{{template "user/auth/change_passwd_inner" .}} | ||
</div> | ||
</div> | ||
{{template "base/footer" .}} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{{if or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn)}} | ||
{{template "base/alert" .}} | ||
{{end}} | ||
<h4 class="ui top attached header center"> | ||
{{.i18n.Tr "settings.change_password"}} | ||
</h4> | ||
<div class="ui attached segment"> | ||
<form class="ui form" action="{{.ChangePasscodeLink}}" method="post"> | ||
{{.CsrfTokenHtml}} | ||
<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}"> | ||
<label for="password">{{.i18n.Tr "password"}}</label> | ||
<input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required> | ||
</div> | ||
|
||
|
||
<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}"> | ||
<label for="retype">{{.i18n.Tr "re_type"}}</label> | ||
<input id="retype" name="retype" type="password" autocomplete="off" required> | ||
</div> | ||
|
||
<div class="inline field"> | ||
<label></label> | ||
<button class="ui green button">{{.i18n.Tr "settings.change_password" }}</button> | ||
</div> | ||
</form> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same new line as v70 should also go between these two imports.