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.

479 lines
13 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
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. "io/ioutil"
  7. "strings"
  8. "github.com/Unknwon/com"
  9. "github.com/gogits/gogs/models"
  10. "github.com/gogits/gogs/modules/auth"
  11. "github.com/gogits/gogs/modules/base"
  12. "github.com/gogits/gogs/modules/log"
  13. "github.com/gogits/gogs/modules/mailer"
  14. "github.com/gogits/gogs/modules/middleware"
  15. "github.com/gogits/gogs/modules/setting"
  16. )
  17. const (
  18. SETTINGS_PROFILE base.TplName = "user/settings/profile"
  19. SETTINGS_PASSWORD base.TplName = "user/settings/password"
  20. SETTINGS_EMAILS base.TplName = "user/settings/email"
  21. SETTINGS_SSH_KEYS base.TplName = "user/settings/sshkeys"
  22. SETTINGS_SOCIAL base.TplName = "user/settings/social"
  23. SETTINGS_APPLICATIONS base.TplName = "user/settings/applications"
  24. SETTINGS_DELETE base.TplName = "user/settings/delete"
  25. NOTIFICATION base.TplName = "user/notification"
  26. SECURITY base.TplName = "user/security"
  27. )
  28. func Settings(ctx *middleware.Context) {
  29. ctx.Data["Title"] = ctx.Tr("settings")
  30. ctx.Data["PageIsUserSettings"] = true
  31. ctx.Data["PageIsSettingsProfile"] = true
  32. ctx.HTML(200, SETTINGS_PROFILE)
  33. }
  34. func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
  35. ctx.Data["Title"] = ctx.Tr("settings")
  36. ctx.Data["PageIsUserSettings"] = true
  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.UserName {
  44. isExist, err := models.IsUserExist(form.UserName)
  45. if err != nil {
  46. ctx.Handle(500, "IsUserExist", err)
  47. return
  48. } else if isExist {
  49. ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), SETTINGS_PROFILE, &form)
  50. return
  51. } else if err = models.ChangeUserName(ctx.User, form.UserName); err != nil {
  52. if err == models.ErrUserNameIllegal {
  53. ctx.Flash.Error(ctx.Tr("form.illegal_username"))
  54. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  55. return
  56. } else {
  57. ctx.Handle(500, "ChangeUserName", err)
  58. }
  59. return
  60. }
  61. log.Trace("User name changed: %s -> %s", ctx.User.Name, form.UserName)
  62. ctx.User.Name = form.UserName
  63. }
  64. ctx.User.FullName = form.FullName
  65. ctx.User.Email = form.Email
  66. ctx.User.Website = form.Website
  67. ctx.User.Location = form.Location
  68. ctx.User.Avatar = base.EncodeMd5(form.Avatar)
  69. ctx.User.AvatarEmail = form.Avatar
  70. if err := models.UpdateUser(ctx.User); err != nil {
  71. ctx.Handle(500, "UpdateUser", err)
  72. return
  73. }
  74. log.Trace("User setting updated: %s", ctx.User.Name)
  75. ctx.Flash.Success(ctx.Tr("settings.update_profile_success"))
  76. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  77. }
  78. // FIXME: limit size.
  79. func SettingsAvatar(ctx *middleware.Context, form auth.UploadAvatarForm) {
  80. defer ctx.Redirect(setting.AppSubUrl + "/user/settings")
  81. ctx.User.UseCustomAvatar = form.Enable
  82. if form.Avatar != nil {
  83. fr, err := form.Avatar.Open()
  84. if err != nil {
  85. ctx.Flash.Error(err.Error())
  86. return
  87. }
  88. data, err := ioutil.ReadAll(fr)
  89. if err != nil {
  90. ctx.Flash.Error(err.Error())
  91. return
  92. }
  93. if _, ok := base.IsImageFile(data); !ok {
  94. ctx.Flash.Error(ctx.Tr("settings.uploaded_avatar_not_a_image"))
  95. return
  96. }
  97. if err = ctx.User.UploadAvatar(data); err != nil {
  98. ctx.Flash.Error(err.Error())
  99. return
  100. }
  101. } else {
  102. // In case no avatar at all.
  103. if form.Enable && !com.IsFile(ctx.User.CustomAvatarPath()) {
  104. ctx.Flash.Error(ctx.Tr("settings.no_custom_avatar_available"))
  105. return
  106. }
  107. }
  108. if err := models.UpdateUser(ctx.User); err != nil {
  109. ctx.Flash.Error(err.Error())
  110. return
  111. }
  112. ctx.Flash.Success(ctx.Tr("settings.update_avatar_success"))
  113. }
  114. func SettingsEmails(ctx *middleware.Context) {
  115. ctx.Data["Title"] = ctx.Tr("settings")
  116. ctx.Data["PageIsUserSettings"] = true
  117. ctx.Data["PageIsSettingsEmails"] = true
  118. var err error
  119. ctx.Data["Emails"], err = models.GetEmailAddresses(ctx.User.Id)
  120. if err != nil {
  121. ctx.Handle(500, "email.GetEmailAddresses", err)
  122. return
  123. }
  124. ctx.HTML(200, SETTINGS_EMAILS)
  125. }
  126. func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
  127. ctx.Data["Title"] = ctx.Tr("settings")
  128. ctx.Data["PageIsUserSettings"] = true
  129. ctx.Data["PageIsSettingsEmails"] = true
  130. var err error
  131. ctx.Data["Emails"], err = models.GetEmailAddresses(ctx.User.Id)
  132. if err != nil {
  133. ctx.Handle(500, "email.GetEmailAddresses", err)
  134. return
  135. }
  136. // Delete Email address.
  137. if ctx.Query("_method") == "DELETE" {
  138. id := com.StrTo(ctx.Query("id")).MustInt64()
  139. if id <= 0 {
  140. return
  141. }
  142. if err = models.DeleteEmailAddress(&models.EmailAddress{Id: id}); err != nil {
  143. ctx.Handle(500, "DeleteEmail", err)
  144. } else {
  145. log.Trace("Email address deleted: %s", ctx.User.Name)
  146. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  147. }
  148. return
  149. }
  150. // Make emailaddress primary.
  151. if ctx.Query("_method") == "PRIMARY" {
  152. id := com.StrTo(ctx.Query("id")).MustInt64()
  153. if id <= 0 {
  154. return
  155. }
  156. if err = models.MakeEmailPrimary(&models.EmailAddress{Id: id}); err != nil {
  157. ctx.Handle(500, "MakeEmailPrimary", err)
  158. } else {
  159. log.Trace("Email made primary: %s", ctx.User.Name)
  160. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  161. }
  162. return
  163. }
  164. // Add Email address.
  165. if ctx.Req.Method == "POST" {
  166. if ctx.HasError() {
  167. ctx.HTML(200, SETTINGS_EMAILS)
  168. return
  169. }
  170. cleanEmail := strings.Replace(form.Email, "\n", "", -1)
  171. e := &models.EmailAddress{
  172. Uid: ctx.User.Id,
  173. Email: cleanEmail,
  174. IsActivated: !setting.Service.RegisterEmailConfirm,
  175. }
  176. if err := models.AddEmailAddress(e); err != nil {
  177. if err == models.ErrEmailAlreadyUsed {
  178. ctx.RenderWithErr(ctx.Tr("form.email_has_been_used"), SETTINGS_EMAILS, &form)
  179. return
  180. }
  181. ctx.Handle(500, "email.AddEmailAddress", err)
  182. return
  183. } else {
  184. // Send confirmation e-mail
  185. if setting.Service.RegisterEmailConfirm {
  186. mailer.SendActivateEmail(ctx.Render, ctx.User, e)
  187. if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
  188. log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
  189. }
  190. ctx.Flash.Success(ctx.Tr("settings.add_email_success_confirmation_email_sent"))
  191. } else {
  192. ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
  193. }
  194. log.Trace("Email address added: %s", e.Email)
  195. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  196. return
  197. }
  198. }
  199. ctx.HTML(200, SETTINGS_EMAILS)
  200. }
  201. func SettingsPassword(ctx *middleware.Context) {
  202. ctx.Data["Title"] = ctx.Tr("settings")
  203. ctx.Data["PageIsUserSettings"] = true
  204. ctx.Data["PageIsSettingsPassword"] = true
  205. ctx.HTML(200, SETTINGS_PASSWORD)
  206. }
  207. func SettingsPasswordPost(ctx *middleware.Context, form auth.ChangePasswordForm) {
  208. ctx.Data["Title"] = ctx.Tr("settings")
  209. ctx.Data["PageIsUserSettings"] = true
  210. ctx.Data["PageIsSettingsPassword"] = true
  211. if ctx.HasError() {
  212. ctx.HTML(200, SETTINGS_PASSWORD)
  213. return
  214. }
  215. tmpUser := &models.User{
  216. Passwd: form.OldPassword,
  217. Salt: ctx.User.Salt,
  218. }
  219. tmpUser.EncodePasswd()
  220. if ctx.User.Passwd != tmpUser.Passwd {
  221. ctx.Flash.Error(ctx.Tr("settings.password_incorrect"))
  222. } else if form.Password != form.Retype {
  223. ctx.Flash.Error(ctx.Tr("form.password_not_match"))
  224. } else {
  225. ctx.User.Passwd = form.Password
  226. ctx.User.Salt = models.GetUserSalt()
  227. ctx.User.EncodePasswd()
  228. if err := models.UpdateUser(ctx.User); err != nil {
  229. ctx.Handle(500, "UpdateUser", err)
  230. return
  231. }
  232. log.Trace("User password updated: %s", ctx.User.Name)
  233. ctx.Flash.Success(ctx.Tr("settings.change_password_success"))
  234. }
  235. ctx.Redirect(setting.AppSubUrl + "/user/settings/password")
  236. }
  237. func SettingsSSHKeys(ctx *middleware.Context) {
  238. ctx.Data["Title"] = ctx.Tr("settings")
  239. ctx.Data["PageIsUserSettings"] = true
  240. ctx.Data["PageIsSettingsSSHKeys"] = true
  241. var err error
  242. ctx.Data["Keys"], err = models.ListPublicKeys(ctx.User.Id)
  243. if err != nil {
  244. ctx.Handle(500, "ssh.ListPublicKey", err)
  245. return
  246. }
  247. ctx.HTML(200, SETTINGS_SSH_KEYS)
  248. }
  249. func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
  250. ctx.Data["Title"] = ctx.Tr("settings")
  251. ctx.Data["PageIsUserSettings"] = true
  252. ctx.Data["PageIsSettingsSSHKeys"] = true
  253. var err error
  254. ctx.Data["Keys"], err = models.ListPublicKeys(ctx.User.Id)
  255. if err != nil {
  256. ctx.Handle(500, "ssh.ListPublicKey", err)
  257. return
  258. }
  259. // Delete SSH key.
  260. if ctx.Query("_method") == "DELETE" {
  261. id := com.StrTo(ctx.Query("id")).MustInt64()
  262. if id <= 0 {
  263. return
  264. }
  265. if err = models.DeletePublicKey(&models.PublicKey{Id: id}); err != nil {
  266. ctx.Handle(500, "DeletePublicKey", err)
  267. } else {
  268. log.Trace("SSH key deleted: %s", ctx.User.Name)
  269. ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
  270. }
  271. return
  272. }
  273. // Add new SSH key.
  274. if ctx.Req.Method == "POST" {
  275. if ctx.HasError() {
  276. ctx.HTML(200, SETTINGS_SSH_KEYS)
  277. return
  278. }
  279. // Remove newline characters from form.KeyContent
  280. cleanContent := strings.Replace(form.Content, "\n", "", -1)
  281. if ok, err := models.CheckPublicKeyString(cleanContent); !ok {
  282. if err == models.ErrKeyUnableVerify {
  283. ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key"))
  284. } else {
  285. ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error()))
  286. ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
  287. return
  288. }
  289. }
  290. k := &models.PublicKey{
  291. OwnerId: ctx.User.Id,
  292. Name: form.SSHTitle,
  293. Content: cleanContent,
  294. }
  295. if err := models.AddPublicKey(k); err != nil {
  296. if err == models.ErrKeyAlreadyExist {
  297. ctx.RenderWithErr(ctx.Tr("form.ssh_key_been_used"), SETTINGS_SSH_KEYS, &form)
  298. return
  299. }
  300. ctx.Handle(500, "ssh.AddPublicKey", err)
  301. return
  302. } else {
  303. log.Trace("SSH key added: %s", ctx.User.Name)
  304. ctx.Flash.Success(ctx.Tr("settings.add_key_success"))
  305. ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
  306. return
  307. }
  308. }
  309. ctx.HTML(200, SETTINGS_SSH_KEYS)
  310. }
  311. func SettingsSocial(ctx *middleware.Context) {
  312. ctx.Data["Title"] = ctx.Tr("settings")
  313. ctx.Data["PageIsUserSettings"] = true
  314. ctx.Data["PageIsSettingsSocial"] = true
  315. // Unbind social account.
  316. remove, _ := com.StrTo(ctx.Query("remove")).Int64()
  317. if remove > 0 {
  318. if err := models.DeleteOauth2ById(remove); err != nil {
  319. ctx.Handle(500, "DeleteOauth2ById", err)
  320. return
  321. }
  322. ctx.Flash.Success(ctx.Tr("settings.unbind_success"))
  323. ctx.Redirect(setting.AppSubUrl + "/user/settings/social")
  324. return
  325. }
  326. socials, err := models.GetOauthByUserId(ctx.User.Id)
  327. if err != nil {
  328. ctx.Handle(500, "GetOauthByUserId", err)
  329. return
  330. }
  331. ctx.Data["Socials"] = socials
  332. ctx.HTML(200, SETTINGS_SOCIAL)
  333. }
  334. func SettingsApplications(ctx *middleware.Context) {
  335. ctx.Data["Title"] = ctx.Tr("settings")
  336. ctx.Data["PageIsUserSettings"] = true
  337. ctx.Data["PageIsSettingsApplications"] = true
  338. // Delete access token.
  339. remove, _ := com.StrTo(ctx.Query("remove")).Int64()
  340. if remove > 0 {
  341. if err := models.DeleteAccessTokenById(remove); err != nil {
  342. ctx.Handle(500, "DeleteAccessTokenById", err)
  343. return
  344. }
  345. ctx.Flash.Success(ctx.Tr("settings.delete_token_success"))
  346. ctx.Redirect(setting.AppSubUrl + "/user/settings/applications")
  347. return
  348. }
  349. tokens, err := models.ListAccessTokens(ctx.User.Id)
  350. if err != nil {
  351. ctx.Handle(500, "ListAccessTokens", err)
  352. return
  353. }
  354. ctx.Data["Tokens"] = tokens
  355. ctx.HTML(200, SETTINGS_APPLICATIONS)
  356. }
  357. // FIXME: split to two different functions and pages to handle access token and oauth2
  358. func SettingsApplicationsPost(ctx *middleware.Context, form auth.NewAccessTokenForm) {
  359. ctx.Data["Title"] = ctx.Tr("settings")
  360. ctx.Data["PageIsUserSettings"] = true
  361. ctx.Data["PageIsSettingsApplications"] = true
  362. switch ctx.Query("type") {
  363. case "token":
  364. if ctx.HasError() {
  365. ctx.HTML(200, SETTINGS_APPLICATIONS)
  366. return
  367. }
  368. t := &models.AccessToken{
  369. Uid: ctx.User.Id,
  370. Name: form.Name,
  371. }
  372. if err := models.NewAccessToken(t); err != nil {
  373. ctx.Handle(500, "NewAccessToken", err)
  374. return
  375. }
  376. ctx.Flash.Success(ctx.Tr("settings.generate_token_succees"))
  377. ctx.Flash.Info(t.Sha1)
  378. }
  379. ctx.Redirect(setting.AppSubUrl + "/user/settings/applications")
  380. }
  381. func SettingsDelete(ctx *middleware.Context) {
  382. ctx.Data["Title"] = ctx.Tr("settings")
  383. ctx.Data["PageIsUserSettings"] = true
  384. ctx.Data["PageIsSettingsDelete"] = true
  385. if ctx.Req.Method == "POST" {
  386. // tmpUser := models.User{
  387. // Passwd: ctx.Query("password"),
  388. // Salt: ctx.User.Salt,
  389. // }
  390. // tmpUser.EncodePasswd()
  391. // if tmpUser.Passwd != ctx.User.Passwd {
  392. // ctx.Flash.Error("Password is not correct. Make sure you are owner of this account.")
  393. // } else {
  394. if err := models.DeleteUser(ctx.User); err != nil {
  395. switch err {
  396. case models.ErrUserOwnRepos:
  397. ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
  398. ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
  399. case models.ErrUserHasOrgs:
  400. ctx.Flash.Error(ctx.Tr("form.still_has_org"))
  401. ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
  402. default:
  403. ctx.Handle(500, "DeleteUser", err)
  404. }
  405. } else {
  406. log.Trace("Account deleted: %s", ctx.User.Name)
  407. ctx.Redirect(setting.AppSubUrl + "/")
  408. }
  409. return
  410. }
  411. ctx.HTML(200, SETTINGS_DELETE)
  412. }