sso.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. //go:embed static/*
  10. var staticFiles embed.FS //Static files for the SSO portal
  11. type SSOConfig struct {
  12. SystemUUID string //System UUID, should be passed in from main scope
  13. AuthURL string //Authentication subdomain URL
  14. PortalServerPort int //SSO portal server port
  15. Database *database.Database
  16. Logger *logger.Logger
  17. }
  18. type SSOHandler struct {
  19. cookieStore *sessions.CookieStore
  20. ssoPortalServer *http.Server
  21. ssoPortalMux *http.ServeMux
  22. Config *SSOConfig
  23. }
  24. // Create a new Zoraxy SSO handler
  25. func NewSSOHandler(config *SSOConfig) (*SSOHandler, error) {
  26. //Create a cookie store for the SSO handler
  27. cookieStore := sessions.NewCookieStore([]byte(config.SystemUUID))
  28. cookieStore.Options = &sessions.Options{
  29. Path: "",
  30. Domain: "",
  31. MaxAge: 0,
  32. Secure: false,
  33. HttpOnly: false,
  34. SameSite: 0,
  35. }
  36. //Create a table for the new sso user management system
  37. err := config.Database.NewTable("sso_users")
  38. if err != nil {
  39. return nil, err
  40. }
  41. //Create the SSO Handler
  42. thisHandler := SSOHandler{
  43. cookieStore: cookieStore,
  44. Config: config,
  45. }
  46. thisHandler.InitSSOPortal(config.PortalServerPort)
  47. return &thisHandler, nil
  48. }
  49. // ServeHTTP handle the SSO request by forwarding auth to the authelia server
  50. // return false if the request is not authorized and shall not be proceed
  51. // Note that only accounts that have SSO enabled will be handled by this handler
  52. func (h *SSOHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) bool {
  53. //Check if the user have the cookie "Zoraxy-SSO" set
  54. session, err := h.cookieStore.Get(r, "Zoraxy-SSO")
  55. if err != nil {
  56. //Redirect to auth subdomain
  57. http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
  58. return false
  59. }
  60. //Check if the user is logged in
  61. if session.Values["username"] != true {
  62. //Redirect to auth subdomain
  63. http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
  64. return false
  65. }
  66. //Check if the current request subdomain is allowed
  67. userName := session.Values["username"].(string)
  68. user, err := h.SSO_GetUser(userName)
  69. if err != nil {
  70. //User might have been removed from SSO. Redirect to auth subdomain
  71. http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
  72. return false
  73. }
  74. //Check if the user have access to the current subdomain
  75. if !user.Subdomains[r.Host].AllowAccess {
  76. //User is not allowed to access the current subdomain. Sent 403
  77. http.Error(w, "Forbidden", http.StatusForbidden)
  78. //TODO: Use better looking template if exists
  79. return false
  80. }
  81. //User is logged in, continue to the next handler
  82. return true
  83. }
  84. // Log a message with the SSO module tag
  85. func (h *SSOHandler) Log(message string, err error) {
  86. h.Config.Logger.PrintAndLog("SSO", message, err)
  87. }