auth.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package user
  2. import (
  3. "fmt"
  4. "github.com/0xJacky/Nginx-UI/api"
  5. "github.com/0xJacky/Nginx-UI/model"
  6. "github.com/0xJacky/Nginx-UI/settings"
  7. "net/http"
  8. "github.com/casdoor/casdoor-go-sdk/casdoorsdk"
  9. "github.com/gin-gonic/gin"
  10. "github.com/pkg/errors"
  11. "golang.org/x/crypto/bcrypt"
  12. "gorm.io/gorm"
  13. )
  14. type LoginUser struct {
  15. Name string `json:"name" binding:"required,max=255"`
  16. Password string `json:"password" binding:"required,max=255"`
  17. }
  18. func Login(c *gin.Context) {
  19. var user LoginUser
  20. ok := api.BindAndValid(c, &user)
  21. if !ok {
  22. return
  23. }
  24. u, _ := model.GetUser(user.Name)
  25. if err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(user.Password)); err != nil {
  26. c.JSON(http.StatusForbidden, gin.H{
  27. "message": "The username or password is incorrect",
  28. })
  29. return
  30. }
  31. token, err := model.GenerateJWT(u.Name)
  32. if err != nil {
  33. c.JSON(http.StatusInternalServerError, gin.H{
  34. "message": err.Error(),
  35. })
  36. return
  37. }
  38. c.JSON(http.StatusOK, gin.H{
  39. "message": "ok",
  40. "token": token,
  41. })
  42. }
  43. func Logout(c *gin.Context) {
  44. token := c.GetHeader("Authorization")
  45. if token != "" {
  46. err := model.DeleteToken(token)
  47. if err != nil {
  48. c.JSON(http.StatusInternalServerError, gin.H{
  49. "message": err.Error(),
  50. })
  51. return
  52. }
  53. }
  54. c.JSON(http.StatusNoContent, nil)
  55. }
  56. type CasdoorLoginUser struct {
  57. Code string `json:"code" binding:"required,max=255"`
  58. State string `json:"state" binding:"required,max=255"`
  59. }
  60. func CasdoorCallback(c *gin.Context) {
  61. var loginUser CasdoorLoginUser
  62. fmt.Println("CasdoorCallback called")
  63. ok := api.BindAndValid(c, &loginUser)
  64. if !ok {
  65. return
  66. }
  67. endpoint := settings.ServerSettings.CasdoorEndpoint
  68. clientId := settings.ServerSettings.CasdoorClientId
  69. clientSecret := settings.ServerSettings.CasdoorClientSecret
  70. certificate := settings.ServerSettings.CasdoorCertificate
  71. organization := settings.ServerSettings.CasdoorOrganization
  72. application := settings.ServerSettings.CasdoorApplication
  73. if endpoint == "" || clientId == "" || clientSecret == "" || certificate == "" || organization == "" || application == "" {
  74. c.JSON(http.StatusInternalServerError, gin.H{
  75. "message": "Casdoor is not configured",
  76. })
  77. return
  78. }
  79. casdoorsdk.InitConfig(endpoint, clientId, clientSecret, certificate, organization, application)
  80. token, err := casdoorsdk.GetOAuthToken(loginUser.Code, loginUser.State)
  81. if err != nil {
  82. c.JSON(http.StatusInternalServerError, gin.H{
  83. "message": err.Error(),
  84. })
  85. return
  86. }
  87. claims, err := casdoorsdk.ParseJwtToken(token.AccessToken)
  88. if err != nil {
  89. c.JSON(http.StatusInternalServerError, gin.H{
  90. "message": err.Error(),
  91. })
  92. return
  93. }
  94. u, err := model.GetUser(claims.Name)
  95. if err != nil {
  96. if errors.Is(err, gorm.ErrRecordNotFound) {
  97. c.JSON(http.StatusForbidden, gin.H{
  98. "message": "User not exist",
  99. })
  100. } else {
  101. c.JSON(http.StatusInternalServerError, gin.H{
  102. "message": err.Error(),
  103. })
  104. }
  105. return
  106. }
  107. userToken, err := model.GenerateJWT(u.Name)
  108. if err != nil {
  109. c.JSON(http.StatusInternalServerError, gin.H{
  110. "message": err.Error(),
  111. })
  112. return
  113. }
  114. c.JSON(http.StatusOK, gin.H{
  115. "message": "ok",
  116. "token": userToken,
  117. })
  118. }