setting.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  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 SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
  36. ctx.Data["Title"] = ctx.Tr("settings")
  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.Name {
  44. if err := models.ChangeUserName(ctx.User, form.Name); err != nil {
  45. switch {
  46. case models.IsErrUserAlreadyExist(err):
  47. ctx.Flash.Error(ctx.Tr("form.name_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.Name)
  64. ctx.User.Name = form.Name
  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.Gravatar)
  71. ctx.User.AvatarEmail = form.Gravatar
  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 UpdateAvatarSetting(ctx *middleware.Context, form auth.UploadAvatarForm, ctxUser *models.User) error {
  82. ctxUser.UseCustomAvatar = form.Enable
  83. if form.Avatar != nil {
  84. fr, err := form.Avatar.Open()
  85. if err != nil {
  86. return fmt.Errorf("Avatar.Open: %v", err)
  87. }
  88. data, err := ioutil.ReadAll(fr)
  89. if err != nil {
  90. return fmt.Errorf("ReadAll: %v", err)
  91. }
  92. if _, ok := base.IsImageFile(data); !ok {
  93. return errors.New(ctx.Tr("settings.uploaded_avatar_not_a_image"))
  94. }
  95. if err = ctxUser.UploadAvatar(data); err != nil {
  96. return fmt.Errorf("UploadAvatar: %v", err)
  97. }
  98. } else {
  99. // In case no avatar at all.
  100. if form.Enable && !com.IsFile(ctx.User.CustomAvatarPath()) {
  101. return errors.New(ctx.Tr("settings.no_custom_avatar_available"))
  102. }
  103. }
  104. if err := models.UpdateUser(ctxUser); err != nil {
  105. return fmt.Errorf("UpdateUser: %v", err)
  106. }
  107. return nil
  108. }
  109. func SettingsAvatar(ctx *middleware.Context, form auth.UploadAvatarForm) {
  110. if err := UpdateAvatarSetting(ctx, form, ctx.User); err != nil {
  111. ctx.Flash.Error(err.Error())
  112. } else {
  113. ctx.Flash.Success(ctx.Tr("settings.update_avatar_success"))
  114. }
  115. ctx.Redirect(setting.AppSubUrl + "/user/settings")
  116. }
  117. func SettingsEmails(ctx *middleware.Context) {
  118. ctx.Data["Title"] = ctx.Tr("settings")
  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["PageIsSettingsEmails"] = true
  131. emails, err := models.GetEmailAddresses(ctx.User.Id)
  132. if err != nil {
  133. ctx.Handle(500, "GetEmailAddresses", err)
  134. return
  135. }
  136. ctx.Data["Emails"] = emails
  137. // Delete E-mail address.
  138. if ctx.Query("_method") == "DELETE" {
  139. id := ctx.QueryInt64("id")
  140. if id <= 0 {
  141. return
  142. }
  143. if err = models.DeleteEmailAddress(&models.EmailAddress{Id: id}); err != nil {
  144. ctx.Handle(500, "DeleteEmail", err)
  145. } else {
  146. log.Trace("Email address deleted: %s", ctx.User.Name)
  147. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  148. }
  149. return
  150. }
  151. // Make emailaddress primary.
  152. if ctx.Query("_method") == "PRIMARY" {
  153. id := ctx.QueryInt64("id")
  154. if id <= 0 {
  155. return
  156. }
  157. if err = models.MakeEmailPrimary(&models.EmailAddress{Id: id}); err != nil {
  158. ctx.Handle(500, "MakeEmailPrimary", err)
  159. } else {
  160. log.Trace("Email made primary: %s", ctx.User.Name)
  161. ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
  162. }
  163. return
  164. }
  165. // Add Email address.
  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 models.IsErrEmailAlreadyUsed(err) {
  178. ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SETTINGS_EMAILS, &form)
  179. return
  180. }
  181. ctx.Handle(500, "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.Info(ctx.Tr("settings.add_email_confirmation_sent", cleanEmail, setting.Service.ActiveCodeLives/60))
  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. ctx.HTML(200, SETTINGS_EMAILS)
  199. }
  200. func SettingsPassword(ctx *middleware.Context) {
  201. ctx.Data["Title"] = ctx.Tr("settings")
  202. ctx.Data["PageIsSettingsPassword"] = true
  203. ctx.HTML(200, SETTINGS_PASSWORD)
  204. }
  205. func SettingsPasswordPost(ctx *middleware.Context, form auth.ChangePasswordForm) {
  206. ctx.Data["Title"] = ctx.Tr("settings")
  207. ctx.Data["PageIsSettingsPassword"] = true
  208. if ctx.HasError() {
  209. ctx.HTML(200, SETTINGS_PASSWORD)
  210. return
  211. }
  212. tmpUser := &models.User{
  213. Passwd: form.OldPassword,
  214. Salt: ctx.User.Salt,
  215. }
  216. tmpUser.EncodePasswd()
  217. if ctx.User.Passwd != tmpUser.Passwd {
  218. ctx.Flash.Error(ctx.Tr("settings.password_incorrect"))
  219. } else if form.Password != form.Retype {
  220. ctx.Flash.Error(ctx.Tr("form.password_not_match"))
  221. } else {
  222. ctx.User.Passwd = form.Password
  223. ctx.User.Salt = models.GetUserSalt()
  224. ctx.User.EncodePasswd()
  225. if err := models.UpdateUser(ctx.User); err != nil {
  226. ctx.Handle(500, "UpdateUser", err)
  227. return
  228. }
  229. log.Trace("User password updated: %s", ctx.User.Name)
  230. ctx.Flash.Success(ctx.Tr("settings.change_password_success"))
  231. }
  232. ctx.Redirect(setting.AppSubUrl + "/user/settings/password")
  233. }
  234. func SettingsSSHKeys(ctx *middleware.Context) {
  235. ctx.Data["Title"] = ctx.Tr("settings")
  236. ctx.Data["PageIsSettingsSSHKeys"] = true
  237. keys, err := models.ListPublicKeys(ctx.User.Id)
  238. if err != nil {
  239. ctx.Handle(500, "ListPublicKeys", err)
  240. return
  241. }
  242. ctx.Data["Keys"] = keys
  243. ctx.HTML(200, SETTINGS_SSH_KEYS)
  244. }
  245. func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
  246. ctx.Data["Title"] = ctx.Tr("settings")
  247. ctx.Data["PageIsSettingsSSHKeys"] = true
  248. keys, err := models.ListPublicKeys(ctx.User.Id)
  249. if err != nil {
  250. ctx.Handle(500, "ListPublicKeys", err)
  251. return
  252. }
  253. ctx.Data["Keys"] = keys
  254. if ctx.HasError() {
  255. ctx.HTML(200, SETTINGS_SSH_KEYS)
  256. return
  257. }
  258. content, err := models.CheckPublicKeyString(form.Content)
  259. if err != nil {
  260. if err == models.ErrKeyUnableVerify {
  261. ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key"))
  262. } else {
  263. ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error()))
  264. ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
  265. return
  266. }
  267. }
  268. if err = models.AddPublicKey(ctx.User.Id, form.Title, content); err != nil {
  269. ctx.Data["HasError"] = true
  270. switch {
  271. case models.IsErrKeyAlreadyExist(err):
  272. ctx.Data["Err_Content"] = true
  273. ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), SETTINGS_SSH_KEYS, &form)
  274. case models.IsErrKeyNameAlreadyUsed(err):
  275. ctx.Data["Err_Title"] = true
  276. ctx.RenderWithErr(ctx.Tr("settings.ssh_key_name_used"), SETTINGS_SSH_KEYS, &form)
  277. default:
  278. ctx.Handle(500, "AddPublicKey", err)
  279. }
  280. return
  281. }
  282. ctx.Flash.Success(ctx.Tr("settings.add_key_success", form.Title))
  283. ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
  284. }
  285. func DeleteSSHKey(ctx *middleware.Context) {
  286. if err := models.DeletePublicKey(ctx.QueryInt64("id")); err != nil {
  287. ctx.Flash.Error("DeletePublicKey: " + err.Error())
  288. } else {
  289. ctx.Flash.Success(ctx.Tr("settings.ssh_key_deletion_success"))
  290. }
  291. ctx.JSON(200, map[string]interface{}{
  292. "redirect": setting.AppSubUrl + "/user/settings/ssh",
  293. })
  294. }
  295. func SettingsSocial(ctx *middleware.Context) {
  296. ctx.Data["Title"] = ctx.Tr("settings")
  297. ctx.Data["PageIsSettingsSocial"] = true
  298. // Unbind social account.
  299. remove, _ := com.StrTo(ctx.Query("remove")).Int64()
  300. if remove > 0 {
  301. if err := models.DeleteOauth2ById(remove); err != nil {
  302. ctx.Handle(500, "DeleteOauth2ById", err)
  303. return
  304. }
  305. ctx.Flash.Success(ctx.Tr("settings.unbind_success"))
  306. ctx.Redirect(setting.AppSubUrl + "/user/settings/social")
  307. return
  308. }
  309. socials, err := models.GetOauthByUserId(ctx.User.Id)
  310. if err != nil {
  311. ctx.Handle(500, "GetOauthByUserId", err)
  312. return
  313. }
  314. ctx.Data["Socials"] = socials
  315. ctx.HTML(200, SETTINGS_SOCIAL)
  316. }
  317. func SettingsApplications(ctx *middleware.Context) {
  318. ctx.Data["Title"] = ctx.Tr("settings")
  319. ctx.Data["PageIsSettingsApplications"] = true
  320. tokens, err := models.ListAccessTokens(ctx.User.Id)
  321. if err != nil {
  322. ctx.Handle(500, "ListAccessTokens", err)
  323. return
  324. }
  325. ctx.Data["Tokens"] = tokens
  326. ctx.HTML(200, SETTINGS_APPLICATIONS)
  327. }
  328. func SettingsApplicationsPost(ctx *middleware.Context, form auth.NewAccessTokenForm) {
  329. ctx.Data["Title"] = ctx.Tr("settings")
  330. ctx.Data["PageIsSettingsApplications"] = true
  331. if ctx.HasError() {
  332. tokens, err := models.ListAccessTokens(ctx.User.Id)
  333. if err != nil {
  334. ctx.Handle(500, "ListAccessTokens", err)
  335. return
  336. }
  337. ctx.Data["Tokens"] = tokens
  338. ctx.HTML(200, SETTINGS_APPLICATIONS)
  339. return
  340. }
  341. t := &models.AccessToken{
  342. UID: ctx.User.Id,
  343. Name: form.Name,
  344. }
  345. if err := models.NewAccessToken(t); err != nil {
  346. ctx.Handle(500, "NewAccessToken", err)
  347. return
  348. }
  349. ctx.Flash.Success(ctx.Tr("settings.generate_token_succees"))
  350. ctx.Flash.Info(t.Sha1)
  351. ctx.Redirect(setting.AppSubUrl + "/user/settings/applications")
  352. }
  353. func SettingsDeleteApplication(ctx *middleware.Context) {
  354. if err := models.DeleteAccessTokenByID(ctx.QueryInt64("id")); err != nil {
  355. ctx.Flash.Error("DeleteAccessTokenByID: " + err.Error())
  356. } else {
  357. ctx.Flash.Success(ctx.Tr("settings.delete_token_success"))
  358. }
  359. ctx.JSON(200, map[string]interface{}{
  360. "redirect": setting.AppSubUrl + "/user/settings/applications",
  361. })
  362. }
  363. func SettingsDelete(ctx *middleware.Context) {
  364. ctx.Data["Title"] = ctx.Tr("settings")
  365. ctx.Data["PageIsSettingsDelete"] = true
  366. if ctx.Req.Method == "POST" {
  367. if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil {
  368. if models.IsErrUserNotExist(err) {
  369. ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), SETTINGS_DELETE, nil)
  370. } else {
  371. ctx.Handle(500, "UserSignIn", err)
  372. }
  373. return
  374. }
  375. if err := models.DeleteUser(ctx.User); err != nil {
  376. switch {
  377. case models.IsErrUserOwnRepos(err):
  378. ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
  379. ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
  380. case models.IsErrUserHasOrgs(err):
  381. ctx.Flash.Error(ctx.Tr("form.still_has_org"))
  382. ctx.Redirect(setting.AppSubUrl + "/user/settings/delete")
  383. default:
  384. ctx.Handle(500, "DeleteUser", err)
  385. }
  386. } else {
  387. log.Trace("Account deleted: %s", ctx.User.Name)
  388. ctx.Redirect(setting.AppSubUrl + "/")
  389. }
  390. return
  391. }
  392. ctx.HTML(200, SETTINGS_DELETE)
  393. }