登录部分
This commit is contained in:
parent
dc39b89657
commit
94bb72eae4
@ -25,6 +25,12 @@ func main() {
|
|||||||
Node: 0,
|
Node: 0,
|
||||||
Epoch: 1693645718534,
|
Epoch: 1693645718534,
|
||||||
Debug: true,
|
Debug: true,
|
||||||
|
Cache: struct {
|
||||||
|
Type string
|
||||||
|
Ram int
|
||||||
|
}{
|
||||||
|
Ram: 1000 * 1000 * 50,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
s, c, err := server.InitializeRoute(ctx, config)
|
s, c, err := server.InitializeRoute(ctx, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
4
db/cache/fastcache.go
vendored
4
db/cache/fastcache.go
vendored
@ -40,6 +40,10 @@ func (f *FastCache) Del(k []byte) error {
|
|||||||
|
|
||||||
func (f *FastCache) Get(k []byte) ([]byte, error) {
|
func (f *FastCache) Get(k []byte) ([]byte, error) {
|
||||||
b := f.c.GetBig(nil, k)
|
b := f.c.GetBig(nil, k)
|
||||||
|
if b == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
me := ttlCache{}
|
me := ttlCache{}
|
||||||
err := binary.Unmarshal(b, &me)
|
err := binary.Unmarshal(b, &me)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -67,11 +67,18 @@ var (
|
|||||||
OnDelete: schema.SetNull,
|
OnDelete: schema.SetNull,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Indexes: []*schema.Index{
|
||||||
|
{
|
||||||
|
Name: "user_email",
|
||||||
|
Unique: true,
|
||||||
|
Columns: []*schema.Column{UsersColumns[1]},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
// UserProfilesColumns holds the columns for the "user_profiles" table.
|
// UserProfilesColumns holds the columns for the "user_profiles" table.
|
||||||
UserProfilesColumns = []*schema.Column{
|
UserProfilesColumns = []*schema.Column{
|
||||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||||
{Name: "name", Type: field.TypeString},
|
{Name: "name", Type: field.TypeString, Unique: true},
|
||||||
{Name: "uuid", Type: field.TypeString},
|
{Name: "uuid", Type: field.TypeString},
|
||||||
{Name: "user_profile", Type: field.TypeInt, Unique: true},
|
{Name: "user_profile", Type: field.TypeInt, Unique: true},
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,5 @@ package runtime
|
|||||||
// The schema-stitching logic is generated in github.com/xmdhs/authlib-skin/db/ent/runtime.go
|
// The schema-stitching logic is generated in github.com/xmdhs/authlib-skin/db/ent/runtime.go
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "v0.12.3" // Version of ent codegen.
|
Version = "(devel)" // Version of ent codegen.
|
||||||
Sum = "h1:N5lO2EOrHpCH5HYfiMOCHYbo+oh5M8GjT0/cx5x6xkk=" // Sum of ent codegen.
|
|
||||||
)
|
)
|
||||||
|
@ -15,7 +15,7 @@ type UserProfile struct {
|
|||||||
// Fields of the UserProfile.
|
// Fields of the UserProfile.
|
||||||
func (UserProfile) Fields() []ent.Field {
|
func (UserProfile) Fields() []ent.Field {
|
||||||
return []ent.Field{
|
return []ent.Field{
|
||||||
field.String("name"),
|
field.String("name").Unique(),
|
||||||
field.String("uuid"),
|
field.String("uuid"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -9,6 +9,7 @@ require (
|
|||||||
github.com/bwmarrin/snowflake v0.3.0
|
github.com/bwmarrin/snowflake v0.3.0
|
||||||
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/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/julienschmidt/httprouter v1.3.0
|
||||||
@ -24,7 +25,6 @@ require (
|
|||||||
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
|
||||||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/go-cmp v0.5.6 // indirect
|
github.com/google/go-cmp v0.5.6 // indirect
|
||||||
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
|
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
|
||||||
|
12
go.sum
12
go.sum
@ -54,6 +54,8 @@ 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/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 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
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=
|
||||||
@ -66,14 +68,22 @@ 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/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 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
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 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
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 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
|
||||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
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 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
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.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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
@ -107,6 +117,8 @@ 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/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-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.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-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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package yggdrasil
|
package yggdrasil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
|
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,11 +16,22 @@ func (y *Yggdrasil) Authenticate() httprouter.Handle {
|
|||||||
cxt := r.Context()
|
cxt := r.Context()
|
||||||
a, err := utils.DeCodeBody[yggdrasil.Authenticate](r.Body, y.validate)
|
a, err := utils.DeCodeBody[yggdrasil.Authenticate](r.Body, y.validate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
y.logger.InfoContext(cxt, err.Error())
|
y.logger.DebugContext(cxt, err.Error())
|
||||||
handleYgError(cxt, w, yggdrasil.Error{ErrorMessage: err.Error()}, 400)
|
handleYgError(cxt, w, yggdrasil.Error{ErrorMessage: err.Error()}, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
t, err := y.yggdrasilService.Authenticate(cxt, a)
|
||||||
_ = a
|
if err != nil {
|
||||||
|
if errors.Is(err, yggdrasilS.ErrPassWord) || errors.Is(err, yggdrasilS.ErrRate) {
|
||||||
|
y.logger.DebugContext(cxt, err.Error())
|
||||||
|
handleYgError(cxt, w, yggdrasil.Error{ErrorMessage: "Invalid credentials. Invalid username or password.", Error: "ForbiddenOperationException"}, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
y.logger.WarnContext(cxt, err.Error())
|
||||||
|
handleYgError(cxt, w, yggdrasil.Error{ErrorMessage: err.Error()}, 500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b, _ := json.Marshal(t)
|
||||||
|
w.Write(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ type Token struct {
|
|||||||
AvailableProfiles []TokenProfile `json:"availableProfiles"`
|
AvailableProfiles []TokenProfile `json:"availableProfiles"`
|
||||||
ClientToken string `json:"clientToken"`
|
ClientToken string `json:"clientToken"`
|
||||||
SelectedProfile TokenProfile `json:"selectedProfile"`
|
SelectedProfile TokenProfile `json:"selectedProfile"`
|
||||||
User TokenUser `json:"user"`
|
User TokenUser `json:"user,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TokenProfile struct {
|
type TokenProfile struct {
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
)
|
)
|
||||||
|
|
||||||
func warpCtJSON(handle httprouter.Handle) httprouter.Handle {
|
func warpHJSON(handle httprouter.Handle) httprouter.Handle {
|
||||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||||
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(w, r, p)
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
func NewRoute(yggService *yggdrasil.Yggdrasil, handel *handle.Handel) (*httprouter.Router, error) {
|
func NewRoute(yggService *yggdrasil.Yggdrasil, handel *handle.Handel) (*httprouter.Router, error) {
|
||||||
r := httprouter.New()
|
r := httprouter.New()
|
||||||
err := newYggdrasil(r)
|
err := newYggdrasil(r, *yggService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("NewRoute: %w", err)
|
return nil, fmt.Errorf("NewRoute: %w", err)
|
||||||
}
|
}
|
||||||
@ -21,8 +21,8 @@ func NewRoute(yggService *yggdrasil.Yggdrasil, handel *handle.Handel) (*httprout
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newYggdrasil(r *httprouter.Router) error {
|
func newYggdrasil(r *httprouter.Router, handelY yggdrasil.Yggdrasil) error {
|
||||||
r.POST("/api/authserver/authenticate", nil)
|
r.POST("/api/authserver/authenticate", warpHJSON(handelY.Authenticate()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"database/sql"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -11,7 +10,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"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/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
@ -22,46 +23,48 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (w *WebService) Reg(ctx context.Context, u model.User) error {
|
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)
|
|
||||||
}
|
|
||||||
defer tx.Rollback()
|
|
||||||
count, err := tx.User.Query().Where(user.EmailEQ(u.Email)).ForUpdate().Count(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Reg: %w", err)
|
|
||||||
}
|
|
||||||
if count != 0 {
|
|
||||||
return fmt.Errorf("Reg: %w", ErrExistUser)
|
|
||||||
}
|
|
||||||
p, s := utils.Argon2ID(u.Password)
|
|
||||||
|
|
||||||
du, err := w.client.User.Create().
|
|
||||||
SetEmail(u.Email).
|
|
||||||
SetPassword(p).
|
|
||||||
SetSalt(s).
|
|
||||||
SetRegTime(time.Now().Unix()).
|
|
||||||
SetState(0).Save(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Reg: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var userUuid string
|
var userUuid string
|
||||||
if w.config.OfflineUUID {
|
if w.config.OfflineUUID {
|
||||||
userUuid = uuidGen(u.Name)
|
userUuid = uuidGen(u.Name)
|
||||||
} else {
|
} else {
|
||||||
userUuid = strings.ReplaceAll(uuid.New().String(), "-", "")
|
userUuid = strings.ReplaceAll(uuid.New().String(), "-", "")
|
||||||
}
|
}
|
||||||
|
p, s := utils.Argon2ID(u.Password)
|
||||||
|
|
||||||
_, err = w.client.UserProfile.Create().
|
err := utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
||||||
SetUser(du).
|
count, err := tx.User.Query().Where(user.EmailEQ(u.Email)).ForUpdate().Count(ctx)
|
||||||
SetName(u.Name).
|
if err != nil {
|
||||||
SetUUID(userUuid).
|
return err
|
||||||
Save(ctx)
|
}
|
||||||
if err != nil {
|
if count != 0 {
|
||||||
return fmt.Errorf("Reg: %w", err)
|
return ErrExistUser
|
||||||
}
|
}
|
||||||
err = tx.Commit()
|
nameCount, err := tx.UserProfile.Query().Where(userprofile.NameEQ(u.Name)).ForUpdate().Count(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if nameCount != 0 {
|
||||||
|
return ErrExitsName
|
||||||
|
}
|
||||||
|
du, err := tx.User.Create().
|
||||||
|
SetEmail(u.Email).
|
||||||
|
SetPassword(p).
|
||||||
|
SetSalt(s).
|
||||||
|
SetRegTime(time.Now().Unix()).
|
||||||
|
SetState(0).Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = tx.UserProfile.Create().
|
||||||
|
SetUser(du).
|
||||||
|
SetName(u.Name).
|
||||||
|
SetUUID(userUuid).
|
||||||
|
Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Reg: %w", err)
|
return fmt.Errorf("Reg: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -37,13 +38,13 @@ func (y *Yggdrasil) Authenticate(cxt context.Context, auth yggdrasil.Authenticat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
b := make([]byte, 8)
|
b := make([]byte, 8)
|
||||||
binary.BigEndian.PutUint64(b, uint64(time.Now().Add(10*time.Second).Unix()))
|
binary.BigEndian.PutUint64(b, uint64(time.Now().Add(5*time.Second).Unix()))
|
||||||
err = y.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 {
|
if err != nil {
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := y.client.User.Query().Where(user.EmailEQ(auth.Username)).WithProfile().WithToken().First(cxt)
|
u, err := y.client.User.Query().Where(user.EmailEQ(auth.Username)).WithProfile().First(cxt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var nf *ent.NotFoundError
|
var nf *ent.NotFoundError
|
||||||
if errors.As(err, &nf) {
|
if errors.As(err, &nf) {
|
||||||
@ -59,15 +60,59 @@ func (y *Yggdrasil) Authenticate(cxt context.Context, auth yggdrasil.Authenticat
|
|||||||
clientToken = strings.ReplaceAll(uuid.New().String(), "-", "")
|
clientToken = strings.ReplaceAll(uuid.New().String(), "-", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var utoken *ent.UserToken
|
||||||
|
err = utils.WithTx(cxt, y.client, func(tx *ent.Tx) error {
|
||||||
|
utoken, err = tx.User.QueryToken(u).ForUpdate().First(cxt)
|
||||||
|
if err != nil {
|
||||||
|
var nf *ent.NotFoundError
|
||||||
|
if !errors.As(err, &nf) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if utoken == nil {
|
||||||
|
ut, err := tx.UserToken.Create().SetTokenID(1).Save(cxt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = tx.User.UpdateOne(u).SetToken(ut).Exec(cxt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
utoken = ut
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
claims := model.TokenClaims{
|
claims := model.TokenClaims{
|
||||||
Tid: u.Edges.Profile.UUID,
|
Tid: strconv.FormatUint(utoken.TokenID, 10),
|
||||||
RegisteredClaims: jwt.RegisteredClaims{
|
RegisteredClaims: jwt.RegisteredClaims{
|
||||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * 24 * time.Hour)),
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * 24 * time.Hour)),
|
||||||
Issuer: "authlib-skin",
|
Issuer: "authlib-skin",
|
||||||
Subject: u.Edges.Profile.UUID,
|
Subject: u.Edges.Profile.UUID,
|
||||||
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_ = claims
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
jwts, err := token.SignedString([]byte(y.config.JwtKey))
|
||||||
|
if err != nil {
|
||||||
|
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||||
|
}
|
||||||
|
p := yggdrasil.TokenProfile{
|
||||||
|
ID: u.Edges.Profile.UUID,
|
||||||
|
Name: u.Edges.Profile.Name,
|
||||||
|
}
|
||||||
|
|
||||||
return yggdrasil.Token{}, nil
|
return yggdrasil.Token{
|
||||||
|
AccessToken: jwts,
|
||||||
|
AvailableProfiles: []yggdrasil.TokenProfile{p},
|
||||||
|
ClientToken: clientToken,
|
||||||
|
SelectedProfile: p,
|
||||||
|
User: yggdrasil.TokenUser{
|
||||||
|
ID: u.Edges.Profile.UUID,
|
||||||
|
Properties: []any{},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,13 @@ import (
|
|||||||
type Yggdrasil struct {
|
type Yggdrasil struct {
|
||||||
client *ent.Client
|
client *ent.Client
|
||||||
cache cache.Cache
|
cache cache.Cache
|
||||||
c config.Config
|
config config.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewYggdrasil(client *ent.Client, cache cache.Cache, c config.Config) *Yggdrasil {
|
func NewYggdrasil(client *ent.Client, cache cache.Cache, c config.Config) *Yggdrasil {
|
||||||
return &Yggdrasil{
|
return &Yggdrasil{
|
||||||
client: client,
|
client: client,
|
||||||
cache: cache,
|
cache: cache,
|
||||||
c: c,
|
config: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ func Argon2ID(pass string) (password string, salt string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Argon2Compare(pass, hashPass string, salt string) bool {
|
func Argon2Compare(pass, hashPass string, salt string) bool {
|
||||||
s, err := base64.StdEncoding.DecodeString(hashPass)
|
s, err := base64.StdEncoding.DecodeString(salt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
55
utils/tx.go
55
utils/tx.go
@ -1,28 +1,31 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
// func WithTx(ctx context.Context, opts *sql.TxOptions, q mysql.Querier, db *sql.DB, f func(mysql.Querier) error) error {
|
import (
|
||||||
// w, ok := q.(interface {
|
"context"
|
||||||
// WithTx(tx *sql.Tx) *mysql.Queries
|
"fmt"
|
||||||
// })
|
|
||||||
// var tx *sql.Tx
|
"github.com/xmdhs/authlib-skin/db/ent"
|
||||||
// if ok {
|
)
|
||||||
// var err error
|
|
||||||
// tx, err = db.BeginTx(ctx, opts)
|
func WithTx(ctx context.Context, client *ent.Client, fn func(tx *ent.Tx) error) error {
|
||||||
// if err != nil {
|
tx, err := client.Tx(ctx)
|
||||||
// return fmt.Errorf("WithTx: %w", err)
|
if err != nil {
|
||||||
// }
|
return err
|
||||||
// defer tx.Rollback()
|
}
|
||||||
// q = w.WithTx(tx)
|
defer func() {
|
||||||
// }
|
if v := recover(); v != nil {
|
||||||
// err := f(q)
|
tx.Rollback()
|
||||||
// if err != nil {
|
panic(v)
|
||||||
// return fmt.Errorf("WithTx: %w", err)
|
}
|
||||||
// }
|
}()
|
||||||
// if tx != nil {
|
if err := fn(tx); err != nil {
|
||||||
// err := tx.Commit()
|
if rerr := tx.Rollback(); rerr != nil {
|
||||||
// if err != nil {
|
err = fmt.Errorf("%w: rolling back transaction: %v", err, rerr)
|
||||||
// return fmt.Errorf("WithTx: %w", err)
|
}
|
||||||
// }
|
return err
|
||||||
// }
|
}
|
||||||
// return nil
|
if err := tx.Commit(); err != nil {
|
||||||
// }
|
return fmt.Errorf("committing transaction: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user