package sso import ( "context" "net/http" "strconv" "time" "github.com/go-oauth2/oauth2/v4/errors" "imuslab.com/zoraxy/mod/utils" ) /* server.go This is the web server for the SSO portal. It contains the HTTP server and the handlers for the SSO portal. If you are looking for handlers that changes the settings of the SSO portale or user management, please refer to handlers.go. */ func (h *SSOHandler) InitSSOPortal(portalServerPort int) { //Create a new web server for the SSO portal pmux := http.NewServeMux() fs := http.FileServer(http.FS(staticFiles)) pmux.Handle("/", fs) //Register API endpoint for the SSO portal pmux.HandleFunc("/sso/login", h.HandleLogin) //Register API endpoint for autodiscovery pmux.HandleFunc("/.well-known/openid-configuration", h.HandleDiscoveryRequest) //Register OAuth2 endpoints h.Oauth2Server.RegisterOauthEndpoints(pmux) h.ssoPortalMux = pmux } // StartSSOPortal start the SSO portal server // This function will block the main thread, call it in a goroutine func (h *SSOHandler) StartSSOPortal() error { if h.ssoPortalServer != nil { return errors.New("SSO portal server already running") } h.ssoPortalServer = &http.Server{ Addr: ":" + strconv.Itoa(h.Config.PortalServerPort), Handler: h.ssoPortalMux, } err := h.ssoPortalServer.ListenAndServe() if err != nil && err != http.ErrServerClosed { h.Log("Failed to start SSO portal server", err) } return err } // StopSSOPortal stop the SSO portal server func (h *SSOHandler) StopSSOPortal() error { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() err := h.ssoPortalServer.Shutdown(ctx) if err != nil { h.Log("Failed to stop SSO portal server", err) return err } h.ssoPortalServer = nil return nil } // StartSSOPortal start the SSO portal server func (h *SSOHandler) RestartSSOServer() error { if h.ssoPortalServer != nil { err := h.StopSSOPortal() if err != nil { return err } } go h.StartSSOPortal() return nil } func (h *SSOHandler) IsRunning() bool { return h.ssoPortalServer != nil } // HandleLogin handle the login request func (h *SSOHandler) HandleLogin(w http.ResponseWriter, r *http.Request) { //Handle the login request username, err := utils.PostPara(r, "username") if err != nil { utils.SendErrorResponse(w, "invalid username or password") return } password, err := utils.PostPara(r, "password") if err != nil { utils.SendErrorResponse(w, "invalid username or password") return } rememberMe, err := utils.PostBool(r, "remember_me") if err != nil { rememberMe = false } //Check if the user exists userEntry, err := h.GetSSOUser(username) if err != nil { utils.SendErrorResponse(w, "user not found") return } //Check if the password is correct if !userEntry.VerifyPassword(password) { utils.SendErrorResponse(w, "incorrect password") return } //Create a new session for the user session, _ := h.cookieStore.Get(r, "Zoraxy-SSO") session.Values["username"] = username if rememberMe { session.Options.MaxAge = 86400 * 15 //15 days } else { session.Options.MaxAge = 3600 //1 hour } session.Save(r, w) //Save the session utils.SendOK(w) }