1
0

sso.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package sso
  2. import (
  3. "embed"
  4. "net/http"
  5. "github.com/gorilla/sessions"
  6. "imuslab.com/zoraxy/mod/database"
  7. "imuslab.com/zoraxy/mod/info/logger"
  8. )
  9. /*
  10. sso.go
  11. This file contains the main SSO handler and the SSO configuration
  12. structure. It also contains the main SSO handler functions.
  13. SSO web interface are stored in the static folder, which is embedded
  14. into the binary.
  15. */
  16. //go:embed static/*
  17. var staticFiles embed.FS //Static files for the SSO portal
  18. type SSOConfig struct {
  19. SystemUUID string //System UUID, should be passed in from main scope
  20. AuthURL string //Authentication subdomain URL, e.g. auth.example.com
  21. PortalServerPort int //SSO portal server port
  22. Database *database.Database
  23. Logger *logger.Logger
  24. }
  25. type SSOHandler struct {
  26. cookieStore *sessions.CookieStore
  27. ssoPortalServer *http.Server
  28. ssoPortalMux *http.ServeMux
  29. Oauth2Server *OAuth2Server
  30. Config *SSOConfig
  31. }
  32. // Create a new Zoraxy SSO handler
  33. func NewSSOHandler(config *SSOConfig) (*SSOHandler, error) {
  34. //Create a cookie store for the SSO handler
  35. cookieStore := sessions.NewCookieStore([]byte(config.SystemUUID))
  36. cookieStore.Options = &sessions.Options{
  37. Path: "",
  38. Domain: "",
  39. MaxAge: 0,
  40. Secure: false,
  41. HttpOnly: false,
  42. SameSite: 0,
  43. }
  44. //Create a table for the new sso user management system
  45. err := config.Database.NewTable("sso_users")
  46. if err != nil {
  47. return nil, err
  48. }
  49. //Create the SSO Handler
  50. thisHandler := SSOHandler{
  51. cookieStore: cookieStore,
  52. Config: config,
  53. }
  54. //Create an oauth2 server
  55. oauth2Server, err := NewOAuth2Server(config, &thisHandler)
  56. if err != nil {
  57. return nil, err
  58. }
  59. //Register endpoints
  60. thisHandler.Oauth2Server = oauth2Server
  61. thisHandler.InitSSOPortal(config.PortalServerPort)
  62. return &thisHandler, nil
  63. }
  64. // ServeForwardAuth handle the SSO request by forwarding auth to the authelia server
  65. // return false if the request is not authorized and shall not be proceed
  66. // Note that only accounts that have SSO enabled will be handled by this handler
  67. func (h *SSOHandler) ServeForwardAuth(w http.ResponseWriter, r *http.Request) bool {
  68. //Get the current uri for appending to the auth subdomain
  69. originalRequestURL := r.RequestURI
  70. //Check if the user have the cookie "Zoraxy-SSO" set
  71. session, err := h.cookieStore.Get(r, "Zoraxy-SSO")
  72. if err != nil {
  73. //Redirect to auth subdomain
  74. http.Redirect(w, r, h.Config.AuthURL+"?m=new&t="+originalRequestURL, http.StatusFound)
  75. return false
  76. }
  77. //Check if the user is logged in
  78. if session.Values["username"] != true {
  79. //Redirect to auth subdomain
  80. http.Redirect(w, r, h.Config.AuthURL+"?m=expired&t="+originalRequestURL, http.StatusFound)
  81. return false
  82. }
  83. //Check if the current request subdomain is allowed
  84. userName := session.Values["username"].(string)
  85. user, err := h.SSO_GetUser(userName)
  86. if err != nil {
  87. //User might have been removed from SSO. Redirect to auth subdomain
  88. http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
  89. return false
  90. }
  91. //Check if the user have access to the current subdomain
  92. if !user.Subdomains[r.Host].AllowAccess {
  93. //User is not allowed to access the current subdomain. Sent 403
  94. http.Error(w, "Forbidden", http.StatusForbidden)
  95. //TODO: Use better looking template if exists
  96. return false
  97. }
  98. //User is logged in, continue to the next handler
  99. return true
  100. }
  101. // Log a message with the SSO module tag
  102. func (h *SSOHandler) Log(message string, err error) {
  103. h.Config.Logger.PrintAndLog("SSO", message, err)
  104. }