package auth import ( "net/url" "nixcn-cms/data" "nixcn-cms/internal/exception" "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 == "" { errorCode := new(exception.Builder). SetStatus(exception.StatusClient). SetService(exception.ServiceAuth). SetEndpoint(exception.EndpointAuthServiceRedirect). SetType(exception.TypeCommon). SetOriginal(exception.CommonErrorInvalidInput). Build() utils.HttpResponse(c, 400, errorCode) return } redirectUri := c.Query("redirect_uri") if redirectUri == "" { errorCode := new(exception.Builder). SetStatus(exception.StatusClient). SetService(exception.ServiceAuth). SetEndpoint(exception.EndpointAuthServiceRedirect). SetType(exception.TypeCommon). SetOriginal(exception.CommonErrorInvalidInput). Build() utils.HttpResponse(c, 400, errorCode) return } state := c.Query("state") if state == "" { errorCode := new(exception.Builder). SetStatus(exception.StatusClient). SetService(exception.ServiceAuth). SetEndpoint(exception.EndpointAuthServiceRedirect). SetType(exception.TypeCommon). SetOriginal(exception.CommonErrorInvalidInput). Build() utils.HttpResponse(c, 400, errorCode) return } code := c.Query("code") // Verify email token authCode, ok := authcode.VerifyAuthCode(code) if !ok { errorCode := new(exception.Builder). SetStatus(exception.StatusClient). SetService(exception.ServiceAuth). SetEndpoint(exception.EndpointAuthServiceRedirect). SetType(exception.TypeSpecific). SetOriginal(exception.AuthRedirectTokenInvalid). Build() utils.HttpResponse(c, 403, errorCode) 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 { errorCode := new(exception.Builder). SetStatus(exception.StatusServer). SetService(exception.ServiceAuth). SetEndpoint(exception.EndpointAuthServiceRedirect). SetType(exception.TypeCommon). SetOriginal(exception.CommonErrorInternal). SetError(err). Build() utils.HttpResponse(c, 500, errorCode) return } } else { errorCode := new(exception.Builder). SetStatus(exception.StatusServer). SetService(exception.ServiceAuth). SetEndpoint(exception.EndpointAuthServiceRedirect). SetType(exception.TypeCommon). SetOriginal(exception.CommonErrorInternal). SetError(err). Build() utils.HttpResponse(c, 500, errorCode) return } } clientData := new(data.Client) client, err := clientData.GetClientByClientId(clientId) if err != nil { errorCode := new(exception.Builder). SetStatus(exception.StatusClient). SetService(exception.ServiceAuth). SetEndpoint(exception.EndpointAuthServiceRedirect). SetType(exception.TypeSpecific). SetOriginal(exception.AuthRedirectClientNotFound). SetError(err). Build() utils.HttpResponse(c, 400, errorCode) return } err = client.ValidateRedirectURI(redirectUri) if err != nil { errorCode := new(exception.Builder). SetStatus(exception.StatusClient). SetService(exception.ServiceAuth). SetEndpoint(exception.EndpointAuthServiceRedirect). SetType(exception.TypeSpecific). SetOriginal(exception.AuthRedirectUriMismatch). SetError(err). Build() utils.HttpResponse(c, 400, errorCode) return } newCode, err := authcode.NewAuthCode(clientId, authCode.Email) if err != nil { errorCode := new(exception.Builder). SetStatus(exception.StatusServer). SetService(exception.ServiceAuth). SetEndpoint(exception.EndpointAuthServiceRedirect). SetType(exception.TypeCommon). SetOriginal(exception.CommonErrorInternal). SetError(err). Build() utils.HttpResponse(c, 500, errorCode) return } url, err := url.Parse(redirectUri) if err != nil { errorCode := new(exception.Builder). SetStatus(exception.StatusClient). SetService(exception.ServiceAuth). SetEndpoint(exception.EndpointAuthServiceRedirect). SetType(exception.TypeSpecific). SetOriginal(exception.AuthRedirectInvalidUri). SetError(err). Build() utils.HttpResponse(c, 400, errorCode) return } query := url.Query() query.Set("code", newCode) url.RawQuery = query.Encode() c.Redirect(302, url.String()) }