auth.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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 middleware
  5. import (
  6. "fmt"
  7. "net/url"
  8. "github.com/go-macaron/csrf"
  9. "gopkg.in/macaron.v1"
  10. "github.com/gogits/gogs/models"
  11. "github.com/gogits/gogs/modules/auth"
  12. "github.com/gogits/gogs/modules/base"
  13. "github.com/gogits/gogs/modules/log"
  14. "github.com/gogits/gogs/modules/setting"
  15. )
  16. type ToggleOptions struct {
  17. SignInRequire bool
  18. SignOutRequire bool
  19. AdminRequire bool
  20. DisableCsrf bool
  21. }
  22. // AutoSignIn reads cookie and try to auto-login.
  23. func AutoSignIn(ctx *Context) (bool, error) {
  24. if !models.HasEngine {
  25. return false, nil
  26. }
  27. uname := ctx.GetCookie(setting.CookieUserName)
  28. if len(uname) == 0 {
  29. return false, nil
  30. }
  31. isSucceed := false
  32. defer func() {
  33. if !isSucceed {
  34. log.Trace("auto-login cookie cleared: %s", uname)
  35. ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl)
  36. ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl)
  37. }
  38. }()
  39. u, err := models.GetUserByName(uname)
  40. if err != nil {
  41. if !models.IsErrUserNotExist(err) {
  42. return false, fmt.Errorf("GetUserByName: %v", err)
  43. }
  44. return false, nil
  45. }
  46. if val, _ := ctx.GetSuperSecureCookie(
  47. base.EncodeMD5(u.Rands+u.Passwd), setting.CookieRememberName); val != u.Name {
  48. return false, nil
  49. }
  50. isSucceed = true
  51. ctx.Session.Set("uid", u.Id)
  52. ctx.Session.Set("uname", u.Name)
  53. return true, nil
  54. }
  55. func Toggle(options *ToggleOptions) macaron.Handler {
  56. return func(ctx *Context) {
  57. // Cannot view any page before installation.
  58. if !setting.InstallLock {
  59. ctx.Redirect(setting.AppSubUrl + "/install")
  60. return
  61. }
  62. // Checking non-logged users landing page.
  63. if !ctx.IsSigned && ctx.Req.RequestURI == "/" && setting.LandingPageUrl != setting.LANDING_PAGE_HOME {
  64. ctx.Redirect(setting.AppSubUrl + string(setting.LandingPageUrl))
  65. return
  66. }
  67. // Redirect to dashboard if user tries to visit any non-login page.
  68. if options.SignOutRequire && ctx.IsSigned && ctx.Req.RequestURI != "/" {
  69. ctx.Redirect(setting.AppSubUrl + "/")
  70. return
  71. }
  72. if !options.SignOutRequire && !options.DisableCsrf && ctx.Req.Method == "POST" && !auth.IsAPIPath(ctx.Req.URL.Path) {
  73. csrf.Validate(ctx.Context, ctx.csrf)
  74. if ctx.Written() {
  75. return
  76. }
  77. }
  78. if options.SignInRequire {
  79. if !ctx.IsSigned {
  80. // Restrict API calls with error message.
  81. if auth.IsAPIPath(ctx.Req.URL.Path) {
  82. ctx.APIError(403, "", "Only signed in user is allowed to call APIs.")
  83. return
  84. }
  85. ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
  86. ctx.Redirect(setting.AppSubUrl + "/user/login")
  87. return
  88. } else if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
  89. ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
  90. ctx.HTML(200, "user/auth/activate")
  91. return
  92. }
  93. }
  94. // Try auto-signin when not signed in.
  95. if !options.SignOutRequire && !ctx.IsSigned && !auth.IsAPIPath(ctx.Req.URL.Path) {
  96. succeed, err := AutoSignIn(ctx)
  97. if err != nil {
  98. ctx.Handle(500, "AutoSignIn", err)
  99. return
  100. } else if succeed {
  101. log.Trace("Auto-login succeed: %s", ctx.Session.Get("uname"))
  102. ctx.Redirect(setting.AppSubUrl + ctx.Req.RequestURI)
  103. return
  104. }
  105. }
  106. if options.AdminRequire {
  107. if !ctx.User.IsAdmin {
  108. ctx.Error(403)
  109. return
  110. }
  111. ctx.Data["PageIsAdmin"] = true
  112. }
  113. }
  114. }