拆分代码
This commit is contained in:
parent
af024ef00e
commit
67eb16c0f1
@ -5,27 +5,45 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
"github.com/xmdhs/authlib-skin/handle/handelerror"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
|
"github.com/xmdhs/authlib-skin/service"
|
||||||
|
|
||||||
U "github.com/xmdhs/authlib-skin/utils"
|
U "github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AdminHandel struct {
|
||||||
|
handleError *handelerror.HandleError
|
||||||
|
adminService *service.AdminService
|
||||||
|
validate *validator.Validate
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAdminHandel(handleError *handelerror.HandleError, adminService *service.AdminService, validate *validator.Validate) *AdminHandel {
|
||||||
|
return &AdminHandel{
|
||||||
|
handleError: handleError,
|
||||||
|
adminService: adminService,
|
||||||
|
validate: validate,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type tokenValue string
|
type tokenValue string
|
||||||
|
|
||||||
const tokenKey = tokenValue("token")
|
const tokenKey = tokenValue("token")
|
||||||
|
|
||||||
func (h *Handel) NeedAuth(handle http.Handler) http.Handler {
|
func (h *AdminHandel) NeedAuth(handle http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
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 == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t, err := h.webService.Auth(ctx, token)
|
t, err := h.adminService.Auth(ctx, token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleErrorService(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r = r.WithContext(context.WithValue(ctx, tokenKey, t))
|
r = r.WithContext(context.WithValue(ctx, tokenKey, t))
|
||||||
@ -33,20 +51,20 @@ func (h *Handel) NeedAuth(handle http.Handler) http.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) NeedAdmin(handle http.Handler) http.Handler {
|
func (h *AdminHandel) NeedAdmin(handle http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
err := h.webService.IsAdmin(ctx, t)
|
err := h.adminService.IsAdmin(ctx, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleErrorService(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
handle.ServeHTTP(w, r)
|
handle.ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) ListUser() http.HandlerFunc {
|
func (h *AdminHandel) ListUser() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
page := r.FormValue("page")
|
page := r.FormValue("page")
|
||||||
@ -54,7 +72,7 @@ func (h *Handel) ListUser() http.HandlerFunc {
|
|||||||
if page != "" {
|
if page != "" {
|
||||||
p, err := strconv.Atoi(page)
|
p, err := strconv.Atoi(page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, "page 必须为数字", model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, "page 必须为数字", model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
@ -65,37 +83,37 @@ func (h *Handel) ListUser() http.HandlerFunc {
|
|||||||
email := r.FormValue("email")
|
email := r.FormValue("email")
|
||||||
name := r.FormValue("name")
|
name := r.FormValue("name")
|
||||||
|
|
||||||
ul, uc, err := h.webService.ListUser(ctx, pagei, email, name)
|
ul, uc, err := h.adminService.ListUser(ctx, pagei, email, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleErrorService(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[model.List[model.UserList]]{Data: model.List[model.UserList]{List: ul, Total: uc}})
|
encodeJson(w, model.API[model.List[model.UserList]]{Data: model.List[model.UserList]{List: ul, Total: uc}})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) EditUser() http.HandlerFunc {
|
func (h *AdminHandel) EditUser() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
uid := chi.URLParamFromCtx(ctx, "uid")
|
uid := chi.URLParamFromCtx(ctx, "uid")
|
||||||
if uid == "" {
|
if uid == "" {
|
||||||
h.handleError(ctx, w, "uid 为空", model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, "uid 为空", model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uidi, err := strconv.Atoi(uid)
|
uidi, err := strconv.Atoi(uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a, err := U.DeCodeBody[model.EditUser](r.Body, h.validate)
|
a, err := U.DeCodeBody[model.EditUser](r.Body, h.validate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = h.webService.EditUser(ctx, a, uidi)
|
err = h.adminService.EditUser(ctx, a, uidi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleErrorService(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson[any](w, model.API[any]{
|
encodeJson[any](w, model.API[any]{
|
||||||
@ -103,3 +121,17 @@ func (h *Handel) EditUser() http.HandlerFunc {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *AdminHandel) getTokenbyAuthorization(ctx context.Context, w http.ResponseWriter, r *http.Request) string {
|
||||||
|
auth := r.Header.Get("Authorization")
|
||||||
|
if auth == "" {
|
||||||
|
h.handleError.Error(ctx, w, "缺少 Authorization", model.ErrAuth, 401, slog.LevelDebug)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
al := strings.Split(auth, " ")
|
||||||
|
if len(al) != 2 || al[0] != "Bearer" {
|
||||||
|
h.handleError.Error(ctx, w, "Authorization 格式错误", model.ErrAuth, 401, slog.LevelDebug)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return al[1]
|
||||||
|
}
|
||||||
|
@ -5,8 +5,19 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
|
"github.com/xmdhs/authlib-skin/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Handel struct {
|
||||||
|
webService *service.WebService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHandel(webService *service.WebService) *Handel {
|
||||||
|
return &Handel{
|
||||||
|
webService: webService,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handel) GetConfig() http.HandlerFunc {
|
func (h *Handel) GetConfig() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
package handle
|
|
||||||
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
func (h *Handel) SendVerifyCode() http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
package handle
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"log/slog"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
|
||||||
"github.com/xmdhs/authlib-skin/service"
|
|
||||||
"github.com/xmdhs/authlib-skin/service/auth"
|
|
||||||
"github.com/xmdhs/authlib-skin/service/captcha"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (h *Handel) handleErrorService(ctx context.Context, w http.ResponseWriter, err error) {
|
|
||||||
if errors.Is(err, service.ErrExistUser) {
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrExistUser, 400, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors.Is(err, service.ErrExitsName) {
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrExitsName, 400, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors.Is(err, service.ErrRegLimit) {
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrRegLimit, 400, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors.Is(err, captcha.ErrCaptcha) {
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrCaptcha, 400, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors.Is(err, service.ErrPassWord) {
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrPassWord, 401, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors.Is(err, auth.ErrUserDisable) {
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrUserDisable, 401, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors.Is(err, service.ErrNotAdmin) {
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrNotAdmin, 401, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors.Is(err, auth.ErrTokenInvalid) {
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrAuth, 401, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handel) handleError(ctx context.Context, w http.ResponseWriter, msg string, code model.APIStatus, httpcode int, level slog.Level) {
|
|
||||||
h.logger.Log(ctx, level, msg)
|
|
||||||
w.WriteHeader(httpcode)
|
|
||||||
b, err := json.Marshal(model.API[any]{Code: code, Msg: msg, Data: nil})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
w.Write(b)
|
|
||||||
}
|
|
71
handle/handelerror/error.go
Normal file
71
handle/handelerror/error.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package handelerror
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
|
"github.com/xmdhs/authlib-skin/service"
|
||||||
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
|
"github.com/xmdhs/authlib-skin/service/captcha"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HandleError struct {
|
||||||
|
logger *slog.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHandleError(logger *slog.Logger) *HandleError {
|
||||||
|
return &HandleError{
|
||||||
|
logger: logger,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HandleError) Service(ctx context.Context, w http.ResponseWriter, err error) {
|
||||||
|
if errors.Is(err, service.ErrExistUser) {
|
||||||
|
h.Error(ctx, w, err.Error(), model.ErrExistUser, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, service.ErrExitsName) {
|
||||||
|
h.Error(ctx, w, err.Error(), model.ErrExitsName, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, service.ErrRegLimit) {
|
||||||
|
h.Error(ctx, w, err.Error(), model.ErrRegLimit, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, captcha.ErrCaptcha) {
|
||||||
|
h.Error(ctx, w, err.Error(), model.ErrCaptcha, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, service.ErrPassWord) {
|
||||||
|
h.Error(ctx, w, err.Error(), model.ErrPassWord, 401, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, auth.ErrUserDisable) {
|
||||||
|
h.Error(ctx, w, err.Error(), model.ErrUserDisable, 401, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, service.ErrNotAdmin) {
|
||||||
|
h.Error(ctx, w, err.Error(), model.ErrNotAdmin, 401, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, auth.ErrTokenInvalid) {
|
||||||
|
h.Error(ctx, w, err.Error(), model.ErrAuth, 401, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Error(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HandleError) Error(ctx context.Context, w http.ResponseWriter, msg string, code model.APIStatus, httpcode int, level slog.Level) {
|
||||||
|
h.logger.Log(ctx, level, msg)
|
||||||
|
w.WriteHeader(httpcode)
|
||||||
|
b, err := json.Marshal(model.API[any]{Code: code, Msg: msg, Data: nil})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
w.Write(b)
|
||||||
|
}
|
@ -1,60 +1,22 @@
|
|||||||
package handle
|
package handle
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
|
||||||
"net/http"
|
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/google/wire"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/xmdhs/authlib-skin/config"
|
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/service"
|
|
||||||
"github.com/xmdhs/authlib-skin/service/email"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handel struct {
|
var HandelSet = wire.NewSet(NewUserHandel, NewAdminHandel, NewHandel)
|
||||||
webService *service.WebService
|
|
||||||
validate *validator.Validate
|
|
||||||
emailService *email.Email
|
|
||||||
config config.Config
|
|
||||||
logger *slog.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHandel(webService *service.WebService, validate *validator.Validate,
|
|
||||||
config config.Config, logger *slog.Logger, email *email.Email) *Handel {
|
|
||||||
return &Handel{
|
|
||||||
webService: webService,
|
|
||||||
validate: validate,
|
|
||||||
config: config,
|
|
||||||
logger: logger,
|
|
||||||
emailService: email,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeJson[T any](w io.Writer, m model.API[T]) {
|
func encodeJson[T any](w io.Writer, m model.API[T]) {
|
||||||
json.NewEncoder(w).Encode(m)
|
json.NewEncoder(w).Encode(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) getTokenbyAuthorization(ctx context.Context, w http.ResponseWriter, r *http.Request) string {
|
|
||||||
auth := r.Header.Get("Authorization")
|
|
||||||
if auth == "" {
|
|
||||||
h.handleError(ctx, w, "缺少 Authorization", model.ErrAuth, 401, slog.LevelDebug)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
al := strings.Split(auth, " ")
|
|
||||||
if len(al) != 2 || al[0] != "Bearer" {
|
|
||||||
h.handleError(ctx, w, "Authorization 格式错误", model.ErrAuth, 401, slog.LevelDebug)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return al[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPrefix(ip string) (string, error) {
|
func getPrefix(ip string) (string, error) {
|
||||||
ipa, err := netip.ParseAddr(ip)
|
ipa, err := netip.ParseAddr(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -9,33 +9,55 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
"github.com/xmdhs/authlib-skin/handle/handelerror"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
|
"github.com/xmdhs/authlib-skin/service"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handel) Reg() http.HandlerFunc {
|
type UserHandel struct {
|
||||||
|
handleError *handelerror.HandleError
|
||||||
|
validate *validator.Validate
|
||||||
|
userService *service.UserSerice
|
||||||
|
logger *slog.Logger
|
||||||
|
textureService *service.TextureService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserHandel(handleError *handelerror.HandleError, validate *validator.Validate,
|
||||||
|
userService *service.UserSerice, logger *slog.Logger, textureService *service.TextureService) *UserHandel {
|
||||||
|
return &UserHandel{
|
||||||
|
handleError: handleError,
|
||||||
|
validate: validate,
|
||||||
|
userService: userService,
|
||||||
|
logger: logger,
|
||||||
|
textureService: textureService,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *UserHandel) Reg() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
ip, err := utils.GetIP(r)
|
ip, err := utils.GetIP(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := utils.DeCodeBody[model.UserReg](r.Body, h.validate)
|
u, err := utils.DeCodeBody[model.UserReg](r.Body, h.validate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rip, err := getPrefix(ip)
|
rip, err := getPrefix(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrUnknown, 500, slog.LevelWarn)
|
h.handleError.Error(ctx, w, err.Error(), model.ErrUnknown, 500, slog.LevelWarn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lr, err := h.webService.Reg(ctx, u, rip, ip)
|
lr, err := h.userService.Reg(ctx, u, rip, ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleErrorService(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[model.LoginRep]{
|
encodeJson(w, model.API[model.LoginRep]{
|
||||||
@ -45,24 +67,24 @@ func (h *Handel) Reg() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) Login() http.HandlerFunc {
|
func (h *UserHandel) Login() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
ip, err := utils.GetIP(r)
|
ip, err := utils.GetIP(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
l, err := utils.DeCodeBody[model.Login](r.Body, h.validate)
|
l, err := utils.DeCodeBody[model.Login](r.Body, h.validate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lr, err := h.webService.Login(ctx, l, ip)
|
lr, err := h.userService.Login(ctx, l, ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleErrorService(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[model.LoginRep]{
|
encodeJson(w, model.API[model.LoginRep]{
|
||||||
@ -72,13 +94,13 @@ func (h *Handel) Login() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) UserInfo() http.HandlerFunc {
|
func (h *UserHandel) UserInfo() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
u, err := h.webService.Info(ctx, t)
|
u, err := h.userService.Info(ctx, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleErrorService(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[model.UserInfo]{
|
encodeJson(w, model.API[model.UserInfo]{
|
||||||
@ -88,19 +110,19 @@ func (h *Handel) UserInfo() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) ChangePasswd() http.HandlerFunc {
|
func (h *UserHandel) ChangePasswd() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
|
|
||||||
c, err := utils.DeCodeBody[model.ChangePasswd](r.Body, h.validate)
|
c, err := utils.DeCodeBody[model.ChangePasswd](r.Body, h.validate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = h.webService.ChangePasswd(ctx, c, t)
|
err = h.userService.ChangePasswd(ctx, c, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleErrorService(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[any]{
|
encodeJson(w, model.API[any]{
|
||||||
@ -110,18 +132,18 @@ func (h *Handel) ChangePasswd() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) ChangeName() http.HandlerFunc {
|
func (h *UserHandel) ChangeName() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
c, err := utils.DeCodeBody[model.ChangeName](r.Body, h.validate)
|
c, err := utils.DeCodeBody[model.ChangeName](r.Body, h.validate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = h.webService.ChangeName(ctx, c.Name, t)
|
err = h.userService.ChangeName(ctx, c.Name, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleErrorService(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[any]{
|
encodeJson(w, model.API[any]{
|
||||||
@ -130,7 +152,7 @@ func (h *Handel) ChangeName() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handel) PutTexture() http.HandlerFunc {
|
func (h *UserHandel) PutTexture() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
@ -139,7 +161,7 @@ func (h *Handel) PutTexture() http.HandlerFunc {
|
|||||||
textureType := chi.URLParamFromCtx(ctx, "textureType")
|
textureType := chi.URLParamFromCtx(ctx, "textureType")
|
||||||
if textureType != "skin" && textureType != "cape" {
|
if textureType != "skin" && textureType != "cape" {
|
||||||
h.logger.DebugContext(ctx, "上传类型错误")
|
h.logger.DebugContext(ctx, "上传类型错误")
|
||||||
h.handleError(ctx, w, "上传类型错误", model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, "上传类型错误", model.ErrInput, 400, slog.LevelDebug)
|
||||||
}
|
}
|
||||||
|
|
||||||
skin, err := func() ([]byte, error) {
|
skin, err := func() ([]byte, error) {
|
||||||
@ -167,7 +189,7 @@ func (h *Handel) PutTexture() http.HandlerFunc {
|
|||||||
return bw.Bytes(), err
|
return bw.Bytes(), err
|
||||||
}()
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,13 +198,13 @@ func (h *Handel) PutTexture() http.HandlerFunc {
|
|||||||
case "":
|
case "":
|
||||||
default:
|
default:
|
||||||
h.logger.DebugContext(ctx, "错误的皮肤的材质模型")
|
h.logger.DebugContext(ctx, "错误的皮肤的材质模型")
|
||||||
h.handleError(ctx, w, "错误的皮肤的材质模型", model.ErrInput, 400, slog.LevelDebug)
|
h.handleError.Error(ctx, w, "错误的皮肤的材质模型", model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.webService.PutTexture(ctx, t, skin, models, textureType)
|
err = h.textureService.PutTexture(ctx, t, skin, models, textureType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleErrorService(ctx, w, err)
|
h.handleError.Service(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[any]{
|
encodeJson(w, model.API[any]{
|
||||||
|
@ -14,7 +14,8 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/server/static"
|
"github.com/xmdhs/authlib-skin/server/static"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRoute(handelY *yggdrasil.Yggdrasil, handel *handle.Handel, c config.Config, sl slog.Handler) http.Handler {
|
func NewRoute(handelY *yggdrasil.Yggdrasil, handel *handle.Handel, c config.Config, sl slog.Handler,
|
||||||
|
userHandel *handle.UserHandel, adminHandel *handle.AdminHandel) http.Handler {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
r.Use(middleware.RequestID)
|
r.Use(middleware.RequestID)
|
||||||
if c.RaelIP {
|
if c.RaelIP {
|
||||||
@ -28,7 +29,7 @@ func NewRoute(handelY *yggdrasil.Yggdrasil, handel *handle.Handel, c config.Conf
|
|||||||
r.Use(APILocationIndication)
|
r.Use(APILocationIndication)
|
||||||
|
|
||||||
r.Mount("/", static.StaticServer())
|
r.Mount("/", static.StaticServer())
|
||||||
r.Mount("/api/v1", newSkinApi(handel))
|
r.Mount("/api/v1", newSkinApi(handel, userHandel, adminHandel))
|
||||||
r.Mount("/api/yggdrasil", newYggdrasil(handelY))
|
r.Mount("/api/yggdrasil", newYggdrasil(handelY))
|
||||||
|
|
||||||
if c.Debug {
|
if c.Debug {
|
||||||
@ -74,26 +75,26 @@ func newYggdrasil(handelY *yggdrasil.Yggdrasil) http.Handler {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSkinApi(handel *handle.Handel) http.Handler {
|
func newSkinApi(handel *handle.Handel, userHandel *handle.UserHandel, adminHandel *handle.AdminHandel) http.Handler {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
|
|
||||||
r.Post("/user/reg", handel.Reg())
|
r.Post("/user/reg", userHandel.Reg())
|
||||||
r.Post("/user/login", handel.Login())
|
r.Post("/user/login", userHandel.Login())
|
||||||
r.Get("/config", handel.GetConfig())
|
r.Get("/config", handel.GetConfig())
|
||||||
|
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Use(handel.NeedAuth)
|
r.Use(adminHandel.NeedAuth)
|
||||||
r.Get("/user", handel.UserInfo())
|
r.Get("/user", userHandel.UserInfo())
|
||||||
r.Post("/user/password", handel.ChangePasswd())
|
r.Post("/user/password", userHandel.ChangePasswd())
|
||||||
r.Post("/user/name", handel.ChangeName())
|
r.Post("/user/name", userHandel.ChangeName())
|
||||||
r.Put("/user/skin/{textureType}", handel.PutTexture())
|
r.Put("/user/skin/{textureType}", userHandel.PutTexture())
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Use(handel.NeedAuth)
|
r.Use(adminHandel.NeedAuth)
|
||||||
r.Use(handel.NeedAdmin)
|
r.Use(adminHandel.NeedAdmin)
|
||||||
r.Get("/admin/users", handel.ListUser())
|
r.Get("/admin/users", adminHandel.ListUser())
|
||||||
r.Patch("/admin/user/{uid}", handel.EditUser())
|
r.Patch("/admin/user/{uid}", adminHandel.EditUser())
|
||||||
})
|
})
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
"github.com/xmdhs/authlib-skin/config"
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
"github.com/xmdhs/authlib-skin/handle"
|
"github.com/xmdhs/authlib-skin/handle"
|
||||||
|
"github.com/xmdhs/authlib-skin/handle/handelerror"
|
||||||
"github.com/xmdhs/authlib-skin/handle/yggdrasil"
|
"github.com/xmdhs/authlib-skin/handle/yggdrasil"
|
||||||
"github.com/xmdhs/authlib-skin/server/route"
|
"github.com/xmdhs/authlib-skin/server/route"
|
||||||
"github.com/xmdhs/authlib-skin/service"
|
"github.com/xmdhs/authlib-skin/service"
|
||||||
@ -18,13 +19,14 @@ import (
|
|||||||
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var serviceSet = wire.NewSet(service.NewWebService, yggdrasilS.NewYggdrasil, email.NewEmail, auth.NewAuthService,
|
var serviceSet = wire.NewSet(service.Service, yggdrasilS.NewYggdrasil, email.NewEmail, auth.NewAuthService,
|
||||||
captcha.NewCaptchaService,
|
captcha.NewCaptchaService,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var handleSet = wire.NewSet(handelerror.NewHandleError, handle.HandelSet, yggdrasil.NewYggdrasil)
|
||||||
|
|
||||||
func InitializeRoute(ctx context.Context, c config.Config) (*http.Server, func(), error) {
|
func InitializeRoute(ctx context.Context, c config.Config) (*http.Server, func(), error) {
|
||||||
panic(wire.Build(Set, route.NewRoute, NewSlog,
|
panic(wire.Build(Set, route.NewRoute, NewSlog,
|
||||||
NewServer, handle.NewHandel, yggdrasil.NewYggdrasil,
|
NewServer, handleSet, serviceSet,
|
||||||
serviceSet,
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,15 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/google/wire"
|
||||||
"github.com/xmdhs/authlib-skin/config"
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
"github.com/xmdhs/authlib-skin/handle"
|
"github.com/xmdhs/authlib-skin/handle"
|
||||||
|
"github.com/xmdhs/authlib-skin/handle/handelerror"
|
||||||
yggdrasil2 "github.com/xmdhs/authlib-skin/handle/yggdrasil"
|
yggdrasil2 "github.com/xmdhs/authlib-skin/handle/yggdrasil"
|
||||||
"github.com/xmdhs/authlib-skin/server/route"
|
"github.com/xmdhs/authlib-skin/server/route"
|
||||||
"github.com/xmdhs/authlib-skin/service"
|
"github.com/xmdhs/authlib-skin/service"
|
||||||
"github.com/xmdhs/authlib-skin/service/auth"
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
|
"github.com/xmdhs/authlib-skin/service/captcha"
|
||||||
"github.com/xmdhs/authlib-skin/service/email"
|
"github.com/xmdhs/authlib-skin/service/email"
|
||||||
"github.com/xmdhs/authlib-skin/service/yggdrasil"
|
"github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -55,16 +58,17 @@ func InitializeRoute(ctx context.Context, c config.Config) (*http.Server, func()
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
yggdrasil3 := yggdrasil2.NewYggdrasil(logger, validate, yggdrasilYggdrasil, c, pubRsaKey)
|
yggdrasil3 := yggdrasil2.NewYggdrasil(logger, validate, yggdrasilYggdrasil, c, pubRsaKey)
|
||||||
|
webService := service.NewWebService(c)
|
||||||
|
handel := handle.NewHandel(webService)
|
||||||
|
handleError := handelerror.NewHandleError(logger)
|
||||||
httpClient := ProvideHttpClient()
|
httpClient := ProvideHttpClient()
|
||||||
webService := service.NewWebService(c, client, httpClient, cache, privateKey, authService)
|
captchaService := captcha.NewCaptchaService(c, httpClient)
|
||||||
emailEmail, err := email.NewEmail(privateKey, c, cache)
|
userSerice := service.NewUserSerice(c, client, captchaService, authService, cache)
|
||||||
if err != nil {
|
textureService := service.NewTextureService(client, c, cache)
|
||||||
cleanup2()
|
userHandel := handle.NewUserHandel(handleError, validate, userSerice, logger, textureService)
|
||||||
cleanup()
|
adminService := service.NewAdminService(authService, client, c, cache)
|
||||||
return nil, nil, err
|
adminHandel := handle.NewAdminHandel(handleError, adminService, validate)
|
||||||
}
|
httpHandler := route.NewRoute(yggdrasil3, handel, c, handler, userHandel, adminHandel)
|
||||||
handel := handle.NewHandel(webService, validate, c, logger, emailEmail)
|
|
||||||
httpHandler := route.NewRoute(yggdrasil3, handel, c, handler)
|
|
||||||
server, cleanup3 := NewServer(c, httpHandler)
|
server, cleanup3 := NewServer(c, httpHandler)
|
||||||
return server, func() {
|
return server, func() {
|
||||||
cleanup3()
|
cleanup3()
|
||||||
@ -72,3 +76,9 @@ func InitializeRoute(ctx context.Context, c config.Config) (*http.Server, func()
|
|||||||
cleanup()
|
cleanup()
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wire.go:
|
||||||
|
|
||||||
|
var serviceSet = wire.NewSet(service.Service, yggdrasil.NewYggdrasil, email.NewEmail, auth.NewAuthService, captcha.NewCaptchaService)
|
||||||
|
|
||||||
|
var handleSet = wire.NewSet(handelerror.NewHandleError, handle.HandelSet, yggdrasil2.NewYggdrasil)
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
|
"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/db/ent/predicate"
|
"github.com/xmdhs/authlib-skin/db/ent/predicate"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/user"
|
"github.com/xmdhs/authlib-skin/db/ent/user"
|
||||||
@ -18,9 +20,26 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AdminService struct {
|
||||||
|
authService *auth.AuthService
|
||||||
|
client *ent.Client
|
||||||
|
config config.Config
|
||||||
|
cache cache.Cache
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAdminService(authService *auth.AuthService, client *ent.Client,
|
||||||
|
config config.Config, cache cache.Cache) *AdminService {
|
||||||
|
return &AdminService{
|
||||||
|
authService: authService,
|
||||||
|
client: client,
|
||||||
|
config: config,
|
||||||
|
cache: cache,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var ErrNotAdmin = errors.New("无权限")
|
var ErrNotAdmin = errors.New("无权限")
|
||||||
|
|
||||||
func (w *WebService) Auth(ctx context.Context, token string) (*model.TokenClaims, error) {
|
func (w *AdminService) Auth(ctx context.Context, token string) (*model.TokenClaims, error) {
|
||||||
t, err := w.authService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, false)
|
t, err := w.authService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("WebService.Auth: %w", err)
|
return nil, fmt.Errorf("WebService.Auth: %w", err)
|
||||||
@ -28,7 +47,7 @@ func (w *WebService) Auth(ctx context.Context, token string) (*model.TokenClaims
|
|||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) IsAdmin(ctx context.Context, t *model.TokenClaims) error {
|
func (w *AdminService) IsAdmin(ctx context.Context, t *model.TokenClaims) error {
|
||||||
u, err := w.client.User.Query().Where(user.ID(t.UID)).First(ctx)
|
u, err := w.client.User.Query().Where(user.ID(t.UID)).First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("IsAdmin: %w", err)
|
return fmt.Errorf("IsAdmin: %w", err)
|
||||||
@ -39,7 +58,7 @@ func (w *WebService) IsAdmin(ctx context.Context, t *model.TokenClaims) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) ListUser(ctx context.Context, page int, email, name string) ([]model.UserList, int, error) {
|
func (w *AdminService) ListUser(ctx context.Context, page int, email, name string) ([]model.UserList, int, error) {
|
||||||
whereL := []predicate.User{}
|
whereL := []predicate.User{}
|
||||||
if email != "" {
|
if email != "" {
|
||||||
whereL = append(whereL, user.EmailHasPrefix(email))
|
whereL = append(whereL, user.EmailHasPrefix(email))
|
||||||
@ -79,7 +98,7 @@ func (w *WebService) ListUser(ctx context.Context, page int, email, name string)
|
|||||||
return ul, uc, nil
|
return ul, uc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) EditUser(ctx context.Context, u model.EditUser, uid int) error {
|
func (w *AdminService) EditUser(ctx context.Context, u model.EditUser, uid int) error {
|
||||||
uuid := ""
|
uuid := ""
|
||||||
changePasswd := false
|
changePasswd := false
|
||||||
err := utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
err := utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
||||||
|
@ -9,9 +9,9 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWebService_Auth(t *testing.T) {
|
func TestAdminSerice_Auth(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
lr, err := webService.Reg(ctx, model.UserReg{
|
lr, err := userSerice.Reg(ctx, model.UserReg{
|
||||||
Email: "TestWebService_Auth@xmdhs.com",
|
Email: "TestWebService_Auth@xmdhs.com",
|
||||||
Password: "TestWebService_Auth",
|
Password: "TestWebService_Auth",
|
||||||
Name: "TestWebService_Auth",
|
Name: "TestWebService_Auth",
|
||||||
@ -20,7 +20,7 @@ func TestWebService_Auth(t *testing.T) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Equal(t, lr.Name, "TestWebService_Auth")
|
require.Equal(t, lr.Name, "TestWebService_Auth")
|
||||||
|
|
||||||
token, err := webService.Auth(ctx, lr.Token)
|
token, err := adminSerice.Auth(ctx, lr.Token)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
assert.Equal(t, token.Subject, lr.UUID)
|
assert.Equal(t, token.Subject, lr.UUID)
|
||||||
@ -32,13 +32,13 @@ func TestWebService_Auth(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
w *WebService
|
w *AdminService
|
||||||
args args
|
args args
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "some string",
|
name: "some string",
|
||||||
w: webService,
|
w: adminSerice,
|
||||||
args: args{
|
args: args{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
token: "123213",
|
token: "123213",
|
||||||
@ -47,7 +47,7 @@ func TestWebService_Auth(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid jwt",
|
name: "valid jwt",
|
||||||
w: webService,
|
w: adminSerice,
|
||||||
args: args{
|
args: args{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjpbeyJ0b29sdHQiOiJodHRwczovL3Rvb2x0dC5jb20ifV0sImlhdCI6MTY5NzEwMjMzOCwiZXhwIjoxNjk3MTI2Mzk5LCJhdWQiOiIiLCJpc3MiOiIiLCJzdWIiOiIifQ.JTQWl1PEX8u7PhVc4dTtv1DRS6e1PbMDZNWOAFJmVqE",
|
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjpbeyJ0b29sdHQiOiJodHRwczovL3Rvb2x0dC5jb20ifV0sImlhdCI6MTY5NzEwMjMzOCwiZXhwIjoxNjk3MTI2Mzk5LCJhdWQiOiIiLCJpc3MiOiIiLCJzdWIiOiIifQ.JTQWl1PEX8u7PhVc4dTtv1DRS6e1PbMDZNWOAFJmVqE",
|
||||||
|
@ -1 +1,5 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
|
import "github.com/google/wire"
|
||||||
|
|
||||||
|
var Service = wire.NewSet(NewUserSerice, NewTextureService, NewAdminService, NewWebService)
|
||||||
|
@ -9,6 +9,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
|
"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/db/ent/texture"
|
"github.com/xmdhs/authlib-skin/db/ent/texture"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/user"
|
"github.com/xmdhs/authlib-skin/db/ent/user"
|
||||||
@ -18,7 +20,21 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *WebService) PutTexture(ctx context.Context, t *model.TokenClaims, texturebyte []byte, model string, textureType string) error {
|
type TextureService struct {
|
||||||
|
client *ent.Client
|
||||||
|
config config.Config
|
||||||
|
cache cache.Cache
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTextureService(client *ent.Client, config config.Config, cache cache.Cache) *TextureService {
|
||||||
|
return &TextureService{
|
||||||
|
client: client,
|
||||||
|
config: config,
|
||||||
|
cache: cache,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *TextureService) PutTexture(ctx context.Context, t *model.TokenClaims, texturebyte []byte, model string, textureType string) error {
|
||||||
up, err := w.client.UserProfile.Query().Where(userprofile.HasUserWith(user.ID(t.UID))).First(ctx)
|
up, err := w.client.UserProfile.Query().Where(userprofile.HasUserWith(user.ID(t.UID))).First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("PutTexture: %w", err)
|
return fmt.Errorf("PutTexture: %w", err)
|
||||||
|
@ -9,11 +9,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
|
"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/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/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/service/auth"
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
|
"github.com/xmdhs/authlib-skin/service/captcha"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,7 +28,26 @@ var (
|
|||||||
ErrChangeName = errors.New("离线模式 uuid 不允许修改用户名")
|
ErrChangeName = errors.New("离线模式 uuid 不允许修改用户名")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *WebService) Reg(ctx context.Context, u model.UserReg, ipPrefix, ip string) (model.LoginRep, error) {
|
type UserSerice struct {
|
||||||
|
config config.Config
|
||||||
|
client *ent.Client
|
||||||
|
captchaService *captcha.CaptchaService
|
||||||
|
authService *auth.AuthService
|
||||||
|
cache cache.Cache
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserSerice(config config.Config, client *ent.Client, captchaService *captcha.CaptchaService,
|
||||||
|
authService *auth.AuthService, cache cache.Cache) *UserSerice {
|
||||||
|
return &UserSerice{
|
||||||
|
config: config,
|
||||||
|
client: client,
|
||||||
|
captchaService: captchaService,
|
||||||
|
authService: authService,
|
||||||
|
cache: cache,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *UserSerice) Reg(ctx context.Context, u model.UserReg, ipPrefix, ip string) (model.LoginRep, error) {
|
||||||
var userUuid string
|
var userUuid string
|
||||||
if w.config.OfflineUUID {
|
if w.config.OfflineUUID {
|
||||||
userUuid = utils.UUIDGen(u.Name)
|
userUuid = utils.UUIDGen(u.Name)
|
||||||
@ -108,7 +130,7 @@ func (w *WebService) Reg(ctx context.Context, u model.UserReg, ipPrefix, ip stri
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) Login(ctx context.Context, l model.Login, ip string) (model.LoginRep, error) {
|
func (w *UserSerice) Login(ctx context.Context, l model.Login, ip string) (model.LoginRep, error) {
|
||||||
err := w.captchaService.VerifyCaptcha(ctx, l.CaptchaToken, ip)
|
err := w.captchaService.VerifyCaptcha(ctx, l.CaptchaToken, ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
||||||
@ -121,7 +143,7 @@ func (w *WebService) Login(ctx context.Context, l model.Login, ip string) (model
|
|||||||
}
|
}
|
||||||
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
||||||
}
|
}
|
||||||
err = w.validatePass(ctx, u, l.Password)
|
err = validatePass(ctx, u, l.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
||||||
}
|
}
|
||||||
@ -136,7 +158,7 @@ func (w *WebService) Login(ctx context.Context, l model.Login, ip string) (model
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) Info(ctx context.Context, t *model.TokenClaims) (model.UserInfo, error) {
|
func (w *UserSerice) Info(ctx context.Context, t *model.TokenClaims) (model.UserInfo, error) {
|
||||||
u, err := w.client.User.Query().Where(user.ID(t.UID)).First(ctx)
|
u, err := w.client.User.Query().Where(user.ID(t.UID)).First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return model.UserInfo{}, fmt.Errorf("Info: %w", err)
|
return model.UserInfo{}, fmt.Errorf("Info: %w", err)
|
||||||
@ -149,12 +171,12 @@ func (w *WebService) Info(ctx context.Context, t *model.TokenClaims) (model.User
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) ChangePasswd(ctx context.Context, p model.ChangePasswd, t *model.TokenClaims) error {
|
func (w *UserSerice) ChangePasswd(ctx context.Context, p model.ChangePasswd, t *model.TokenClaims) error {
|
||||||
u, err := w.client.User.Query().Where(user.IDEQ(t.UID)).WithToken().First(ctx)
|
u, err := w.client.User.Query().Where(user.IDEQ(t.UID)).WithToken().First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ChangePasswd: %w", err)
|
return fmt.Errorf("ChangePasswd: %w", err)
|
||||||
}
|
}
|
||||||
err = w.validatePass(ctx, u, p.Old)
|
err = validatePass(ctx, u, p.Old)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ChangePasswd: %w", err)
|
return fmt.Errorf("ChangePasswd: %w", err)
|
||||||
}
|
}
|
||||||
@ -176,7 +198,7 @@ func (w *WebService) ChangePasswd(ctx context.Context, p model.ChangePasswd, t *
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) changeName(ctx context.Context, newName string, uid int, uuid string) error {
|
func (w *UserSerice) changeName(ctx context.Context, newName string, uid int, uuid string) error {
|
||||||
if w.config.OfflineUUID {
|
if w.config.OfflineUUID {
|
||||||
return fmt.Errorf("changeName: %w", ErrChangeName)
|
return fmt.Errorf("changeName: %w", ErrChangeName)
|
||||||
}
|
}
|
||||||
@ -195,7 +217,7 @@ func (w *WebService) changeName(ctx context.Context, newName string, uid int, uu
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) ChangeName(ctx context.Context, newName string, t *model.TokenClaims) error {
|
func (w *UserSerice) ChangeName(ctx context.Context, newName string, t *model.TokenClaims) error {
|
||||||
err := w.changeName(ctx, newName, t.UID, t.Subject)
|
err := w.changeName(ctx, newName, t.UID, t.Subject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ChangeName: %w", err)
|
return fmt.Errorf("ChangeName: %w", err)
|
||||||
|
@ -19,12 +19,15 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/service/captcha"
|
"github.com/xmdhs/authlib-skin/service/captcha"
|
||||||
)
|
)
|
||||||
|
|
||||||
var webService *WebService
|
var (
|
||||||
|
userSerice *UserSerice
|
||||||
|
adminSerice *AdminService
|
||||||
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
clean := initWebService(ctx)
|
clean := initSerice(ctx)
|
||||||
code := m.Run()
|
code := m.Run()
|
||||||
|
|
||||||
clean()
|
clean()
|
||||||
@ -32,12 +35,16 @@ func TestMain(m *testing.M) {
|
|||||||
os.Exit(code)
|
os.Exit(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initWebService(ctx context.Context) func() {
|
func initSerice(ctx context.Context) func() {
|
||||||
c := lo.Must(ent.Open("mysql", "root:root@tcp(127.0.0.1)/test"))
|
c := lo.Must(ent.Open("mysql", "root:root@tcp(127.0.0.1)/test"))
|
||||||
lo.Must0(c.Schema.Create(context.Background(), migrate.WithForeignKeys(false), migrate.WithDropIndex(true), migrate.WithDropColumn(true)))
|
lo.Must0(c.Schema.Create(context.Background(), migrate.WithForeignKeys(false), migrate.WithDropIndex(true), migrate.WithDropColumn(true)))
|
||||||
rsa4 := lo.Must(rsa.GenerateKey(rand.Reader, 4096))
|
rsa4 := lo.Must(rsa.GenerateKey(rand.Reader, 4096))
|
||||||
cache := cache.NewFastCache(100000)
|
cache := cache.NewFastCache(100000)
|
||||||
webService = NewWebService(config.Default(), c, &http.Client{}, cache, rsa4, auth.NewAuthService(c, cache, &rsa4.PublicKey, rsa4), captcha.NewCaptchaService(config.Default(), &http.Client{}))
|
config := config.Default()
|
||||||
|
authService := auth.NewAuthService(c, cache, &rsa4.PublicKey, rsa4)
|
||||||
|
|
||||||
|
userSerice = NewUserSerice(config, c, captcha.NewCaptchaService(config, &http.Client{}), authService, cache)
|
||||||
|
adminSerice = NewAdminService(authService, c, config, cache)
|
||||||
|
|
||||||
return func() {
|
return func() {
|
||||||
c.User.Delete().Exec(ctx)
|
c.User.Delete().Exec(ctx)
|
||||||
@ -48,9 +55,9 @@ func initWebService(ctx context.Context) func() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWebService_Reg(t *testing.T) {
|
func TestUserSerice_Reg(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
webService.config.MaxIpUser = 1
|
userSerice.config.MaxIpUser = 1
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
u model.UserReg
|
u model.UserReg
|
||||||
@ -59,13 +66,13 @@ func TestWebService_Reg(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
w *WebService
|
w *UserSerice
|
||||||
args args
|
args args
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "1",
|
name: "1",
|
||||||
w: webService,
|
w: userSerice,
|
||||||
args: args{
|
args: args{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
u: model.UserReg{
|
u: model.UserReg{
|
||||||
@ -81,7 +88,7 @@ func TestWebService_Reg(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "email duplicate",
|
name: "email duplicate",
|
||||||
w: webService,
|
w: userSerice,
|
||||||
args: args{
|
args: args{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
u: model.UserReg{
|
u: model.UserReg{
|
||||||
@ -97,7 +104,7 @@ func TestWebService_Reg(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "name duplicate",
|
name: "name duplicate",
|
||||||
w: webService,
|
w: userSerice,
|
||||||
args: args{
|
args: args{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
u: model.UserReg{
|
u: model.UserReg{
|
||||||
@ -113,7 +120,7 @@ func TestWebService_Reg(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "MaxIpUser",
|
name: "MaxIpUser",
|
||||||
w: webService,
|
w: userSerice,
|
||||||
args: args{
|
args: args{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
u: model.UserReg{
|
u: model.UserReg{
|
||||||
@ -129,7 +136,7 @@ func TestWebService_Reg(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "MaxIpUser",
|
name: "MaxIpUser",
|
||||||
w: webService,
|
w: userSerice,
|
||||||
args: args{
|
args: args{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
u: model.UserReg{
|
u: model.UserReg{
|
||||||
@ -151,5 +158,5 @@ func TestWebService_Reg(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
webService.config.MaxIpUser = 0
|
userSerice.config.MaxIpUser = 0
|
||||||
}
|
}
|
||||||
|
@ -2,43 +2,25 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/rsa"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/xmdhs/authlib-skin/config"
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
"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/service/auth"
|
|
||||||
"github.com/xmdhs/authlib-skin/service/captcha"
|
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WebService struct {
|
type WebService struct {
|
||||||
config config.Config
|
config config.Config
|
||||||
client *ent.Client
|
|
||||||
httpClient *http.Client
|
|
||||||
cache cache.Cache
|
|
||||||
prikey *rsa.PrivateKey
|
|
||||||
authService *auth.AuthService
|
|
||||||
captchaService *captcha.CaptchaService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWebService(c config.Config, e *ent.Client, hc *http.Client,
|
func NewWebService(c config.Config) *WebService {
|
||||||
cache cache.Cache, prikey *rsa.PrivateKey, authService *auth.AuthService, captchaService *captcha.CaptchaService) *WebService {
|
|
||||||
return &WebService{
|
return &WebService{
|
||||||
config: c,
|
config: c,
|
||||||
client: e,
|
|
||||||
httpClient: hc,
|
|
||||||
cache: cache,
|
|
||||||
prikey: prikey,
|
|
||||||
authService: authService,
|
|
||||||
captchaService: captchaService,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) validatePass(ctx context.Context, u *ent.User, password string) error {
|
func validatePass(ctx context.Context, u *ent.User, password string) error {
|
||||||
if !utils.Argon2Compare(password, u.Password, u.Salt) {
|
if !utils.Argon2Compare(password, u.Password, u.Salt) {
|
||||||
return fmt.Errorf("validatePass: %w", ErrPassWord)
|
return fmt.Errorf("validatePass: %w", ErrPassWord)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user