123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- package sso
- import (
- "embed"
- "net/http"
- "github.com/gorilla/sessions"
- "imuslab.com/zoraxy/mod/database"
- "imuslab.com/zoraxy/mod/info/logger"
- )
- //go:embed static/*
- var staticFiles embed.FS //Static files for the SSO portal
- type SSOConfig struct {
- SystemUUID string //System UUID, should be passed in from main scope
- AuthURL string //Authentication subdomain URL
- PortalServerPort int //SSO portal server port
- Database *database.Database
- Logger *logger.Logger
- }
- type SSOHandler struct {
- cookieStore *sessions.CookieStore
- ssoPortalServer *http.Server
- ssoPortalMux *http.ServeMux
- Config *SSOConfig
- }
- // Create a new Zoraxy SSO handler
- func NewSSOHandler(config *SSOConfig) (*SSOHandler, error) {
- //Create a cookie store for the SSO handler
- cookieStore := sessions.NewCookieStore([]byte(config.SystemUUID))
- cookieStore.Options = &sessions.Options{
- Path: "",
- Domain: "",
- MaxAge: 0,
- Secure: false,
- HttpOnly: false,
- SameSite: 0,
- }
- //Create a table for the new sso user management system
- err := config.Database.NewTable("sso_users")
- if err != nil {
- return nil, err
- }
- //Create the SSO Handler
- thisHandler := SSOHandler{
- cookieStore: cookieStore,
- Config: config,
- }
- thisHandler.InitSSOPortal(config.PortalServerPort)
- return &thisHandler, nil
- }
- // ServeHTTP handle the SSO request by forwarding auth to the authelia server
- // return false if the request is not authorized and shall not be proceed
- // Note that only accounts that have SSO enabled will be handled by this handler
- func (h *SSOHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) bool {
- //Check if the user have the cookie "Zoraxy-SSO" set
- session, err := h.cookieStore.Get(r, "Zoraxy-SSO")
- if err != nil {
- //Redirect to auth subdomain
- http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
- return false
- }
- //Check if the user is logged in
- if session.Values["username"] != true {
- //Redirect to auth subdomain
- http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
- return false
- }
- //Check if the current request subdomain is allowed
- userName := session.Values["username"].(string)
- user, err := h.SSO_GetUser(userName)
- if err != nil {
- //User might have been removed from SSO. Redirect to auth subdomain
- http.Redirect(w, r, h.Config.AuthURL, http.StatusFound)
- return false
- }
- //Check if the user have access to the current subdomain
- if !user.Subdomains[r.Host].AllowAccess {
- //User is not allowed to access the current subdomain. Sent 403
- http.Error(w, "Forbidden", http.StatusForbidden)
- //TODO: Use better looking template if exists
- return false
- }
- //User is logged in, continue to the next handler
- return true
- }
- // Log a message with the SSO module tag
- func (h *SSOHandler) Log(message string, err error) {
- h.Config.Logger.PrintAndLog("SSO", message, err)
- }
|