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.ErrorStatusClient). SetService(exception.AuthService). SetEndpoint(exception.AuthRedirectEndpoint). SetType(exception.ErrorTypeCommon). SetOriginal(exception.CommonErrorInvalidInput). Build() utils.HttpResponse(c, 400, errorCode) return } redirectUri := c.Query("redirect_uri") if redirectUri == "" { errorCode := new(exception.Builder). SetStatus(exception.ErrorStatusClient). SetService(exception.AuthService). SetEndpoint(exception.AuthRedirectEndpoint). SetType(exception.ErrorTypeCommon). SetOriginal(exception.CommonErrorInvalidInput). Build() utils.HttpResponse(c, 400, errorCode) return } state := c.Query("state") if state == "" { errorCode := new(exception.Builder). SetStatus(exception.ErrorStatusClient). SetService(exception.AuthService). SetEndpoint(exception.AuthRedirectEndpoint). SetType(exception.ErrorTypeCommon). 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.ErrorStatusClient). SetService(exception.AuthService). SetEndpoint(exception.AuthRedirectEndpoint). SetType(exception.ErrorTypeSpecific). 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.ErrorStatusServer). SetService(exception.AuthService). SetEndpoint(exception.AuthRedirectEndpoint). SetType(exception.ErrorTypeCommon). SetOriginal(exception.CommonErrorInternal). Build() utils.HttpResponse(c, 500, errorCode) return } } else { errorCode := new(exception.Builder). SetStatus(exception.ErrorStatusServer). SetService(exception.AuthService). SetEndpoint(exception.AuthRedirectEndpoint). SetType(exception.ErrorTypeCommon). SetOriginal(exception.CommonErrorInternal). 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.ErrorStatusClient). SetService(exception.AuthService). SetEndpoint(exception.AuthRedirectEndpoint). SetType(exception.ErrorTypeSpecific). SetOriginal(exception.AuthRedirectClientNotFound). Build() utils.HttpResponse(c, 400, errorCode) return } err = client.ValidateRedirectURI(redirectUri) if err != nil { errorCode := new(exception.Builder). SetStatus(exception.ErrorStatusClient). SetService(exception.AuthService). SetEndpoint(exception.AuthRedirectEndpoint). SetType(exception.ErrorTypeSpecific). SetOriginal(exception.AuthRedirectUriMismatch). Build() utils.HttpResponse(c, 400, errorCode) return } newCode, err := authcode.NewAuthCode(clientId, authCode.Email) if err != nil { errorCode := new(exception.Builder). SetStatus(exception.ErrorStatusServer). SetService(exception.AuthService). SetEndpoint(exception.AuthRedirectEndpoint). SetType(exception.ErrorTypeCommon). SetOriginal(exception.CommonErrorInternal). Build() utils.HttpResponse(c, 500, errorCode) return } url, err := url.Parse(redirectUri) if err != nil { errorCode := new(exception.Builder). SetStatus(exception.ErrorStatusClient). SetService(exception.AuthService). SetEndpoint(exception.AuthRedirectEndpoint). SetType(exception.ErrorTypeSpecific). SetOriginal(exception.AuthRedirectInvalidUri). Build() utils.HttpResponse(c, 400, errorCode) return } query := url.Query() query.Set("code", newCode) url.RawQuery = query.Encode() c.Redirect(302, url.String()) }