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

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
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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  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["PageIsSettingsProfile"] = true
  31. ctx.HTML(200, SETTINGS_PROFILE)
  32. }
  33. func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
  34. ctx.Data["Title"] = ctx.Tr("settings")
  35. ctx.Data["PageIsSettingsProfile"] = true
  36. if ctx.HasError() {
  37. ctx.HTML(200, SETTINGS_PROFILE)
  38. return
  39. }
  40. // Check if user name has been changed.
  41. if ctx.User.Name != form.UserName {
  42. if err := models.ChangeUserName(ctx.User, form.UserName); err != nil {
  43. switch {
  44. case models.IsErrUserAlreadyExist(err):
  45. ctx.Flash.Error(ctx.Tr("form.username_been_taken"))
  46. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  47. case models.IsErrEmailAlreadyUsed(err):
  48. ctx.Flash.Error(ctx.Tr("form.email_been_used"))
  49. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  50. case models.IsErrNameReserved(err):
  51. ctx.Flash.Error(ctx.Tr("user.form.name_reserved"))
  52. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  53. case models.IsErrNamePatternNotAllowed(err):
  54. ctx.Flash.Error(ctx.Tr("user.form.name_pattern_not_allowed"))
  55. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  56. default:
  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["PageIsSettingsEmails"] = true
  117. emails, err := models.GetEmailAddresses(ctx.User.Id)
  118. if err != nil {
  119. ctx.Handle(500, "GetEmailAddresses", err)
  120. return
  121. }
  122. ctx.Data["Emails"] = emails
  123. ctx.HTML(200, SETTINGS_EMAILS)
  124. }
  125. func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
  126. ctx.Data["Title"] = ctx.Tr("settings")
  127. ctx.Data["PageIsSettingsEmails"] = true
  128. emails, err := models.GetEmailAddresses(ctx.User.Id)
  129. if err != nil {
  130. ctx.Handle(500, "GetEmailAddresses", err)
  131. return
  132. }
  133. ctx.Data["Emails"] = emails
  134. // Delete E-mail address.
  135. if ctx.Query("_method") == "DELETE" {
  136. id := ctx.QueryInt64("id")
  137. if id <= 0 {
  138. return
  139. }
  140. if err = models.DeleteEmailAddress(&models.EmailAddress{Id: id}); err != nil {
  141. ctx.Handle(500, "DeleteEmail", err)
  142. } else {
  143. log.Trace("Email address deleted: %s", ctx.User.Name)
  144. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  145. }
  146. return
  147. }
  148. // Make emailaddress primary.
  149. if ctx.Query("_method") == "PRIMARY" {
  150. id := ctx.QueryInt64("id")
  151. if id <= 0 {
  152. return
  153. }
  154. if err = models.MakeEmailPrimary(&models.EmailAddress{Id: id}); err != nil {
  155. ctx.Handle(500, "MakeEmailPrimary", err)
  156. } else {
  157. log.Trace("Email made primary: %s", ctx.User.Name)
  158. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  159. }
  160. return
  161. }
  162. // Add Email address.
  163. if ctx.HasError() {
  164. ctx.HTML(200, SETTINGS_EMAILS)
  165. return
  166. }
  167. cleanEmail := strings.Replace(form.Email, "\n", "", -1)
  168. e := &models.EmailAddress{
  169. Uid: ctx.User.Id,
  170. Email: cleanEmail,
  171. IsActivated: !setting.Service.RegisterEmailConfirm,
  172. }
  173. if err := models.AddEmailAddress(e); err != nil {
  174. if models.IsErrEmailAlreadyUsed(err) {
  175. ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SETTINGS_EMAILS, &form)
  176. return
  177. }
  178. ctx.Handle(500, "AddEmailAddress", err)
  179. return
  180. } else {
  181. // Send confirmation e-mail
  182. if setting.Service.RegisterEmailConfirm {
  183. mailer.SendActivateEmail(ctx.Render, ctx.User, e)
  184. if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
  185. log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
  186. }
  187. ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", cleanEmail, setting.Service.ActiveCodeLives/60))
  188. } else {
  189. ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
  190. }
  191. log.Trace("Email address added: %s", e.Email)
  192. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  193. return
  194. }
  195. ctx.HTML(200, SETTINGS_EMAILS)
  196. }
  197. func SettingsPassword(ctx *middleware.Context) {
  198. ctx.Data["Title"] = ctx.Tr("settings")
  199. ctx.Data["PageIsSettingsPassword"] = true
  200. ctx.HTML(200, SETTINGS_PASSWORD)
  201. }
  202. func SettingsPasswordPost(ctx *middleware.Context, form auth.ChangePasswordForm) {
  203. ctx.Data["Title"] = ctx.Tr("settings")
  204. ctx.Data["PageIsSettingsPassword"] = true
  205. if ctx.HasError() {
  206. ctx.HTML(200, SETTINGS_PASSWORD)
  207. return
  208. }
  209. tmpUser := &models.User{
  210. Passwd: form.OldPassword,
  211. Salt: ctx.User.Salt,
  212. }
  213. tmpUser.EncodePasswd()
  214. if ctx.User.Passwd != tmpUser.Passwd {
  215. ctx.Flash.Error(ctx.Tr("settings.password_incorrect"))
  216. } else if form.Password != form.Retype {
  217. ctx.Flash.Error(ctx.Tr("form.password_not_match"))
  218. } else {
  219. ctx.User.Passwd = form.Password
  220. ctx.User.Salt = models.GetUserSalt()
  221. ctx.User.EncodePasswd()
  222. if err := models.UpdateUser(ctx.User); err != nil {
  223. ctx.Handle(500, "UpdateUser", err)
  224. return
  225. }
  226. log.Trace("User password updated: %s", ctx.User.Name)
  227. ctx.Flash.Success(ctx.Tr("settings.change_password_success"))
  228. }
  229. ctx.Redirect(setting.AppSubUrl + "/user/settings/password")
  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 err == models.ErrKeyUnableVerify {
  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.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 SettingsSocial(ctx *middleware.Context) {
  293. ctx.Data["Title"] = ctx.Tr("settings")
  294. ctx.Data["PageIsSettingsSocial"] = true
  295. // Unbind social account.
  296. remove, _ := com.StrTo(ctx.Query("remove")).Int64()
  297. if remove > 0 {
  298. if err := models.DeleteOauth2ById(remove); err != nil {
  299. ctx.Handle(500, "DeleteOauth2ById", err)
  300. return
  301. }
  302. ctx.Flash.Success(ctx.Tr("settings.unbind_success"))
  303. ctx.Redirect(setting.AppSubUrl + "/user/settings/social")
  304. return
  305. }
  306. socials, err := models.GetOauthByUserId(ctx.User.Id)
  307. if err != nil {
  308. ctx.Handle(500, "GetOauthByUserId", err)
  309. return
  310. }
  311. ctx.Data["Socials"] = socials
  312. ctx.HTML(200, SETTINGS_SOCIAL)
  313. }
  314. func SettingsApplications(ctx *middleware.Context) {
  315. ctx.Data["Title"] = ctx.Tr("settings")
  316. ctx.Data["PageIsSettingsApplications"] = true
  317. tokens, err := models.ListAccessTokens(ctx.User.Id)
  318. if err != nil {
  319. ctx.Handle(500, "ListAccessTokens", err)
  320. return
  321. }
  322. ctx.Data["Tokens"] = tokens
  323. ctx.HTML(200, SETTINGS_APPLICATIONS)
  324. }
  325. func SettingsApplicationsPost(ctx *middleware.Context, form auth.NewAccessTokenForm) {
  326. ctx.Data["Title"] = ctx.Tr("settings")
  327. ctx.Data["PageIsSettingsApplications"] = true
  328. if ctx.HasError() {
  329. tokens, err := models.ListAccessTokens(ctx.User.Id)
  330. if err != nil {
  331. ctx.Handle(500, "ListAccessTokens", err)
  332. return
  333. }
  334. ctx.Data["Tokens"] = tokens
  335. ctx.HTML(200, SETTINGS_APPLICATIONS)
  336. return
  337. }
  338. t := &models.AccessToken{
  339. UID: ctx.User.Id,
  340. Name: form.Name,
  341. }
  342. if err := models.NewAccessToken(t); err != nil {
  343. ctx.Handle(500, "NewAccessToken", err)
  344. return
  345. }
  346. ctx.Flash.Success(ctx.Tr("settings.generate_token_succees"))
  347. ctx.Flash.Info(t.Sha1)
  348. ctx.Redirect(setting.AppSubUrl + "/user/settings/applications")
  349. }
  350. func SettingsDeleteApplication(ctx *middleware.Context) {
  351. if err := models.DeleteAccessTokenByID(ctx.QueryInt64("id")); err != nil {
  352. ctx.Flash.Error("DeleteAccessTokenByID: " + err.Error())
  353. } else {
  354. ctx.Flash.Success(ctx.Tr("settings.delete_token_success"))
  355. }
  356. ctx.JSON(200, map[string]interface{}{
  357. "redirect": setting.AppSubUrl + "/user/settings/applications",
  358. })
  359. }
  360. func SettingsDelete(ctx *middleware.Context) {
  361. ctx.Data["Title"] = ctx.Tr("settings")
  362. ctx.Data["PageIsSettingsDelete"] = true
  363. if ctx.Req.Method == "POST" {
  364. if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil {
  365. if models.IsErrUserNotExist(err) {
  366. ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), SETTINGS_DELETE, nil)
  367. } else {
  368. ctx.Handle(500, "UserSignIn", err)
  369. }
  370. return
  371. }
  372. if err := models.DeleteUser(ctx.User); err != nil {
  373. switch {
  374. case models.IsErrUserOwnRepos(err):
  375. ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
  376. ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
  377. case models.IsErrUserHasOrgs(err):
  378. ctx.Flash.Error(ctx.Tr("form.still_has_org"))
  379. ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
  380. default:
  381. ctx.Handle(500, "DeleteUser", err)
  382. }
  383. } else {
  384. log.Trace("Account deleted: %s", ctx.User.Name)
  385. ctx.Redirect(setting.AppSubUrl + "/")
  386. }
  387. return
  388. }
  389. ctx.HTML(200, SETTINGS_DELETE)
  390. }