sso.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. //Get the current uri for appending to the auth subdomain
  61. originalRequestURL := r.RequestURI
  62. //Check if the user have the cookie "Zoraxy-SSO" set
  63. session, err := h.cookieStore.Get(r, "Zoraxy-SSO")
  64. if err != nil {
  65. //Redirect to auth subdomain
  66. http.Redirect(w, r, h.Config.AuthURL+"?m=new&t="+originalRequestURL, http.StatusFound)
  67. return false
  68. }
  69. //Check if the user is logged in
  70. if session.Values["username"] != true {
  71. //Redirect to auth subdomain
  72. http.Redirect(w, r, h.Config.AuthURL+"?m=expired&t="+originalRequestURL, http.StatusFound)
  73. return false
  74. }
  75. //Check if the current request subdomain is allowed
  76. userName := session.Values["username"].(string)
  77. user, err := h.SSO_GetUser(userName)
  78. if err != nil {
  79. //User might have been removed from SSO. Redirect to auth subdomain
  80. http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
  81. return false
  82. }
  83. //Check if the user have access to the current subdomain
  84. if !user.Subdomains[r.Host].AllowAccess {
  85. //User is not allowed to access the current subdomain. Sent 403
  86. http.Error(w, "Forbidden", http.StatusForbidden)
  87. //TODO: Use better looking template if exists
  88. return false
  89. }
  90. //User is logged in, continue to the next handler
  91. return true
  92. }
  93. // Log a message with the SSO module tag
  94. func (h *SSOHandler) Log(message string, err error) {
  95. h.Config.Logger.PrintAndLog("SSO", message, err)
  96. }