auth.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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 context
  5. import (
  6. "net/http"
  7. "net/url"
  8. "strings"
  9. "github.com/go-macaron/csrf"
  10. "gopkg.in/macaron.v1"
  11. "gogs.io/gogs/internal/auth"
  12. "gogs.io/gogs/internal/conf"
  13. "gogs.io/gogs/internal/tool"
  14. )
  15. type ToggleOptions struct {
  16. SignInRequired bool
  17. SignOutRequired bool
  18. AdminRequired bool
  19. DisableCSRF bool
  20. }
  21. func Toggle(options *ToggleOptions) macaron.Handler {
  22. return func(c *Context) {
  23. // Cannot view any page before installation.
  24. if !conf.Security.InstallLock {
  25. c.RedirectSubpath("/install")
  26. return
  27. }
  28. // Check prohibit login users.
  29. if c.IsLogged && c.User.ProhibitLogin {
  30. c.Data["Title"] = c.Tr("auth.prohibit_login")
  31. c.Success("user/auth/prohibit_login")
  32. return
  33. }
  34. // Check non-logged users landing page.
  35. if !c.IsLogged && c.Req.RequestURI == "/" && conf.Server.LandingURL != "/" {
  36. c.RedirectSubpath(conf.Server.LandingURL)
  37. return
  38. }
  39. // Redirect to dashboard if user tries to visit any non-login page.
  40. if options.SignOutRequired && c.IsLogged && c.Req.RequestURI != "/" {
  41. c.RedirectSubpath("/")
  42. return
  43. }
  44. if !options.SignOutRequired && !options.DisableCSRF && c.Req.Method == "POST" && !auth.IsAPIPath(c.Req.URL.Path) {
  45. csrf.Validate(c.Context, c.csrf)
  46. if c.Written() {
  47. return
  48. }
  49. }
  50. if options.SignInRequired {
  51. if !c.IsLogged {
  52. // Restrict API calls with error message.
  53. if auth.IsAPIPath(c.Req.URL.Path) {
  54. c.JSON(http.StatusForbidden, map[string]string{
  55. "message": "Only authenticated user is allowed to call APIs.",
  56. })
  57. return
  58. }
  59. c.SetCookie("redirect_to", url.QueryEscape(conf.Server.Subpath+c.Req.RequestURI), 0, conf.Server.Subpath)
  60. c.RedirectSubpath("/user/login")
  61. return
  62. } else if !c.User.IsActive && conf.Auth.RequireEmailConfirmation {
  63. c.Title("auth.active_your_account")
  64. c.Success("user/auth/activate")
  65. return
  66. }
  67. }
  68. // Redirect to log in page if auto-signin info is provided and has not signed in.
  69. if !options.SignOutRequired && !c.IsLogged && !auth.IsAPIPath(c.Req.URL.Path) &&
  70. len(c.GetCookie(conf.Security.CookieUsername)) > 0 {
  71. c.SetCookie("redirect_to", url.QueryEscape(conf.Server.Subpath+c.Req.RequestURI), 0, conf.Server.Subpath)
  72. c.RedirectSubpath("/user/login")
  73. return
  74. }
  75. if options.AdminRequired {
  76. if !c.User.IsAdmin {
  77. c.Status(http.StatusForbidden)
  78. return
  79. }
  80. c.PageIs("Admin")
  81. }
  82. }
  83. }
  84. // RequireBasicAuth verifies HTTP Basic Authentication header with given credentials.
  85. func (c *Context) RequireBasicAuth(username, password string) {
  86. fields := strings.Fields(c.Req.Header.Get("Authorization"))
  87. if len(fields) != 2 || fields[0] != "Basic" {
  88. c.Status(http.StatusUnauthorized)
  89. return
  90. }
  91. uname, passwd, _ := tool.BasicAuthDecode(fields[1])
  92. if uname != username || passwd != password {
  93. c.Status(http.StatusForbidden)
  94. return
  95. }
  96. }