sso.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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
  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. Config *SSOConfig
  30. }
  31. // Create a new Zoraxy SSO handler
  32. func NewSSOHandler(config *SSOConfig) (*SSOHandler, error) {
  33. //Create a cookie store for the SSO handler
  34. cookieStore := sessions.NewCookieStore([]byte(config.SystemUUID))
  35. cookieStore.Options = &sessions.Options{
  36. Path: "",
  37. Domain: "",
  38. MaxAge: 0,
  39. Secure: false,
  40. HttpOnly: false,
  41. SameSite: 0,
  42. }
  43. //Create a table for the new sso user management system
  44. err := config.Database.NewTable("sso_users")
  45. if err != nil {
  46. return nil, err
  47. }
  48. //Create the SSO Handler
  49. thisHandler := SSOHandler{
  50. cookieStore: cookieStore,
  51. Config: config,
  52. }
  53. thisHandler.InitSSOPortal(config.PortalServerPort)
  54. return &thisHandler, nil
  55. }
  56. // ServeForwardAuth handle the SSO request by forwarding auth to the authelia server
  57. // return false if the request is not authorized and shall not be proceed
  58. // Note that only accounts that have SSO enabled will be handled by this handler
  59. func (h *SSOHandler) ServeForwardAuth(w http.ResponseWriter, r *http.Request) bool {
  60. //Check if the user have the cookie "Zoraxy-SSO" set
  61. session, err := h.cookieStore.Get(r, "Zoraxy-SSO")
  62. if err != nil {
  63. //Redirect to auth subdomain
  64. http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
  65. return false
  66. }
  67. //Check if the user is logged in
  68. if session.Values["username"] != true {
  69. //Redirect to auth subdomain
  70. http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
  71. return false
  72. }
  73. //Check if the current request subdomain is allowed
  74. userName := session.Values["username"].(string)
  75. user, err := h.SSO_GetUser(userName)
  76. if err != nil {
  77. //User might have been removed from SSO. Redirect to auth subdomain
  78. http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
  79. return false
  80. }
  81. //Check if the user have access to the current subdomain
  82. if !user.Subdomains[r.Host].AllowAccess {
  83. //User is not allowed to access the current subdomain. Sent 403
  84. http.Error(w, "Forbidden", http.StatusForbidden)
  85. //TODO: Use better looking template if exists
  86. return false
  87. }
  88. //User is logged in, continue to the next handler
  89. return true
  90. }
  91. // Log a message with the SSO module tag
  92. func (h *SSOHandler) Log(message string, err error) {
  93. h.Config.Logger.PrintAndLog("SSO", message, err)
  94. }