Skip to content

Commit 9e865ce

Browse files
lunnybkcsoft
authored andcommitted
Merge password and 2fa page on user settings (#2695)
* merge password and 2fa page on user settings
1 parent c1b0c9e commit 9e865ce

File tree

7 files changed

+117
-89
lines changed

7 files changed

+117
-89
lines changed

integrations/links_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ func testLinksAsUser(userName string, t *testing.T) {
7171
"/user2?tab=activity",
7272
"/user/settings",
7373
"/user/settings/avatar",
74-
"/user/settings/password",
74+
"/user/settings/security",
75+
"/user/settings/security/two_factor/enroll",
7576
"/user/settings/email",
7677
"/user/settings/keys",
7778
"/user/settings/applications",
78-
"/user/settings/two_factor",
7979
"/user/settings/account_link",
8080
"/user/settings/organization",
8181
"/user/settings/delete",

options/locale/locale_en-US.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ form.name_pattern_not_allowed = The username pattern '%s' is not allowed.
303303
[settings]
304304
profile = Profile
305305
password = Password
306+
security = Security
306307
avatar = Avatar
307308
ssh_gpg_keys = SSH / GPG Keys
308309
social = Social Accounts

routers/routes/routes.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ func RegisterRoutes(m *macaron.Macaron) {
220220
m.Combo("/email").Get(user.SettingsEmails).
221221
Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
222222
m.Post("/email/delete", user.DeleteEmail)
223-
m.Get("/password", user.SettingsPassword)
224-
m.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost)
223+
m.Get("/security", user.SettingsSecurity)
224+
m.Post("/security", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsSecurityPost)
225225
m.Group("/openid", func() {
226226
m.Combo("").Get(user.SettingsOpenID).
227227
Post(bindIgnErr(auth.AddOpenIDForm{}), user.SettingsOpenIDPost)
@@ -238,8 +238,7 @@ func RegisterRoutes(m *macaron.Macaron) {
238238
m.Combo("/account_link").Get(user.SettingsAccountLinks).Post(user.SettingsDeleteAccountLink)
239239
m.Get("/organization", user.SettingsOrganization)
240240
m.Get("/repos", user.SettingsRepos)
241-
m.Group("/two_factor", func() {
242-
m.Get("", user.SettingsTwoFactor)
241+
m.Group("/security/two_factor", func() {
243242
m.Post("/regenerate_scratch", user.SettingsTwoFactorRegenerateScratch)
244243
m.Post("/disable", user.SettingsTwoFactorDisable)
245244
m.Get("/enroll", user.SettingsTwoFactorEnroll)

routers/user/setting.go

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const (
4141
tplSettingsOrganization base.TplName = "user/settings/organization"
4242
tplSettingsRepositories base.TplName = "user/settings/repos"
4343
tplSettingsDelete base.TplName = "user/settings/delete"
44-
tplSecurity base.TplName = "user/security"
44+
tplSettingsSecurity base.TplName = "user/settings/security"
4545
)
4646

4747
// Settings render user's profile page
@@ -191,22 +191,35 @@ func SettingsDeleteAvatar(ctx *context.Context) {
191191
ctx.Redirect(setting.AppSubURL + "/user/settings/avatar")
192192
}
193193

194-
// SettingsPassword render change user's password page
195-
func SettingsPassword(ctx *context.Context) {
194+
// SettingsSecurity render change user's password page and 2FA
195+
func SettingsSecurity(ctx *context.Context) {
196196
ctx.Data["Title"] = ctx.Tr("settings")
197-
ctx.Data["PageIsSettingsPassword"] = true
197+
ctx.Data["PageIsSettingsSecurity"] = true
198198
ctx.Data["Email"] = ctx.User.Email
199-
ctx.HTML(200, tplSettingsPassword)
199+
200+
enrolled := true
201+
_, err := models.GetTwoFactorByUID(ctx.User.ID)
202+
if err != nil {
203+
if models.IsErrTwoFactorNotEnrolled(err) {
204+
enrolled = false
205+
} else {
206+
ctx.Handle(500, "SettingsTwoFactor", err)
207+
return
208+
}
209+
}
210+
211+
ctx.Data["TwofaEnrolled"] = enrolled
212+
ctx.HTML(200, tplSettingsSecurity)
200213
}
201214

202-
// SettingsPasswordPost response for change user's password
203-
func SettingsPasswordPost(ctx *context.Context, form auth.ChangePasswordForm) {
215+
// SettingsSecurityPost response for change user's password
216+
func SettingsSecurityPost(ctx *context.Context, form auth.ChangePasswordForm) {
204217
ctx.Data["Title"] = ctx.Tr("settings")
205-
ctx.Data["PageIsSettingsPassword"] = true
218+
ctx.Data["PageIsSettingsSecurity"] = true
206219
ctx.Data["PageIsSettingsDelete"] = true
207220

208221
if ctx.HasError() {
209-
ctx.HTML(200, tplSettingsPassword)
222+
ctx.HTML(200, tplSettingsSecurity)
210223
return
211224
}
212225

@@ -230,7 +243,7 @@ func SettingsPasswordPost(ctx *context.Context, form auth.ChangePasswordForm) {
230243
ctx.Flash.Success(ctx.Tr("settings.change_password_success"))
231244
}
232245

233-
ctx.Redirect(setting.AppSubURL + "/user/settings/password")
246+
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
234247
}
235248

236249
// SettingsEmails render user's emails page
@@ -509,30 +522,10 @@ func SettingsDeleteApplication(ctx *context.Context) {
509522
})
510523
}
511524

512-
// SettingsTwoFactor renders the 2FA page.
513-
func SettingsTwoFactor(ctx *context.Context) {
514-
ctx.Data["Title"] = ctx.Tr("settings")
515-
ctx.Data["PageIsSettingsTwofa"] = true
516-
517-
enrolled := true
518-
_, err := models.GetTwoFactorByUID(ctx.User.ID)
519-
if err != nil {
520-
if models.IsErrTwoFactorNotEnrolled(err) {
521-
enrolled = false
522-
} else {
523-
ctx.Handle(500, "SettingsTwoFactor", err)
524-
return
525-
}
526-
}
527-
528-
ctx.Data["TwofaEnrolled"] = enrolled
529-
ctx.HTML(200, tplSettingsTwofa)
530-
}
531-
532525
// SettingsTwoFactorRegenerateScratch regenerates the user's 2FA scratch code.
533526
func SettingsTwoFactorRegenerateScratch(ctx *context.Context) {
534527
ctx.Data["Title"] = ctx.Tr("settings")
535-
ctx.Data["PageIsSettingsTwofa"] = true
528+
ctx.Data["PageIsSettingsSecurity"] = true
536529

537530
t, err := models.GetTwoFactorByUID(ctx.User.ID)
538531
if err != nil {
@@ -551,13 +544,13 @@ func SettingsTwoFactorRegenerateScratch(ctx *context.Context) {
551544
}
552545

553546
ctx.Flash.Success(ctx.Tr("settings.twofa_scratch_token_regenerated", t.ScratchToken))
554-
ctx.Redirect(setting.AppSubURL + "/user/settings/two_factor")
547+
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
555548
}
556549

557550
// SettingsTwoFactorDisable deletes the user's 2FA settings.
558551
func SettingsTwoFactorDisable(ctx *context.Context) {
559552
ctx.Data["Title"] = ctx.Tr("settings")
560-
ctx.Data["PageIsSettingsTwofa"] = true
553+
ctx.Data["PageIsSettingsSecurity"] = true
561554

562555
t, err := models.GetTwoFactorByUID(ctx.User.ID)
563556
if err != nil {
@@ -571,7 +564,7 @@ func SettingsTwoFactorDisable(ctx *context.Context) {
571564
}
572565

573566
ctx.Flash.Success(ctx.Tr("settings.twofa_disabled"))
574-
ctx.Redirect(setting.AppSubURL + "/user/settings/two_factor")
567+
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
575568
}
576569

577570
func twofaGenerateSecretAndQr(ctx *context.Context) bool {
@@ -615,7 +608,7 @@ func twofaGenerateSecretAndQr(ctx *context.Context) bool {
615608
// SettingsTwoFactorEnroll shows the page where the user can enroll into 2FA.
616609
func SettingsTwoFactorEnroll(ctx *context.Context) {
617610
ctx.Data["Title"] = ctx.Tr("settings")
618-
ctx.Data["PageIsSettingsTwofa"] = true
611+
ctx.Data["PageIsSettingsSecurity"] = true
619612

620613
t, err := models.GetTwoFactorByUID(ctx.User.ID)
621614
if t != nil {
@@ -638,7 +631,7 @@ func SettingsTwoFactorEnroll(ctx *context.Context) {
638631
// SettingsTwoFactorEnrollPost handles enrolling the user into 2FA.
639632
func SettingsTwoFactorEnrollPost(ctx *context.Context, form auth.TwoFactorAuthForm) {
640633
ctx.Data["Title"] = ctx.Tr("settings")
641-
ctx.Data["PageIsSettingsTwofa"] = true
634+
ctx.Data["PageIsSettingsSecurity"] = true
642635

643636
t, err := models.GetTwoFactorByUID(ctx.User.ID)
644637
if t != nil {
@@ -691,7 +684,7 @@ func SettingsTwoFactorEnrollPost(ctx *context.Context, form auth.TwoFactorAuthFo
691684
ctx.Session.Delete("twofaSecret")
692685
ctx.Session.Delete("twofaUri")
693686
ctx.Flash.Success(ctx.Tr("settings.twofa_enrolled", t.ScratchToken))
694-
ctx.Redirect(setting.AppSubURL + "/user/settings/two_factor")
687+
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
695688
}
696689

697690
// SettingsAccountLinks render the account links settings page

templates/user/settings/navbar.tmpl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<a class="{{if .PageIsSettingsAvatar}}active{{end}} item" href="{{AppSubUrl}}/user/settings/avatar">
66
{{.i18n.Tr "settings.avatar"}}
77
</a>
8-
<a class="{{if .PageIsSettingsPassword}}active{{end}} item" href="{{AppSubUrl}}/user/settings/password">
9-
{{.i18n.Tr "settings.password"}}
8+
<a class="{{if .PageIsSettingsSecurity}}active{{end}} item" href="{{AppSubUrl}}/user/settings/security">
9+
{{.i18n.Tr "settings.security"}}
1010
</a>
1111
<a class="{{if .PageIsSettingsEmails}}active{{end}} item" href="{{AppSubUrl}}/user/settings/email">
1212
{{.i18n.Tr "settings.emails"}}
@@ -22,9 +22,6 @@
2222
<a class="{{if .PageIsSettingsApplications}}active{{end}} item" href="{{AppSubUrl}}/user/settings/applications">
2323
{{.i18n.Tr "settings.applications"}}
2424
</a>
25-
<a class="{{if .PageIsSettingsTwofa}}active{{end}} item" href="{{AppSubUrl}}/user/settings/two_factor">
26-
{{.i18n.Tr "settings.twofa"}}
27-
</a>
2825
<a class="{{if .PageIsSettingsAccountLink}}active{{end}} item" href="{{AppSubUrl}}/user/settings/account_link">
2926
{{.i18n.Tr "settings.account_link"}}
3027
</a>

templates/user/settings/password.tmpl

Lines changed: 0 additions & 41 deletions
This file was deleted.

templates/user/settings/security.tmpl

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{{template "base/head" .}}
2+
<div class="user settings password">
3+
{{template "user/settings/navbar" .}}
4+
<div class="ui container">
5+
{{template "base/alert" .}}
6+
<h4 class="ui top attached header">
7+
{{.i18n.Tr "settings.password"}}
8+
</h4>
9+
<div class="ui attached segment">
10+
{{if or (.SignedUser.IsLocal) (.SignedUser.IsOAuth2)}}
11+
<form class="ui form" action="{{.Link}}?tp=password" method="post">
12+
{{.CsrfTokenHtml}}
13+
{{if .SignedUser.IsPasswordSet}}
14+
<div class="required field {{if .Err_OldPassword}}error{{end}}">
15+
<label for="old_password">{{.i18n.Tr "settings.old_password"}}</label>
16+
<input id="old_password" name="old_password" type="password" autocomplete="off" autofocus required>
17+
</div>
18+
{{end}}
19+
<div class="required field {{if .Err_Password}}error{{end}}">
20+
<label for="password">{{.i18n.Tr "settings.new_password"}}</label>
21+
<input id="password" name="password" type="password" autocomplete="off" required>
22+
</div>
23+
<div class="required field {{if .Err_Password}}error{{end}}">
24+
<label for="retype">{{.i18n.Tr "settings.retype_new_password"}}</label>
25+
<input id="retype" name="retype" type="password" autocomplete="off" required>
26+
</div>
27+
28+
<div class="field">
29+
<button class="ui green button">{{$.i18n.Tr "settings.change_password"}}</button>
30+
<a href="{{AppSubUrl}}/user/forgot_password?email={{.Email}}">{{.i18n.Tr "auth.forgot_password"}}</a>
31+
</div>
32+
</form>
33+
{{else}}
34+
<div class="ui info message">
35+
<p class="text left">{{$.i18n.Tr "settings.password_change_disabled"}}</p>
36+
</div>
37+
{{end}}
38+
</div>
39+
<br/>
40+
41+
<h4 class="ui top attached header">
42+
{{.i18n.Tr "settings.twofa"}}
43+
</h4>
44+
<div class="ui attached segment">
45+
<p>{{.i18n.Tr "settings.twofa_desc"}}</p>
46+
{{if .TwofaEnrolled}}
47+
<p>{{$.i18n.Tr "settings.twofa_is_enrolled" | Str2html }}</p>
48+
<form class="ui form" action="{{.Link}}/two_factor/regenerate_scratch" method="post" enctype="multipart/form-data">
49+
{{.CsrfTokenHtml}}
50+
<p>{{.i18n.Tr "settings.regenerate_scratch_token_desc"}}</p>
51+
<button class="ui blue button">{{$.i18n.Tr "settings.twofa_scratch_token_regenerate"}}</button>
52+
</form>
53+
<form class="ui form" action="{{.Link}}/two_factor/disable" method="post" enctype="multipart/form-data" id="disable-form">
54+
{{.CsrfTokenHtml}}
55+
<p>{{.i18n.Tr "settings.twofa_disable_note"}}</p>
56+
<div class="ui red button delete-button" data-type="form" data-form="#disable-form">{{$.i18n.Tr "settings.twofa_disable"}}</div>
57+
</form>
58+
{{else}}
59+
<p>{{.i18n.Tr "settings.twofa_not_enrolled"}}</p>
60+
<div class="inline field">
61+
<a class="ui green button" href="{{.Link}}/two_factor/enroll">{{$.i18n.Tr "settings.twofa_enroll"}}</a>
62+
</div>
63+
{{end}}
64+
</div>
65+
</div>
66+
</div>
67+
68+
<div class="ui small basic delete modal">
69+
<div class="ui icon header">
70+
<i class="trash icon"></i>
71+
{{.i18n.Tr "settings.twofa_disable"}}
72+
</div>
73+
<div class="content">
74+
<p>{{.i18n.Tr "settings.twofa_disable_desc"}}</p>
75+
</div>
76+
{{template "base/delete_modal_actions" .}}
77+
</div>
78+
79+
{{template "base/footer" .}}

0 commit comments

Comments
 (0)