casdoor.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package user
  2. import (
  3. "fmt"
  4. "github.com/0xJacky/Nginx-UI/api"
  5. "github.com/0xJacky/Nginx-UI/internal/user"
  6. "github.com/0xJacky/Nginx-UI/settings"
  7. "github.com/casdoor/casdoor-go-sdk/casdoorsdk"
  8. "github.com/gin-gonic/gin"
  9. "errors"
  10. "github.com/uozi-tech/cosy"
  11. "gorm.io/gorm"
  12. "net/http"
  13. "net/url"
  14. "os"
  15. )
  16. type CasdoorLoginUser struct {
  17. Code string `json:"code" binding:"required,max=255"`
  18. State string `json:"state" binding:"required,max=255"`
  19. }
  20. func CasdoorCallback(c *gin.Context) {
  21. var loginUser CasdoorLoginUser
  22. ok := cosy.BindAndValid(c, &loginUser)
  23. if !ok {
  24. return
  25. }
  26. endpoint := settings.CasdoorSettings.Endpoint
  27. clientId := settings.CasdoorSettings.ClientId
  28. clientSecret := settings.CasdoorSettings.ClientSecret
  29. certificatePath := settings.CasdoorSettings.CertificatePath
  30. organization := settings.CasdoorSettings.Organization
  31. application := settings.CasdoorSettings.Application
  32. if endpoint == "" || clientId == "" || clientSecret == "" || certificatePath == "" ||
  33. organization == "" || application == "" {
  34. c.JSON(http.StatusInternalServerError, gin.H{
  35. "message": "Casdoor is not configured",
  36. })
  37. return
  38. }
  39. certBytes, err := os.ReadFile(certificatePath)
  40. if err != nil {
  41. api.ErrHandler(c, err)
  42. return
  43. }
  44. casdoorsdk.InitConfig(endpoint, clientId, clientSecret, string(certBytes), organization, application)
  45. token, err := casdoorsdk.GetOAuthToken(loginUser.Code, loginUser.State)
  46. if err != nil {
  47. api.ErrHandler(c, err)
  48. return
  49. }
  50. claims, err := casdoorsdk.ParseJwtToken(token.AccessToken)
  51. if err != nil {
  52. api.ErrHandler(c, err)
  53. return
  54. }
  55. u, err := user.GetUser(claims.Name)
  56. if err != nil {
  57. if errors.Is(err, gorm.ErrRecordNotFound) {
  58. c.JSON(http.StatusForbidden, gin.H{
  59. "message": "User not exist",
  60. })
  61. } else {
  62. api.ErrHandler(c, err)
  63. }
  64. return
  65. }
  66. userToken, err := user.GenerateJWT(u)
  67. if err != nil {
  68. api.ErrHandler(c, err)
  69. return
  70. }
  71. c.JSON(http.StatusOK, LoginResponse{
  72. Message: "ok",
  73. Token: userToken,
  74. })
  75. }
  76. func GetCasdoorUri(c *gin.Context) {
  77. clientId := settings.CasdoorSettings.ClientId
  78. redirectUri := settings.CasdoorSettings.RedirectUri
  79. state := settings.CasdoorSettings.Application
  80. endpoint := settings.CasdoorSettings.Endpoint
  81. // feature request #603
  82. if settings.CasdoorSettings.ExternalUrl != "" {
  83. endpoint = settings.CasdoorSettings.ExternalUrl
  84. }
  85. if endpoint == "" || clientId == "" || redirectUri == "" || state == "" {
  86. c.JSON(http.StatusOK, gin.H{
  87. "uri": "",
  88. })
  89. return
  90. }
  91. encodedRedirectUri := url.QueryEscape(redirectUri)
  92. c.JSON(http.StatusOK, gin.H{
  93. "uri": fmt.Sprintf(
  94. "%s/login/oauth/authorize?client_id=%s&response_type=code&redirect_uri=%s&state=%s&scope=read",
  95. endpoint, clientId, encodedRedirectUri, state),
  96. })
  97. }