server.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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 API endpoint for autodiscovery
  26. pmux.HandleFunc("/.well-known/openid-configuration", h.HandleDiscoveryRequest)
  27. //Register OAuth2 endpoints
  28. h.Oauth2Server.RegisterOauthEndpoints(pmux)
  29. h.ssoPortalMux = pmux
  30. }
  31. // StartSSOPortal start the SSO portal server
  32. // This function will block the main thread, call it in a goroutine
  33. func (h *SSOHandler) StartSSOPortal() error {
  34. if h.ssoPortalServer != nil {
  35. return errors.New("SSO portal server already running")
  36. }
  37. h.ssoPortalServer = &http.Server{
  38. Addr: ":" + strconv.Itoa(h.Config.PortalServerPort),
  39. Handler: h.ssoPortalMux,
  40. }
  41. err := h.ssoPortalServer.ListenAndServe()
  42. if err != nil && err != http.ErrServerClosed {
  43. h.Log("Failed to start SSO portal server", err)
  44. }
  45. return err
  46. }
  47. // StopSSOPortal stop the SSO portal server
  48. func (h *SSOHandler) StopSSOPortal() error {
  49. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  50. defer cancel()
  51. err := h.ssoPortalServer.Shutdown(ctx)
  52. if err != nil {
  53. h.Log("Failed to stop SSO portal server", err)
  54. return err
  55. }
  56. h.ssoPortalServer = nil
  57. return nil
  58. }
  59. // StartSSOPortal start the SSO portal server
  60. func (h *SSOHandler) RestartSSOServer() error {
  61. if h.ssoPortalServer != nil {
  62. err := h.StopSSOPortal()
  63. if err != nil {
  64. return err
  65. }
  66. }
  67. go h.StartSSOPortal()
  68. return nil
  69. }
  70. func (h *SSOHandler) IsRunning() bool {
  71. return h.ssoPortalServer != nil
  72. }
  73. // HandleLogin handle the login request
  74. func (h *SSOHandler) HandleLogin(w http.ResponseWriter, r *http.Request) {
  75. //Handle the login request
  76. username, err := utils.PostPara(r, "username")
  77. if err != nil {
  78. utils.SendErrorResponse(w, "invalid username or password")
  79. return
  80. }
  81. password, err := utils.PostPara(r, "password")
  82. if err != nil {
  83. utils.SendErrorResponse(w, "invalid username or password")
  84. return
  85. }
  86. rememberMe, err := utils.PostBool(r, "remember_me")
  87. if err != nil {
  88. rememberMe = false
  89. }
  90. //Check if the user exists
  91. userEntry, err := h.GetSSOUser(username)
  92. if err != nil {
  93. utils.SendErrorResponse(w, "user not found")
  94. return
  95. }
  96. //Check if the password is correct
  97. if !userEntry.VerifyPassword(password) {
  98. utils.SendErrorResponse(w, "incorrect password")
  99. return
  100. }
  101. //Create a new session for the user
  102. session, _ := h.cookieStore.Get(r, "Zoraxy-SSO")
  103. session.Values["username"] = username
  104. if rememberMe {
  105. session.Options.MaxAge = 86400 * 15 //15 days
  106. } else {
  107. session.Options.MaxAge = 3600 //1 hour
  108. }
  109. session.Save(r, w) //Save the session
  110. utils.SendOK(w)
  111. }