Files
cms-server/service/service_auth/redirect.go
Asai Neko 0f1c5b1293
All checks were successful
Client CMS Check Build (NixCN CMS) TeamCity build finished
Backend Check Build (NixCN CMS) TeamCity build finished
Fix new user create 500 error
Signed-off-by: Asai Neko <sugar@sne.moe>
2026-01-29 13:42:00 +08:00

212 lines
5.0 KiB
Go

package service_auth
import (
"context"
"net/url"
"nixcn-cms/data"
"nixcn-cms/internal/authcode"
"nixcn-cms/internal/exception"
"nixcn-cms/service/shared"
"github.com/google/uuid"
"gorm.io/gorm"
)
type RedirectData struct {
ClientId string `json:"client_id"`
RedirectUri string `json:"redirect_uri"`
State string `json:"state"`
Code string `json:"code"`
}
type RedirectPayload struct {
Context context.Context
Data *RedirectData
}
type RedirectResult struct {
Common shared.CommonResult
Data string
}
func (self *AuthServiceImpl) Redirect(payload *RedirectPayload) (result *RedirectResult) {
var err error
authCode, ok := authcode.VerifyAuthCode(payload.Context, payload.Data.Code)
if !ok {
exception := new(exception.Builder).
SetStatus(exception.StatusUser).
SetService(exception.ServiceAuth).
SetEndpoint(exception.EndpointAuthServiceRedirect).
SetType(exception.TypeSpecific).
SetOriginal(exception.AuthRedirectTokenInvalid).
Throw(payload.Context)
result = &RedirectResult{
Common: shared.CommonResult{
HttpCode: 403,
Exception: exception,
},
}
return
}
userData, err := new(data.User).
GetByEmail(payload.Context, &authCode.Email)
if err != nil {
if err == gorm.ErrRecordNotFound {
userData = &data.User{}
userData.UUID = uuid.New()
userData.UserId = uuid.New()
userData.Email = authCode.Email
userData.Username = userData.UserId.String()
userData.PermissionLevel = 10
if err := userData.Create(payload.Context); err != nil {
exception := new(exception.Builder).
SetStatus(exception.StatusServer).
SetService(exception.ServiceAuth).
SetEndpoint(exception.EndpointAuthServiceRedirect).
SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorInternal).
SetError(err).
Throw(payload.Context)
result = &RedirectResult{
Common: shared.CommonResult{
HttpCode: 500,
Exception: exception,
},
}
return
}
} else {
exception := new(exception.Builder).
SetStatus(exception.StatusServer).
SetService(exception.ServiceAuth).
SetEndpoint(exception.EndpointAuthServiceRedirect).
SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorInternal).
SetError(err).
Throw(payload.Context)
result = &RedirectResult{
Common: shared.CommonResult{
HttpCode: 500,
Exception: exception,
},
}
return
}
}
clientData := new(data.Client)
client, err := clientData.GetClientByClientId(payload.Context, payload.Data.ClientId)
if err != nil {
exception := new(exception.Builder).
SetStatus(exception.StatusUser).
SetService(exception.ServiceAuth).
SetEndpoint(exception.EndpointAuthServiceRedirect).
SetType(exception.TypeSpecific).
SetOriginal(exception.AuthRedirectClientNotFound).
SetError(err).
Throw(payload.Context)
result = &RedirectResult{
Common: shared.CommonResult{
HttpCode: 400,
Exception: exception,
},
}
return
}
if err = client.ValidateRedirectURI(payload.Data.RedirectUri); err != nil {
exception := new(exception.Builder).
SetStatus(exception.StatusUser).
SetService(exception.ServiceAuth).
SetEndpoint(exception.EndpointAuthServiceRedirect).
SetType(exception.TypeSpecific).
SetOriginal(exception.AuthRedirectUriMismatch).
SetError(err).
Throw(payload.Context)
result = &RedirectResult{
Common: shared.CommonResult{
HttpCode: 400,
Exception: exception,
},
}
return
}
newCode, err := authcode.NewAuthCode(payload.Context, payload.Data.ClientId, authCode.Email)
if err != nil {
exception := new(exception.Builder).
SetStatus(exception.StatusServer).
SetService(exception.ServiceAuth).
SetEndpoint(exception.EndpointAuthServiceRedirect).
SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorInternal).
SetError(err).
Throw(payload.Context)
result = &RedirectResult{
Common: shared.CommonResult{
HttpCode: 500,
Exception: exception,
},
}
return
}
targetUrl, err := url.Parse(payload.Data.RedirectUri)
if err != nil {
exception := new(exception.Builder).
SetStatus(exception.StatusUser).
SetService(exception.ServiceAuth).
SetEndpoint(exception.EndpointAuthServiceRedirect).
SetType(exception.TypeSpecific).
SetOriginal(exception.AuthRedirectInvalidUri).
SetError(err).
Throw(payload.Context)
result = &RedirectResult{
Common: shared.CommonResult{
HttpCode: 400,
Exception: exception,
},
}
return
}
query := targetUrl.Query()
query.Set("code", newCode)
if payload.Data.State != "" {
query.Set("state", payload.Data.State)
}
targetUrl.RawQuery = query.Encode()
result = &RedirectResult{
Common: shared.CommonResult{
HttpCode: 200,
Exception: new(exception.Builder).
SetStatus(exception.StatusSuccess).
SetService(exception.ServiceAuth).
SetEndpoint(exception.EndpointAuthServiceRedirect).
SetType(exception.TypeCommon).
SetOriginal(exception.CommonSuccess).
Throw(payload.Context),
},
Data: targetUrl.String(),
}
return
}