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