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.

setting.go 13KB

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
9 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
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
8 years ago
9 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  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. if err := models.ChangeUserName(ctx.User, form.UserName); err != nil {
  45. switch {
  46. case models.IsErrUserAlreadyExist(err):
  47. ctx.Flash.Error(ctx.Tr("form.username_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.UserName)
  64. ctx.User.Name = form.UserName
  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.Avatar)
  71. ctx.User.AvatarEmail = form.Avatar
  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 SettingsAvatar(ctx *middleware.Context, form auth.UploadAvatarForm) {
  82. defer ctx.Redirect(setting.AppSubUrl + "/user/settings")
  83. ctx.User.UseCustomAvatar = form.Enable
  84. if form.Avatar != nil {
  85. fr, err := form.Avatar.Open()
  86. if err != nil {
  87. ctx.Flash.Error(err.Error())
  88. return
  89. }
  90. data, err := ioutil.ReadAll(fr)
  91. if err != nil {
  92. ctx.Flash.Error(err.Error())
  93. return
  94. }
  95. if _, ok := base.IsImageFile(data); !ok {
  96. ctx.Flash.Error(ctx.Tr("settings.uploaded_avatar_not_a_image"))
  97. return
  98. }
  99. if err = ctx.User.UploadAvatar(data); err != nil {
  100. ctx.Flash.Error(err.Error())
  101. return
  102. }
  103. } else {
  104. // In case no avatar at all.
  105. if form.Enable && !com.IsFile(ctx.User.CustomAvatarPath()) {
  106. ctx.Flash.Error(ctx.Tr("settings.no_custom_avatar_available"))
  107. return
  108. }
  109. }
  110. if err := models.UpdateUser(ctx.User); err != nil {
  111. ctx.Flash.Error(err.Error())
  112. return
  113. }
  114. ctx.Flash.Success(ctx.Tr("settings.update_avatar_success"))
  115. }
  116. func SettingsEmails(ctx *middleware.Context) {
  117. ctx.Data["Title"] = ctx.Tr("settings")
  118. ctx.Data["PageIsUserSettings"] = true
  119. ctx.Data["PageIsSettingsEmails"] = true
  120. emails, err := models.GetEmailAddresses(ctx.User.Id)
  121. if err != nil {
  122. ctx.Handle(500, "GetEmailAddresses", err)
  123. return
  124. }
  125. ctx.Data["Emails"] = emails
  126. ctx.HTML(200, SETTINGS_EMAILS)
  127. }
  128. func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
  129. ctx.Data["Title"] = ctx.Tr("settings")
  130. ctx.Data["PageIsUserSettings"] = true
  131. ctx.Data["PageIsSettingsEmails"] = true
  132. emails, err := models.GetEmailAddresses(ctx.User.Id)
  133. if err != nil {
  134. ctx.Handle(500, "GetEmailAddresses", err)
  135. return
  136. }
  137. ctx.Data["Emails"] = emails
  138. // Delete E-mail address.
  139. if ctx.Query("_method") == "DELETE" {
  140. id := ctx.QueryInt64("id")
  141. if id <= 0 {
  142. return
  143. }
  144. if err = models.DeleteEmailAddress(&models.EmailAddress{Id: id}); err != nil {
  145. ctx.Handle(500, "DeleteEmail", err)
  146. } else {
  147. log.Trace("Email address deleted: %s", ctx.User.Name)
  148. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  149. }
  150. return
  151. }
  152. // Make emailaddress primary.
  153. if ctx.Query("_method") == "PRIMARY" {
  154. id := ctx.QueryInt64("id")
  155. if id <= 0 {
  156. return
  157. }
  158. if err = models.MakeEmailPrimary(&models.EmailAddress{Id: id}); err != nil {
  159. ctx.Handle(500, "MakeEmailPrimary", err)
  160. } else {
  161. log.Trace("Email made primary: %s", ctx.User.Name)
  162. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  163. }
  164. return
  165. }
  166. // Add Email address.
  167. if ctx.HasError() {
  168. ctx.HTML(200, SETTINGS_EMAILS)
  169. return
  170. }
  171. cleanEmail := strings.Replace(form.Email, "\n", "", -1)
  172. e := &models.EmailAddress{
  173. Uid: ctx.User.Id,
  174. Email: cleanEmail,
  175. IsActivated: !setting.Service.RegisterEmailConfirm,
  176. }
  177. if err := models.AddEmailAddress(e); err != nil {
  178. if models.IsErrEmailAlreadyUsed(err) {
  179. ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SETTINGS_EMAILS, &form)
  180. return
  181. }
  182. ctx.Handle(500, "AddEmailAddress", err)
  183. return
  184. } else {
  185. // Send confirmation e-mail
  186. if setting.Service.RegisterEmailConfirm {
  187. mailer.SendActivateEmail(ctx.Render, ctx.User, e)
  188. if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
  189. log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
  190. }
  191. ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", cleanEmail, setting.Service.ActiveCodeLives/60))
  192. } else {
  193. ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
  194. }
  195. log.Trace("Email address added: %s", e.Email)
  196. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  197. return
  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. content, err := models.CheckPublicKeyString(form.Content)
  280. if err != nil {
  281. if err == models.ErrKeyUnableVerify {
  282. ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key"))
  283. } else {
  284. ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error()))
  285. ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
  286. return
  287. }
  288. }
  289. if err = models.AddPublicKey(ctx.User.Id, form.Title, content); err != nil {
  290. switch {
  291. case models.IsErrKeyAlreadyExist(err):
  292. ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), SETTINGS_SSH_KEYS, &form)
  293. case models.IsErrKeyNameAlreadyUsed(err):
  294. ctx.RenderWithErr(ctx.Tr("settings.ssh_key_name_used"), SETTINGS_SSH_KEYS, &form)
  295. default:
  296. ctx.Handle(500, "AddPublicKey", err)
  297. }
  298. return
  299. } else {
  300. log.Trace("SSH key added: %s", ctx.User.Name)
  301. ctx.Flash.Success(ctx.Tr("settings.add_key_success", form.Title))
  302. ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
  303. return
  304. }
  305. }
  306. ctx.HTML(200, SETTINGS_SSH_KEYS)
  307. }
  308. func SettingsSocial(ctx *middleware.Context) {
  309. ctx.Data["Title"] = ctx.Tr("settings")
  310. ctx.Data["PageIsUserSettings"] = true
  311. ctx.Data["PageIsSettingsSocial"] = true
  312. // Unbind social account.
  313. remove, _ := com.StrTo(ctx.Query("remove")).Int64()
  314. if remove > 0 {
  315. if err := models.DeleteOauth2ById(remove); err != nil {
  316. ctx.Handle(500, "DeleteOauth2ById", err)
  317. return
  318. }
  319. ctx.Flash.Success(ctx.Tr("settings.unbind_success"))
  320. ctx.Redirect(setting.AppSubUrl + "/user/settings/social")
  321. return
  322. }
  323. socials, err := models.GetOauthByUserId(ctx.User.Id)
  324. if err != nil {
  325. ctx.Handle(500, "GetOauthByUserId", err)
  326. return
  327. }
  328. ctx.Data["Socials"] = socials
  329. ctx.HTML(200, SETTINGS_SOCIAL)
  330. }
  331. func SettingsApplications(ctx *middleware.Context) {
  332. ctx.Data["Title"] = ctx.Tr("settings")
  333. ctx.Data["PageIsUserSettings"] = true
  334. ctx.Data["PageIsSettingsApplications"] = true
  335. // Delete access token.
  336. remove, _ := com.StrTo(ctx.Query("remove")).Int64()
  337. if remove > 0 {
  338. if err := models.DeleteAccessTokenById(remove); err != nil {
  339. ctx.Handle(500, "DeleteAccessTokenById", err)
  340. return
  341. }
  342. ctx.Flash.Success(ctx.Tr("settings.delete_token_success"))
  343. ctx.Redirect(setting.AppSubUrl + "/user/settings/applications")
  344. return
  345. }
  346. tokens, err := models.ListAccessTokens(ctx.User.Id)
  347. if err != nil {
  348. ctx.Handle(500, "ListAccessTokens", err)
  349. return
  350. }
  351. ctx.Data["Tokens"] = tokens
  352. ctx.HTML(200, SETTINGS_APPLICATIONS)
  353. }
  354. // FIXME: split to two different functions and pages to handle access token and oauth2
  355. func SettingsApplicationsPost(ctx *middleware.Context, form auth.NewAccessTokenForm) {
  356. ctx.Data["Title"] = ctx.Tr("settings")
  357. ctx.Data["PageIsUserSettings"] = true
  358. ctx.Data["PageIsSettingsApplications"] = true
  359. switch ctx.Query("type") {
  360. case "token":
  361. if ctx.HasError() {
  362. ctx.HTML(200, SETTINGS_APPLICATIONS)
  363. return
  364. }
  365. t := &models.AccessToken{
  366. UID: ctx.User.Id,
  367. Name: form.Name,
  368. }
  369. if err := models.NewAccessToken(t); err != nil {
  370. ctx.Handle(500, "NewAccessToken", err)
  371. return
  372. }
  373. ctx.Flash.Success(ctx.Tr("settings.generate_token_succees"))
  374. ctx.Flash.Info(t.Sha1)
  375. }
  376. ctx.Redirect(setting.AppSubUrl + "/user/settings/applications")
  377. }
  378. func SettingsDelete(ctx *middleware.Context) {
  379. ctx.Data["Title"] = ctx.Tr("settings")
  380. ctx.Data["PageIsUserSettings"] = true
  381. ctx.Data["PageIsSettingsDelete"] = true
  382. if ctx.Req.Method == "POST" {
  383. // FIXME: validate password.
  384. if err := models.DeleteUser(ctx.User); err != nil {
  385. switch {
  386. case models.IsErrUserOwnRepos(err):
  387. ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
  388. ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
  389. case models.IsErrUserHasOrgs(err):
  390. ctx.Flash.Error(ctx.Tr("form.still_has_org"))
  391. ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
  392. default:
  393. ctx.Handle(500, "DeleteUser", err)
  394. }
  395. } else {
  396. log.Trace("Account deleted: %s", ctx.User.Name)
  397. ctx.Redirect(setting.AppSubUrl + "/")
  398. }
  399. return
  400. }
  401. ctx.HTML(200, SETTINGS_DELETE)
  402. }