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.

457 lines
12 KiB

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
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
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
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
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
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
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
10 years ago
10 years ago
10 years ago
10 years ago
  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. "net/url"
  7. "strings"
  8. "github.com/gogits/gogs/models"
  9. "github.com/gogits/gogs/modules/auth"
  10. "github.com/gogits/gogs/modules/base"
  11. "github.com/gogits/gogs/modules/log"
  12. "github.com/gogits/gogs/modules/mailer"
  13. "github.com/gogits/gogs/modules/middleware"
  14. "github.com/gogits/gogs/modules/setting"
  15. )
  16. const (
  17. SIGNIN base.TplName = "user/signin"
  18. SIGNUP base.TplName = "user/signup"
  19. DELETE base.TplName = "user/delete"
  20. ACTIVATE base.TplName = "user/activate"
  21. FORGOT_PASSWORD base.TplName = "user/forgot_passwd"
  22. RESET_PASSWORD base.TplName = "user/reset_passwd"
  23. )
  24. func SignIn(ctx *middleware.Context) {
  25. ctx.Data["Title"] = "Log In"
  26. if _, ok := ctx.Session.Get("socialId").(int64); ok {
  27. ctx.Data["IsSocialLogin"] = true
  28. ctx.HTML(200, SIGNIN)
  29. return
  30. }
  31. if setting.OauthService != nil {
  32. ctx.Data["OauthEnabled"] = true
  33. ctx.Data["OauthService"] = setting.OauthService
  34. }
  35. // Check auto-login.
  36. uname := ctx.GetCookie(setting.CookieUserName)
  37. if len(uname) == 0 {
  38. ctx.HTML(200, SIGNIN)
  39. return
  40. }
  41. isSucceed := false
  42. defer func() {
  43. if !isSucceed {
  44. log.Trace("user.SignIn(auto-login cookie cleared): %s", uname)
  45. ctx.SetCookie(setting.CookieUserName, "", -1)
  46. ctx.SetCookie(setting.CookieRememberName, "", -1)
  47. return
  48. }
  49. }()
  50. user, err := models.GetUserByName(uname)
  51. if err != nil {
  52. ctx.Handle(500, "user.SignIn(GetUserByName)", err)
  53. return
  54. }
  55. secret := base.EncodeMd5(user.Rands + user.Passwd)
  56. value, _ := ctx.GetSecureCookie(secret, setting.CookieRememberName)
  57. if value != user.Name {
  58. ctx.HTML(200, SIGNIN)
  59. return
  60. }
  61. isSucceed = true
  62. ctx.Session.Set("userId", user.Id)
  63. ctx.Session.Set("userName", user.Name)
  64. if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
  65. ctx.SetCookie("redirect_to", "", -1)
  66. ctx.Redirect(redirectTo)
  67. return
  68. }
  69. ctx.Redirect("/")
  70. }
  71. func SignInPost(ctx *middleware.Context, form auth.LogInForm) {
  72. ctx.Data["Title"] = "Log In"
  73. sid, isOauth := ctx.Session.Get("socialId").(int64)
  74. if isOauth {
  75. ctx.Data["IsSocialLogin"] = true
  76. } else if setting.OauthService != nil {
  77. ctx.Data["OauthEnabled"] = true
  78. ctx.Data["OauthService"] = setting.OauthService
  79. }
  80. if ctx.HasError() {
  81. ctx.HTML(200, SIGNIN)
  82. return
  83. }
  84. user, err := models.UserSignIn(form.UserName, form.Password)
  85. if err != nil {
  86. if err == models.ErrUserNotExist {
  87. log.Trace("%s Log in failed: %s", ctx.Req.RequestURI, form.UserName)
  88. ctx.RenderWithErr("Username or password is not correct", SIGNIN, &form)
  89. return
  90. }
  91. ctx.Handle(500, "user.SignInPost(UserSignIn)", err)
  92. return
  93. }
  94. if form.Remember {
  95. secret := base.EncodeMd5(user.Rands + user.Passwd)
  96. days := 86400 * setting.LogInRememberDays
  97. ctx.SetCookie(setting.CookieUserName, user.Name, days)
  98. ctx.SetSecureCookie(secret, setting.CookieRememberName, user.Name, days)
  99. }
  100. // Bind with social account.
  101. if isOauth {
  102. if err = models.BindUserOauth2(user.Id, sid); err != nil {
  103. if err == models.ErrOauth2RecordNotExist {
  104. ctx.Handle(404, "user.SignInPost(GetOauth2ById)", err)
  105. } else {
  106. ctx.Handle(500, "user.SignInPost(GetOauth2ById)", err)
  107. }
  108. return
  109. }
  110. ctx.Session.Delete("socialId")
  111. log.Trace("%s OAuth binded: %s -> %d", ctx.Req.RequestURI, form.UserName, sid)
  112. }
  113. ctx.Session.Set("userId", user.Id)
  114. ctx.Session.Set("userName", user.Name)
  115. if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
  116. ctx.SetCookie("redirect_to", "", -1)
  117. ctx.Redirect(redirectTo)
  118. return
  119. }
  120. ctx.Redirect("/")
  121. }
  122. func SignOut(ctx *middleware.Context) {
  123. ctx.Session.Delete("userId")
  124. ctx.Session.Delete("userName")
  125. ctx.Session.Delete("socialId")
  126. ctx.Session.Delete("socialName")
  127. ctx.Session.Delete("socialEmail")
  128. ctx.SetCookie(setting.CookieUserName, "", -1)
  129. ctx.SetCookie(setting.CookieRememberName, "", -1)
  130. ctx.Redirect("/")
  131. }
  132. func SignUp(ctx *middleware.Context) {
  133. ctx.Data["Title"] = "Sign Up"
  134. ctx.Data["PageIsSignUp"] = true
  135. if setting.Service.DisableRegistration {
  136. ctx.Data["DisableRegistration"] = true
  137. ctx.HTML(200, SIGNUP)
  138. return
  139. }
  140. if sid, ok := ctx.Session.Get("socialId").(int64); ok {
  141. oauthSignUp(ctx, sid)
  142. return
  143. }
  144. ctx.HTML(200, SIGNUP)
  145. }
  146. func oauthSignUp(ctx *middleware.Context, sid int64) {
  147. ctx.Data["Title"] = "OAuth Sign Up"
  148. ctx.Data["PageIsSignUp"] = true
  149. if _, err := models.GetOauth2ById(sid); err != nil {
  150. if err == models.ErrOauth2RecordNotExist {
  151. ctx.Handle(404, "user.oauthSignUp(GetOauth2ById)", err)
  152. } else {
  153. ctx.Handle(500, "user.oauthSignUp(GetOauth2ById)", err)
  154. }
  155. return
  156. }
  157. ctx.Data["IsSocialLogin"] = true
  158. ctx.Data["username"] = strings.Replace(ctx.Session.Get("socialName").(string), " ", "", -1)
  159. ctx.Data["email"] = ctx.Session.Get("socialEmail")
  160. log.Trace("user.oauthSignUp(social ID): %v", ctx.Session.Get("socialId"))
  161. ctx.HTML(200, SIGNUP)
  162. }
  163. func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) {
  164. ctx.Data["Title"] = "Sign Up"
  165. ctx.Data["PageIsSignUp"] = true
  166. if setting.Service.DisableRegistration {
  167. ctx.Handle(403, "user.SignUpPost", nil)
  168. return
  169. }
  170. sid, isOauth := ctx.Session.Get("socialId").(int64)
  171. if isOauth {
  172. ctx.Data["IsSocialLogin"] = true
  173. }
  174. if ctx.HasError() {
  175. ctx.HTML(200, SIGNUP)
  176. return
  177. }
  178. if form.Password != form.RetypePasswd {
  179. ctx.Data["Err_Password"] = true
  180. ctx.Data["Err_RetypePasswd"] = true
  181. ctx.RenderWithErr("Password and re-type password are not same.", SIGNUP, &form)
  182. return
  183. }
  184. u := &models.User{
  185. Name: form.UserName,
  186. Email: form.Email,
  187. Passwd: form.Password,
  188. IsActive: !setting.Service.RegisterEmailConfirm || isOauth,
  189. }
  190. var err error
  191. if u, err = models.CreateUser(u); err != nil {
  192. switch err {
  193. case models.ErrUserAlreadyExist:
  194. ctx.Data["Err_UserName"] = true
  195. ctx.RenderWithErr("Username has been already taken", SIGNUP, &form)
  196. case models.ErrEmailAlreadyUsed:
  197. ctx.Data["Err_Email"] = true
  198. ctx.RenderWithErr("E-mail address has been already used", SIGNUP, &form)
  199. case models.ErrUserNameIllegal:
  200. ctx.Data["Err_UserName"] = true
  201. ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), SIGNUP, &form)
  202. default:
  203. ctx.Handle(500, "user.SignUpPost(CreateUser)", err)
  204. }
  205. return
  206. }
  207. log.Trace("%s User created: %s", ctx.Req.RequestURI, u.Name)
  208. // Bind social account.
  209. if isOauth {
  210. if err = models.BindUserOauth2(u.Id, sid); err != nil {
  211. ctx.Handle(500, "user.SignUp(BindUserOauth2)", err)
  212. return
  213. }
  214. ctx.Session.Delete("socialId")
  215. log.Trace("%s OAuth binded: %s -> %d", ctx.Req.RequestURI, form.UserName, sid)
  216. }
  217. // Send confirmation e-mail, no need for social account.
  218. if !isOauth && setting.Service.RegisterEmailConfirm && u.Id > 1 {
  219. mailer.SendRegisterMail(ctx.Render, u)
  220. ctx.Data["IsSendRegisterMail"] = true
  221. ctx.Data["Email"] = u.Email
  222. ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60
  223. ctx.HTML(200, "user/activate")
  224. if err = ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
  225. log.Error("Set cache(MailResendLimit) fail: %v", err)
  226. }
  227. return
  228. }
  229. ctx.Redirect("/user/login")
  230. }
  231. func Delete(ctx *middleware.Context) {
  232. ctx.Data["Title"] = "Delete Account"
  233. ctx.Data["PageIsUserSetting"] = true
  234. ctx.Data["IsUserPageSettingDelete"] = true
  235. ctx.HTML(200, DELETE)
  236. }
  237. func DeletePost(ctx *middleware.Context) {
  238. ctx.Data["Title"] = "Delete Account"
  239. ctx.Data["PageIsUserSetting"] = true
  240. ctx.Data["IsUserPageSettingDelete"] = true
  241. tmpUser := models.User{
  242. Passwd: ctx.Query("password"),
  243. Salt: ctx.User.Salt,
  244. }
  245. tmpUser.EncodePasswd()
  246. if tmpUser.Passwd != ctx.User.Passwd {
  247. ctx.Flash.Error("Password is not correct. Make sure you are owner of this account.")
  248. } else {
  249. if err := models.DeleteUser(ctx.User); err != nil {
  250. switch err {
  251. case models.ErrUserOwnRepos:
  252. ctx.Flash.Error("Your account still have ownership of repository, you have to delete or transfer them first.")
  253. default:
  254. ctx.Handle(500, "user.DeletePost(DeleteUser)", err)
  255. return
  256. }
  257. } else {
  258. ctx.Redirect("/")
  259. return
  260. }
  261. }
  262. ctx.Redirect("/user/delete")
  263. }
  264. func Activate(ctx *middleware.Context) {
  265. code := ctx.Query("code")
  266. if len(code) == 0 {
  267. ctx.Data["IsActivatePage"] = true
  268. if ctx.User.IsActive {
  269. ctx.Handle(404, "user.Activate", nil)
  270. return
  271. }
  272. // Resend confirmation e-mail.
  273. if setting.Service.RegisterEmailConfirm {
  274. if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) {
  275. ctx.Data["ResendLimited"] = true
  276. } else {
  277. ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60
  278. mailer.SendActiveMail(ctx.Render, ctx.User)
  279. if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
  280. log.Error("Set cache(MailResendLimit) fail: %v", err)
  281. }
  282. }
  283. } else {
  284. ctx.Data["ServiceNotEnabled"] = true
  285. }
  286. ctx.HTML(200, ACTIVATE)
  287. return
  288. }
  289. // Verify code.
  290. if user := models.VerifyUserActiveCode(code); user != nil {
  291. user.IsActive = true
  292. user.Rands = models.GetUserSalt()
  293. if err := models.UpdateUser(user); err != nil {
  294. ctx.Handle(404, "user.Activate", err)
  295. return
  296. }
  297. log.Trace("%s User activated: %s", ctx.Req.RequestURI, user.Name)
  298. ctx.Session.Set("userId", user.Id)
  299. ctx.Session.Set("userName", user.Name)
  300. ctx.Redirect("/")
  301. return
  302. }
  303. ctx.Data["IsActivateFailed"] = true
  304. ctx.HTML(200, ACTIVATE)
  305. }
  306. func ForgotPasswd(ctx *middleware.Context) {
  307. ctx.Data["Title"] = "Forgot Password"
  308. if setting.MailService == nil {
  309. ctx.Data["IsResetDisable"] = true
  310. ctx.HTML(200, FORGOT_PASSWORD)
  311. return
  312. }
  313. ctx.Data["IsResetRequest"] = true
  314. ctx.HTML(200, FORGOT_PASSWORD)
  315. }
  316. func ForgotPasswdPost(ctx *middleware.Context) {
  317. ctx.Data["Title"] = "Forgot Password"
  318. if setting.MailService == nil {
  319. ctx.Handle(403, "user.ForgotPasswdPost", nil)
  320. return
  321. }
  322. ctx.Data["IsResetRequest"] = true
  323. email := ctx.Query("email")
  324. u, err := models.GetUserByEmail(email)
  325. if err != nil {
  326. if err == models.ErrUserNotExist {
  327. ctx.RenderWithErr("This e-mail address does not associate to any account.", "user/forgot_passwd", nil)
  328. } else {
  329. ctx.Handle(500, "user.ResetPasswd(check existence)", err)
  330. }
  331. return
  332. }
  333. if ctx.Cache.IsExist("MailResendLimit_" + u.LowerName) {
  334. ctx.Data["ResendLimited"] = true
  335. ctx.HTML(200, FORGOT_PASSWORD)
  336. return
  337. }
  338. mailer.SendResetPasswdMail(ctx.Render, u)
  339. if err = ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
  340. log.Error("Set cache(MailResendLimit) fail: %v", err)
  341. }
  342. ctx.Data["Email"] = email
  343. ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60
  344. ctx.Data["IsResetSent"] = true
  345. ctx.HTML(200, FORGOT_PASSWORD)
  346. }
  347. func ResetPasswd(ctx *middleware.Context) {
  348. ctx.Data["Title"] = "Reset Password"
  349. code := ctx.Query("code")
  350. if len(code) == 0 {
  351. ctx.Error(404)
  352. return
  353. }
  354. ctx.Data["Code"] = code
  355. ctx.Data["IsResetForm"] = true
  356. ctx.HTML(200, RESET_PASSWORD)
  357. }
  358. func ResetPasswdPost(ctx *middleware.Context) {
  359. ctx.Data["Title"] = "Reset Password"
  360. code := ctx.Query("code")
  361. if len(code) == 0 {
  362. ctx.Error(404)
  363. return
  364. }
  365. ctx.Data["Code"] = code
  366. if u := models.VerifyUserActiveCode(code); u != nil {
  367. // Validate password length.
  368. passwd := ctx.Query("passwd")
  369. if len(passwd) < 6 || len(passwd) > 30 {
  370. ctx.Data["IsResetForm"] = true
  371. ctx.RenderWithErr("Password length should be in 6 and 30.", "user/reset_passwd", nil)
  372. return
  373. }
  374. u.Passwd = passwd
  375. u.Rands = models.GetUserSalt()
  376. u.Salt = models.GetUserSalt()
  377. u.EncodePasswd()
  378. if err := models.UpdateUser(u); err != nil {
  379. ctx.Handle(500, "user.ResetPasswd(UpdateUser)", err)
  380. return
  381. }
  382. log.Trace("%s User password reset: %s", ctx.Req.RequestURI, u.Name)
  383. ctx.Redirect("/user/login")
  384. return
  385. }
  386. ctx.Data["IsResetFailed"] = true
  387. ctx.HTML(200, RESET_PASSWORD)
  388. }