Update multiple services and middlewares to pass the original error to exception.Builder before building the error code. Co-authored-by: Gemini <gemini@google.com>
171 lines
4.5 KiB
Go
171 lines
4.5 KiB
Go
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())
|
|
}
|