改成类
This commit is contained in:
parent
829efda6a7
commit
dc39b89657
@ -10,7 +10,12 @@ type Config struct {
|
||||
Sql struct {
|
||||
MysqlDsn string
|
||||
}
|
||||
Node int64
|
||||
Epoch int64
|
||||
Debug bool
|
||||
Node int64
|
||||
Epoch int64
|
||||
Debug bool
|
||||
JwtKey string
|
||||
Cache struct {
|
||||
Type string
|
||||
Ram int
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ func (User) Fields() []ent.Field {
|
||||
field.String("email").Unique(),
|
||||
field.String("password"),
|
||||
field.String("salt"),
|
||||
// 二进制状态位,保留
|
||||
field.Int("state"),
|
||||
field.Int64("reg_time"),
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ type UserToken struct {
|
||||
// Fields of the UserToken.
|
||||
func (UserToken) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
// 用于验证 jwt token 是否被注销,若相同则有效
|
||||
field.Uint64("token_id"),
|
||||
}
|
||||
}
|
||||
|
5
go.mod
5
go.mod
@ -4,6 +4,8 @@ go 1.21.0
|
||||
|
||||
require (
|
||||
entgo.io/ent v0.12.3
|
||||
github.com/VictoriaMetrics/fastcache v1.12.1
|
||||
github.com/alecthomas/binary v0.0.0-20221018225505-74871811ee56
|
||||
github.com/bwmarrin/snowflake v0.3.0
|
||||
github.com/go-playground/validator/v10 v10.15.3
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
@ -15,15 +17,14 @@ require (
|
||||
|
||||
require (
|
||||
ariga.io/atlas v0.10.2-0.20230427182402-87a07dfb83bf // indirect
|
||||
github.com/VictoriaMetrics/fastcache v1.12.1 // indirect
|
||||
github.com/agext/levenshtein v1.2.1 // indirect
|
||||
github.com/alecthomas/binary v0.0.0-20221018225505-74871811ee56 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
|
||||
|
15
go.sum
15
go.sum
@ -10,6 +10,7 @@ github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tj
|
||||
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/alecthomas/binary v0.0.0-20221018225505-74871811ee56 h1:CXWdlGkIdY4W1KGym1dFxwzRrLhneeonNSOwrhuhwQM=
|
||||
github.com/alecthomas/binary v0.0.0-20221018225505-74871811ee56/go.mod h1:v4e05/vzE8ubOim1No9Xx5eIQ/WRq6AtcnQIy/Z/JPs=
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
@ -36,6 +37,8 @@ github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrt
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
@ -51,8 +54,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/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc=
|
||||
github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
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=
|
||||
@ -65,22 +66,14 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3v
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@ -114,8 +107,6 @@ golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.8.1-0.20230428195545-5283a0178901 h1:0wxTF6pSjIIhNt7mo9GvjDfzyCOiWhmICgtO/Ah948s=
|
||||
golang.org/x/tools v0.8.1-0.20230428195545-5283a0178901/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
25
handle/handle.go
Normal file
25
handle/handle.go
Normal file
@ -0,0 +1,25 @@
|
||||
package handle
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/xmdhs/authlib-skin/config"
|
||||
"github.com/xmdhs/authlib-skin/service"
|
||||
)
|
||||
|
||||
type Handel struct {
|
||||
webService *service.WebService
|
||||
validate *validator.Validate
|
||||
config config.Config
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewHandel(webService *service.WebService, validate *validator.Validate, config config.Config, logger *slog.Logger) *Handel {
|
||||
return &Handel{
|
||||
webService: webService,
|
||||
validate: validate,
|
||||
config: config,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
@ -2,37 +2,32 @@ package handle
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"github.com/bwmarrin/snowflake"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/xmdhs/authlib-skin/config"
|
||||
"github.com/xmdhs/authlib-skin/db/ent"
|
||||
"github.com/xmdhs/authlib-skin/model"
|
||||
"github.com/xmdhs/authlib-skin/service"
|
||||
"github.com/xmdhs/authlib-skin/utils"
|
||||
)
|
||||
|
||||
func Reg(l *slog.Logger, client *ent.Client, v *validator.Validate, snow *snowflake.Node, c config.Config) httprouter.Handle {
|
||||
func (h *Handel) Reg() httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
ctx := r.Context()
|
||||
|
||||
u, err := utils.DeCodeBody[model.User](r.Body, v)
|
||||
u, err := utils.DeCodeBody[model.User](r.Body, h.validate)
|
||||
if err != nil {
|
||||
l.InfoContext(ctx, err.Error())
|
||||
h.logger.InfoContext(ctx, err.Error())
|
||||
handleError(ctx, w, err.Error(), model.ErrInput, 400)
|
||||
return
|
||||
}
|
||||
err = service.Reg(ctx, u, snow, c, client)
|
||||
err = h.webService.Reg(ctx, u)
|
||||
if err != nil {
|
||||
if errors.Is(err, service.ErrExistUser) {
|
||||
l.DebugContext(ctx, err.Error())
|
||||
h.logger.DebugContext(ctx, err.Error())
|
||||
handleError(ctx, w, err.Error(), model.ErrExistUser, 400)
|
||||
return
|
||||
}
|
||||
l.WarnContext(ctx, err.Error())
|
||||
h.logger.WarnContext(ctx, err.Error())
|
||||
handleError(ctx, w, err.Error(), model.ErrService, 500)
|
||||
return
|
||||
}
|
||||
|
@ -1,21 +1,19 @@
|
||||
package yggdrasil
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||
"github.com/xmdhs/authlib-skin/utils"
|
||||
)
|
||||
|
||||
func Authenticate(l *slog.Logger, v *validator.Validate) httprouter.Handle {
|
||||
func (y *Yggdrasil) Authenticate() httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
cxt := r.Context()
|
||||
a, err := utils.DeCodeBody[yggdrasil.Authenticate](r.Body, v)
|
||||
a, err := utils.DeCodeBody[yggdrasil.Authenticate](r.Body, y.validate)
|
||||
if err != nil {
|
||||
l.InfoContext(cxt, err.Error())
|
||||
y.logger.InfoContext(cxt, err.Error())
|
||||
handleYgError(cxt, w, yggdrasil.Error{ErrorMessage: err.Error()}, 400)
|
||||
return
|
||||
}
|
||||
|
22
handle/yggdrasil/yggdrasil.go
Normal file
22
handle/yggdrasil/yggdrasil.go
Normal file
@ -0,0 +1,22 @@
|
||||
package yggdrasil
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||
)
|
||||
|
||||
type Yggdrasil struct {
|
||||
logger *slog.Logger
|
||||
validate *validator.Validate
|
||||
yggdrasilService *yggdrasilS.Yggdrasil
|
||||
}
|
||||
|
||||
func NewYggdrasil(logger *slog.Logger, validate *validator.Validate, yggdrasilService *yggdrasilS.Yggdrasil) *Yggdrasil {
|
||||
return &Yggdrasil{
|
||||
logger: logger,
|
||||
validate: validate,
|
||||
yggdrasilService: yggdrasilService,
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package model
|
||||
|
||||
import "github.com/golang-jwt/jwt/v5"
|
||||
|
||||
type API[T any] struct {
|
||||
Code APIStatus `json:"code"`
|
||||
Data T `json:"data"`
|
||||
@ -11,3 +13,8 @@ type User struct {
|
||||
Password string `validate:"required,min=6,max=50"`
|
||||
Name string `validate:"required,min=3,max=16"`
|
||||
}
|
||||
|
||||
type TokenClaims struct {
|
||||
Tid string `json:"tid"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
@ -16,3 +16,21 @@ type Error struct {
|
||||
Error string `json:"error,omitempty"`
|
||||
ErrorMessage string `json:"errorMessage,omitempty"`
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
AvailableProfiles []TokenProfile `json:"availableProfiles"`
|
||||
ClientToken string `json:"clientToken"`
|
||||
SelectedProfile TokenProfile `json:"selectedProfile"`
|
||||
User TokenUser `json:"user"`
|
||||
}
|
||||
|
||||
type TokenProfile struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type TokenUser struct {
|
||||
ID string `json:"id"`
|
||||
Properties []any `json:"properties"`
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/google/wire"
|
||||
"github.com/xmdhs/authlib-skin/config"
|
||||
"github.com/xmdhs/authlib-skin/db/cache"
|
||||
"github.com/xmdhs/authlib-skin/db/ent"
|
||||
)
|
||||
|
||||
@ -81,4 +82,8 @@ func ProvideSnowflake(c config.Config) (*snowflake.Node, error) {
|
||||
return n, nil
|
||||
}
|
||||
|
||||
var Set = wire.NewSet(ProvideSlog, ProvideDB, ProvideEnt, ProvideValidate, ProvideSnowflake)
|
||||
func ProvideCache(c config.Config) cache.Cache {
|
||||
return cache.NewFastCache(c.Cache.Ram)
|
||||
}
|
||||
|
||||
var Set = wire.NewSet(ProvideSlog, ProvideDB, ProvideEnt, ProvideValidate, ProvideSnowflake, ProvideCache)
|
||||
|
@ -2,23 +2,19 @@ package route
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/bwmarrin/snowflake"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/xmdhs/authlib-skin/config"
|
||||
"github.com/xmdhs/authlib-skin/db/ent"
|
||||
"github.com/xmdhs/authlib-skin/handle"
|
||||
"github.com/xmdhs/authlib-skin/handle/yggdrasil"
|
||||
)
|
||||
|
||||
func NewRoute(l *slog.Logger, client *ent.Client, v *validator.Validate, snow *snowflake.Node, c config.Config) (*httprouter.Router, error) {
|
||||
func NewRoute(yggService *yggdrasil.Yggdrasil, handel *handle.Handel) (*httprouter.Router, error) {
|
||||
r := httprouter.New()
|
||||
err := newYggdrasil(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewRoute: %w", err)
|
||||
}
|
||||
err = newSkinApi(r, l, client, v, snow, c)
|
||||
err = newSkinApi(r, handel)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewRoute: %w", err)
|
||||
}
|
||||
@ -30,7 +26,7 @@ func newYggdrasil(r *httprouter.Router) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newSkinApi(r *httprouter.Router, l *slog.Logger, client *ent.Client, v *validator.Validate, snow *snowflake.Node, c config.Config) error {
|
||||
r.PUT("/api/v1/user/reg", handle.Reg(l, client, v, snow, c))
|
||||
func newSkinApi(r *httprouter.Router, handel *handle.Handel) error {
|
||||
r.PUT("/api/v1/user/reg", handel.Reg())
|
||||
return nil
|
||||
}
|
||||
|
@ -8,9 +8,16 @@ import (
|
||||
|
||||
"github.com/google/wire"
|
||||
"github.com/xmdhs/authlib-skin/config"
|
||||
"github.com/xmdhs/authlib-skin/handle"
|
||||
"github.com/xmdhs/authlib-skin/handle/yggdrasil"
|
||||
"github.com/xmdhs/authlib-skin/server/route"
|
||||
"github.com/xmdhs/authlib-skin/service"
|
||||
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||
)
|
||||
|
||||
func InitializeRoute(ctx context.Context, c config.Config) (*http.Server, func(), error) {
|
||||
panic(wire.Build(Set, route.NewRoute, NewSlog, NewServer))
|
||||
panic(wire.Build(Set, route.NewRoute, NewSlog,
|
||||
NewServer, handle.NewHandel, yggdrasil.NewYggdrasil,
|
||||
service.NewWebService, yggdrasilS.NewYggdrasil,
|
||||
))
|
||||
}
|
||||
|
@ -9,7 +9,11 @@ package server
|
||||
import (
|
||||
"context"
|
||||
"github.com/xmdhs/authlib-skin/config"
|
||||
"github.com/xmdhs/authlib-skin/handle"
|
||||
yggdrasil2 "github.com/xmdhs/authlib-skin/handle/yggdrasil"
|
||||
"github.com/xmdhs/authlib-skin/server/route"
|
||||
"github.com/xmdhs/authlib-skin/service"
|
||||
"github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@ -22,6 +26,7 @@ import (
|
||||
func InitializeRoute(ctx context.Context, c config.Config) (*http.Server, func(), error) {
|
||||
handler := ProvideSlog(c)
|
||||
logger := NewSlog(handler)
|
||||
validate := ProvideValidate()
|
||||
db, cleanup, err := ProvideDB(c)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@ -31,14 +36,12 @@ func InitializeRoute(ctx context.Context, c config.Config) (*http.Server, func()
|
||||
cleanup()
|
||||
return nil, nil, err
|
||||
}
|
||||
validate := ProvideValidate()
|
||||
node, err := ProvideSnowflake(c)
|
||||
if err != nil {
|
||||
cleanup2()
|
||||
cleanup()
|
||||
return nil, nil, err
|
||||
}
|
||||
router, err := route.NewRoute(logger, client, validate, node, c)
|
||||
cache := ProvideCache(c)
|
||||
yggdrasilYggdrasil := yggdrasil.NewYggdrasil(client, cache, c)
|
||||
yggdrasil3 := yggdrasil2.NewYggdrasil(logger, validate, yggdrasilYggdrasil)
|
||||
webService := service.NewWebService(c, client)
|
||||
handel := handle.NewHandel(webService, validate, c, logger)
|
||||
router, err := route.NewRoute(yggdrasil3, handel)
|
||||
if err != nil {
|
||||
cleanup2()
|
||||
cleanup()
|
||||
|
@ -10,10 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/snowflake"
|
||||
"github.com/google/uuid"
|
||||
"github.com/xmdhs/authlib-skin/config"
|
||||
"github.com/xmdhs/authlib-skin/db/ent"
|
||||
"github.com/xmdhs/authlib-skin/db/ent/user"
|
||||
"github.com/xmdhs/authlib-skin/model"
|
||||
"github.com/xmdhs/authlib-skin/utils"
|
||||
@ -24,10 +21,8 @@ var (
|
||||
ErrExitsName = errors.New("用户名已存在")
|
||||
)
|
||||
|
||||
func Reg(ctx context.Context, u model.User, snow *snowflake.Node,
|
||||
c config.Config, e *ent.Client,
|
||||
) error {
|
||||
tx, err := e.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelReadCommitted})
|
||||
func (w *WebService) Reg(ctx context.Context, u model.User) error {
|
||||
tx, err := w.client.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelReadCommitted})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Reg: %w", err)
|
||||
}
|
||||
@ -41,7 +36,7 @@ func Reg(ctx context.Context, u model.User, snow *snowflake.Node,
|
||||
}
|
||||
p, s := utils.Argon2ID(u.Password)
|
||||
|
||||
du, err := e.User.Create().
|
||||
du, err := w.client.User.Create().
|
||||
SetEmail(u.Email).
|
||||
SetPassword(p).
|
||||
SetSalt(s).
|
||||
@ -52,13 +47,13 @@ func Reg(ctx context.Context, u model.User, snow *snowflake.Node,
|
||||
}
|
||||
|
||||
var userUuid string
|
||||
if c.OfflineUUID {
|
||||
if w.config.OfflineUUID {
|
||||
userUuid = uuidGen(u.Name)
|
||||
} else {
|
||||
userUuid = strings.ReplaceAll(uuid.New().String(), "-", "")
|
||||
}
|
||||
|
||||
_, err = e.UserProfile.Create().
|
||||
_, err = w.client.UserProfile.Create().
|
||||
SetUser(du).
|
||||
SetName(u.Name).
|
||||
SetUUID(userUuid).
|
||||
|
18
service/web.go
Normal file
18
service/web.go
Normal file
@ -0,0 +1,18 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/xmdhs/authlib-skin/config"
|
||||
"github.com/xmdhs/authlib-skin/db/ent"
|
||||
)
|
||||
|
||||
type WebService struct {
|
||||
config config.Config
|
||||
client *ent.Client
|
||||
}
|
||||
|
||||
func NewWebService(c config.Config, e *ent.Client) *WebService {
|
||||
return &WebService{
|
||||
config: c,
|
||||
client: e,
|
||||
}
|
||||
}
|
@ -5,37 +5,69 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/xmdhs/authlib-skin/db/cache"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/google/uuid"
|
||||
"github.com/xmdhs/authlib-skin/db/ent"
|
||||
"github.com/xmdhs/authlib-skin/db/ent/user"
|
||||
"github.com/xmdhs/authlib-skin/model"
|
||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||
"github.com/xmdhs/authlib-skin/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrRate = errors.New("频率限制")
|
||||
ErrRate = errors.New("频率限制")
|
||||
ErrPassWord = errors.New("错误的密码或邮箱")
|
||||
)
|
||||
|
||||
func Authenticate(cxt context.Context, client *ent.Client, auth yggdrasil.Authenticate, cache cache.Cache) error {
|
||||
func (y *Yggdrasil) Authenticate(cxt context.Context, auth yggdrasil.Authenticate) (yggdrasil.Token, error) {
|
||||
key := []byte("Authenticate" + auth.Username)
|
||||
|
||||
v, err := cache.Get(key)
|
||||
v, err := y.cache.Get(key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Authenticate: %w", err)
|
||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||
}
|
||||
if v != nil {
|
||||
u := binary.BigEndian.Uint64(v)
|
||||
t := time.Unix(int64(u), 0)
|
||||
if time.Now().Before(t) {
|
||||
return fmt.Errorf("Authenticate: %w", ErrRate)
|
||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", ErrRate)
|
||||
}
|
||||
}
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, uint64(time.Now().Add(10*time.Second).Unix()))
|
||||
err = cache.Put(key, b, time.Now().Add(20*time.Second))
|
||||
err = y.cache.Put(key, b, time.Now().Add(20*time.Second))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Authenticate: %w", err)
|
||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
u, err := y.client.User.Query().Where(user.EmailEQ(auth.Username)).WithProfile().WithToken().First(cxt)
|
||||
if err != nil {
|
||||
var nf *ent.NotFoundError
|
||||
if errors.As(err, &nf) {
|
||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", ErrPassWord)
|
||||
}
|
||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||
}
|
||||
if !utils.Argon2Compare(auth.Password, u.Password, u.Salt) {
|
||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", ErrPassWord)
|
||||
}
|
||||
clientToken := auth.ClientToken
|
||||
if clientToken == "" {
|
||||
clientToken = strings.ReplaceAll(uuid.New().String(), "-", "")
|
||||
}
|
||||
|
||||
claims := model.TokenClaims{
|
||||
Tid: u.Edges.Profile.UUID,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * 24 * time.Hour)),
|
||||
Issuer: "authlib-skin",
|
||||
Subject: u.Edges.Profile.UUID,
|
||||
},
|
||||
}
|
||||
_ = claims
|
||||
|
||||
return yggdrasil.Token{}, nil
|
||||
}
|
||||
|
21
service/yggdrasil/yggdrasil.go
Normal file
21
service/yggdrasil/yggdrasil.go
Normal file
@ -0,0 +1,21 @@
|
||||
package yggdrasil
|
||||
|
||||
import (
|
||||
"github.com/xmdhs/authlib-skin/config"
|
||||
"github.com/xmdhs/authlib-skin/db/cache"
|
||||
"github.com/xmdhs/authlib-skin/db/ent"
|
||||
)
|
||||
|
||||
type Yggdrasil struct {
|
||||
client *ent.Client
|
||||
cache cache.Cache
|
||||
c config.Config
|
||||
}
|
||||
|
||||
func NewYggdrasil(client *ent.Client, cache cache.Cache, c config.Config) *Yggdrasil {
|
||||
return &Yggdrasil{
|
||||
client: client,
|
||||
cache: cache,
|
||||
c: c,
|
||||
}
|
||||
}
|
@ -18,8 +18,12 @@ func Argon2ID(pass string) (password string, salt string) {
|
||||
return base64.StdEncoding.EncodeToString(b), base64.StdEncoding.EncodeToString(s)
|
||||
}
|
||||
|
||||
func Argon2Compare(pass, hashPass string, salt []byte) bool {
|
||||
b := argon2.IDKey([]byte(pass), salt, 1, 64*1024, 1, 32)
|
||||
func Argon2Compare(pass, hashPass string, salt string) bool {
|
||||
s, err := base64.StdEncoding.DecodeString(hashPass)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
b := argon2.IDKey([]byte(pass), s, 1, 64*1024, 1, 32)
|
||||
hb, err := base64.StdEncoding.DecodeString(hashPass)
|
||||
if err != nil {
|
||||
return false
|
||||
|
Loading…
x
Reference in New Issue
Block a user