皮肤删除接口
This commit is contained in:
parent
f966b1bfdc
commit
bdd93bd7d2
@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"image/png"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@ -46,14 +47,14 @@ func (y *Yggdrasil) validTextureType(ctx context.Context, w http.ResponseWriter,
|
||||
func (y *Yggdrasil) PutTexture() httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
ctx := r.Context()
|
||||
uuid := p.ByName("uuid")
|
||||
textureType := p.ByName("textureType")
|
||||
if uuid == "" || textureType == "" {
|
||||
y.logger.DebugContext(ctx, "路径中缺少参数 uuid / textureType")
|
||||
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: "路径中缺少参数 uuid / textureType"}, 400)
|
||||
uuid, textureType, ok := getUUIDbyParams(ctx, p, y.logger, w)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
token := y.getTokenbyAuthorization(ctx, w, r)
|
||||
if token == "" {
|
||||
return
|
||||
}
|
||||
|
||||
model := r.FormValue("model")
|
||||
|
||||
@ -114,3 +115,40 @@ func (y *Yggdrasil) PutTexture() httprouter.Handle {
|
||||
w.WriteHeader(204)
|
||||
}
|
||||
}
|
||||
|
||||
func getUUIDbyParams(ctx context.Context, p httprouter.Params, l *slog.Logger, w http.ResponseWriter) (string, string, bool) {
|
||||
uuid := p.ByName("uuid")
|
||||
textureType := p.ByName("textureType")
|
||||
if uuid == "" || textureType == "" {
|
||||
l.DebugContext(ctx, "路径中缺少参数 uuid / textureType")
|
||||
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: "路径中缺少参数 uuid / textureType"}, 400)
|
||||
return "", "", false
|
||||
}
|
||||
return uuid, textureType, true
|
||||
}
|
||||
|
||||
func (y *Yggdrasil) DelTexture() httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
ctx := r.Context()
|
||||
uuid, textureType, ok := getUUIDbyParams(ctx, p, y.logger, w)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
token := y.getTokenbyAuthorization(ctx, w, r)
|
||||
if token == "" {
|
||||
return
|
||||
}
|
||||
err := y.yggdrasilService.DelTexture(ctx, uuid, token, textureType)
|
||||
if err != nil {
|
||||
if errors.Is(err, utils.ErrTokenInvalid) {
|
||||
y.logger.DebugContext(ctx, err.Error())
|
||||
w.WriteHeader(401)
|
||||
return
|
||||
}
|
||||
y.logger.WarnContext(ctx, err.Error())
|
||||
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: err.Error()}, 500)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(204)
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ func newYggdrasil(r *httprouter.Router, handelY yggdrasil.Yggdrasil) error {
|
||||
r.POST("/api/yggdrasil/authserver/invalidate", handelY.Invalidate())
|
||||
r.POST("/api/yggdrasil/authserver/refresh", handelY.Refresh())
|
||||
r.PUT("/api/yggdrasil/api/user/profile/:uuid/:textureType", handelY.PutTexture())
|
||||
r.DELETE("/api/yggdrasil/api/user/profile/:uuid/:textureType", handelY.DelTexture())
|
||||
r.GET("/api/yggdrasil", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
w.Write([]byte(`{
|
||||
"meta": {
|
||||
|
@ -24,21 +24,11 @@ var (
|
||||
ErrUUIDNotEq = errors.New("uuid 不相同")
|
||||
)
|
||||
|
||||
func (y *Yggdrasil) PutTexture(ctx context.Context, token string, texturebyte []byte, model string, uuid string, textureType string) error {
|
||||
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, y.client, &y.prikey.PublicKey, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("PutTexture: %w", err)
|
||||
}
|
||||
if uuid != t.Subject {
|
||||
return fmt.Errorf("PutTexture: %w", ErrUUIDNotEq)
|
||||
}
|
||||
|
||||
up, err := y.client.UserProfile.Query().Where(userprofile.HasUserWith(user.ID(t.UID))).First(ctx)
|
||||
|
||||
err = utils.WithTx(ctx, y.client, func(tx *ent.Tx) error {
|
||||
func (y *Yggdrasil) delTexture(ctx context.Context, userProfileID int, textureType string) error {
|
||||
err := utils.WithTx(ctx, y.client, func(tx *ent.Tx) error {
|
||||
// 查找此用户该类型下是否已经存在皮肤
|
||||
tl, err := tx.UserTexture.Query().Where(usertexture.And(
|
||||
usertexture.UserProfileID(up.ID),
|
||||
usertexture.UserProfileID(userProfileID),
|
||||
usertexture.Type(textureType),
|
||||
)).ForUpdate().All(ctx)
|
||||
if err != nil {
|
||||
@ -75,11 +65,55 @@ func (y *Yggdrasil) PutTexture(ctx context.Context, token string, texturebyte []
|
||||
return item.UserProfileID
|
||||
})
|
||||
// 中间表删除记录
|
||||
// UserProfile 上没有于此相关的字段,所以无需操作
|
||||
_, err = tx.UserTexture.Delete().Where(usertexture.UserProfileIDIn(ids...)).Exec(ctx)
|
||||
return err
|
||||
// 小概率皮肤上传后,高并发时被此处清理。问题不大重新上传一遍就行。
|
||||
// 条件为使用一个独一无二的皮肤的用户,更换皮肤时,另一个用户同时更换自己的皮肤到这个独一无二的皮肤上。
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("delTexture: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (y *Yggdrasil) DelTexture(ctx context.Context, uuid string, token string, textureType string) error {
|
||||
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, y.client, &y.prikey.PublicKey, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("DelTexture: %w", err)
|
||||
}
|
||||
if uuid != t.Subject {
|
||||
return fmt.Errorf("PutTexture: %w", errors.Join(ErrUUIDNotEq, utilsService.ErrTokenInvalid))
|
||||
}
|
||||
up, err := y.client.UserProfile.Query().Where(userprofile.HasUserWith(user.ID(t.UID))).First(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("DelTexture: %w", err)
|
||||
}
|
||||
err = y.delTexture(ctx, up.ID, textureType)
|
||||
if err != nil {
|
||||
return fmt.Errorf("DelTexture: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (y *Yggdrasil) PutTexture(ctx context.Context, token string, texturebyte []byte, model string, uuid string, textureType string) error {
|
||||
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, y.client, &y.prikey.PublicKey, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("PutTexture: %w", err)
|
||||
}
|
||||
if uuid != t.Subject {
|
||||
return fmt.Errorf("PutTexture: %w", errors.Join(ErrUUIDNotEq, utilsService.ErrTokenInvalid))
|
||||
}
|
||||
|
||||
up, err := y.client.UserProfile.Query().Where(userprofile.HasUserWith(user.ID(t.UID))).First(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("PutTexture: %w", err)
|
||||
}
|
||||
|
||||
err = y.delTexture(ctx, up.ID, textureType)
|
||||
if err != nil {
|
||||
return fmt.Errorf("PutTexture: %w", err)
|
||||
}
|
||||
|
||||
hashstr, err := createTextureFile(y.config.TexturePath, texturebyte)
|
||||
if err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user