You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
12 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package user
  5. import (
  6. "errors"
  7. "fmt"
  8. "io/ioutil"
  9. "strings"
  10. "github.com/Unknwon/com"
  11. "github.com/gogits/gogs/models"
  12. "github.com/gogits/gogs/modules/auth"
  13. "github.com/gogits/gogs/modules/base"
  14. "github.com/gogits/gogs/modules/log"
  15. "github.com/gogits/gogs/modules/mailer"
  16. "github.com/gogits/gogs/modules/middleware"
  17. "github.com/gogits/gogs/modules/setting"
  18. )
  19. const (
  20. SETTINGS_PROFILE base.TplName = "user/settings/profile"
  21. SETTINGS_PASSWORD base.TplName = "user/settings/password"
  22. SETTINGS_EMAILS base.TplName = "user/settings/email"
  23. SETTINGS_SSH_KEYS base.TplName = "user/settings/sshkeys"
  24. SETTINGS_SOCIAL base.TplName = "user/settings/social"
  25. SETTINGS_APPLICATIONS base.TplName = "user/settings/applications"
  26. SETTINGS_DELETE base.TplName = "user/settings/delete"
  27. NOTIFICATION base.TplName = "user/notification"
  28. SECURITY base.TplName = "user/security"
  29. )
  30. func Settings(ctx *middleware.Context) {
  31. ctx.Data["Title"] = ctx.Tr("settings")
  32. ctx.Data["PageIsSettingsProfile"] = true
  33. ctx.HTML(200, SETTINGS_PROFILE)
  34. }
  35. func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
  36. ctx.Data["Title"] = ctx.Tr("settings")
  37. ctx.Data["PageIsSettingsProfile"] = true
  38. if ctx.HasError() {
  39. ctx.HTML(200, SETTINGS_PROFILE)
  40. return
  41. }
  42. // Check if user name has been changed.
  43. if ctx.User.Name != form.Name {
  44. if err := models.ChangeUserName(ctx.User, form.Name); err != nil {
  45. switch {
  46. case models.IsErrUserAlreadyExist(err):
  47. ctx.Flash.Error(ctx.Tr("form.name_been_taken"))
  48. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  49. case models.IsErrEmailAlreadyUsed(err):
  50. ctx.Flash.Error(ctx.Tr("form.email_been_used"))
  51. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  52. case models.IsErrNameReserved(err):
  53. ctx.Flash.Error(ctx.Tr("user.form.name_reserved"))
  54. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  55. case models.IsErrNamePatternNotAllowed(err):
  56. ctx.Flash.Error(ctx.Tr("user.form.name_pattern_not_allowed"))
  57. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  58. default:
  59. ctx.Handle(500, "ChangeUserName", err)
  60. }
  61. return
  62. }
  63. log.Trace("User name changed: %s -> %s", ctx.User.Name, form.Name)
  64. ctx.User.Name = form.Name
  65. }
  66. ctx.User.FullName = form.FullName
  67. ctx.User.Email = form.Email
  68. ctx.User.Website = form.Website
  69. ctx.User.Location = form.Location
  70. ctx.User.Avatar = base.EncodeMd5(form.Gravatar)
  71. ctx.User.AvatarEmail = form.Gravatar
  72. if err := models.UpdateUser(ctx.User); err != nil {
  73. ctx.Handle(500, "UpdateUser", err)
  74. return
  75. }
  76. log.Trace("User setting updated: %s", ctx.User.Name)
  77. ctx.Flash.Success(ctx.Tr("settings.update_profile_success"))
  78. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  79. }
  80. // FIXME: limit size.
  81. func UpdateAvatarSetting(ctx *middleware.Context, form auth.UploadAvatarForm, ctxUser *models.User) error {
  82. ctxUser.UseCustomAvatar = form.Enable
  83. if form.Avatar != nil {
  84. fr, err := form.Avatar.Open()
  85. if err != nil {
  86. return fmt.Errorf("Avatar.Open: %v", err)
  87. }
  88. data, err := ioutil.ReadAll(fr)
  89. if err != nil {
  90. return fmt.Errorf("ReadAll: %v", err)
  91. }
  92. if _, ok := base.IsImageFile(data); !ok {
  93. return errors.New(ctx.Tr("settings.uploaded_avatar_not_a_image"))
  94. }
  95. if err = ctxUser.UploadAvatar(data); err != nil {
  96. return fmt.Errorf("UploadAvatar: %v", err)
  97. }
  98. } else {
  99. // In case no avatar at all.
  100. if form.Enable && !com.IsFile(ctx.User.CustomAvatarPath()) {
  101. return errors.New(ctx.Tr("settings.no_custom_avatar_available"))
  102. }
  103. }
  104. if err := models.UpdateUser(ctxUser); err != nil {
  105. return fmt.Errorf("UpdateUser: %v", err)
  106. }
  107. return nil
  108. }
  109. func SettingsAvatar(ctx *middleware.Context, form auth.UploadAvatarForm) {
  110. if err := UpdateAvatarSetting(ctx, form, ctx.User); err != nil {
  111. ctx.Flash.Error(err.Error())
  112. } else {
  113. ctx.Flash.Success(ctx.Tr("settings.update_avatar_success"))
  114. }
  115. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  116. }
  117. func SettingsPassword(ctx *middleware.Context) {
  118. ctx.Data["Title"] = ctx.Tr("settings")
  119. ctx.Data["PageIsSettingsPassword"] = true
  120. ctx.HTML(200, SETTINGS_PASSWORD)
  121. }
  122. func SettingsPasswordPost(ctx *middleware.Context, form auth.ChangePasswordForm) {
  123. ctx.Data["Title"] = ctx.Tr("settings")
  124. ctx.Data["PageIsSettingsPassword"] = true
  125. if ctx.HasError() {
  126. ctx.HTML(200, SETTINGS_PASSWORD)
  127. return
  128. }
  129. if !ctx.User.ValidatePassword(form.OldPassword) {
  130. ctx.Flash.Error(ctx.Tr("settings.password_incorrect"))
  131. } else if form.Password != form.Retype {
  132. ctx.Flash.Error(ctx.Tr("form.password_not_match"))
  133. } else {
  134. ctx.User.Passwd = form.Password
  135. ctx.User.Salt = models.GetUserSalt()
  136. ctx.User.EncodePasswd()
  137. if err := models.UpdateUser(ctx.User); err != nil {
  138. ctx.Handle(500, "UpdateUser", err)
  139. return
  140. }
  141. log.Trace("User password updated: %s", ctx.User.Name)
  142. ctx.Flash.Success(ctx.Tr("settings.change_password_success"))
  143. }
  144. ctx.Redirect(setting.AppSubUrl + "/user/settings/password")
  145. }
  146. func SettingsEmails(ctx *middleware.Context) {
  147. ctx.Data["Title"] = ctx.Tr("settings")
  148. ctx.Data["PageIsSettingsEmails"] = true
  149. emails, err := models.GetEmailAddresses(ctx.User.Id)
  150. if err != nil {
  151. ctx.Handle(500, "GetEmailAddresses", err)
  152. return
  153. }
  154. ctx.Data["Emails"] = emails
  155. ctx.HTML(200, SETTINGS_EMAILS)
  156. }
  157. func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
  158. ctx.Data["Title"] = ctx.Tr("settings")
  159. ctx.Data["PageIsSettingsEmails"] = true
  160. // Make emailaddress primary.
  161. if ctx.Query("_method") == "PRIMARY" {
  162. if err := models.MakeEmailPrimary(&models.EmailAddress{ID: ctx.QueryInt64("id")}); err != nil {
  163. ctx.Handle(500, "MakeEmailPrimary", err)
  164. return
  165. }
  166. log.Trace("Email made primary: %s", ctx.User.Name)
  167. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  168. return
  169. }
  170. // Add Email address.
  171. emails, err := models.GetEmailAddresses(ctx.User.Id)
  172. if err != nil {
  173. ctx.Handle(500, "GetEmailAddresses", err)
  174. return
  175. }
  176. ctx.Data["Emails"] = emails
  177. if ctx.HasError() {
  178. ctx.HTML(200, SETTINGS_EMAILS)
  179. return
  180. }
  181. e := &models.EmailAddress{
  182. UID: ctx.User.Id,
  183. Email: strings.TrimSpace(form.Email),
  184. IsActivated: !setting.Service.RegisterEmailConfirm,
  185. }
  186. if err := models.AddEmailAddress(e); err != nil {
  187. if models.IsErrEmailAlreadyUsed(err) {
  188. ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SETTINGS_EMAILS, &form)
  189. return
  190. }
  191. ctx.Handle(500, "AddEmailAddress", err)
  192. return
  193. }
  194. // Send confirmation e-mail
  195. if setting.Service.RegisterEmailConfirm {
  196. mailer.SendActivateEmail(ctx.Render, ctx.User, e)
  197. if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
  198. log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
  199. }
  200. ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", e.Email, setting.Service.ActiveCodeLives/60))
  201. } else {
  202. ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
  203. }
  204. log.Trace("Email address added: %s", e.Email)
  205. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  206. }
  207. func DeleteEmail(ctx *middleware.Context) {
  208. if err := models.DeleteEmailAddress(&models.EmailAddress{ID: ctx.QueryInt64("id")}); err != nil {
  209. ctx.Handle(500, "DeleteEmail", err)
  210. return
  211. }
  212. log.Trace("Email address deleted: %s", ctx.User.Name)
  213. ctx.Flash.Success(ctx.Tr("settings.email_deletion_success"))
  214. ctx.JSON(200, map[string]interface{}{
  215. "redirect": setting.AppSubUrl + "/user/settings/email",
  216. })
  217. }
  218. func SettingsSSHKeys(ctx *middleware.Context) {
  219. ctx.Data["Title"] = ctx.Tr("settings")
  220. ctx.Data["PageIsSettingsSSHKeys"] = true
  221. keys, err := models.ListPublicKeys(ctx.User.Id)
  222. if err != nil {
  223. ctx.Handle(500, "ListPublicKeys", err)
  224. return
  225. }
  226. ctx.Data["Keys"] = keys
  227. ctx.HTML(200, SETTINGS_SSH_KEYS)
  228. }
  229. func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
  230. ctx.Data["Title"] = ctx.Tr("settings")
  231. ctx.Data["PageIsSettingsSSHKeys"] = true
  232. keys, err := models.ListPublicKeys(ctx.User.Id)
  233. if err != nil {
  234. ctx.Handle(500, "ListPublicKeys", err)
  235. return
  236. }
  237. ctx.Data["Keys"] = keys
  238. if ctx.HasError() {
  239. ctx.HTML(200, SETTINGS_SSH_KEYS)
  240. return
  241. }
  242. content, err := models.CheckPublicKeyString(form.Content)
  243. if err != nil {
  244. if err == models.ErrKeyUnableVerify {
  245. ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key"))
  246. } else {
  247. ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error()))
  248. ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
  249. return
  250. }
  251. }
  252. if err = models.AddPublicKey(ctx.User.Id, form.Title, content); err != nil {
  253. ctx.Data["HasError"] = true
  254. switch {
  255. case models.IsErrKeyAlreadyExist(err):
  256. ctx.Data["Err_Content"] = true
  257. ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), SETTINGS_SSH_KEYS, &form)
  258. case models.IsErrKeyNameAlreadyUsed(err):
  259. ctx.Data["Err_Title"] = true
  260. ctx.RenderWithErr(ctx.Tr("settings.ssh_key_name_used"), SETTINGS_SSH_KEYS, &form)
  261. default:
  262. ctx.Handle(500, "AddPublicKey", err)
  263. }
  264. return
  265. }
  266. ctx.Flash.Success(ctx.Tr("settings.add_key_success", form.Title))
  267. ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
  268. }
  269. func DeleteSSHKey(ctx *middleware.Context) {
  270. if err := models.DeletePublicKey(ctx.QueryInt64("id")); err != nil {
  271. ctx.Flash.Error("DeletePublicKey: " + err.Error())
  272. } else {
  273. ctx.Flash.Success(ctx.Tr("settings.ssh_key_deletion_success"))
  274. }
  275. ctx.JSON(200, map[string]interface{}{
  276. "redirect": setting.AppSubUrl + "/user/settings/ssh",
  277. })
  278. }
  279. func SettingsSocial(ctx *middleware.Context) {
  280. ctx.Data["Title"] = ctx.Tr("settings")
  281. ctx.Data["PageIsSettingsSocial"] = true
  282. // Unbind social account.
  283. remove, _ := com.StrTo(ctx.Query("remove")).Int64()
  284. if remove > 0 {
  285. if err := models.DeleteOauth2ById(remove); err != nil {
  286. ctx.Handle(500, "DeleteOauth2ById", err)
  287. return
  288. }
  289. ctx.Flash.Success(ctx.Tr("settings.unbind_success"))
  290. ctx.Redirect(setting.AppSubUrl + "/user/settings/social")
  291. return
  292. }
  293. socials, err := models.GetOauthByUserId(ctx.User.Id)
  294. if err != nil {
  295. ctx.Handle(500, "GetOauthByUserId", err)
  296. return
  297. }
  298. ctx.Data["Socials"] = socials
  299. ctx.HTML(200, SETTINGS_SOCIAL)
  300. }
  301. func SettingsApplications(ctx *middleware.Context) {
  302. ctx.Data["Title"] = ctx.Tr("settings")
  303. ctx.Data["PageIsSettingsApplications"] = true
  304. tokens, err := models.ListAccessTokens(ctx.User.Id)
  305. if err != nil {
  306. ctx.Handle(500, "ListAccessTokens", err)
  307. return
  308. }
  309. ctx.Data["Tokens"] = tokens
  310. ctx.HTML(200, SETTINGS_APPLICATIONS)
  311. }
  312. func SettingsApplicationsPost(ctx *middleware.Context, form auth.NewAccessTokenForm) {
  313. ctx.Data["Title"] = ctx.Tr("settings")
  314. ctx.Data["PageIsSettingsApplications"] = true
  315. if ctx.HasError() {
  316. tokens, err := models.ListAccessTokens(ctx.User.Id)
  317. if err != nil {
  318. ctx.Handle(500, "ListAccessTokens", err)
  319. return
  320. }
  321. ctx.Data["Tokens"] = tokens
  322. ctx.HTML(200, SETTINGS_APPLICATIONS)
  323. return
  324. }
  325. t := &models.AccessToken{
  326. UID: ctx.User.Id,
  327. Name: form.Name,
  328. }
  329. if err := models.NewAccessToken(t); err != nil {
  330. ctx.Handle(500, "NewAccessToken", err)
  331. return
  332. }
  333. ctx.Flash.Success(ctx.Tr("settings.generate_token_succees"))
  334. ctx.Flash.Info(t.Sha1)
  335. ctx.Redirect(setting.AppSubUrl + "/user/settings/applications")
  336. }
  337. func SettingsDeleteApplication(ctx *middleware.Context) {
  338. if err := models.DeleteAccessTokenByID(ctx.QueryInt64("id")); err != nil {
  339. ctx.Flash.Error("DeleteAccessTokenByID: " + err.Error())
  340. } else {
  341. ctx.Flash.Success(ctx.Tr("settings.delete_token_success"))
  342. }
  343. ctx.JSON(200, map[string]interface{}{
  344. "redirect": setting.AppSubUrl + "/user/settings/applications",
  345. })
  346. }
  347. func SettingsDelete(ctx *middleware.Context) {
  348. ctx.Data["Title"] = ctx.Tr("settings")
  349. ctx.Data["PageIsSettingsDelete"] = true
  350. if ctx.Req.Method == "POST" {
  351. if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil {
  352. if models.IsErrUserNotExist(err) {
  353. ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), SETTINGS_DELETE, nil)
  354. } else {
  355. ctx.Handle(500, "UserSignIn", err)
  356. }
  357. return
  358. }
  359. if err := models.DeleteUser(ctx.User); err != nil {
  360. switch {
  361. case models.IsErrUserOwnRepos(err):
  362. ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
  363. ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
  364. case models.IsErrUserHasOrgs(err):
  365. ctx.Flash.Error(ctx.Tr("form.still_has_org"))
  366. ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
  367. default:
  368. ctx.Handle(500, "DeleteUser", err)
  369. }
  370. } else {
  371. log.Trace("Account deleted: %s", ctx.User.Name)
  372. ctx.Redirect(setting.AppSubUrl + "/")
  373. }
  374. return
  375. }
  376. ctx.HTML(200, SETTINGS_DELETE)
  377. }