-
+
- {{.i18n.Tr "settings.email_desc"}} + {{range .Emails}} +
-
+ ++ {{if not .IsPrimary}} + {{if .IsActivated}} + + {{end}} + + {{end}} +
{{.Email}}
+
+ {{end}}
+
diff --git a/cmd/web.go b/cmd/web.go index 38b802b68..eeb2f5d28 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -241,6 +241,8 @@ func runWeb(*cli.Context) { m.Get("", user.Settings) m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost) m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), user.SettingsAvatar) + m.Get("/email", user.SettingsEmails) + m.Post("/email", bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost) m.Get("/password", user.SettingsPassword) m.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost) m.Get("/ssh", user.SettingsSSHKeys) @@ -252,6 +254,7 @@ func runWeb(*cli.Context) { m.Group("/user", func() { // r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds) m.Any("/activate", user.Activate) + m.Any("/activate_email", user.ActivateEmail) m.Get("/email2user", user.Email2User) m.Get("/forget_password", user.ForgotPasswd) m.Post("/forget_password", user.ForgotPasswdPost) diff --git a/modules/auth/user_form.go b/modules/auth/user_form.go index 4dfe2499f..becd5cbca 100644 --- a/modules/auth/user_form.go +++ b/modules/auth/user_form.go @@ -97,6 +97,14 @@ func (f *UploadAvatarForm) Validate(ctx *macaron.Context, errs binding.Errors) b return validate(errs, ctx.Data, f, ctx.Locale) } +type AddEmailForm struct { + Email string `form:"email" binding:"Required;Email;MaxSize(50)"` +} + +func (f *AddEmailForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { + return validate(errs, ctx.Data, f, ctx.Locale) +} + type ChangePasswordForm struct { OldPassword string `form:"old_password" binding:"Required;MinSize(6);MaxSize(255)"` Password string `form:"password" binding:"Required;MinSize(6);MaxSize(255)"` diff --git a/routers/user/setting.go b/routers/user/setting.go index 304ddd362..7dca5d869 100644 --- a/routers/user/setting.go +++ b/routers/user/setting.go @@ -14,6 +14,7 @@ import ( "github.com/gogits/gogs/modules/auth" "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/log" + "github.com/gogits/gogs/modules/mailer" "github.com/gogits/gogs/modules/middleware" "github.com/gogits/gogs/modules/setting" ) @@ -21,6 +22,7 @@ import ( const ( SETTINGS_PROFILE base.TplName = "user/settings/profile" SETTINGS_PASSWORD base.TplName = "user/settings/password" + SETTINGS_EMAILS base.TplName = "user/settings/email" SETTINGS_SSH_KEYS base.TplName = "user/settings/sshkeys" SETTINGS_SOCIAL base.TplName = "user/settings/social" SETTINGS_APPLICATIONS base.TplName = "user/settings/applications" @@ -126,6 +128,112 @@ func SettingsAvatar(ctx *middleware.Context, form auth.UploadAvatarForm) { ctx.Flash.Success(ctx.Tr("settings.update_avatar_success")) } +func SettingsEmails(ctx *middleware.Context) { + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsUserSettings"] = true + ctx.Data["PageIsSettingsEmails"] = true + + var err error + ctx.Data["Emails"], err = models.GetEmailAddresses(ctx.User.Id) + + if err != nil { + ctx.Handle(500, "email.GetEmailAddresses", err) + return + } + + ctx.HTML(200, SETTINGS_EMAILS) +} + +func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) { + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsUserSettings"] = true + ctx.Data["PageIsSettingsEmails"] = true + + var err error + ctx.Data["Emails"], err = models.GetEmailAddresses(ctx.User.Id) + if err != nil { + ctx.Handle(500, "email.GetEmailAddresses", err) + return + } + + // Delete Email address. + if ctx.Query("_method") == "DELETE" { + id := com.StrTo(ctx.Query("id")).MustInt64() + if id <= 0 { + return + } + + if err = models.DeleteEmailAddress(&models.EmailAddress{Id: id}); err != nil { + ctx.Handle(500, "DeleteEmail", err) + } else { + log.Trace("Email address deleted: %s", ctx.User.Name) + ctx.Redirect(setting.AppSubUrl + "/user/settings/email") + } + return + } + + // Make emailaddress primary. + if ctx.Query("_method") == "PRIMARY" { + id := com.StrTo(ctx.Query("id")).MustInt64() + if id <= 0 { + return + } + + if err = models.MakeEmailPrimary(&models.EmailAddress{Id: id}); err != nil { + ctx.Handle(500, "MakeEmailPrimary", err) + } else { + log.Trace("Email made primary: %s", ctx.User.Name) + ctx.Redirect(setting.AppSubUrl + "/user/settings/email") + } + return + } + + // Add Email address. + if ctx.Req.Method == "POST" { + if ctx.HasError() { + ctx.HTML(200, SETTINGS_EMAILS) + return + } + + cleanEmail := strings.Replace(form.Email, "\n", "", -1) + e := &models.EmailAddress{ + OwnerId: ctx.User.Id, + Email: cleanEmail, + IsActivated: !setting.Service.RegisterEmailConfirm, + } + + if err := models.AddEmailAddress(e); err != nil { + if err == models.ErrEmailAlreadyUsed { + ctx.RenderWithErr(ctx.Tr("form.email_has_been_used"), SETTINGS_EMAILS, &form) + return + } + ctx.Handle(500, "email.AddEmailAddress", err) + return + } else { + + // Send confirmation e-mail + if setting.Service.RegisterEmailConfirm { + mailer.SendActivateEmail(ctx.Render, ctx.User, e) + + if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil { + log.Error(4, "Set cache(MailResendLimit) fail: %v", err) + } + ctx.Flash.Success(ctx.Tr("settings.add_email_success_confirmation_email_sent")) + } else { + ctx.Flash.Success(ctx.Tr("settings.add_email_success")) + } + + log.Trace("Email address added: %s", e.Email) + + ctx.Redirect(setting.AppSubUrl + "/user/settings/email") + return + } + + } + + ctx.HTML(200, SETTINGS_EMAILS) +} + func SettingsPassword(ctx *middleware.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsUserSettings"] = true diff --git a/templates/user/settings/email.tmpl b/templates/user/settings/email.tmpl new file mode 100644 index 000000000..6f2a85a3c --- /dev/null +++ b/templates/user/settings/email.tmpl @@ -0,0 +1,58 @@ +{{template "ng/base/head" .}} +{{template "ng/base/header" .}} +
{{.Email}}
+