server.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package sso
  2. import (
  3. "context"
  4. "net/http"
  5. "strconv"
  6. "time"
  7. "github.com/go-oauth2/oauth2/v4/errors"
  8. "imuslab.com/zoraxy/mod/utils"
  9. )
  10. /*
  11. server.go
  12. This is the web server for the SSO portal. It contains the
  13. HTTP server and the handlers for the SSO portal.
  14. If you are looking for handlers that changes the settings
  15. of the SSO portale or user management, please refer to
  16. handlers.go.
  17. */
  18. func (h *SSOHandler) InitSSOPortal(portalServerPort int) {
  19. //Create a new web server for the SSO portal
  20. pmux := http.NewServeMux()
  21. fs := http.FileServer(http.FS(staticFiles))
  22. pmux.Handle("/", fs)
  23. //Register API endpoint for the SSO portal
  24. pmux.HandleFunc("/sso/login", h.HandleLogin)
  25. //Register OAuth2 endpoints
  26. h.Oauth2Server.RegisterOauthEndpoints(pmux)
  27. h.ssoPortalMux = pmux
  28. }
  29. // StartSSOPortal start the SSO portal server
  30. // This function will block the main thread, call it in a goroutine
  31. func (h *SSOHandler) StartSSOPortal() error {
  32. if h.ssoPortalServer != nil {
  33. return errors.New("SSO portal server already running")
  34. }
  35. h.ssoPortalServer = &http.Server{
  36. Addr: ":" + strconv.Itoa(h.Config.PortalServerPort),
  37. Handler: h.ssoPortalMux,
  38. }
  39. err := h.ssoPortalServer.ListenAndServe()
  40. if err != nil && err != http.ErrServerClosed {
  41. h.Log("Failed to start SSO portal server", err)
  42. }
  43. return err
  44. }
  45. // StopSSOPortal stop the SSO portal server
  46. func (h *SSOHandler) StopSSOPortal() error {
  47. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  48. defer cancel()
  49. err := h.ssoPortalServer.Shutdown(ctx)
  50. if err != nil {
  51. h.Log("Failed to stop SSO portal server", err)
  52. return err
  53. }
  54. h.ssoPortalServer = nil
  55. return nil
  56. }
  57. // StartSSOPortal start the SSO portal server
  58. func (h *SSOHandler) RestartSSOServer() error {
  59. if h.ssoPortalServer != nil {
  60. err := h.StopSSOPortal()
  61. if err != nil {
  62. return err
  63. }
  64. }
  65. go h.StartSSOPortal()
  66. return nil
  67. }
  68. func (h *SSOHandler) IsRunning() bool {
  69. return h.ssoPortalServer != nil
  70. }
  71. // HandleLogin handle the login request
  72. func (h *SSOHandler) HandleLogin(w http.ResponseWriter, r *http.Request) {
  73. //Handle the login request
  74. username, err := utils.PostPara(r, "username")
  75. if err != nil {
  76. utils.SendErrorResponse(w, "invalid username or password")
  77. return
  78. }
  79. password, err := utils.PostPara(r, "password")
  80. if err != nil {
  81. utils.SendErrorResponse(w, "invalid username or password")
  82. return
  83. }
  84. rememberMe, err := utils.PostBool(r, "remember_me")
  85. if err != nil {
  86. rememberMe = false
  87. }
  88. //Check if the user exists
  89. userEntry, err := h.GetSSOUser(username)
  90. if err != nil {
  91. utils.SendErrorResponse(w, "user not found")
  92. return
  93. }
  94. //Check if the password is correct
  95. if !userEntry.VerifyPassword(password) {
  96. utils.SendErrorResponse(w, "incorrect password")
  97. return
  98. }
  99. //Create a new session for the user
  100. session, _ := h.cookieStore.Get(r, "Zoraxy-SSO")
  101. session.Values["username"] = username
  102. if rememberMe {
  103. session.Options.MaxAge = 86400 * 15 //15 days
  104. } else {
  105. session.Options.MaxAge = 3600 //1 hour
  106. }
  107. session.Save(r, w) //Save the session
  108. utils.SendOK(w)
  109. }