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

setting.go 13 kB

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