改成 go-chi/chi
This commit is contained in:
parent
a64ab9e838
commit
b011910d20
4
go.mod
4
go.mod
@ -6,12 +6,13 @@ require (
|
|||||||
entgo.io/ent v0.12.3
|
entgo.io/ent v0.12.3
|
||||||
github.com/VictoriaMetrics/fastcache v1.12.1
|
github.com/VictoriaMetrics/fastcache v1.12.1
|
||||||
github.com/alecthomas/binary v0.0.0-20221018225505-74871811ee56
|
github.com/alecthomas/binary v0.0.0-20221018225505-74871811ee56
|
||||||
|
github.com/go-chi/chi/v5 v5.0.10
|
||||||
|
github.com/go-chi/cors v1.2.1
|
||||||
github.com/go-playground/validator/v10 v10.15.3
|
github.com/go-playground/validator/v10 v10.15.3
|
||||||
github.com/go-sql-driver/mysql v1.7.1
|
github.com/go-sql-driver/mysql v1.7.1
|
||||||
github.com/golang-jwt/jwt/v5 v5.0.0
|
github.com/golang-jwt/jwt/v5 v5.0.0
|
||||||
github.com/google/uuid v1.3.1
|
github.com/google/uuid v1.3.1
|
||||||
github.com/google/wire v0.5.0
|
github.com/google/wire v0.5.0
|
||||||
github.com/julienschmidt/httprouter v1.3.0
|
|
||||||
github.com/samber/lo v1.38.1
|
github.com/samber/lo v1.38.1
|
||||||
golang.org/x/crypto v0.7.0
|
golang.org/x/crypto v0.7.0
|
||||||
)
|
)
|
||||||
@ -22,6 +23,7 @@ require (
|
|||||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||||
|
github.com/go-chi/chi v1.5.5
|
||||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
8
go.sum
8
go.sum
@ -21,6 +21,12 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||||
|
github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
|
||||||
|
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
|
||||||
|
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
|
||||||
|
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
|
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||||
|
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||||
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
|
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
|
||||||
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
|
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
@ -52,8 +58,6 @@ github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
|
|||||||
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
|
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
|
||||||
github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc=
|
github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc=
|
||||||
github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
|
github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
|
||||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
@ -6,13 +6,12 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handel) NeedAdmin(handle httprouter.Handle) httprouter.Handle {
|
func (h *Handel) NeedAdmin(handle http.Handler) http.Handler {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
token := h.getTokenbyAuthorization(ctx, w, r)
|
token := h.getTokenbyAuthorization(ctx, w, r)
|
||||||
if token == "" {
|
if token == "" {
|
||||||
@ -27,12 +26,12 @@ func (h *Handel) NeedAdmin(handle httprouter.Handle) httprouter.Handle {
|
|||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
handle(w, r, p)
|
handle.ServeHTTP(w, r)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) ListUser() httprouter.Handle {
|
func (h *Handel) ListUser() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
page := r.FormValue("page")
|
page := r.FormValue("page")
|
||||||
pagei := 1
|
pagei := 1
|
||||||
|
@ -4,12 +4,11 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handel) GetConfig() httprouter.Handle {
|
func (h *Handel) GetConfig() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
c := h.webService.GetConfig(ctx)
|
c := h.webService.GetConfig(ctx)
|
||||||
m := model.API[model.Config]{
|
m := model.API[model.Config]{
|
||||||
|
@ -5,18 +5,17 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
|
||||||
"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"
|
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handel) Reg() httprouter.Handle {
|
func (h *Handel) Reg() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
ip, err := utils.GetIP(r, h.config.RaelIP)
|
ip, err := utils.GetIP(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
@ -55,8 +54,8 @@ func (h *Handel) Reg() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) UserInfo() httprouter.Handle {
|
func (h *Handel) UserInfo() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
token := h.getTokenbyAuthorization(ctx, w, r)
|
token := h.getTokenbyAuthorization(ctx, w, r)
|
||||||
if token == "" {
|
if token == "" {
|
||||||
@ -79,8 +78,8 @@ func (h *Handel) UserInfo() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) ChangePasswd() httprouter.Handle {
|
func (h *Handel) ChangePasswd() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
token := h.getTokenbyAuthorization(ctx, w, r)
|
token := h.getTokenbyAuthorization(ctx, w, r)
|
||||||
if token == "" {
|
if token == "" {
|
||||||
@ -108,8 +107,8 @@ func (h *Handel) ChangePasswd() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) ChangeName() httprouter.Handle {
|
func (h *Handel) ChangeName() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
token := h.getTokenbyAuthorization(ctx, w, r)
|
token := h.getTokenbyAuthorization(ctx, w, r)
|
||||||
if token == "" {
|
if token == "" {
|
||||||
|
@ -20,5 +20,4 @@ func handleYgError(ctx context.Context, w http.ResponseWriter, e yggdrasil.Error
|
|||||||
func (y *Yggdrasil) handleYgError(ctx context.Context, w http.ResponseWriter, err error) {
|
func (y *Yggdrasil) handleYgError(ctx context.Context, w http.ResponseWriter, err error) {
|
||||||
y.logger.WarnContext(ctx, err.Error())
|
y.logger.WarnContext(ctx, err.Error())
|
||||||
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: err.Error()}, 500)
|
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: err.Error()}, 500)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
@ -5,21 +5,20 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"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"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (y *Yggdrasil) SessionJoin() httprouter.Handle {
|
func (y *Yggdrasil) SessionJoin() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
a, has := getAnyModel[yggdrasil.Session](ctx, w, r.Body, y.validate, y.logger)
|
a, has := getAnyModel[yggdrasil.Session](ctx, w, r.Body, y.validate, y.logger)
|
||||||
if !has {
|
if !has {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ip, err := utils.GetIP(r, y.config.RaelIP)
|
ip, err := utils.GetIP(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
y.handleYgError(ctx, w, err)
|
y.handleYgError(ctx, w, err)
|
||||||
return
|
return
|
||||||
@ -38,8 +37,8 @@ func (y *Yggdrasil) SessionJoin() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) HasJoined() httprouter.Handle {
|
func (y *Yggdrasil) HasJoined() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
name := r.FormValue("username")
|
name := r.FormValue("username")
|
||||||
serverId := r.FormValue("serverId")
|
serverId := r.FormValue("serverId")
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
"github.com/xmdhs/authlib-skin/service/utils"
|
"github.com/xmdhs/authlib-skin/service/utils"
|
||||||
)
|
)
|
||||||
@ -44,10 +44,10 @@ func (y *Yggdrasil) validTextureType(ctx context.Context, w http.ResponseWriter,
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) PutTexture() httprouter.Handle {
|
func (y *Yggdrasil) PutTexture() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
uuid, textureType, ok := getUUIDbyParams(ctx, p, y.logger, w)
|
uuid, textureType, ok := getUUIDbyParams(ctx, y.logger, w)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -115,9 +115,9 @@ func (y *Yggdrasil) PutTexture() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUUIDbyParams(ctx context.Context, p httprouter.Params, l *slog.Logger, w http.ResponseWriter) (string, string, bool) {
|
func getUUIDbyParams(ctx context.Context, l *slog.Logger, w http.ResponseWriter) (string, string, bool) {
|
||||||
uuid := p.ByName("uuid")
|
uuid := chi.URLParamFromCtx(ctx, "uuid")
|
||||||
textureType := p.ByName("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 / textureType"}, 400)
|
||||||
@ -132,10 +132,10 @@ func getUUIDbyParams(ctx context.Context, p httprouter.Params, l *slog.Logger, w
|
|||||||
return uuid, textureType, true
|
return uuid, textureType, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) DelTexture() httprouter.Handle {
|
func (y *Yggdrasil) DelTexture() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
uuid, textureType, ok := getUUIDbyParams(ctx, p, y.logger, w)
|
uuid, textureType, ok := getUUIDbyParams(ctx, y.logger, w)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,15 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"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"
|
||||||
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (y *Yggdrasil) Authenticate() httprouter.Handle {
|
func (y *Yggdrasil) Authenticate() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
cxt := r.Context()
|
cxt := r.Context()
|
||||||
a, has := getAnyModel[yggdrasil.Authenticate](cxt, w, r.Body, y.validate, y.logger)
|
a, has := getAnyModel[yggdrasil.Authenticate](cxt, w, r.Body, y.validate, y.logger)
|
||||||
if !has {
|
if !has {
|
||||||
@ -34,8 +34,8 @@ func (y *Yggdrasil) Authenticate() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) Validate() httprouter.Handle {
|
func (y *Yggdrasil) Validate() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
cxt := r.Context()
|
cxt := r.Context()
|
||||||
a, has := getAnyModel[yggdrasil.ValidateToken](cxt, w, r.Body, y.validate, y.logger)
|
a, has := getAnyModel[yggdrasil.ValidateToken](cxt, w, r.Body, y.validate, y.logger)
|
||||||
if !has {
|
if !has {
|
||||||
@ -55,8 +55,8 @@ func (y *Yggdrasil) Validate() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) Signout() httprouter.Handle {
|
func (y *Yggdrasil) Signout() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
cxt := r.Context()
|
cxt := r.Context()
|
||||||
a, has := getAnyModel[yggdrasil.Pass](cxt, w, r.Body, y.validate, y.logger)
|
a, has := getAnyModel[yggdrasil.Pass](cxt, w, r.Body, y.validate, y.logger)
|
||||||
if !has {
|
if !has {
|
||||||
@ -76,8 +76,8 @@ func (y *Yggdrasil) Signout() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) Invalidate() httprouter.Handle {
|
func (y *Yggdrasil) Invalidate() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
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)
|
a, has := getAnyModel[yggdrasil.ValidateToken](cxt, w, r.Body, y.validate, y.logger)
|
||||||
@ -95,8 +95,8 @@ func (y *Yggdrasil) Invalidate() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) Refresh() httprouter.Handle {
|
func (y *Yggdrasil) Refresh() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
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)
|
a, has := getAnyModel[yggdrasil.RefreshToken](cxt, w, r.Body, y.validate, y.logger)
|
||||||
if !has {
|
if !has {
|
||||||
@ -117,10 +117,11 @@ func (y *Yggdrasil) Refresh() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) GetProfile() httprouter.Handle {
|
func (y *Yggdrasil) GetProfile() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
uuid := p.ByName("uuid")
|
uuid := chi.URLParamFromCtx(ctx, "uuid")
|
||||||
|
|
||||||
unsigned := r.FormValue("unsigned")
|
unsigned := r.FormValue("unsigned")
|
||||||
|
|
||||||
unsignedBool := true
|
unsignedBool := true
|
||||||
@ -151,8 +152,8 @@ func (y *Yggdrasil) GetProfile() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) BatchProfile() httprouter.Handle {
|
func (y *Yggdrasil) BatchProfile() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
a, has := getAnyModel[[]string](ctx, w, r.Body, nil, y.logger)
|
a, has := getAnyModel[[]string](ctx, w, r.Body, nil, y.logger)
|
||||||
if !has {
|
if !has {
|
||||||
@ -172,8 +173,8 @@ func (y *Yggdrasil) BatchProfile() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) PlayerCertificates() httprouter.Handle {
|
func (y *Yggdrasil) PlayerCertificates() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
token := y.getTokenbyAuthorization(ctx, w, r)
|
token := y.getTokenbyAuthorization(ctx, w, r)
|
||||||
if token == "" {
|
if token == "" {
|
||||||
|
@ -10,11 +10,9 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"github.com/julienschmidt/httprouter"
|
|
||||||
"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"
|
||||||
yggdrasilM "github.com/xmdhs/authlib-skin/model/yggdrasil"
|
|
||||||
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"
|
||||||
)
|
)
|
||||||
@ -49,8 +47,8 @@ func getAnyModel[K any](ctx context.Context, w http.ResponseWriter, r io.Reader,
|
|||||||
return a, true
|
return a, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) YggdrasilRoot() httprouter.Handle {
|
func (y *Yggdrasil) YggdrasilRoot() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var host string
|
var host string
|
||||||
if y.config.TextureBaseUrl != "" {
|
if y.config.TextureBaseUrl != "" {
|
||||||
u := lo.Must(url.Parse(y.config.TextureBaseUrl))
|
u := lo.Must(url.Parse(y.config.TextureBaseUrl))
|
||||||
@ -64,11 +62,11 @@ func (y *Yggdrasil) YggdrasilRoot() httprouter.Handle {
|
|||||||
homepage, _ := url.JoinPath(y.config.WebBaseUrl, "/login")
|
homepage, _ := url.JoinPath(y.config.WebBaseUrl, "/login")
|
||||||
register, _ := url.JoinPath(y.config.WebBaseUrl, "/register")
|
register, _ := url.JoinPath(y.config.WebBaseUrl, "/register")
|
||||||
|
|
||||||
w.Write(lo.Must1(json.Marshal(yggdrasilM.Yggdrasil{
|
w.Write(lo.Must1(json.Marshal(yggdrasil.Yggdrasil{
|
||||||
Meta: yggdrasilM.YggdrasilMeta{
|
Meta: yggdrasil.YggdrasilMeta{
|
||||||
ImplementationName: "authlib-skin",
|
ImplementationName: "authlib-skin",
|
||||||
ImplementationVersion: "0.0.1",
|
ImplementationVersion: "0.0.1",
|
||||||
Links: yggdrasilM.YggdrasilMetaLinks{
|
Links: yggdrasil.YggdrasilMetaLinks{
|
||||||
Homepage: homepage,
|
Homepage: homepage,
|
||||||
Register: register,
|
Register: register,
|
||||||
},
|
},
|
||||||
@ -82,8 +80,8 @@ func (y *Yggdrasil) YggdrasilRoot() httprouter.Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) TextureAssets() httprouter.Handle {
|
func (y *Yggdrasil) TextureAssets() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "image/png")
|
w.Header().Set("Content-Type", "image/png")
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ type UserList struct {
|
|||||||
UserInfo
|
UserInfo
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
RegIp string `json:"reg_ip"`
|
RegIp string `json:"reg_ip"`
|
||||||
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChangeName struct {
|
type ChangeName struct {
|
||||||
|
@ -1,14 +1,75 @@
|
|||||||
package route
|
package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
func warpHJSON(handle httprouter.Handle) httprouter.Handle {
|
func warpHJSON(handle http.Handler) http.Handler {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
handle(w, r, p)
|
handle.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewStructuredLogger(handler slog.Handler) func(next http.Handler) http.Handler {
|
||||||
|
return middleware.RequestLogger(&StructuredLogger{Logger: handler})
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructuredLogger struct {
|
||||||
|
Logger slog.Handler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *StructuredLogger) NewLogEntry(r *http.Request) middleware.LogEntry {
|
||||||
|
var logFields []slog.Attr
|
||||||
|
logFields = append(logFields, slog.String("ts", time.Now().UTC().Format(time.RFC1123)))
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
|
if reqID := middleware.GetReqID(ctx); reqID != "" {
|
||||||
|
logFields = append(logFields, slog.String("req_id", reqID))
|
||||||
|
}
|
||||||
|
|
||||||
|
scheme := "http"
|
||||||
|
if r.TLS != nil {
|
||||||
|
scheme = "https"
|
||||||
|
}
|
||||||
|
|
||||||
|
handler := l.Logger.WithAttrs(append(logFields,
|
||||||
|
slog.String("http_scheme", scheme),
|
||||||
|
slog.String("http_proto", r.Proto),
|
||||||
|
slog.String("http_method", r.Method),
|
||||||
|
slog.String("remote_addr", r.RemoteAddr),
|
||||||
|
slog.String("user_agent", r.UserAgent()),
|
||||||
|
slog.String("uri", fmt.Sprintf("%s://%s%s", scheme, r.Host, r.RequestURI))))
|
||||||
|
|
||||||
|
entry := StructuredLoggerEntry{Logger: slog.New(handler), ctx: ctx}
|
||||||
|
|
||||||
|
entry.Logger.LogAttrs(ctx, slog.LevelDebug, "request started")
|
||||||
|
|
||||||
|
return &entry
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructuredLoggerEntry struct {
|
||||||
|
Logger *slog.Logger
|
||||||
|
ctx context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *StructuredLoggerEntry) Write(status, bytes int, header http.Header, elapsed time.Duration, extra interface{}) {
|
||||||
|
l.Logger.LogAttrs(l.ctx, slog.LevelDebug, "request complete",
|
||||||
|
slog.Int("resp_status", status),
|
||||||
|
slog.Int("resp_byte_length", bytes),
|
||||||
|
slog.Float64("resp_elapsed_ms", float64(elapsed.Nanoseconds())/1000000.0),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *StructuredLoggerEntry) Panic(v interface{}, stack []byte) {
|
||||||
|
l.Logger.LogAttrs(l.ctx, slog.LevelDebug, "",
|
||||||
|
slog.String("stack", string(stack)),
|
||||||
|
slog.String("panic", fmt.Sprintf("%+v", v)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,63 +1,73 @@
|
|||||||
package route
|
package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
|
"github.com/go-chi/cors"
|
||||||
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
"github.com/xmdhs/authlib-skin/handle"
|
"github.com/xmdhs/authlib-skin/handle"
|
||||||
"github.com/xmdhs/authlib-skin/handle/yggdrasil"
|
"github.com/xmdhs/authlib-skin/handle/yggdrasil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRoute(yggService *yggdrasil.Yggdrasil, handel *handle.Handel) (*httprouter.Router, error) {
|
func NewRoute(handelY *yggdrasil.Yggdrasil, handel *handle.Handel, c config.Config, sl slog.Handler) http.Handler {
|
||||||
r := httprouter.New()
|
r := chi.NewRouter()
|
||||||
r.HandleOPTIONS = true
|
r.Use(middleware.RequestID)
|
||||||
r.GlobalOPTIONS = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
r.Use(NewStructuredLogger(sl))
|
||||||
w.WriteHeader(204)
|
r.Use(middleware.Recoverer)
|
||||||
|
r.Use(cors.AllowAll().Handler)
|
||||||
|
if c.RaelIP {
|
||||||
|
r.Use(middleware.RealIP)
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Mount("/api/v1", newSkinApi(handel))
|
||||||
|
r.Mount("/api/yggdrasil", newYggdrasil(handelY))
|
||||||
|
|
||||||
|
r.Get("/texture/*", handelY.TextureAssets())
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func newYggdrasil(handelY *yggdrasil.Yggdrasil) http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
r.Use(warpHJSON)
|
||||||
|
|
||||||
|
r.Post("/authserver/authenticate", handelY.Authenticate())
|
||||||
|
r.Post("/authserver/validate", handelY.Validate())
|
||||||
|
r.Post("/authserver/signout", handelY.Signout())
|
||||||
|
r.Post("/authserver/invalidate", handelY.Invalidate())
|
||||||
|
r.Post("/authserver/refresh", handelY.Refresh())
|
||||||
|
|
||||||
|
r.Put("/api/user/profile/{uuid}/{textureType}", handelY.PutTexture())
|
||||||
|
r.Delete("/api/user/profile/{uuid}/{textureType}", handelY.DelTexture())
|
||||||
|
|
||||||
|
r.Get("/sessionserver/session/minecraft/profile/{uuid}", handelY.GetProfile())
|
||||||
|
r.Post("/api/profiles/minecraft", handelY.BatchProfile())
|
||||||
|
|
||||||
|
r.Post("/sessionserver/session/minecraft/join", handelY.SessionJoin())
|
||||||
|
r.Get("/sessionserver/session/minecraft/hasJoined", handelY.HasJoined())
|
||||||
|
|
||||||
|
r.Post("/minecraftservices/player/certificates", handelY.PlayerCertificates())
|
||||||
|
|
||||||
|
r.Get("/", handelY.YggdrasilRoot())
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSkinApi(handel *handle.Handel) http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
r.Put("/user/reg", handel.Reg())
|
||||||
|
r.Get("/config", handel.GetConfig())
|
||||||
|
r.Get("/user", handel.UserInfo())
|
||||||
|
r.Post("/user/password", handel.ChangePasswd())
|
||||||
|
r.Post("/user/name", handel.ChangeName())
|
||||||
|
|
||||||
|
r.Group(func(r chi.Router) {
|
||||||
|
r.Use(handel.NeedAdmin)
|
||||||
|
r.Get("/admin/users", handel.ListUser())
|
||||||
|
|
||||||
})
|
})
|
||||||
err := newYggdrasil(r, *yggService)
|
return r
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("NewRoute: %w", err)
|
|
||||||
}
|
|
||||||
err = newSkinApi(r, handel)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("NewRoute: %w", err)
|
|
||||||
}
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newYggdrasil(r *httprouter.Router, handelY yggdrasil.Yggdrasil) error {
|
|
||||||
r.POST("/api/yggdrasil/authserver/authenticate", warpHJSON(handelY.Authenticate()))
|
|
||||||
r.POST("/api/yggdrasil/authserver/validate", warpHJSON(handelY.Validate()))
|
|
||||||
r.POST("/api/yggdrasil/authserver/signout", warpHJSON(handelY.Signout()))
|
|
||||||
r.POST("/api/yggdrasil/authserver/invalidate", handelY.Invalidate())
|
|
||||||
r.POST("/api/yggdrasil/authserver/refresh", warpHJSON(handelY.Refresh()))
|
|
||||||
|
|
||||||
r.PUT("/api/yggdrasil/api/user/profile/:uuid/:textureType", handelY.PutTexture())
|
|
||||||
r.DELETE("/api/yggdrasil/api/user/profile/:uuid/:textureType", warpHJSON(handelY.DelTexture()))
|
|
||||||
|
|
||||||
r.GET("/api/yggdrasil/sessionserver/session/minecraft/profile/:uuid", warpHJSON(handelY.GetProfile()))
|
|
||||||
r.POST("/api/yggdrasil/api/profiles/minecraft", warpHJSON(handelY.BatchProfile()))
|
|
||||||
|
|
||||||
r.POST("/api/yggdrasil/sessionserver/session/minecraft/join", warpHJSON(handelY.SessionJoin()))
|
|
||||||
r.GET("/api/yggdrasil/sessionserver/session/minecraft/hasJoined", warpHJSON(handelY.HasJoined()))
|
|
||||||
|
|
||||||
r.POST("/api/yggdrasil/minecraftservices/player/certificates", warpHJSON(handelY.PlayerCertificates()))
|
|
||||||
|
|
||||||
r.GET("/api/yggdrasil", warpHJSON(handelY.YggdrasilRoot()))
|
|
||||||
r.GET("/api/yggdrasil/", warpHJSON(handelY.YggdrasilRoot()))
|
|
||||||
|
|
||||||
r.GET("/texture/*filepath", handelY.TextureAssets())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSkinApi(r *httprouter.Router, handel *handle.Handel) error {
|
|
||||||
r.PUT("/api/v1/user/reg", handel.Reg())
|
|
||||||
r.GET("/api/v1/config", handel.GetConfig())
|
|
||||||
r.GET("/api/v1/user", handel.UserInfo())
|
|
||||||
r.POST("/api/v1/user/password", handel.ChangePasswd())
|
|
||||||
r.POST("/api/v1/user/name", handel.ChangeName())
|
|
||||||
|
|
||||||
r.GET("/api/v1/admin/users", handel.NeedAdmin(handel.ListUser()))
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -1,54 +1,19 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
|
||||||
"github.com/xmdhs/authlib-skin/config"
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewServer(c config.Config, sl *slog.Logger, route *httprouter.Router) (*http.Server, func()) {
|
func NewServer(c config.Config, route http.Handler) (*http.Server, func()) {
|
||||||
trackid := atomic.Uint64{}
|
|
||||||
s := &http.Server{
|
s := &http.Server{
|
||||||
ReadTimeout: 10 * time.Second,
|
ReadTimeout: 10 * time.Second,
|
||||||
ReadHeaderTimeout: 5 * time.Second,
|
ReadHeaderTimeout: 5 * time.Second,
|
||||||
WriteTimeout: 20 * time.Second,
|
WriteTimeout: 20 * time.Second,
|
||||||
Addr: c.Port,
|
Addr: c.Port,
|
||||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
Handler: route,
|
||||||
ctx := r.Context()
|
|
||||||
if sl.Enabled(ctx, slog.LevelInfo) {
|
|
||||||
ip, _ := utils.GetIP(r, c.RaelIP)
|
|
||||||
trackid.Add(1)
|
|
||||||
ctx = setCtx(ctx, &reqInfo{
|
|
||||||
URL: r.URL.String(),
|
|
||||||
IP: ip,
|
|
||||||
TrackId: trackid.Load(),
|
|
||||||
})
|
|
||||||
r = r.WithContext(ctx)
|
|
||||||
}
|
|
||||||
if c.Debug && sl.Enabled(ctx, slog.LevelDebug) {
|
|
||||||
sl.DebugContext(ctx, r.Method)
|
|
||||||
}
|
|
||||||
cors(route).ServeHTTP(w, r)
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
return s, func() { s.Close() }
|
return s, func() { s.Close() }
|
||||||
}
|
}
|
||||||
|
|
||||||
func cors(h http.Handler) http.Handler {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
header := w.Header()
|
|
||||||
if r.Header.Get("Access-Control-Request-Method") != "" {
|
|
||||||
header.Set("Access-Control-Allow-Methods", r.Header.Get("Access-Control-Request-Method"))
|
|
||||||
}
|
|
||||||
header.Set("Access-Control-Allow-Origin", "*")
|
|
||||||
header.Set("Access-Control-Allow-Headers", "*")
|
|
||||||
header.Set("Access-Control-Allow-Private-Network", "true")
|
|
||||||
header.Set("Access-Control-Max-Age", "3600")
|
|
||||||
h.ServeHTTP(w, r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
@ -3,40 +3,18 @@ package server
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
type reqInfo struct {
|
|
||||||
URL string
|
|
||||||
IP string
|
|
||||||
TrackId uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
type reqInfoKeyType string
|
|
||||||
|
|
||||||
var reqinfoKey reqInfoKeyType = "reqinfoKey"
|
|
||||||
|
|
||||||
func setCtx(ctx context.Context, r *reqInfo) context.Context {
|
|
||||||
return context.WithValue(ctx, reqinfoKey, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFromCtx(ctx context.Context) *reqInfo {
|
|
||||||
v := ctx.Value(reqinfoKey)
|
|
||||||
if v == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return v.(*reqInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
type warpSlogHandle struct {
|
type warpSlogHandle struct {
|
||||||
slog.Handler
|
slog.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *warpSlogHandle) Handle(ctx context.Context, r slog.Record) error {
|
func (w *warpSlogHandle) Handle(ctx context.Context, r slog.Record) error {
|
||||||
if w.Enabled(ctx, slog.LevelInfo) {
|
id := middleware.GetReqID(ctx)
|
||||||
ri := getFromCtx(ctx)
|
if id != "" {
|
||||||
if ri != nil {
|
r.AddAttrs(slog.String("trackID", id))
|
||||||
r.AddAttrs(slog.String("ip", ri.IP), slog.String("url", ri.URL), slog.Uint64("trackID", ri.TrackId))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return w.Handler.Handle(ctx, r)
|
return w.Handler.Handle(ctx, r)
|
||||||
}
|
}
|
||||||
|
@ -54,13 +54,8 @@ func InitializeRoute(ctx context.Context, c config.Config) (*http.Server, func()
|
|||||||
httpClient := ProvideHttpClient()
|
httpClient := ProvideHttpClient()
|
||||||
webService := service.NewWebService(c, client, httpClient, cache, privateKey)
|
webService := service.NewWebService(c, client, httpClient, cache, privateKey)
|
||||||
handel := handle.NewHandel(webService, validate, c, logger)
|
handel := handle.NewHandel(webService, validate, c, logger)
|
||||||
router, err := route.NewRoute(yggdrasil3, handel)
|
httpHandler := route.NewRoute(yggdrasil3, handel, c, handler)
|
||||||
if err != nil {
|
server, cleanup3 := NewServer(c, httpHandler)
|
||||||
cleanup2()
|
|
||||||
cleanup()
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
server, cleanup3 := NewServer(c, logger, router)
|
|
||||||
return server, func() {
|
return server, func() {
|
||||||
cleanup3()
|
cleanup3()
|
||||||
cleanup2()
|
cleanup2()
|
||||||
|
@ -36,6 +36,9 @@ func (w *WebService) ListUser(ctx context.Context, page int) ([]model.UserList,
|
|||||||
ul := make([]model.UserList, 0, len(u))
|
ul := make([]model.UserList, 0, len(u))
|
||||||
|
|
||||||
for _, v := range u {
|
for _, v := range u {
|
||||||
|
if v.Edges.Profile == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
ul = append(ul, model.UserList{
|
ul = append(ul, model.UserList{
|
||||||
UserInfo: model.UserInfo{
|
UserInfo: model.UserInfo{
|
||||||
UID: v.ID,
|
UID: v.ID,
|
||||||
@ -44,6 +47,7 @@ func (w *WebService) ListUser(ctx context.Context, page int) ([]model.UserList,
|
|||||||
},
|
},
|
||||||
Email: v.Email,
|
Email: v.Email,
|
||||||
RegIp: v.RegIP,
|
RegIp: v.RegIP,
|
||||||
|
Name: v.Edges.Profile.Name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,11 +124,12 @@ func (w *WebService) ChangePasswd(ctx context.Context, p model.ChangePasswd, tok
|
|||||||
return fmt.Errorf("ChangePasswd: %w", ErrPassWord)
|
return fmt.Errorf("ChangePasswd: %w", ErrPassWord)
|
||||||
}
|
}
|
||||||
pass, salt := utils.Argon2ID(p.New)
|
pass, salt := utils.Argon2ID(p.New)
|
||||||
|
if u.Edges.Token != nil {
|
||||||
err = w.client.UserToken.UpdateOne(u.Edges.Token).AddTokenID(1).Exec(ctx)
|
err := w.client.UserToken.UpdateOne(u.Edges.Token).AddTokenID(1).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ChangePasswd: %w", err)
|
return fmt.Errorf("ChangePasswd: %w", err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
err = w.cache.Del([]byte("auth" + strconv.Itoa(t.UID)))
|
err = w.cache.Del([]byte("auth" + strconv.Itoa(t.UID)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ChangePasswd: %w", err)
|
return fmt.Errorf("ChangePasswd: %w", err)
|
||||||
|
@ -95,6 +95,10 @@ func (y *Yggdrasil) Authenticate(cxt context.Context, auth yggdrasil.Authenticat
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||||
}
|
}
|
||||||
|
if u.Edges.Profile == nil {
|
||||||
|
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", ErrUserDisable)
|
||||||
|
}
|
||||||
|
|
||||||
jwts, err := newJwtToken(y.prikey, strconv.FormatUint(utoken.TokenID, 10), clientToken, u.Edges.Profile.UUID, u.ID)
|
jwts, err := newJwtToken(y.prikey, strconv.FormatUint(utoken.TokenID, 10), clientToken, u.Edges.Profile.UUID, u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||||
|
23
utils/ip.go
23
utils/ip.go
@ -4,30 +4,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetIP(r *http.Request, fromHeader bool) (string, error) {
|
func GetIP(r *http.Request) (string, error) {
|
||||||
if fromHeader {
|
|
||||||
//Get IP from the X-REAL-IP header
|
|
||||||
ip := r.Header.Get("X-REAL-IP")
|
|
||||||
netIP := net.ParseIP(ip)
|
|
||||||
if netIP != nil {
|
|
||||||
return ip, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get IP from X-FORWARDED-FOR header
|
|
||||||
ips := r.Header.Get("X-FORWARDED-FOR")
|
|
||||||
splitIps := strings.Split(ips, ",")
|
|
||||||
for _, ip := range splitIps {
|
|
||||||
netIP := net.ParseIP(ip)
|
|
||||||
if netIP != nil {
|
|
||||||
return ip, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get IP from RemoteAddr
|
|
||||||
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
Loading…
x
Reference in New Issue
Block a user