用中间件验证
This commit is contained in:
parent
a51d39b141
commit
fc7f3234dc
@ -7,7 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/service"
|
"github.com/xmdhs/authlib-skin/service"
|
||||||
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -60,10 +59,6 @@ func (h *Handel) UserInfo() http.HandlerFunc {
|
|||||||
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
u, err := h.webService.Info(ctx, t)
|
u, err := h.webService.Info(ctx, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, utilsService.ErrTokenInvalid) {
|
|
||||||
h.handleError(ctx, w, "token 无效", model.ErrAuth, 401, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,11 @@ package yggdrasil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,18 +17,15 @@ func (y *Yggdrasil) SessionJoin() http.HandlerFunc {
|
|||||||
if !has {
|
if !has {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
|
|
||||||
ip, err := utils.GetIP(r)
|
ip, err := utils.GetIP(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
y.handleYgError(ctx, w, err)
|
y.handleYgError(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = y.yggdrasilService.SessionJoin(ctx, a, ip)
|
err = y.yggdrasilService.SessionJoin(ctx, a, t, ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sutils.ErrTokenInvalid) {
|
|
||||||
y.logger.DebugContext(ctx, err.Error())
|
|
||||||
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: "Invalid token.", Error: "ForbiddenOperationException"}, 403)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
y.handleYgError(ctx, w, err)
|
y.handleYgError(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
"github.com/xmdhs/authlib-skin/service/utils"
|
|
||||||
|
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (y *Yggdrasil) getTokenbyAuthorization(ctx context.Context, w http.ResponseWriter, r *http.Request) string {
|
func (y *Yggdrasil) getTokenbyAuthorization(ctx context.Context, w http.ResponseWriter, r *http.Request) string {
|
||||||
@ -51,10 +53,7 @@ func (y *Yggdrasil) PutTexture() http.HandlerFunc {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
token := y.getTokenbyAuthorization(ctx, w, r)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
if token == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
model := r.FormValue("model")
|
model := r.FormValue("model")
|
||||||
|
|
||||||
@ -100,9 +99,9 @@ func (y *Yggdrasil) PutTexture() http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = y.yggdrasilService.PutTexture(ctx, token, skin, model, uuid, textureType)
|
err = y.yggdrasilService.PutTexture(ctx, t, skin, model, uuid, textureType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, utils.ErrTokenInvalid) {
|
if errors.Is(err, yggdrasilS.ErrUUIDNotEq) {
|
||||||
y.logger.DebugContext(ctx, err.Error())
|
y.logger.DebugContext(ctx, err.Error())
|
||||||
w.WriteHeader(401)
|
w.WriteHeader(401)
|
||||||
return
|
return
|
||||||
@ -120,7 +119,7 @@ func getUUIDbyParams(ctx context.Context, l *slog.Logger, w http.ResponseWriter)
|
|||||||
textureType := chi.URLParamFromCtx(ctx, "textureType")
|
textureType := chi.URLParamFromCtx(ctx, "textureType")
|
||||||
if uuid == "" {
|
if uuid == "" {
|
||||||
l.DebugContext(ctx, "路径中缺少参数 uuid")
|
l.DebugContext(ctx, "路径中缺少参数 uuid")
|
||||||
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: "路径中缺少参数 uuid / textureType"}, 400)
|
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: "路径中缺少参数 uuid"}, 400)
|
||||||
return "", "", false
|
return "", "", false
|
||||||
}
|
}
|
||||||
if textureType != "skin" && textureType != "cape" {
|
if textureType != "skin" && textureType != "cape" {
|
||||||
@ -139,13 +138,10 @@ func (y *Yggdrasil) DelTexture() http.HandlerFunc {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
token := y.getTokenbyAuthorization(ctx, w, r)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
if token == "" {
|
err := y.yggdrasilService.DelTexture(ctx, uuid, t, textureType)
|
||||||
return
|
|
||||||
}
|
|
||||||
err := y.yggdrasilService.DelTexture(ctx, uuid, token, textureType)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, utils.ErrTokenInvalid) {
|
if errors.Is(err, yggdrasilS.ErrUUIDNotEq) {
|
||||||
y.logger.DebugContext(ctx, err.Error())
|
y.logger.DebugContext(ctx, err.Error())
|
||||||
w.WriteHeader(401)
|
w.WriteHeader(401)
|
||||||
return
|
return
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
|
||||||
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,21 +36,6 @@ func (y *Yggdrasil) Authenticate() http.HandlerFunc {
|
|||||||
|
|
||||||
func (y *Yggdrasil) Validate() http.HandlerFunc {
|
func (y *Yggdrasil) Validate() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
cxt := r.Context()
|
|
||||||
a, has := getAnyModel[yggdrasil.ValidateToken](cxt, w, r.Body, y.validate, y.logger)
|
|
||||||
if !has {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err := y.yggdrasilService.ValidateToken(cxt, a)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, sutils.ErrTokenInvalid) {
|
|
||||||
y.logger.DebugContext(cxt, err.Error())
|
|
||||||
handleYgError(cxt, w, yggdrasil.Error{ErrorMessage: "Invalid token.", Error: "ForbiddenOperationException"}, 403)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
y.handleYgError(cxt, w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(204)
|
w.WriteHeader(204)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,16 +65,11 @@ func (y *Yggdrasil) Invalidate() http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(204)
|
w.WriteHeader(204)
|
||||||
cxt := r.Context()
|
cxt := r.Context()
|
||||||
a, has := getAnyModel[yggdrasil.ValidateToken](cxt, w, r.Body, y.validate, y.logger)
|
|
||||||
if !has {
|
t := cxt.Value(tokenKey).(*model.TokenClaims)
|
||||||
return
|
|
||||||
}
|
err := y.yggdrasilService.Invalidate(cxt, t)
|
||||||
err := y.yggdrasilService.Invalidate(cxt, a.AccessToken)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sutils.ErrTokenInvalid) {
|
|
||||||
y.logger.DebugContext(cxt, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
y.logger.WarnContext(cxt, err.Error())
|
y.logger.WarnContext(cxt, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,17 +78,9 @@ func (y *Yggdrasil) Invalidate() http.HandlerFunc {
|
|||||||
func (y *Yggdrasil) Refresh() http.HandlerFunc {
|
func (y *Yggdrasil) Refresh() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
cxt := r.Context()
|
cxt := r.Context()
|
||||||
a, has := getAnyModel[yggdrasil.RefreshToken](cxt, w, r.Body, y.validate, y.logger)
|
token := cxt.Value(tokenKey).(*model.TokenClaims)
|
||||||
if !has {
|
t, err := y.yggdrasilService.Refresh(cxt, token)
|
||||||
return
|
|
||||||
}
|
|
||||||
t, err := y.yggdrasilService.Refresh(cxt, a)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sutils.ErrTokenInvalid) {
|
|
||||||
y.logger.DebugContext(cxt, err.Error())
|
|
||||||
handleYgError(cxt, w, yggdrasil.Error{ErrorMessage: "Invalid token.", Error: "ForbiddenOperationException"}, 403)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
y.handleYgError(cxt, w, err)
|
y.handleYgError(cxt, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -176,17 +148,9 @@ func (y *Yggdrasil) BatchProfile() http.HandlerFunc {
|
|||||||
func (y *Yggdrasil) PlayerCertificates() http.HandlerFunc {
|
func (y *Yggdrasil) PlayerCertificates() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
token := y.getTokenbyAuthorization(ctx, w, r)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
if token == "" {
|
c, err := y.yggdrasilService.PlayerCertificates(ctx, t)
|
||||||
return
|
|
||||||
}
|
|
||||||
c, err := y.yggdrasilService.PlayerCertificates(ctx, token)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sutils.ErrTokenInvalid) {
|
|
||||||
y.logger.DebugContext(ctx, err.Error())
|
|
||||||
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: "Invalid token.", Error: "ForbiddenOperationException"}, 403)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
y.handleYgError(ctx, w, err)
|
y.handleYgError(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package yggdrasil
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net"
|
"net"
|
||||||
@ -13,6 +14,7 @@ import (
|
|||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/xmdhs/authlib-skin/config"
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
|
utilsS "github.com/xmdhs/authlib-skin/service/utils"
|
||||||
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
@ -86,3 +88,33 @@ func (y *Yggdrasil) TextureAssets() http.HandlerFunc {
|
|||||||
http.StripPrefix("/texture/", http.FileServer(http.Dir(y.config.TexturePath))).ServeHTTP(w, r)
|
http.StripPrefix("/texture/", http.FileServer(http.Dir(y.config.TexturePath))).ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tokenValue string
|
||||||
|
|
||||||
|
const tokenKey = tokenValue("token")
|
||||||
|
|
||||||
|
func (y *Yggdrasil) Auth(handle http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
a, err := utils.DeCodeBody[yggdrasil.ValidateToken](r.Body, y.validate)
|
||||||
|
if err != nil {
|
||||||
|
token := y.getTokenbyAuthorization(ctx, w, r)
|
||||||
|
if token == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
a.AccessToken = token
|
||||||
|
}
|
||||||
|
t, err := y.yggdrasilService.Auth(ctx, a)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, utilsS.ErrTokenInvalid) {
|
||||||
|
y.logger.DebugContext(ctx, err.Error())
|
||||||
|
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: "Invalid token.", Error: "ForbiddenOperationException"}, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
y.handleYgError(ctx, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r = r.WithContext(context.WithValue(ctx, tokenKey, t))
|
||||||
|
handle.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -34,23 +34,28 @@ func newYggdrasil(handelY *yggdrasil.Yggdrasil) http.Handler {
|
|||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
r.Use(warpHJSON)
|
r.Use(warpHJSON)
|
||||||
|
|
||||||
r.Post("/authserver/authenticate", handelY.Authenticate())
|
r.Group(func(r chi.Router) {
|
||||||
r.Post("/authserver/validate", handelY.Validate())
|
r.Use(handelY.Auth)
|
||||||
r.Post("/authserver/signout", handelY.Signout())
|
r.Post("/authserver/validate", handelY.Validate())
|
||||||
r.Post("/authserver/invalidate", handelY.Invalidate())
|
r.Post("/authserver/invalidate", handelY.Invalidate())
|
||||||
r.Post("/authserver/refresh", handelY.Refresh())
|
r.Post("/authserver/refresh", handelY.Refresh())
|
||||||
|
|
||||||
r.Put("/api/user/profile/{uuid}/{textureType}", handelY.PutTexture())
|
r.Put("/api/user/profile/{uuid}/{textureType}", handelY.PutTexture())
|
||||||
r.Delete("/api/user/profile/{uuid}/{textureType}", handelY.DelTexture())
|
r.Delete("/api/user/profile/{uuid}/{textureType}", handelY.DelTexture())
|
||||||
|
|
||||||
|
r.Post("/sessionserver/session/minecraft/join", handelY.SessionJoin())
|
||||||
|
r.Post("/minecraftservices/player/certificates", handelY.PlayerCertificates())
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
r.Post("/authserver/authenticate", handelY.Authenticate())
|
||||||
|
r.Post("/authserver/signout", handelY.Signout())
|
||||||
|
|
||||||
r.Get("/sessionserver/session/minecraft/profile/{uuid}", handelY.GetProfile())
|
r.Get("/sessionserver/session/minecraft/profile/{uuid}", handelY.GetProfile())
|
||||||
r.Post("/api/profiles/minecraft", handelY.BatchProfile())
|
r.Post("/api/profiles/minecraft", handelY.BatchProfile())
|
||||||
|
|
||||||
r.Post("/sessionserver/session/minecraft/join", handelY.SessionJoin())
|
|
||||||
r.Get("/sessionserver/session/minecraft/hasJoined", handelY.HasJoined())
|
r.Get("/sessionserver/session/minecraft/hasJoined", handelY.HasJoined())
|
||||||
|
|
||||||
r.Post("/minecraftservices/player/certificates", handelY.PlayerCertificates())
|
|
||||||
|
|
||||||
r.Get("/", handelY.YggdrasilRoot())
|
r.Get("/", handelY.YggdrasilRoot())
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
@ -17,17 +17,11 @@ type sessionWithIP struct {
|
|||||||
IP string
|
IP string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) SessionJoin(ctx context.Context, s yggdrasil.Session, ip string) error {
|
func (y *Yggdrasil) SessionJoin(ctx context.Context, s yggdrasil.Session, t *model.TokenClaims, ip string) error {
|
||||||
t, err := sutils.Auth(ctx, yggdrasil.ValidateToken{
|
|
||||||
AccessToken: s.AccessToken,
|
|
||||||
}, y.client, y.cache, &y.prikey.PublicKey, true)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("SessionJoin: %w", err)
|
|
||||||
}
|
|
||||||
if s.SelectedProfile != t.Subject {
|
if s.SelectedProfile != t.Subject {
|
||||||
return fmt.Errorf("SessionJoin: %w", sutils.ErrTokenInvalid)
|
return fmt.Errorf("SessionJoin: %w", sutils.ErrTokenInvalid)
|
||||||
}
|
}
|
||||||
err = cache.CacheHelp[sessionWithIP]{Cache: y.cache}.Put([]byte("session"+s.ServerID), sessionWithIP{
|
err := cache.CacheHelp[sessionWithIP]{Cache: y.cache}.Put([]byte("session"+s.ServerID), sessionWithIP{
|
||||||
User: *t,
|
User: *t,
|
||||||
IP: ip,
|
IP: ip,
|
||||||
}, time.Now().Add(30*time.Second))
|
}, time.Now().Add(30*time.Second))
|
||||||
|
@ -15,8 +15,7 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/db/ent/user"
|
"github.com/xmdhs/authlib-skin/db/ent/user"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/userprofile"
|
"github.com/xmdhs/authlib-skin/db/ent/userprofile"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/usertexture"
|
"github.com/xmdhs/authlib-skin/db/ent/usertexture"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -78,13 +77,9 @@ func (y *Yggdrasil) delTexture(ctx context.Context, userProfileID int, textureTy
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) DelTexture(ctx context.Context, uuid string, token string, textureType string) error {
|
func (y *Yggdrasil) DelTexture(ctx context.Context, uuid string, t *model.TokenClaims, textureType string) error {
|
||||||
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, y.client, y.cache, &y.prikey.PublicKey, true)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("DelTexture: %w", err)
|
|
||||||
}
|
|
||||||
if uuid != t.Subject {
|
if uuid != t.Subject {
|
||||||
return fmt.Errorf("PutTexture: %w", errors.Join(ErrUUIDNotEq, utilsService.ErrTokenInvalid))
|
return fmt.Errorf("PutTexture: %w", ErrUUIDNotEq)
|
||||||
}
|
}
|
||||||
up, err := y.client.UserProfile.Query().Where(userprofile.HasUserWith(user.ID(t.UID))).First(ctx)
|
up, err := y.client.UserProfile.Query().Where(userprofile.HasUserWith(user.ID(t.UID))).First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -101,13 +96,9 @@ func (y *Yggdrasil) DelTexture(ctx context.Context, uuid string, token string, t
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) PutTexture(ctx context.Context, token string, texturebyte []byte, model string, uuid string, textureType string) error {
|
func (y *Yggdrasil) PutTexture(ctx context.Context, t *model.TokenClaims, texturebyte []byte, model string, uuid string, textureType string) error {
|
||||||
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, y.client, y.cache, &y.prikey.PublicKey, true)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("PutTexture: %w", err)
|
|
||||||
}
|
|
||||||
if uuid != t.Subject {
|
if uuid != t.Subject {
|
||||||
return fmt.Errorf("PutTexture: %w", errors.Join(ErrUUIDNotEq, utilsService.ErrTokenInvalid))
|
return fmt.Errorf("PutTexture: %w", ErrUUIDNotEq)
|
||||||
}
|
}
|
||||||
|
|
||||||
up, err := y.client.UserProfile.Query().Where(userprofile.HasUserWith(user.ID(t.UID))).First(ctx)
|
up, err := y.client.UserProfile.Query().Where(userprofile.HasUserWith(user.ID(t.UID))).First(ctx)
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/db/ent/user"
|
"github.com/xmdhs/authlib-skin/db/ent/user"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/userprofile"
|
"github.com/xmdhs/authlib-skin/db/ent/userprofile"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/usertoken"
|
"github.com/xmdhs/authlib-skin/db/ent/usertoken"
|
||||||
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
@ -120,14 +121,6 @@ func (y *Yggdrasil) Authenticate(cxt context.Context, auth yggdrasil.Authenticat
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) ValidateToken(ctx context.Context, t yggdrasil.ValidateToken) error {
|
|
||||||
_, err := sutils.Auth(ctx, t, y.client, y.cache, &y.prikey.PublicKey, true)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("ValidateToken: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (y *Yggdrasil) SignOut(ctx context.Context, t yggdrasil.Pass) error {
|
func (y *Yggdrasil) SignOut(ctx context.Context, t yggdrasil.Pass) error {
|
||||||
u, err := y.validatePass(ctx, t.Username, t.Password)
|
u, err := y.validatePass(ctx, t.Username, t.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -152,12 +145,8 @@ func (y *Yggdrasil) SignOut(ctx context.Context, t yggdrasil.Pass) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) Invalidate(ctx context.Context, accessToken string) error {
|
func (y *Yggdrasil) Invalidate(ctx context.Context, t *model.TokenClaims) error {
|
||||||
t, err := sutils.Auth(ctx, yggdrasil.ValidateToken{AccessToken: accessToken}, y.client, y.cache, &y.prikey.PublicKey, true)
|
err := y.client.UserToken.Update().Where(usertoken.HasUserWith(user.ID(t.UID))).AddTokenID(1).Exec(ctx)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Invalidate: %w", err)
|
|
||||||
}
|
|
||||||
err = y.client.UserToken.Update().Where(usertoken.HasUserWith(user.ID(t.UID))).AddTokenID(1).Exec(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalidate: %w", err)
|
return fmt.Errorf("Invalidate: %w", err)
|
||||||
}
|
}
|
||||||
@ -168,11 +157,7 @@ func (y *Yggdrasil) Invalidate(ctx context.Context, accessToken string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) Refresh(ctx context.Context, token yggdrasil.RefreshToken) (yggdrasil.Token, error) {
|
func (y *Yggdrasil) Refresh(ctx context.Context, t *model.TokenClaims) (yggdrasil.Token, error) {
|
||||||
t, err := sutils.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token.AccessToken, ClientToken: token.ClientToken}, y.client, y.cache, &y.prikey.PublicKey, false)
|
|
||||||
if err != nil {
|
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Refresh: %w", err)
|
|
||||||
}
|
|
||||||
jwts, err := newJwtToken(y.prikey, t.Tid, t.CID, t.Subject, t.UID)
|
jwts, err := newJwtToken(y.prikey, t.Tid, t.CID, t.Subject, t.UID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Refresh: %w", err)
|
return yggdrasil.Token{}, fmt.Errorf("Refresh: %w", err)
|
||||||
@ -315,11 +300,7 @@ func (y *Yggdrasil) BatchProfile(ctx context.Context, names []string) ([]yggdras
|
|||||||
// privateKey 为 PKCS #8, pem type 为 RSA PUBLIC KEY
|
// privateKey 为 PKCS #8, pem type 为 RSA PUBLIC KEY
|
||||||
// 签名使用 rsaWIthsha1
|
// 签名使用 rsaWIthsha1
|
||||||
|
|
||||||
func (y *Yggdrasil) PlayerCertificates(ctx context.Context, token string) (yggdrasil.Certificates, error) {
|
func (y *Yggdrasil) PlayerCertificates(ctx context.Context, t *model.TokenClaims) (yggdrasil.Certificates, error) {
|
||||||
t, err := sutils.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, y.client, y.cache, &y.prikey.PublicKey, false)
|
|
||||||
if err != nil {
|
|
||||||
return yggdrasil.Certificates{}, fmt.Errorf("PlayerCertificates: %w", err)
|
|
||||||
}
|
|
||||||
rsa2048, err := rsa.GenerateKey(rand.Reader, 2048)
|
rsa2048, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return yggdrasil.Certificates{}, fmt.Errorf("PlayerCertificates: %w", err)
|
return yggdrasil.Certificates{}, fmt.Errorf("PlayerCertificates: %w", err)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package yggdrasil
|
package yggdrasil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -11,6 +12,8 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/db/cache"
|
"github.com/xmdhs/authlib-skin/db/cache"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent"
|
"github.com/xmdhs/authlib-skin/db/ent"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
|
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Yggdrasil struct {
|
type Yggdrasil struct {
|
||||||
@ -82,3 +85,11 @@ func newJwtToken(jwtKey *rsa.PrivateKey, tokenID, clientToken, UUID string, user
|
|||||||
}
|
}
|
||||||
return jwts, nil
|
return jwts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (y *Yggdrasil) Auth(ctx context.Context, t yggdrasil.ValidateToken) (*model.TokenClaims, error) {
|
||||||
|
u, err := sutils.Auth(ctx, t, y.client, y.cache, &y.prikey.PublicKey, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("ValidateToken: %w", err)
|
||||||
|
}
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user