From 73925841a3e87410fb52a044682e6bfa33c59dca Mon Sep 17 00:00:00 2001 From: David Schneiderbauer Date: Fri, 4 May 2018 18:21:07 +0200 Subject: [PATCH 01/10] moved avatar to profile page --- integrations/links_test.go | 1 - routers/routes/routes.go | 3 +- routers/user/setting.go | 12 ++------ templates/user/settings/avatar.tmpl | 46 ---------------------------- templates/user/settings/navbar.tmpl | 3 -- templates/user/settings/profile.tmpl | 37 ++++++++++++++++++++++ 6 files changed, 40 insertions(+), 62 deletions(-) delete mode 100644 templates/user/settings/avatar.tmpl diff --git a/integrations/links_test.go b/integrations/links_test.go index b0abbd708994..2dc1e5ffe71e 100644 --- a/integrations/links_test.go +++ b/integrations/links_test.go @@ -93,7 +93,6 @@ func testLinksAsUser(userName string, t *testing.T) { "/user2?tab=stars", "/user2?tab=activity", "/user/settings", - "/user/settings/avatar", "/user/settings/security", "/user/settings/security/two_factor/enroll", "/user/settings/email", diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 9618d252689c..2949bbde8861 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -217,8 +217,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/user/settings", func() { m.Get("", user.Settings) m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost) - m.Combo("/avatar").Get(user.SettingsAvatar). - Post(binding.MultipartForm(auth.AvatarForm{}), user.SettingsAvatarPost) + m.Post("/avatar", binding.MultipartForm(auth.AvatarForm{}), user.SettingsAvatarPost) m.Post("/avatar/delete", user.SettingsDeleteAvatar) m.Combo("/email").Get(user.SettingsEmails). Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost) diff --git a/routers/user/setting.go b/routers/user/setting.go index f4326bf0f57c..026f15b2658a 100644 --- a/routers/user/setting.go +++ b/routers/user/setting.go @@ -30,7 +30,6 @@ import ( const ( tplSettingsProfile base.TplName = "user/settings/profile" - tplSettingsAvatar base.TplName = "user/settings/avatar" tplSettingsEmails base.TplName = "user/settings/email" tplSettingsKeys base.TplName = "user/settings/keys" tplSettingsSocial base.TplName = "user/settings/social" @@ -168,13 +167,6 @@ func UpdateAvatarSetting(ctx *context.Context, form auth.AvatarForm, ctxUser *mo return nil } -// SettingsAvatar render user avatar page -func SettingsAvatar(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsAvatar"] = true - ctx.HTML(200, tplSettingsAvatar) -} - // SettingsAvatarPost response for change user's avatar request func SettingsAvatarPost(ctx *context.Context, form auth.AvatarForm) { if err := UpdateAvatarSetting(ctx, form, ctx.User); err != nil { @@ -183,7 +175,7 @@ func SettingsAvatarPost(ctx *context.Context, form auth.AvatarForm) { ctx.Flash.Success(ctx.Tr("settings.update_avatar_success")) } - ctx.Redirect(setting.AppSubURL + "/user/settings/avatar") + ctx.Redirect(setting.AppSubURL + "/user/settings") } // SettingsDeleteAvatar render delete avatar page @@ -192,7 +184,7 @@ func SettingsDeleteAvatar(ctx *context.Context) { ctx.Flash.Error(err.Error()) } - ctx.Redirect(setting.AppSubURL + "/user/settings/avatar") + ctx.Redirect(setting.AppSubURL + "/user/settings") } // SettingsSecurity render change user's password page and 2FA diff --git a/templates/user/settings/avatar.tmpl b/templates/user/settings/avatar.tmpl deleted file mode 100644 index 72d2eb6ad496..000000000000 --- a/templates/user/settings/avatar.tmpl +++ /dev/null @@ -1,46 +0,0 @@ -{{template "base/head" .}} -
- {{template "user/settings/navbar" .}} -
- {{template "base/alert" .}} -

- {{.i18n.Tr "settings.avatar"}} -

-
- -
- {{.CsrfTokenHtml}} - {{if not DisableGravatar}} -
-
- - -
-
-
- - -
- {{end}} - -
-
- - -
-
- -
- - -
- -
- - {{$.i18n.Tr "settings.delete_current_avatar"}} -
-
-
-
-
-{{template "base/footer" .}} diff --git a/templates/user/settings/navbar.tmpl b/templates/user/settings/navbar.tmpl index 4e0c7048ee5e..237199d939b8 100644 --- a/templates/user/settings/navbar.tmpl +++ b/templates/user/settings/navbar.tmpl @@ -2,9 +2,6 @@ {{.i18n.Tr "settings.profile"}} - - {{.i18n.Tr "settings.avatar"}} - {{.i18n.Tr "settings.security"}} diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 4e6930e0f596..e5bb2df0111a 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -58,7 +58,44 @@ + + +

+ {{.i18n.Tr "settings.avatar"}} +

+
+
+ {{.CsrfTokenHtml}} + {{if not DisableGravatar}} +
+
+ + +
+
+
+ + +
+ {{end}} +
+
+ + +
+
+ +
+ + +
+ +
+ + {{$.i18n.Tr "settings.delete_current_avatar"}} +
+
From 47faa79e9bea9b59981ed4017a586f759a3c96ee Mon Sep 17 00:00:00 2001 From: David Schneiderbauer Date: Fri, 4 May 2018 19:19:36 +0200 Subject: [PATCH 02/10] combined password change, email and account deletion into account settings page --- integrations/delete_user_test.go | 8 +- integrations/links_test.go | 3 +- options/locale/locale_en-US.ini | 1 + routers/routes/routes.go | 11 +- routers/user/setting.go | 150 ++++++++++++-------------- routers/user/setting_test.go | 2 +- templates/user/settings/account.tmpl | 135 +++++++++++++++++++++++ templates/user/settings/delete.tmpl | 41 ------- templates/user/settings/email.tmpl | 66 ------------ templates/user/settings/navbar.tmpl | 9 +- templates/user/settings/security.tmpl | 35 ------ 11 files changed, 222 insertions(+), 239 deletions(-) create mode 100644 templates/user/settings/account.tmpl delete mode 100644 templates/user/settings/delete.tmpl delete mode 100644 templates/user/settings/email.tmpl diff --git a/integrations/delete_user_test.go b/integrations/delete_user_test.go index a6e44c15c09b..2a5ca89860f2 100644 --- a/integrations/delete_user_test.go +++ b/integrations/delete_user_test.go @@ -43,8 +43,8 @@ func TestUserDeleteAccount(t *testing.T) { prepareTestEnv(t) session := loginUser(t, "user8") - csrf := GetCSRF(t, session, "/user/settings/delete") - urlStr := fmt.Sprintf("/user/settings/delete?password=%s", userPassword) + csrf := GetCSRF(t, session, "/user/settings/account") + urlStr := fmt.Sprintf("/user/settings/account/delete?password=%s", userPassword) req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ "_csrf": csrf, }) @@ -58,8 +58,8 @@ func TestUserDeleteAccountStillOwnRepos(t *testing.T) { prepareTestEnv(t) session := loginUser(t, "user2") - csrf := GetCSRF(t, session, "/user/settings/delete") - urlStr := fmt.Sprintf("/user/settings/delete?password=%s", userPassword) + csrf := GetCSRF(t, session, "/user/settings/account") + urlStr := fmt.Sprintf("/user/settings/account/delete?password=%s", userPassword) req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ "_csrf": csrf, }) diff --git a/integrations/links_test.go b/integrations/links_test.go index 2dc1e5ffe71e..587e0406bcd1 100644 --- a/integrations/links_test.go +++ b/integrations/links_test.go @@ -93,14 +93,13 @@ func testLinksAsUser(userName string, t *testing.T) { "/user2?tab=stars", "/user2?tab=activity", "/user/settings", + "/user/settings/account", "/user/settings/security", "/user/settings/security/two_factor/enroll", - "/user/settings/email", "/user/settings/keys", "/user/settings/applications", "/user/settings/account_link", "/user/settings/organization", - "/user/settings/delete", } session := loginUser(t, userName) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 2c8e9cd0ba1c..16d316ee7f37 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -305,6 +305,7 @@ form.name_pattern_not_allowed = The pattern '%s' is not allowed in a username. [settings] profile = Profile +account = Account password = Password security = Security avatar = Avatar diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 2949bbde8861..bb0e7d3043a7 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -219,11 +219,13 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost) m.Post("/avatar", binding.MultipartForm(auth.AvatarForm{}), user.SettingsAvatarPost) m.Post("/avatar/delete", user.SettingsDeleteAvatar) - m.Combo("/email").Get(user.SettingsEmails). - Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost) - m.Post("/email/delete", user.DeleteEmail) + m.Group("/account", func() { + m.Combo("").Get(user.SettingsAccount).Post(bindIgnErr(auth.ChangePasswordForm{}), user.SettingsAccountPost) + m.Post("/email", bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost) + m.Post("/email/delete", user.DeleteEmail) + m.Post("/delete", user.SettingsDelete) + }) m.Get("/security", user.SettingsSecurity) - m.Post("/security", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsSecurityPost) m.Group("/openid", func() { m.Combo("").Get(user.SettingsOpenID). Post(bindIgnErr(auth.AddOpenIDForm{}), user.SettingsOpenIDPost) @@ -236,7 +238,6 @@ func RegisterRoutes(m *macaron.Macaron) { m.Combo("/applications").Get(user.SettingsApplications). Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost) m.Post("/applications/delete", user.SettingsDeleteApplication) - m.Route("/delete", "GET,POST", user.SettingsDelete) m.Combo("/account_link").Get(user.SettingsAccountLinks).Post(user.SettingsDeleteAccountLink) m.Get("/organization", user.SettingsOrganization) m.Get("/repos", user.SettingsRepos) diff --git a/routers/user/setting.go b/routers/user/setting.go index 026f15b2658a..42f0409c1d09 100644 --- a/routers/user/setting.go +++ b/routers/user/setting.go @@ -30,7 +30,7 @@ import ( const ( tplSettingsProfile base.TplName = "user/settings/profile" - tplSettingsEmails base.TplName = "user/settings/email" + tplSettingsAccount base.TplName = "user/settings/account" tplSettingsKeys base.TplName = "user/settings/keys" tplSettingsSocial base.TplName = "user/settings/social" tplSettingsApplications base.TplName = "user/settings/applications" @@ -39,7 +39,6 @@ const ( tplSettingsAccountLink base.TplName = "user/settings/account_link" tplSettingsOrganization base.TplName = "user/settings/organization" tplSettingsRepositories base.TplName = "user/settings/repos" - tplSettingsDelete base.TplName = "user/settings/delete" tplSettingsSecurity base.TplName = "user/settings/security" ) @@ -187,35 +186,29 @@ func SettingsDeleteAvatar(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/user/settings") } -// SettingsSecurity render change user's password page and 2FA -func SettingsSecurity(ctx *context.Context) { +// SettingsAccount renders change user's password, user's email and user suicide page +func SettingsAccount(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsSecurity"] = true + ctx.Data["PageIsSettingsAccount"] = true ctx.Data["Email"] = ctx.User.Email - enrolled := true - _, err := models.GetTwoFactorByUID(ctx.User.ID) + emails, err := models.GetEmailAddresses(ctx.User.ID) if err != nil { - if models.IsErrTwoFactorNotEnrolled(err) { - enrolled = false - } else { - ctx.ServerError("SettingsTwoFactor", err) - return - } + ctx.ServerError("GetEmailAddresses", err) + return } + ctx.Data["Emails"] = emails - ctx.Data["TwofaEnrolled"] = enrolled - ctx.HTML(200, tplSettingsSecurity) + ctx.HTML(200, tplSettingsAccount) } -// SettingsSecurityPost response for change user's password -func SettingsSecurityPost(ctx *context.Context, form auth.ChangePasswordForm) { +// SettingsAccountPost response for change user's password +func SettingsAccountPost(ctx *context.Context, form auth.ChangePasswordForm) { ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsSecurity"] = true - ctx.Data["PageIsSettingsDelete"] = true + ctx.Data["PageIsSettingsAccount"] = true if ctx.HasError() { - ctx.HTML(200, tplSettingsSecurity) + ctx.HTML(200, tplSettingsAccount) return } @@ -240,28 +233,13 @@ func SettingsSecurityPost(ctx *context.Context, form auth.ChangePasswordForm) { ctx.Flash.Success(ctx.Tr("settings.change_password_success")) } - ctx.Redirect(setting.AppSubURL + "/user/settings/security") -} - -// SettingsEmails render user's emails page -func SettingsEmails(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsEmails"] = true - - emails, err := models.GetEmailAddresses(ctx.User.ID) - if err != nil { - ctx.ServerError("GetEmailAddresses", err) - return - } - ctx.Data["Emails"] = emails - - ctx.HTML(200, tplSettingsEmails) + ctx.Redirect(setting.AppSubURL + "/user/settings/account") } // SettingsEmailPost response for change user's email func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) { ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsEmails"] = true + ctx.Data["PageIsSettingsAccount"] = true // Make emailaddress primary. if ctx.Query("_method") == "PRIMARY" { @@ -271,7 +249,7 @@ func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) { } log.Trace("Email made primary: %s", ctx.User.Name) - ctx.Redirect(setting.AppSubURL + "/user/settings/email") + ctx.Redirect(setting.AppSubURL + "/user/settings/account") return } @@ -284,7 +262,7 @@ func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) { ctx.Data["Emails"] = emails if ctx.HasError() { - ctx.HTML(200, tplSettingsEmails) + ctx.HTML(200, tplSettingsAccount) return } @@ -295,7 +273,7 @@ func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) { } if err := models.AddEmailAddress(email); err != nil { if models.IsErrEmailAlreadyUsed(err) { - ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSettingsEmails, &form) + ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSettingsAccount, &form) return } ctx.ServerError("AddEmailAddress", err) @@ -315,7 +293,7 @@ func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) { } log.Trace("Email address added: %s", email.Email) - ctx.Redirect(setting.AppSubURL + "/user/settings/email") + ctx.Redirect(setting.AppSubURL + "/user/settings/account") } // DeleteEmail response for delete user's email @@ -328,10 +306,61 @@ func DeleteEmail(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("settings.email_deletion_success")) ctx.JSON(200, map[string]interface{}{ - "redirect": setting.AppSubURL + "/user/settings/email", + "redirect": setting.AppSubURL + "/user/settings/account", }) } +// SettingsDelete render user suicide page and response for delete user himself +func SettingsDelete(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsSettingsAccount"] = true + + if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil { + if models.IsErrUserNotExist(err) { + ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), tplSettingsAccount, nil) + } else { + ctx.ServerError("UserSignIn", err) + } + return + } + + if err := models.DeleteUser(ctx.User); err != nil { + switch { + case models.IsErrUserOwnRepos(err): + ctx.Flash.Error(ctx.Tr("form.still_own_repo")) + ctx.Redirect(setting.AppSubURL + "/user/settings/account") + case models.IsErrUserHasOrgs(err): + ctx.Flash.Error(ctx.Tr("form.still_has_org")) + ctx.Redirect(setting.AppSubURL + "/user/settings/account") + default: + ctx.ServerError("DeleteUser", err) + } + } else { + log.Trace("Account deleted: %s", ctx.User.Name) + ctx.Redirect(setting.AppSubURL + "/") + } +} + +// SettingsSecurity render change user's password page and 2FA +func SettingsSecurity(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsSettingsSecurity"] = true + + enrolled := true + _, err := models.GetTwoFactorByUID(ctx.User.ID) + if err != nil { + if models.IsErrTwoFactorNotEnrolled(err) { + enrolled = false + } else { + ctx.ServerError("SettingsTwoFactor", err) + return + } + } + + ctx.Data["TwofaEnrolled"] = enrolled + ctx.HTML(200, tplSettingsSecurity) +} + // SettingsKeys render user's SSH/GPG public keys page func SettingsKeys(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") @@ -730,43 +759,6 @@ func SettingsDeleteAccountLink(ctx *context.Context) { }) } -// SettingsDelete render user suicide page and response for delete user himself -func SettingsDelete(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsDelete"] = true - ctx.Data["Email"] = ctx.User.Email - - if ctx.Req.Method == "POST" { - if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil { - if models.IsErrUserNotExist(err) { - ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), tplSettingsDelete, nil) - } else { - ctx.ServerError("UserSignIn", err) - } - return - } - - if err := models.DeleteUser(ctx.User); err != nil { - switch { - case models.IsErrUserOwnRepos(err): - ctx.Flash.Error(ctx.Tr("form.still_own_repo")) - ctx.Redirect(setting.AppSubURL + "/user/settings/delete") - case models.IsErrUserHasOrgs(err): - ctx.Flash.Error(ctx.Tr("form.still_has_org")) - ctx.Redirect(setting.AppSubURL + "/user/settings/delete") - default: - ctx.ServerError("DeleteUser", err) - } - } else { - log.Trace("Account deleted: %s", ctx.User.Name) - ctx.Redirect(setting.AppSubURL + "/") - } - return - } - - ctx.HTML(200, tplSettingsDelete) -} - // SettingsOrganization render all the organization of the user func SettingsOrganization(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") diff --git a/routers/user/setting_test.go b/routers/user/setting_test.go index 72b1b831438d..6aa9a074395f 100644 --- a/routers/user/setting_test.go +++ b/routers/user/setting_test.go @@ -56,7 +56,7 @@ func TestChangePassword(t *testing.T) { test.LoadUser(t, ctx, 2) test.LoadRepo(t, ctx, 1) - SettingsSecurityPost(ctx, auth.ChangePasswordForm{ + SettingsAccountPost(ctx, auth.ChangePasswordForm{ OldPassword: req.OldPassword, Password: req.NewPassword, Retype: req.Retype, diff --git a/templates/user/settings/account.tmpl b/templates/user/settings/account.tmpl new file mode 100644 index 000000000000..16abf878e8da --- /dev/null +++ b/templates/user/settings/account.tmpl @@ -0,0 +1,135 @@ +{{template "base/head" .}} + + + + + + +{{template "base/footer" .}} diff --git a/templates/user/settings/delete.tmpl b/templates/user/settings/delete.tmpl deleted file mode 100644 index 76ac7233bd55..000000000000 --- a/templates/user/settings/delete.tmpl +++ /dev/null @@ -1,41 +0,0 @@ -{{template "base/head" .}} -
- {{template "user/settings/navbar" .}} -
- {{template "base/alert" .}} -

- {{.i18n.Tr "settings.delete_account"}} -

-
-
-

{{.i18n.Tr "settings.delete_prompt" | Str2html}}

-
-
- {{.CsrfTokenHtml}} - -
- - -
-
-
- {{.i18n.Tr "settings.confirm_delete_account"}} -
- {{.i18n.Tr "auth.forgot_password"}} -
-
-
-
-
- - -{{template "base/footer" .}} diff --git a/templates/user/settings/email.tmpl b/templates/user/settings/email.tmpl deleted file mode 100644 index 62dc1d5e590d..000000000000 --- a/templates/user/settings/email.tmpl +++ /dev/null @@ -1,66 +0,0 @@ -{{template "base/head" .}} -
- {{template "user/settings/navbar" .}} -
- {{template "base/alert" .}} -

- {{.i18n.Tr "settings.manage_emails"}} -

-
- -
-
-
- {{.CsrfTokenHtml}} -
- - -
- -
-
-
-
- - -{{template "base/footer" .}} diff --git a/templates/user/settings/navbar.tmpl b/templates/user/settings/navbar.tmpl index 237199d939b8..2fdb70428aaa 100644 --- a/templates/user/settings/navbar.tmpl +++ b/templates/user/settings/navbar.tmpl @@ -2,12 +2,12 @@ {{.i18n.Tr "settings.profile"}} + + {{.i18n.Tr "settings.account"}} + {{.i18n.Tr "settings.security"}} - - {{.i18n.Tr "settings.emails"}} - {{if .EnableOpenIDSignIn}} OpenID @@ -28,7 +28,4 @@ {{.i18n.Tr "settings.repos"}} - - {{.i18n.Tr "settings.delete"}} - diff --git a/templates/user/settings/security.tmpl b/templates/user/settings/security.tmpl index b7cd222b3041..90babdc296f7 100644 --- a/templates/user/settings/security.tmpl +++ b/templates/user/settings/security.tmpl @@ -3,41 +3,6 @@ {{template "user/settings/navbar" .}}
{{template "base/alert" .}} -

- {{.i18n.Tr "settings.password"}} -

-
- {{if or (.SignedUser.IsLocal) (.SignedUser.IsOAuth2)}} -
- {{.CsrfTokenHtml}} - {{if .SignedUser.IsPasswordSet}} -
- - -
- {{end}} -
- - -
-
- - -
- -
- - {{.i18n.Tr "auth.forgot_password"}} -
-
- {{else}} -
-

{{$.i18n.Tr "settings.password_change_disabled"}}

-
- {{end}} -
-
-

{{.i18n.Tr "settings.twofa"}}

From 81076622ea628fa73695b0ad08168cba17419008 Mon Sep 17 00:00:00 2001 From: David Schneiderbauer Date: Sat, 5 May 2018 13:24:15 +0200 Subject: [PATCH 03/10] combined totp, access tokens, linked accounts and openid into security settings page --- integrations/links_test.go | 3 +- routers/routes/routes.go | 34 +-- routers/user/setting.go | 210 +++++++++--------- routers/user/setting_openid.go | 47 +--- templates/user/settings/account_link.tmpl | 44 ---- templates/user/settings/applications.tmpl | 70 ------ templates/user/settings/navbar.tmpl | 11 - templates/user/settings/openid.tmpl | 71 ------ templates/user/settings/security.tmpl | 41 +--- .../user/settings/security_accountlinks.tmpl | 36 +++ .../user/settings/security_applications.tmpl | 62 ++++++ templates/user/settings/security_openid.tmpl | 63 ++++++ templates/user/settings/security_twofa.tmpl | 35 +++ templates/user/settings/twofa.tmpl | 44 ---- 14 files changed, 332 insertions(+), 439 deletions(-) delete mode 100644 templates/user/settings/account_link.tmpl delete mode 100644 templates/user/settings/applications.tmpl delete mode 100644 templates/user/settings/openid.tmpl create mode 100644 templates/user/settings/security_accountlinks.tmpl create mode 100644 templates/user/settings/security_applications.tmpl create mode 100644 templates/user/settings/security_openid.tmpl create mode 100644 templates/user/settings/security_twofa.tmpl delete mode 100644 templates/user/settings/twofa.tmpl diff --git a/integrations/links_test.go b/integrations/links_test.go index 587e0406bcd1..803d992055cf 100644 --- a/integrations/links_test.go +++ b/integrations/links_test.go @@ -97,9 +97,8 @@ func testLinksAsUser(userName string, t *testing.T) { "/user/settings/security", "/user/settings/security/two_factor/enroll", "/user/settings/keys", - "/user/settings/applications", - "/user/settings/account_link", "/user/settings/organization", + "/user/settings/repos", } session := loginUser(t, userName) diff --git a/routers/routes/routes.go b/routers/routes/routes.go index bb0e7d3043a7..702da6792437 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -225,28 +225,28 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/email/delete", user.DeleteEmail) m.Post("/delete", user.SettingsDelete) }) - m.Get("/security", user.SettingsSecurity) - m.Group("/openid", func() { - m.Combo("").Get(user.SettingsOpenID). - Post(bindIgnErr(auth.AddOpenIDForm{}), user.SettingsOpenIDPost) - m.Post("/delete", user.DeleteOpenID) - m.Post("/toggle_visibility", user.ToggleOpenIDVisibility) - }, openIDSignInEnabled) + m.Group("/security", func() { + m.Get("", user.SettingsSecurity) + m.Group("/two_factor", func() { + m.Post("/regenerate_scratch", user.SettingsTwoFactorRegenerateScratch) + m.Post("/disable", user.SettingsTwoFactorDisable) + m.Get("/enroll", user.SettingsTwoFactorEnroll) + m.Post("/enroll", bindIgnErr(auth.TwoFactorAuthForm{}), user.SettingsTwoFactorEnrollPost) + }) + m.Group("/openid", func() { + m.Post("", bindIgnErr(auth.AddOpenIDForm{}), user.SettingsOpenIDPost) + m.Post("/delete", user.DeleteOpenID) + m.Post("/toggle_visibility", user.ToggleOpenIDVisibility) + }, openIDSignInEnabled) + m.Post("/applications", bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost) + m.Post("/applications/delete", user.SettingsDeleteApplication) + m.Post("/account_link", user.SettingsDeleteAccountLink) + }) m.Combo("/keys").Get(user.SettingsKeys). Post(bindIgnErr(auth.AddKeyForm{}), user.SettingsKeysPost) m.Post("/keys/delete", user.DeleteKey) - m.Combo("/applications").Get(user.SettingsApplications). - Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost) - m.Post("/applications/delete", user.SettingsDeleteApplication) - m.Combo("/account_link").Get(user.SettingsAccountLinks).Post(user.SettingsDeleteAccountLink) m.Get("/organization", user.SettingsOrganization) m.Get("/repos", user.SettingsRepos) - m.Group("/security/two_factor", func() { - m.Post("/regenerate_scratch", user.SettingsTwoFactorRegenerateScratch) - m.Post("/disable", user.SettingsTwoFactorDisable) - m.Get("/enroll", user.SettingsTwoFactorEnroll) - m.Post("/enroll", bindIgnErr(auth.TwoFactorAuthForm{}), user.SettingsTwoFactorEnrollPost) - }) }, reqSignIn, func(ctx *context.Context) { ctx.Data["PageIsUserSettings"] = true }) diff --git a/routers/user/setting.go b/routers/user/setting.go index 42f0409c1d09..2fcc16ab7575 100644 --- a/routers/user/setting.go +++ b/routers/user/setting.go @@ -31,15 +31,11 @@ import ( const ( tplSettingsProfile base.TplName = "user/settings/profile" tplSettingsAccount base.TplName = "user/settings/account" - tplSettingsKeys base.TplName = "user/settings/keys" - tplSettingsSocial base.TplName = "user/settings/social" - tplSettingsApplications base.TplName = "user/settings/applications" - tplSettingsTwofa base.TplName = "user/settings/twofa" + tplSettingsSecurity base.TplName = "user/settings/security" tplSettingsTwofaEnroll base.TplName = "user/settings/twofa_enroll" - tplSettingsAccountLink base.TplName = "user/settings/account_link" + tplSettingsKeys base.TplName = "user/settings/keys" tplSettingsOrganization base.TplName = "user/settings/organization" tplSettingsRepositories base.TplName = "user/settings/repos" - tplSettingsSecurity base.TplName = "user/settings/security" ) // Settings render user's profile page @@ -356,11 +352,109 @@ func SettingsSecurity(ctx *context.Context) { return } } - ctx.Data["TwofaEnrolled"] = enrolled + + tokens, err := models.ListAccessTokens(ctx.User.ID) + if err != nil { + ctx.ServerError("ListAccessTokens", err) + return + } + ctx.Data["Tokens"] = tokens + + accountLinks, err := models.ListAccountLinks(ctx.User) + if err != nil { + ctx.ServerError("ListAccountLinks", err) + return + } + + // map the provider display name with the LoginSource + sources := make(map[*models.LoginSource]string) + for _, externalAccount := range accountLinks { + if loginSource, err := models.GetLoginSourceByID(externalAccount.LoginSourceID); err == nil { + var providerDisplayName string + if loginSource.IsOAuth2() { + providerTechnicalName := loginSource.OAuth2().Provider + providerDisplayName = models.OAuth2Providers[providerTechnicalName].DisplayName + } else { + providerDisplayName = loginSource.Name + } + sources[loginSource] = providerDisplayName + } + } + ctx.Data["AccountLinks"] = sources + + if ctx.Query("openid.return_to") != "" { + settingsOpenIDVerify(ctx) + return + } + + openid, err := models.GetUserOpenIDs(ctx.User.ID) + if err != nil { + ctx.ServerError("GetUserOpenIDs", err) + return + } + ctx.Data["OpenIDs"] = openid + ctx.HTML(200, tplSettingsSecurity) } +// SettingsApplicationsPost response for add user's access token +func SettingsApplicationsPost(ctx *context.Context, form auth.NewAccessTokenForm) { + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsSettingsApplications"] = true + + if ctx.HasError() { + tokens, err := models.ListAccessTokens(ctx.User.ID) + if err != nil { + ctx.ServerError("ListAccessTokens", err) + return + } + ctx.Data["Tokens"] = tokens + ctx.HTML(200, tplSettingsSecurity) + return + } + + t := &models.AccessToken{ + UID: ctx.User.ID, + Name: form.Name, + } + if err := models.NewAccessToken(t); err != nil { + ctx.ServerError("NewAccessToken", err) + return + } + + ctx.Flash.Success(ctx.Tr("settings.generate_token_success")) + ctx.Flash.Info(t.Sha1) + + ctx.Redirect(setting.AppSubURL + "/user/settings/security") +} + +// SettingsDeleteApplication response for delete user access token +func SettingsDeleteApplication(ctx *context.Context) { + if err := models.DeleteAccessTokenByID(ctx.QueryInt64("id"), ctx.User.ID); err != nil { + ctx.Flash.Error("DeleteAccessTokenByID: " + err.Error()) + } else { + ctx.Flash.Success(ctx.Tr("settings.delete_token_success")) + } + + ctx.JSON(200, map[string]interface{}{ + "redirect": setting.AppSubURL + "/user/settings/security", + }) +} + +// SettingsDeleteAccountLink delete a single account link +func SettingsDeleteAccountLink(ctx *context.Context) { + if _, err := models.RemoveAccountLink(ctx.User, ctx.QueryInt64("loginSourceID")); err != nil { + ctx.Flash.Error("RemoveAccountLink: " + err.Error()) + } else { + ctx.Flash.Success(ctx.Tr("settings.remove_account_link_success")) + } + + ctx.JSON(200, map[string]interface{}{ + "redirect": setting.AppSubURL + "/user/settings/security", + }) +} + // SettingsKeys render user's SSH/GPG public keys page func SettingsKeys(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") @@ -492,65 +586,6 @@ func DeleteKey(ctx *context.Context) { }) } -// SettingsApplications render user's access tokens page -func SettingsApplications(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsApplications"] = true - - tokens, err := models.ListAccessTokens(ctx.User.ID) - if err != nil { - ctx.ServerError("ListAccessTokens", err) - return - } - ctx.Data["Tokens"] = tokens - - ctx.HTML(200, tplSettingsApplications) -} - -// SettingsApplicationsPost response for add user's access token -func SettingsApplicationsPost(ctx *context.Context, form auth.NewAccessTokenForm) { - ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsApplications"] = true - - if ctx.HasError() { - tokens, err := models.ListAccessTokens(ctx.User.ID) - if err != nil { - ctx.ServerError("ListAccessTokens", err) - return - } - ctx.Data["Tokens"] = tokens - ctx.HTML(200, tplSettingsApplications) - return - } - - t := &models.AccessToken{ - UID: ctx.User.ID, - Name: form.Name, - } - if err := models.NewAccessToken(t); err != nil { - ctx.ServerError("NewAccessToken", err) - return - } - - ctx.Flash.Success(ctx.Tr("settings.generate_token_success")) - ctx.Flash.Info(t.Sha1) - - ctx.Redirect(setting.AppSubURL + "/user/settings/applications") -} - -// SettingsDeleteApplication response for delete user access token -func SettingsDeleteApplication(ctx *context.Context) { - if err := models.DeleteAccessTokenByID(ctx.QueryInt64("id"), ctx.User.ID); err != nil { - ctx.Flash.Error("DeleteAccessTokenByID: " + err.Error()) - } else { - ctx.Flash.Success(ctx.Tr("settings.delete_token_success")) - } - - ctx.JSON(200, map[string]interface{}{ - "redirect": setting.AppSubURL + "/user/settings/applications", - }) -} - // SettingsTwoFactorRegenerateScratch regenerates the user's 2FA scratch code. func SettingsTwoFactorRegenerateScratch(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") @@ -716,49 +751,6 @@ func SettingsTwoFactorEnrollPost(ctx *context.Context, form auth.TwoFactorAuthFo ctx.Redirect(setting.AppSubURL + "/user/settings/security") } -// SettingsAccountLinks render the account links settings page -func SettingsAccountLinks(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsAccountLink"] = true - - accountLinks, err := models.ListAccountLinks(ctx.User) - if err != nil { - ctx.ServerError("ListAccountLinks", err) - return - } - - // map the provider display name with the LoginSource - sources := make(map[*models.LoginSource]string) - for _, externalAccount := range accountLinks { - if loginSource, err := models.GetLoginSourceByID(externalAccount.LoginSourceID); err == nil { - var providerDisplayName string - if loginSource.IsOAuth2() { - providerTechnicalName := loginSource.OAuth2().Provider - providerDisplayName = models.OAuth2Providers[providerTechnicalName].DisplayName - } else { - providerDisplayName = loginSource.Name - } - sources[loginSource] = providerDisplayName - } - } - ctx.Data["AccountLinks"] = sources - - ctx.HTML(200, tplSettingsAccountLink) -} - -// SettingsDeleteAccountLink delete a single account link -func SettingsDeleteAccountLink(ctx *context.Context) { - if _, err := models.RemoveAccountLink(ctx.User, ctx.QueryInt64("loginSourceID")); err != nil { - ctx.Flash.Error("RemoveAccountLink: " + err.Error()) - } else { - ctx.Flash.Success(ctx.Tr("settings.remove_account_link_success")) - } - - ctx.JSON(200, map[string]interface{}{ - "redirect": setting.AppSubURL + "/user/settings/account_link", - }) -} - // SettingsOrganization render all the organization of the user func SettingsOrganization(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") diff --git a/routers/user/setting_openid.go b/routers/user/setting_openid.go index 92eb636e2942..771646612052 100644 --- a/routers/user/setting_openid.go +++ b/routers/user/setting_openid.go @@ -8,40 +8,15 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/auth/openid" - "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) -const ( - tplSettingsOpenID base.TplName = "user/settings/openid" -) - -// SettingsOpenID renders change user's openid page -func SettingsOpenID(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsOpenID"] = true - - if ctx.Query("openid.return_to") != "" { - settingsOpenIDVerify(ctx) - return - } - - openid, err := models.GetUserOpenIDs(ctx.User.ID) - if err != nil { - ctx.ServerError("GetUserOpenIDs", err) - return - } - ctx.Data["OpenIDs"] = openid - - ctx.HTML(200, tplSettingsOpenID) -} - // SettingsOpenIDPost response for change user's openid func SettingsOpenIDPost(ctx *context.Context, form auth.AddOpenIDForm) { ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsOpenID"] = true + ctx.Data["PageIsSettingsSecurity"] = true if ctx.HasError() { openid, err := models.GetUserOpenIDs(ctx.User.ID) @@ -50,7 +25,7 @@ func SettingsOpenIDPost(ctx *context.Context, form auth.AddOpenIDForm) { return } ctx.Data["OpenIDs"] = openid - ctx.HTML(200, tplSettingsOpenID) + ctx.HTML(200, tplSettingsSecurity) return } @@ -62,7 +37,7 @@ func SettingsOpenIDPost(ctx *context.Context, form auth.AddOpenIDForm) { id, err := openid.Normalize(form.Openid) if err != nil { - ctx.RenderWithErr(err.Error(), tplSettingsOpenID, &form) + ctx.RenderWithErr(err.Error(), tplSettingsSecurity, &form) return } form.Openid = id @@ -78,15 +53,15 @@ func SettingsOpenIDPost(ctx *context.Context, form auth.AddOpenIDForm) { // Check that the OpenID is not already used for _, obj := range oids { if obj.URI == id { - ctx.RenderWithErr(ctx.Tr("form.openid_been_used", id), tplSettingsOpenID, &form) + ctx.RenderWithErr(ctx.Tr("form.openid_been_used", id), tplSettingsSecurity, &form) return } } - redirectTo := setting.AppURL + "user/settings/openid" + redirectTo := setting.AppURL + "user/settings/security" url, err := openid.RedirectURL(id, redirectTo, setting.AppURL) if err != nil { - ctx.RenderWithErr(err.Error(), tplSettingsOpenID, &form) + ctx.RenderWithErr(err.Error(), tplSettingsSecurity, &form) return } ctx.Redirect(url) @@ -107,7 +82,7 @@ func settingsOpenIDVerify(ctx *context.Context) { id, err := openid.Verify(fullURL) if err != nil { - ctx.RenderWithErr(err.Error(), tplSettingsOpenID, &auth.AddOpenIDForm{ + ctx.RenderWithErr(err.Error(), tplSettingsSecurity, &auth.AddOpenIDForm{ Openid: id, }) return @@ -118,7 +93,7 @@ func settingsOpenIDVerify(ctx *context.Context) { oid := &models.UserOpenID{UID: ctx.User.ID, URI: id} if err = models.AddUserOpenID(oid); err != nil { if models.IsErrOpenIDAlreadyUsed(err) { - ctx.RenderWithErr(ctx.Tr("form.openid_been_used", id), tplSettingsOpenID, &auth.AddOpenIDForm{Openid: id}) + ctx.RenderWithErr(ctx.Tr("form.openid_been_used", id), tplSettingsSecurity, &auth.AddOpenIDForm{Openid: id}) return } ctx.ServerError("AddUserOpenID", err) @@ -127,7 +102,7 @@ func settingsOpenIDVerify(ctx *context.Context) { log.Trace("Associated OpenID %s to user %s", id, ctx.User.Name) ctx.Flash.Success(ctx.Tr("settings.add_openid_success")) - ctx.Redirect(setting.AppSubURL + "/user/settings/openid") + ctx.Redirect(setting.AppSubURL + "/user/settings/security") } // DeleteOpenID response for delete user's openid @@ -140,7 +115,7 @@ func DeleteOpenID(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("settings.openid_deletion_success")) ctx.JSON(200, map[string]interface{}{ - "redirect": setting.AppSubURL + "/user/settings/openid", + "redirect": setting.AppSubURL + "/user/settings/security", }) } @@ -151,5 +126,5 @@ func ToggleOpenIDVisibility(ctx *context.Context) { return } - ctx.Redirect(setting.AppSubURL + "/user/settings/openid") + ctx.Redirect(setting.AppSubURL + "/user/settings/security") } diff --git a/templates/user/settings/account_link.tmpl b/templates/user/settings/account_link.tmpl deleted file mode 100644 index 81ddf626e16e..000000000000 --- a/templates/user/settings/account_link.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -{{template "base/head" .}} - - - -{{template "base/footer" .}} diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl deleted file mode 100644 index 4ad5eaa71474..000000000000 --- a/templates/user/settings/applications.tmpl +++ /dev/null @@ -1,70 +0,0 @@ -{{template "base/head" .}} -
- {{template "user/settings/navbar" .}} -
- {{template "base/alert" .}} -

- {{.i18n.Tr "settings.manage_access_token"}} -

-
-
-
- {{.i18n.Tr "settings.tokens_desc"}} -
- {{range .Tokens}} -
-
- -
- -
- {{.Name}} -
- {{$.i18n.Tr "settings.add_on"}} {{.CreatedUnix.FormatShort}} {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{.UpdatedUnix.FormatShort}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}} -
-
-
- {{end}} -
-
-

- {{.i18n.Tr "settings.generate_new_token"}} -

-
-

{{.i18n.Tr "settings.new_token_desc"}}

-
- {{.CsrfTokenHtml}} -
- - -
- -
-
-
-
- - -{{template "base/footer" .}} diff --git a/templates/user/settings/navbar.tmpl b/templates/user/settings/navbar.tmpl index 2fdb70428aaa..70f1fc3388eb 100644 --- a/templates/user/settings/navbar.tmpl +++ b/templates/user/settings/navbar.tmpl @@ -8,20 +8,9 @@ {{.i18n.Tr "settings.security"}} - {{if .EnableOpenIDSignIn}} - - OpenID - - {{end}} {{.i18n.Tr "settings.ssh_gpg_keys"}} - - {{.i18n.Tr "settings.applications"}} - - - {{.i18n.Tr "settings.account_link"}} - {{.i18n.Tr "settings.organization"}} diff --git a/templates/user/settings/openid.tmpl b/templates/user/settings/openid.tmpl deleted file mode 100644 index 6ae4a8dee803..000000000000 --- a/templates/user/settings/openid.tmpl +++ /dev/null @@ -1,71 +0,0 @@ -{{template "base/head" .}} -
- {{template "user/settings/navbar" .}} -
- {{template "base/alert" .}} -

- {{.i18n.Tr "settings.manage_openid"}} -

-
-
-
- {{.i18n.Tr "settings.openid_desc"}} -
- {{range .OpenIDs}} -
-
- -
-
-
- {{$.CsrfTokenHtml}} - - {{if .Show}} - - {{else}} - - {{end}} - -
-
-
- {{.URI}} -
-
- {{end}} -
-
-
-
- {{.CsrfTokenHtml}} -
- - -
- -
-
-
-
- - -{{template "base/footer" .}} diff --git a/templates/user/settings/security.tmpl b/templates/user/settings/security.tmpl index 90babdc296f7..a212660dc247 100644 --- a/templates/user/settings/security.tmpl +++ b/templates/user/settings/security.tmpl @@ -3,42 +3,13 @@ {{template "user/settings/navbar" .}}
{{template "base/alert" .}} -

- {{.i18n.Tr "settings.twofa"}} -

-
-

{{.i18n.Tr "settings.twofa_desc"}}

- {{if .TwofaEnrolled}} -

{{$.i18n.Tr "settings.twofa_is_enrolled" | Str2html }}

-
- {{.CsrfTokenHtml}} -

{{.i18n.Tr "settings.regenerate_scratch_token_desc"}}

- -
-
- {{.CsrfTokenHtml}} -

{{.i18n.Tr "settings.twofa_disable_note"}}

-
{{$.i18n.Tr "settings.twofa_disable"}}
-
- {{else}} -

{{.i18n.Tr "settings.twofa_not_enrolled"}}

- - {{end}} -
+ {{template "user/settings/security_twofa" .}} + {{template "user/settings/security_applications" .}} + {{template "user/settings/security_accountlinks" .}} + {{if .EnableOpenIDSignIn}} + {{template "user/settings/security_openid" .}} + {{end}}
- - {{template "base/footer" .}} diff --git a/templates/user/settings/security_accountlinks.tmpl b/templates/user/settings/security_accountlinks.tmpl new file mode 100644 index 000000000000..93cc508a54e6 --- /dev/null +++ b/templates/user/settings/security_accountlinks.tmpl @@ -0,0 +1,36 @@ +

+ {{.i18n.Tr "settings.manage_account_links"}} +

+
+
+
+ {{.i18n.Tr "settings.manage_account_links_desc"}} +
+ {{if .AccountLinks}} + {{range $loginSource, $provider := .AccountLinks}} +
+
+ +
+
+ {{$provider}} + {{if $loginSource.IsActived}}{{$.i18n.Tr "settings.active"}}{{end}} +
+
+ {{end}} + {{end}} +
+
+ + diff --git a/templates/user/settings/security_applications.tmpl b/templates/user/settings/security_applications.tmpl new file mode 100644 index 000000000000..d05667c60a87 --- /dev/null +++ b/templates/user/settings/security_applications.tmpl @@ -0,0 +1,62 @@ +

+ {{.i18n.Tr "settings.manage_access_token"}} +

+
+
+
+ {{.i18n.Tr "settings.tokens_desc"}} +
+ {{range .Tokens}} +
+
+ +
+ +
+ {{.Name}} +
+ {{$.i18n.Tr "settings.add_on"}} {{.CreatedUnix.FormatShort}} {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{.UpdatedUnix.FormatShort}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}} +
+
+
+ {{end}} +
+
+
+
+ {{.i18n.Tr "settings.generate_new_token"}} +
+

{{.i18n.Tr "settings.new_token_desc"}}

+
+ {{.CsrfTokenHtml}} +
+ + +
+ +
+
+ + diff --git a/templates/user/settings/security_openid.tmpl b/templates/user/settings/security_openid.tmpl new file mode 100644 index 000000000000..12f4aab4194c --- /dev/null +++ b/templates/user/settings/security_openid.tmpl @@ -0,0 +1,63 @@ +

+ {{.i18n.Tr "settings.manage_openid"}} +

+
+
+
+ {{.i18n.Tr "settings.openid_desc"}} +
+ {{range .OpenIDs}} +
+
+ +
+
+
+ {{$.CsrfTokenHtml}} + + {{if .Show}} + + {{else}} + + {{end}} + +
+
+
+ {{.URI}} +
+
+ {{end}} +
+
+
+
+ {{.CsrfTokenHtml}} +
+ + +
+ +
+
+ + diff --git a/templates/user/settings/security_twofa.tmpl b/templates/user/settings/security_twofa.tmpl new file mode 100644 index 000000000000..05112a21bb15 --- /dev/null +++ b/templates/user/settings/security_twofa.tmpl @@ -0,0 +1,35 @@ +

+ {{.i18n.Tr "settings.twofa"}} +

+
+

{{.i18n.Tr "settings.twofa_desc"}}

+ {{if .TwofaEnrolled}} +

{{$.i18n.Tr "settings.twofa_is_enrolled" | Str2html }}

+
+ {{.CsrfTokenHtml}} +

{{.i18n.Tr "settings.regenerate_scratch_token_desc"}}

+ +
+
+ {{.CsrfTokenHtml}} +

{{.i18n.Tr "settings.twofa_disable_note"}}

+
{{$.i18n.Tr "settings.twofa_disable"}}
+
+ {{else}} +

{{.i18n.Tr "settings.twofa_not_enrolled"}}

+ + {{end}} +
+ + diff --git a/templates/user/settings/twofa.tmpl b/templates/user/settings/twofa.tmpl deleted file mode 100644 index c6a7a7cba099..000000000000 --- a/templates/user/settings/twofa.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -{{template "base/head" .}} -
- {{template "user/settings/navbar" .}} -
- {{template "base/alert" .}} -

- {{.i18n.Tr "settings.twofa"}} -

-
-

{{.i18n.Tr "settings.twofa_desc"}}

- {{if .TwofaEnrolled}} -

{{$.i18n.Tr "settings.twofa_is_enrolled" | Str2html }}

-
- {{.CsrfTokenHtml}} -

{{.i18n.Tr "settings.regenerate_scratch_token_desc"}}

- -
-
- {{.CsrfTokenHtml}} -

{{.i18n.Tr "settings.twofa_disable_note"}}

-
{{$.i18n.Tr "settings.twofa_disable"}}
-
- {{else}} -

{{.i18n.Tr "settings.twofa_not_enrolled"}}

- - {{end}} -
-
-
- - - -{{template "base/footer" .}} From 6f11a3e74a04dcb14dbfeeed32c9ebf634af7938 Mon Sep 17 00:00:00 2001 From: David Schneiderbauer Date: Wed, 9 May 2018 18:21:00 +0200 Subject: [PATCH 04/10] move access tokens to applications settings page --- options/locale/locale_en-US.ini | 2 +- routers/routes/routes.go | 5 +- routers/user/setting.go | 55 ++++++++------ templates/user/settings/applications.tmpl | 71 +++++++++++++++++++ templates/user/settings/navbar.tmpl | 3 + templates/user/settings/organization.tmpl | 2 +- templates/user/settings/repos.tmpl | 2 +- templates/user/settings/security.tmpl | 3 +- .../user/settings/security_applications.tmpl | 62 ---------------- templates/user/settings/twofa_enroll.tmpl | 2 +- 10 files changed, 114 insertions(+), 93 deletions(-) create mode 100644 templates/user/settings/applications.tmpl delete mode 100644 templates/user/settings/security_applications.tmpl diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 16d316ee7f37..882c5ee5505d 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -311,7 +311,7 @@ security = Security avatar = Avatar ssh_gpg_keys = SSH / GPG Keys social = Social Accounts -applications = Access Tokens +applications = Applications orgs = Manage Organizations repos = Repositories delete = Delete Account diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 702da6792437..02e047884fba 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -238,10 +238,11 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/delete", user.DeleteOpenID) m.Post("/toggle_visibility", user.ToggleOpenIDVisibility) }, openIDSignInEnabled) - m.Post("/applications", bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost) - m.Post("/applications/delete", user.SettingsDeleteApplication) m.Post("/account_link", user.SettingsDeleteAccountLink) }) + m.Combo("/applications").Get(user.SettingsApplications). + Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost) + m.Post("/applications/delete", user.SettingsDeleteApplication) m.Combo("/keys").Get(user.SettingsKeys). Post(bindIgnErr(auth.AddKeyForm{}), user.SettingsKeysPost) m.Post("/keys/delete", user.DeleteKey) diff --git a/routers/user/setting.go b/routers/user/setting.go index 2fcc16ab7575..5dee8c405a9e 100644 --- a/routers/user/setting.go +++ b/routers/user/setting.go @@ -33,6 +33,7 @@ const ( tplSettingsAccount base.TplName = "user/settings/account" tplSettingsSecurity base.TplName = "user/settings/security" tplSettingsTwofaEnroll base.TplName = "user/settings/twofa_enroll" + tplSettingsApplications base.TplName = "user/settings/applications" tplSettingsKeys base.TplName = "user/settings/keys" tplSettingsOrganization base.TplName = "user/settings/organization" tplSettingsRepositories base.TplName = "user/settings/repos" @@ -354,13 +355,6 @@ func SettingsSecurity(ctx *context.Context) { } ctx.Data["TwofaEnrolled"] = enrolled - tokens, err := models.ListAccessTokens(ctx.User.ID) - if err != nil { - ctx.ServerError("ListAccessTokens", err) - return - } - ctx.Data["Tokens"] = tokens - accountLinks, err := models.ListAccountLinks(ctx.User) if err != nil { ctx.ServerError("ListAccountLinks", err) @@ -398,6 +392,34 @@ func SettingsSecurity(ctx *context.Context) { ctx.HTML(200, tplSettingsSecurity) } +// SettingsDeleteAccountLink delete a single account link +func SettingsDeleteAccountLink(ctx *context.Context) { + if _, err := models.RemoveAccountLink(ctx.User, ctx.QueryInt64("loginSourceID")); err != nil { + ctx.Flash.Error("RemoveAccountLink: " + err.Error()) + } else { + ctx.Flash.Success(ctx.Tr("settings.remove_account_link_success")) + } + + ctx.JSON(200, map[string]interface{}{ + "redirect": setting.AppSubURL + "/user/settings/security", + }) +} + +// SettingsApplications renders access token page +func SettingsApplications(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsSettingsApplications"] = true + + tokens, err := models.ListAccessTokens(ctx.User.ID) + if err != nil { + ctx.ServerError("ListAccessTokens", err) + return + } + ctx.Data["Tokens"] = tokens + + ctx.HTML(200, tplSettingsApplications) +} + // SettingsApplicationsPost response for add user's access token func SettingsApplicationsPost(ctx *context.Context, form auth.NewAccessTokenForm) { ctx.Data["Title"] = ctx.Tr("settings") @@ -410,7 +432,7 @@ func SettingsApplicationsPost(ctx *context.Context, form auth.NewAccessTokenForm return } ctx.Data["Tokens"] = tokens - ctx.HTML(200, tplSettingsSecurity) + ctx.HTML(200, tplSettingsApplications) return } @@ -426,7 +448,7 @@ func SettingsApplicationsPost(ctx *context.Context, form auth.NewAccessTokenForm ctx.Flash.Success(ctx.Tr("settings.generate_token_success")) ctx.Flash.Info(t.Sha1) - ctx.Redirect(setting.AppSubURL + "/user/settings/security") + ctx.Redirect(setting.AppSubURL + "/user/settings/applications") } // SettingsDeleteApplication response for delete user access token @@ -438,20 +460,7 @@ func SettingsDeleteApplication(ctx *context.Context) { } ctx.JSON(200, map[string]interface{}{ - "redirect": setting.AppSubURL + "/user/settings/security", - }) -} - -// SettingsDeleteAccountLink delete a single account link -func SettingsDeleteAccountLink(ctx *context.Context) { - if _, err := models.RemoveAccountLink(ctx.User, ctx.QueryInt64("loginSourceID")); err != nil { - ctx.Flash.Error("RemoveAccountLink: " + err.Error()) - } else { - ctx.Flash.Success(ctx.Tr("settings.remove_account_link_success")) - } - - ctx.JSON(200, map[string]interface{}{ - "redirect": setting.AppSubURL + "/user/settings/security", + "redirect": setting.AppSubURL + "/user/settings/applications", }) } diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl new file mode 100644 index 000000000000..f1a3e4811519 --- /dev/null +++ b/templates/user/settings/applications.tmpl @@ -0,0 +1,71 @@ +{{template "base/head" .}} +
+ {{template "user/settings/navbar" .}} +
+

+ {{.i18n.Tr "settings.manage_access_token"}} +

+
+
+
+ {{.i18n.Tr "settings.tokens_desc"}} +
+ {{range .Tokens}} +
+
+ +
+ +
+ {{.Name}} +
+ {{$.i18n.Tr "settings.add_on"}} {{.CreatedUnix.FormatShort}} {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{.UpdatedUnix.FormatShort}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}} +
+
+
+ {{end}} +
+
+
+
+ {{.i18n.Tr "settings.generate_new_token"}} +
+

{{.i18n.Tr "settings.new_token_desc"}}

+
+ {{.CsrfTokenHtml}} +
+ + +
+ +
+
+
+
+ + + + +{{template "base/footer" .}} diff --git a/templates/user/settings/navbar.tmpl b/templates/user/settings/navbar.tmpl index 70f1fc3388eb..18bd9a4f8d6e 100644 --- a/templates/user/settings/navbar.tmpl +++ b/templates/user/settings/navbar.tmpl @@ -8,6 +8,9 @@ {{.i18n.Tr "settings.security"}} + + {{.i18n.Tr "settings.applications"}} + {{.i18n.Tr "settings.ssh_gpg_keys"}} diff --git a/templates/user/settings/organization.tmpl b/templates/user/settings/organization.tmpl index 2d357cb3b56d..de541dcd1749 100644 --- a/templates/user/settings/organization.tmpl +++ b/templates/user/settings/organization.tmpl @@ -1,5 +1,5 @@ {{template "base/head" .}} -