auth.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Copyright 2015 - Present, The Gogs Authors. All rights reserved.
  2. // Copyright 2018 - Present, Gitote. All rights reserved.
  3. //
  4. // This source code is licensed under the MIT license found in the
  5. // LICENSE file in the root directory of this source tree.
  6. package context
  7. import (
  8. "gitote/gitote/pkg/auth"
  9. "gitote/gitote/pkg/setting"
  10. "gitote/gitote/pkg/tool"
  11. "net/http"
  12. "net/url"
  13. "strings"
  14. "github.com/go-macaron/csrf"
  15. "gopkg.in/macaron.v1"
  16. )
  17. // ToggleOptions contains required or check options
  18. type ToggleOptions struct {
  19. SignInRequired bool
  20. SignOutRequired bool
  21. AdminRequired bool
  22. DisableCSRF bool
  23. }
  24. // Toggle returns toggle options as middleware
  25. func Toggle(options *ToggleOptions) macaron.Handler {
  26. return func(c *Context) {
  27. // Cannot view any page before installation.
  28. if !setting.InstallLock {
  29. c.Redirect(setting.AppSubURL + "/install")
  30. return
  31. }
  32. // Check prohibit login users.
  33. if c.IsLogged && c.User.Suspended {
  34. c.Data["Title"] = c.Tr("auth.prohibit_login")
  35. c.Data["PageIsSuspended"] = true
  36. c.HTML(200, "user/auth/prohibit_login")
  37. return
  38. }
  39. // Check non-logged users landing page.
  40. if !c.IsLogged && c.Req.RequestURI == "/" && setting.LandingPageURL != setting.LandingPageHome {
  41. c.Redirect(setting.AppSubURL + string(setting.LandingPageURL))
  42. return
  43. }
  44. // Redirect to dashboard if user tries to visit any non-login page.
  45. if options.SignOutRequired && c.IsLogged && c.Req.RequestURI != "/" {
  46. c.Redirect(setting.AppSubURL + "/")
  47. return
  48. }
  49. if !options.SignOutRequired && !options.DisableCSRF && c.Req.Method == "POST" && !auth.IsAPIPath(c.Req.URL.Path) {
  50. csrf.Validate(c.Context, c.csrf)
  51. if c.Written() {
  52. return
  53. }
  54. }
  55. if options.SignInRequired {
  56. if !c.IsLogged {
  57. // Restrict API calls with error message.
  58. if auth.IsAPIPath(c.Req.URL.Path) {
  59. c.JSON(403, map[string]string{
  60. "message": "Only signed in user is allowed to call APIs.",
  61. })
  62. return
  63. }
  64. c.SetCookie("redirect_to", url.QueryEscape(setting.AppSubURL+c.Req.RequestURI), 0, setting.AppSubURL)
  65. c.Redirect(setting.AppSubURL + "/login")
  66. return
  67. } else if !c.User.IsActive && setting.Service.RegisterEmailConfirm {
  68. c.Data["Title"] = c.Tr("auth.active_your_account")
  69. c.HTML(200, "user/auth/activate")
  70. return
  71. }
  72. }
  73. // Redirect to log in page if auto-signin info is provided and has not signed in.
  74. if !options.SignOutRequired && !c.IsLogged && !auth.IsAPIPath(c.Req.URL.Path) &&
  75. len(c.GetCookie(setting.CookieUserName)) > 0 {
  76. c.SetCookie("redirect_to", url.QueryEscape(setting.AppSubURL+c.Req.RequestURI), 0, setting.AppSubURL)
  77. c.Redirect(setting.AppSubURL + "/login")
  78. return
  79. }
  80. if options.AdminRequired {
  81. if !c.User.IsAdmin {
  82. c.Redirect(setting.AppSubURL + "/")
  83. return
  84. }
  85. c.Data["PageIsAdmin"] = true
  86. }
  87. }
  88. }
  89. // RequireBasicAuth verifies HTTP Basic Authentication header with given credentials
  90. func (c *Context) RequireBasicAuth(username, password string) {
  91. fields := strings.Fields(c.Req.Header.Get("Authorization"))
  92. if len(fields) != 2 || fields[0] != "Basic" {
  93. c.Status(http.StatusUnauthorized)
  94. return
  95. }
  96. uname, passwd, _ := tool.BasicAuthDecode(fields[1])
  97. if uname != username || passwd != password {
  98. c.Status(http.StatusForbidden)
  99. return
  100. }
  101. }