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.

431 lines
12 KiB

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