setting.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  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. "bytes"
  7. "encoding/base64"
  8. "fmt"
  9. "html/template"
  10. "image/png"
  11. "io/ioutil"
  12. "strings"
  13. "github.com/pquerna/otp"
  14. "github.com/pquerna/otp/totp"
  15. "github.com/unknwon/com"
  16. log "unknwon.dev/clog/v2"
  17. "gogs.io/gogs/internal/conf"
  18. "gogs.io/gogs/internal/context"
  19. "gogs.io/gogs/internal/db"
  20. "gogs.io/gogs/internal/db/errors"
  21. "gogs.io/gogs/internal/email"
  22. "gogs.io/gogs/internal/form"
  23. "gogs.io/gogs/internal/tool"
  24. )
  25. const (
  26. SETTINGS_PROFILE = "user/settings/profile"
  27. SETTINGS_AVATAR = "user/settings/avatar"
  28. SETTINGS_PASSWORD = "user/settings/password"
  29. SETTINGS_EMAILS = "user/settings/email"
  30. SETTINGS_SSH_KEYS = "user/settings/sshkeys"
  31. SETTINGS_SECURITY = "user/settings/security"
  32. SETTINGS_TWO_FACTOR_ENABLE = "user/settings/two_factor_enable"
  33. SETTINGS_TWO_FACTOR_RECOVERY_CODES = "user/settings/two_factor_recovery_codes"
  34. SETTINGS_REPOSITORIES = "user/settings/repositories"
  35. SETTINGS_ORGANIZATIONS = "user/settings/organizations"
  36. SETTINGS_APPLICATIONS = "user/settings/applications"
  37. SETTINGS_DELETE = "user/settings/delete"
  38. NOTIFICATION = "user/notification"
  39. )
  40. func Settings(c *context.Context) {
  41. c.Title("settings.profile")
  42. c.PageIs("SettingsProfile")
  43. c.Data["origin_name"] = c.User.Name
  44. c.Data["name"] = c.User.Name
  45. c.Data["full_name"] = c.User.FullName
  46. c.Data["email"] = c.User.Email
  47. c.Data["website"] = c.User.Website
  48. c.Data["location"] = c.User.Location
  49. c.Success(SETTINGS_PROFILE)
  50. }
  51. func SettingsPost(c *context.Context, f form.UpdateProfile) {
  52. c.Title("settings.profile")
  53. c.PageIs("SettingsProfile")
  54. c.Data["origin_name"] = c.User.Name
  55. if c.HasError() {
  56. c.Success(SETTINGS_PROFILE)
  57. return
  58. }
  59. // Non-local users are not allowed to change their username
  60. if c.User.IsLocal() {
  61. // Check if username characters have been changed
  62. if c.User.LowerName != strings.ToLower(f.Name) {
  63. if err := db.ChangeUserName(c.User, f.Name); err != nil {
  64. c.FormErr("Name")
  65. var msg string
  66. switch {
  67. case db.IsErrUserAlreadyExist(err):
  68. msg = c.Tr("form.username_been_taken")
  69. case db.IsErrNameReserved(err):
  70. msg = c.Tr("form.name_reserved")
  71. case db.IsErrNamePatternNotAllowed(err):
  72. msg = c.Tr("form.name_pattern_not_allowed")
  73. default:
  74. c.ServerError("ChangeUserName", err)
  75. return
  76. }
  77. c.RenderWithErr(msg, SETTINGS_PROFILE, &f)
  78. return
  79. }
  80. log.Trace("Username changed: %s -> %s", c.User.Name, f.Name)
  81. }
  82. // In case it's just a case change
  83. c.User.Name = f.Name
  84. c.User.LowerName = strings.ToLower(f.Name)
  85. }
  86. c.User.FullName = f.FullName
  87. c.User.Email = f.Email
  88. c.User.Website = f.Website
  89. c.User.Location = f.Location
  90. if err := db.UpdateUser(c.User); err != nil {
  91. if db.IsErrEmailAlreadyUsed(err) {
  92. msg := c.Tr("form.email_been_used")
  93. c.RenderWithErr(msg, SETTINGS_PROFILE, &f)
  94. return
  95. }
  96. c.ServerError("UpdateUser", err)
  97. return
  98. }
  99. c.Flash.Success(c.Tr("settings.update_profile_success"))
  100. c.SubURLRedirect("/user/settings")
  101. }
  102. // FIXME: limit upload size
  103. func UpdateAvatarSetting(c *context.Context, f form.Avatar, ctxUser *db.User) error {
  104. ctxUser.UseCustomAvatar = f.Source == form.AVATAR_LOCAL
  105. if len(f.Gravatar) > 0 {
  106. ctxUser.Avatar = tool.MD5(f.Gravatar)
  107. ctxUser.AvatarEmail = f.Gravatar
  108. }
  109. if f.Avatar != nil && f.Avatar.Filename != "" {
  110. r, err := f.Avatar.Open()
  111. if err != nil {
  112. return fmt.Errorf("open avatar reader: %v", err)
  113. }
  114. defer r.Close()
  115. data, err := ioutil.ReadAll(r)
  116. if err != nil {
  117. return fmt.Errorf("read avatar content: %v", err)
  118. }
  119. if !tool.IsImageFile(data) {
  120. return errors.New(c.Tr("settings.uploaded_avatar_not_a_image"))
  121. }
  122. if err = ctxUser.UploadAvatar(data); err != nil {
  123. return fmt.Errorf("upload avatar: %v", err)
  124. }
  125. } else {
  126. // No avatar is uploaded but setting has been changed to enable,
  127. // generate a random one when needed.
  128. if ctxUser.UseCustomAvatar && !com.IsFile(ctxUser.CustomAvatarPath()) {
  129. if err := ctxUser.GenerateRandomAvatar(); err != nil {
  130. log.Error("generate random avatar [%d]: %v", ctxUser.ID, err)
  131. }
  132. }
  133. }
  134. if err := db.UpdateUser(ctxUser); err != nil {
  135. return fmt.Errorf("update user: %v", err)
  136. }
  137. return nil
  138. }
  139. func SettingsAvatar(c *context.Context) {
  140. c.Title("settings.avatar")
  141. c.PageIs("SettingsAvatar")
  142. c.Success(SETTINGS_AVATAR)
  143. }
  144. func SettingsAvatarPost(c *context.Context, f form.Avatar) {
  145. if err := UpdateAvatarSetting(c, f, c.User); err != nil {
  146. c.Flash.Error(err.Error())
  147. } else {
  148. c.Flash.Success(c.Tr("settings.update_avatar_success"))
  149. }
  150. c.SubURLRedirect("/user/settings/avatar")
  151. }
  152. func SettingsDeleteAvatar(c *context.Context) {
  153. if err := c.User.DeleteAvatar(); err != nil {
  154. c.Flash.Error(fmt.Sprintf("Failed to delete avatar: %v", err))
  155. }
  156. c.SubURLRedirect("/user/settings/avatar")
  157. }
  158. func SettingsPassword(c *context.Context) {
  159. c.Title("settings.password")
  160. c.PageIs("SettingsPassword")
  161. c.Success(SETTINGS_PASSWORD)
  162. }
  163. func SettingsPasswordPost(c *context.Context, f form.ChangePassword) {
  164. c.Title("settings.password")
  165. c.PageIs("SettingsPassword")
  166. if c.HasError() {
  167. c.Success(SETTINGS_PASSWORD)
  168. return
  169. }
  170. if !c.User.ValidatePassword(f.OldPassword) {
  171. c.Flash.Error(c.Tr("settings.password_incorrect"))
  172. } else if f.Password != f.Retype {
  173. c.Flash.Error(c.Tr("form.password_not_match"))
  174. } else {
  175. c.User.Passwd = f.Password
  176. var err error
  177. if c.User.Salt, err = db.GetUserSalt(); err != nil {
  178. c.ServerError("GetUserSalt", err)
  179. return
  180. }
  181. c.User.EncodePasswd()
  182. if err := db.UpdateUser(c.User); err != nil {
  183. c.ServerError("UpdateUser", err)
  184. return
  185. }
  186. c.Flash.Success(c.Tr("settings.change_password_success"))
  187. }
  188. c.SubURLRedirect("/user/settings/password")
  189. }
  190. func SettingsEmails(c *context.Context) {
  191. c.Title("settings.emails")
  192. c.PageIs("SettingsEmails")
  193. emails, err := db.GetEmailAddresses(c.User.ID)
  194. if err != nil {
  195. c.ServerError("GetEmailAddresses", err)
  196. return
  197. }
  198. c.Data["Emails"] = emails
  199. c.Success(SETTINGS_EMAILS)
  200. }
  201. func SettingsEmailPost(c *context.Context, f form.AddEmail) {
  202. c.Title("settings.emails")
  203. c.PageIs("SettingsEmails")
  204. // Make emailaddress primary.
  205. if c.Query("_method") == "PRIMARY" {
  206. if err := db.MakeEmailPrimary(&db.EmailAddress{ID: c.QueryInt64("id")}); err != nil {
  207. c.ServerError("MakeEmailPrimary", err)
  208. return
  209. }
  210. c.SubURLRedirect("/user/settings/email")
  211. return
  212. }
  213. // Add Email address.
  214. emails, err := db.GetEmailAddresses(c.User.ID)
  215. if err != nil {
  216. c.ServerError("GetEmailAddresses", err)
  217. return
  218. }
  219. c.Data["Emails"] = emails
  220. if c.HasError() {
  221. c.Success(SETTINGS_EMAILS)
  222. return
  223. }
  224. emailAddr := &db.EmailAddress{
  225. UID: c.User.ID,
  226. Email: f.Email,
  227. IsActivated: !conf.Auth.RequireEmailConfirmation,
  228. }
  229. if err := db.AddEmailAddress(emailAddr); err != nil {
  230. if db.IsErrEmailAlreadyUsed(err) {
  231. c.RenderWithErr(c.Tr("form.email_been_used"), SETTINGS_EMAILS, &f)
  232. } else {
  233. c.ServerError("AddEmailAddress", err)
  234. }
  235. return
  236. }
  237. // Send confirmation email
  238. if conf.Auth.RequireEmailConfirmation {
  239. email.SendActivateEmailMail(c.Context, db.NewMailerUser(c.User), emailAddr.Email)
  240. if err := c.Cache.Put("MailResendLimit_"+c.User.LowerName, c.User.LowerName, 180); err != nil {
  241. log.Error("Set cache 'MailResendLimit' failed: %v", err)
  242. }
  243. c.Flash.Info(c.Tr("settings.add_email_confirmation_sent", emailAddr.Email, conf.Auth.ActivateCodeLives/60))
  244. } else {
  245. c.Flash.Success(c.Tr("settings.add_email_success"))
  246. }
  247. c.SubURLRedirect("/user/settings/email")
  248. }
  249. func DeleteEmail(c *context.Context) {
  250. if err := db.DeleteEmailAddress(&db.EmailAddress{
  251. ID: c.QueryInt64("id"),
  252. UID: c.User.ID,
  253. }); err != nil {
  254. c.ServerError("DeleteEmailAddress", err)
  255. return
  256. }
  257. c.Flash.Success(c.Tr("settings.email_deletion_success"))
  258. c.JSONSuccess(map[string]interface{}{
  259. "redirect": conf.Server.Subpath + "/user/settings/email",
  260. })
  261. }
  262. func SettingsSSHKeys(c *context.Context) {
  263. c.Title("settings.ssh_keys")
  264. c.PageIs("SettingsSSHKeys")
  265. keys, err := db.ListPublicKeys(c.User.ID)
  266. if err != nil {
  267. c.ServerError("ListPublicKeys", err)
  268. return
  269. }
  270. c.Data["Keys"] = keys
  271. c.Success(SETTINGS_SSH_KEYS)
  272. }
  273. func SettingsSSHKeysPost(c *context.Context, f form.AddSSHKey) {
  274. c.Title("settings.ssh_keys")
  275. c.PageIs("SettingsSSHKeys")
  276. keys, err := db.ListPublicKeys(c.User.ID)
  277. if err != nil {
  278. c.ServerError("ListPublicKeys", err)
  279. return
  280. }
  281. c.Data["Keys"] = keys
  282. if c.HasError() {
  283. c.Success(SETTINGS_SSH_KEYS)
  284. return
  285. }
  286. content, err := db.CheckPublicKeyString(f.Content)
  287. if err != nil {
  288. if db.IsErrKeyUnableVerify(err) {
  289. c.Flash.Info(c.Tr("form.unable_verify_ssh_key"))
  290. } else {
  291. c.Flash.Error(c.Tr("form.invalid_ssh_key", err.Error()))
  292. c.SubURLRedirect("/user/settings/ssh")
  293. return
  294. }
  295. }
  296. if _, err = db.AddPublicKey(c.User.ID, f.Title, content); err != nil {
  297. c.Data["HasError"] = true
  298. switch {
  299. case db.IsErrKeyAlreadyExist(err):
  300. c.FormErr("Content")
  301. c.RenderWithErr(c.Tr("settings.ssh_key_been_used"), SETTINGS_SSH_KEYS, &f)
  302. case db.IsErrKeyNameAlreadyUsed(err):
  303. c.FormErr("Title")
  304. c.RenderWithErr(c.Tr("settings.ssh_key_name_used"), SETTINGS_SSH_KEYS, &f)
  305. default:
  306. c.ServerError("AddPublicKey", err)
  307. }
  308. return
  309. }
  310. c.Flash.Success(c.Tr("settings.add_key_success", f.Title))
  311. c.SubURLRedirect("/user/settings/ssh")
  312. }
  313. func DeleteSSHKey(c *context.Context) {
  314. if err := db.DeletePublicKey(c.User, c.QueryInt64("id")); err != nil {
  315. c.Flash.Error("DeletePublicKey: " + err.Error())
  316. } else {
  317. c.Flash.Success(c.Tr("settings.ssh_key_deletion_success"))
  318. }
  319. c.JSONSuccess(map[string]interface{}{
  320. "redirect": conf.Server.Subpath + "/user/settings/ssh",
  321. })
  322. }
  323. func SettingsSecurity(c *context.Context) {
  324. c.Title("settings.security")
  325. c.PageIs("SettingsSecurity")
  326. t, err := db.GetTwoFactorByUserID(c.UserID())
  327. if err != nil && !errors.IsTwoFactorNotFound(err) {
  328. c.ServerError("GetTwoFactorByUserID", err)
  329. return
  330. }
  331. c.Data["TwoFactor"] = t
  332. c.Success(SETTINGS_SECURITY)
  333. }
  334. func SettingsTwoFactorEnable(c *context.Context) {
  335. if c.User.IsEnabledTwoFactor() {
  336. c.NotFound()
  337. return
  338. }
  339. c.Title("settings.two_factor_enable_title")
  340. c.PageIs("SettingsSecurity")
  341. var key *otp.Key
  342. var err error
  343. keyURL := c.Session.Get("twoFactorURL")
  344. if keyURL != nil {
  345. key, _ = otp.NewKeyFromURL(keyURL.(string))
  346. }
  347. if key == nil {
  348. key, err = totp.Generate(totp.GenerateOpts{
  349. Issuer: conf.App.BrandName,
  350. AccountName: c.User.Email,
  351. })
  352. if err != nil {
  353. c.ServerError("Generate", err)
  354. return
  355. }
  356. }
  357. c.Data["TwoFactorSecret"] = key.Secret()
  358. img, err := key.Image(240, 240)
  359. if err != nil {
  360. c.ServerError("Image", err)
  361. return
  362. }
  363. var buf bytes.Buffer
  364. if err = png.Encode(&buf, img); err != nil {
  365. c.ServerError("Encode", err)
  366. return
  367. }
  368. c.Data["QRCode"] = template.URL("data:image/png;base64," + base64.StdEncoding.EncodeToString(buf.Bytes()))
  369. c.Session.Set("twoFactorSecret", c.Data["TwoFactorSecret"])
  370. c.Session.Set("twoFactorURL", key.String())
  371. c.Success(SETTINGS_TWO_FACTOR_ENABLE)
  372. }
  373. func SettingsTwoFactorEnablePost(c *context.Context) {
  374. secret, ok := c.Session.Get("twoFactorSecret").(string)
  375. if !ok {
  376. c.NotFound()
  377. return
  378. }
  379. if !totp.Validate(c.Query("passcode"), secret) {
  380. c.Flash.Error(c.Tr("settings.two_factor_invalid_passcode"))
  381. c.SubURLRedirect("/user/settings/security/two_factor_enable")
  382. return
  383. }
  384. if err := db.NewTwoFactor(c.UserID(), secret); err != nil {
  385. c.Flash.Error(c.Tr("settings.two_factor_enable_error", err))
  386. c.SubURLRedirect("/user/settings/security/two_factor_enable")
  387. return
  388. }
  389. c.Session.Delete("twoFactorSecret")
  390. c.Session.Delete("twoFactorURL")
  391. c.Flash.Success(c.Tr("settings.two_factor_enable_success"))
  392. c.SubURLRedirect("/user/settings/security/two_factor_recovery_codes")
  393. }
  394. func SettingsTwoFactorRecoveryCodes(c *context.Context) {
  395. if !c.User.IsEnabledTwoFactor() {
  396. c.NotFound()
  397. return
  398. }
  399. c.Title("settings.two_factor_recovery_codes_title")
  400. c.PageIs("SettingsSecurity")
  401. recoveryCodes, err := db.GetRecoveryCodesByUserID(c.UserID())
  402. if err != nil {
  403. c.ServerError("GetRecoveryCodesByUserID", err)
  404. return
  405. }
  406. c.Data["RecoveryCodes"] = recoveryCodes
  407. c.Success(SETTINGS_TWO_FACTOR_RECOVERY_CODES)
  408. }
  409. func SettingsTwoFactorRecoveryCodesPost(c *context.Context) {
  410. if !c.User.IsEnabledTwoFactor() {
  411. c.NotFound()
  412. return
  413. }
  414. if err := db.RegenerateRecoveryCodes(c.UserID()); err != nil {
  415. c.Flash.Error(c.Tr("settings.two_factor_regenerate_recovery_codes_error", err))
  416. } else {
  417. c.Flash.Success(c.Tr("settings.two_factor_regenerate_recovery_codes_success"))
  418. }
  419. c.SubURLRedirect("/user/settings/security/two_factor_recovery_codes")
  420. }
  421. func SettingsTwoFactorDisable(c *context.Context) {
  422. if !c.User.IsEnabledTwoFactor() {
  423. c.NotFound()
  424. return
  425. }
  426. if err := db.DeleteTwoFactor(c.UserID()); err != nil {
  427. c.ServerError("DeleteTwoFactor", err)
  428. return
  429. }
  430. c.Flash.Success(c.Tr("settings.two_factor_disable_success"))
  431. c.JSONSuccess(map[string]interface{}{
  432. "redirect": conf.Server.Subpath + "/user/settings/security",
  433. })
  434. }
  435. func SettingsRepos(c *context.Context) {
  436. c.Title("settings.repos")
  437. c.PageIs("SettingsRepositories")
  438. repos, err := db.GetUserAndCollaborativeRepositories(c.User.ID)
  439. if err != nil {
  440. c.ServerError("GetUserAndCollaborativeRepositories", err)
  441. return
  442. }
  443. if err = db.RepositoryList(repos).LoadAttributes(); err != nil {
  444. c.ServerError("LoadAttributes", err)
  445. return
  446. }
  447. c.Data["Repos"] = repos
  448. c.Success(SETTINGS_REPOSITORIES)
  449. }
  450. func SettingsLeaveRepo(c *context.Context) {
  451. repo, err := db.GetRepositoryByID(c.QueryInt64("id"))
  452. if err != nil {
  453. c.NotFoundOrServerError("GetRepositoryByID", errors.IsRepoNotExist, err)
  454. return
  455. }
  456. if err = repo.DeleteCollaboration(c.User.ID); err != nil {
  457. c.ServerError("DeleteCollaboration", err)
  458. return
  459. }
  460. c.Flash.Success(c.Tr("settings.repos.leave_success", repo.FullName()))
  461. c.JSONSuccess(map[string]interface{}{
  462. "redirect": conf.Server.Subpath + "/user/settings/repositories",
  463. })
  464. }
  465. func SettingsOrganizations(c *context.Context) {
  466. c.Title("settings.orgs")
  467. c.PageIs("SettingsOrganizations")
  468. orgs, err := db.GetOrgsByUserID(c.User.ID, true)
  469. if err != nil {
  470. c.ServerError("GetOrgsByUserID", err)
  471. return
  472. }
  473. c.Data["Orgs"] = orgs
  474. c.Success(SETTINGS_ORGANIZATIONS)
  475. }
  476. func SettingsLeaveOrganization(c *context.Context) {
  477. if err := db.RemoveOrgUser(c.QueryInt64("id"), c.User.ID); err != nil {
  478. if db.IsErrLastOrgOwner(err) {
  479. c.Flash.Error(c.Tr("form.last_org_owner"))
  480. } else {
  481. c.ServerError("RemoveOrgUser", err)
  482. return
  483. }
  484. }
  485. c.JSONSuccess(map[string]interface{}{
  486. "redirect": conf.Server.Subpath + "/user/settings/organizations",
  487. })
  488. }
  489. func SettingsApplications(c *context.Context) {
  490. c.Title("settings.applications")
  491. c.PageIs("SettingsApplications")
  492. tokens, err := db.ListAccessTokens(c.User.ID)
  493. if err != nil {
  494. c.ServerError("ListAccessTokens", err)
  495. return
  496. }
  497. c.Data["Tokens"] = tokens
  498. c.Success(SETTINGS_APPLICATIONS)
  499. }
  500. func SettingsApplicationsPost(c *context.Context, f form.NewAccessToken) {
  501. c.Title("settings.applications")
  502. c.PageIs("SettingsApplications")
  503. if c.HasError() {
  504. tokens, err := db.ListAccessTokens(c.User.ID)
  505. if err != nil {
  506. c.ServerError("ListAccessTokens", err)
  507. return
  508. }
  509. c.Data["Tokens"] = tokens
  510. c.Success(SETTINGS_APPLICATIONS)
  511. return
  512. }
  513. t := &db.AccessToken{
  514. UID: c.User.ID,
  515. Name: f.Name,
  516. }
  517. if err := db.NewAccessToken(t); err != nil {
  518. if errors.IsAccessTokenNameAlreadyExist(err) {
  519. c.Flash.Error(c.Tr("settings.token_name_exists"))
  520. c.SubURLRedirect("/user/settings/applications")
  521. } else {
  522. c.ServerError("NewAccessToken", err)
  523. }
  524. return
  525. }
  526. c.Flash.Success(c.Tr("settings.generate_token_succees"))
  527. c.Flash.Info(t.Sha1)
  528. c.SubURLRedirect("/user/settings/applications")
  529. }
  530. func SettingsDeleteApplication(c *context.Context) {
  531. if err := db.DeleteAccessTokenOfUserByID(c.User.ID, c.QueryInt64("id")); err != nil {
  532. c.Flash.Error("DeleteAccessTokenByID: " + err.Error())
  533. } else {
  534. c.Flash.Success(c.Tr("settings.delete_token_success"))
  535. }
  536. c.JSONSuccess(map[string]interface{}{
  537. "redirect": conf.Server.Subpath + "/user/settings/applications",
  538. })
  539. }
  540. func SettingsDelete(c *context.Context) {
  541. c.Title("settings.delete")
  542. c.PageIs("SettingsDelete")
  543. if c.Req.Method == "POST" {
  544. if _, err := db.UserLogin(c.User.Name, c.Query("password"), c.User.LoginSource); err != nil {
  545. if errors.IsUserNotExist(err) {
  546. c.RenderWithErr(c.Tr("form.enterred_invalid_password"), SETTINGS_DELETE, nil)
  547. } else {
  548. c.ServerError("UserLogin", err)
  549. }
  550. return
  551. }
  552. if err := db.DeleteUser(c.User); err != nil {
  553. switch {
  554. case db.IsErrUserOwnRepos(err):
  555. c.Flash.Error(c.Tr("form.still_own_repo"))
  556. c.Redirect(conf.Server.Subpath + "/user/settings/delete")
  557. case db.IsErrUserHasOrgs(err):
  558. c.Flash.Error(c.Tr("form.still_has_org"))
  559. c.Redirect(conf.Server.Subpath + "/user/settings/delete")
  560. default:
  561. c.ServerError("DeleteUser", err)
  562. }
  563. } else {
  564. log.Trace("Account deleted: %s", c.User.Name)
  565. c.Redirect(conf.Server.Subpath + "/")
  566. }
  567. return
  568. }
  569. c.Success(SETTINGS_DELETE)
  570. }