package auth import ( "net/url" "nixcn-cms/data" "nixcn-cms/pkgs/authcode" "github.com/gin-gonic/gin" "github.com/google/uuid" "gorm.io/gorm" ) func Redirect(c *gin.Context) { clientId := c.Query("client_id") if clientId == "" { c.JSON(400, gin.H{"status": "invalid request"}) return } redirectUri := c.Query("redirect_uri") if redirectUri == "" { c.JSON(400, gin.H{"status": "invalid request"}) return } state := c.Query("state") if state == "" { c.JSON(400, gin.H{"status": "invalid request"}) return } code := c.Query("code") if code == "" { userIdOrig, ok := c.Get("user_id") if !ok || userIdOrig == "" { c.JSON(401, gin.H{"status": "unauthorized"}) return } userId, err := uuid.Parse(userIdOrig.(string)) if err != nil { c.JSON(500, gin.H{"status": "failed to parse uuid"}) return } userData := new(data.User) user, err := userData.GetByUserId(userId) if err != nil { c.JSON(500, gin.H{"status": "failed to get user id"}) return } code, err := authcode.NewAuthCode(clientId, user.Email) if err != nil { c.JSON(500, gin.H{"status": "code gen failed"}) return } url, err := url.Parse(redirectUri) if err != nil { c.JSON(400, gin.H{"status": "invalid redirect uri"}) return } query := url.Query() query.Set("code", code) url.RawQuery = query.Encode() c.Redirect(302, url.String()) } // Verify email token authCode, ok := authcode.VerifyAuthCode(code) if !ok { c.JSON(403, gin.H{"status": "invalid or expired token"}) return } // Verify if user exists userData := new(data.User) user, err := userData.GetByEmail(authCode.Email) if err != nil { if err == gorm.ErrRecordNotFound { // Create user user.UUID = uuid.New() user.UserId = uuid.New() user.Email = authCode.Email user.PermissionLevel = 10 if err := user.Create(); err != nil { c.JSON(500, gin.H{"status": "internal server error"}) return } } else { c.JSON(500, gin.H{"status": "internal server error"}) return } } clientData := new(data.Client) client, err := clientData.GetClientByClientId(clientId) if err != nil { c.JSON(400, gin.H{"status": "client not found"}) return } err = client.ValidateRedirectURI(redirectUri) if err != nil { c.JSON(400, gin.H{"status": "redirect uri not match"}) return } newCode, err := authcode.NewAuthCode(clientId, authCode.Email) if err != nil { c.JSON(500, gin.H{"status": "internal server error"}) return } url, err := url.Parse(redirectUri) if err != nil { c.JSON(400, gin.H{"status": "invalid redirect uri"}) return } query := url.Query() query.Set("code", newCode) url.RawQuery = query.Encode() c.Redirect(302, url.String()) }