认证提取为 service
This commit is contained in:
parent
cd66d3823e
commit
9147dc6b1d
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/service"
|
"github.com/xmdhs/authlib-skin/service"
|
||||||
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handel) handleErrorService(ctx context.Context, w http.ResponseWriter, err error) {
|
func (h *Handel) handleErrorService(ctx context.Context, w http.ResponseWriter, err error) {
|
||||||
@ -33,7 +33,7 @@ func (h *Handel) handleErrorService(ctx context.Context, w http.ResponseWriter,
|
|||||||
h.handleError(ctx, w, err.Error(), model.ErrPassWord, 401, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrPassWord, 401, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if errors.Is(err, sutils.ErrUserDisable) {
|
if errors.Is(err, auth.ErrUserDisable) {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrUserDisable, 401, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrUserDisable, 401, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ func (h *Handel) handleErrorService(ctx context.Context, w http.ResponseWriter,
|
|||||||
h.handleError(ctx, w, err.Error(), model.ErrNotAdmin, 401, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrNotAdmin, 401, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if errors.Is(err, sutils.ErrTokenInvalid) {
|
if errors.Is(err, auth.ErrTokenInvalid) {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrAuth, 401, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrAuth, 401, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/xmdhs/authlib-skin/config"
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
utilsS "github.com/xmdhs/authlib-skin/service/utils"
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
@ -111,7 +111,7 @@ func (y *Yggdrasil) Auth(handle http.Handler) http.Handler {
|
|||||||
|
|
||||||
t, err := y.yggdrasilService.Auth(ctx, a)
|
t, err := y.yggdrasilService.Auth(ctx, a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, utilsS.ErrTokenInvalid) {
|
if errors.Is(err, auth.ErrTokenInvalid) {
|
||||||
y.logger.DebugContext(ctx, err.Error())
|
y.logger.DebugContext(ctx, err.Error())
|
||||||
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: "Invalid token.", Error: "ForbiddenOperationException"}, 403)
|
handleYgError(ctx, w, yggdrasil.Error{ErrorMessage: "Invalid token.", Error: "ForbiddenOperationException"}, 403)
|
||||||
return
|
return
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/db/ent/usertoken"
|
"github.com/xmdhs/authlib-skin/db/ent/usertoken"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
@ -20,7 +21,7 @@ import (
|
|||||||
var ErrNotAdmin = errors.New("无权限")
|
var ErrNotAdmin = errors.New("无权限")
|
||||||
|
|
||||||
func (w *WebService) Auth(ctx context.Context, token string) (*model.TokenClaims, error) {
|
func (w *WebService) Auth(ctx context.Context, token string) (*model.TokenClaims, error) {
|
||||||
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, w.client, w.cache, &w.prikey.PublicKey, 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)
|
||||||
}
|
}
|
||||||
@ -32,7 +33,7 @@ func (w *WebService) IsAdmin(ctx context.Context, t *model.TokenClaims) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("IsAdmin: %w", err)
|
return fmt.Errorf("IsAdmin: %w", err)
|
||||||
}
|
}
|
||||||
if !utilsService.IsAdmin(u.State) {
|
if !auth.IsAdmin(u.State) {
|
||||||
return fmt.Errorf("IsAdmin: %w", ErrNotAdmin)
|
return fmt.Errorf("IsAdmin: %w", ErrNotAdmin)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -62,12 +63,12 @@ func (w *WebService) ListUser(ctx context.Context, page int, email, name string)
|
|||||||
UserInfo: model.UserInfo{
|
UserInfo: model.UserInfo{
|
||||||
UID: v.ID,
|
UID: v.ID,
|
||||||
UUID: v.Edges.Profile.UUID,
|
UUID: v.Edges.Profile.UUID,
|
||||||
IsAdmin: utilsService.IsAdmin(v.State),
|
IsAdmin: auth.IsAdmin(v.State),
|
||||||
},
|
},
|
||||||
Email: v.Email,
|
Email: v.Email,
|
||||||
RegIp: v.RegIP,
|
RegIp: v.RegIP,
|
||||||
Name: v.Edges.Profile.Name,
|
Name: v.Edges.Profile.Name,
|
||||||
IsDisable: utilsService.IsDisable(v.State),
|
IsDisable: auth.IsDisable(v.State),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,13 +132,13 @@ func (w *WebService) EditUser(ctx context.Context, u model.EditUser, uid int) er
|
|||||||
|
|
||||||
state := aUser.State
|
state := aUser.State
|
||||||
if u.IsAdmin != nil {
|
if u.IsAdmin != nil {
|
||||||
state = utilsService.SetAdmin(state, *u.IsAdmin)
|
state = auth.SetAdmin(state, *u.IsAdmin)
|
||||||
}
|
}
|
||||||
if u.IsDisable != nil {
|
if u.IsDisable != nil {
|
||||||
if *u.IsDisable {
|
if *u.IsDisable {
|
||||||
changePasswd = true
|
changePasswd = true
|
||||||
}
|
}
|
||||||
state = utilsService.SetDisable(state, *u.IsDisable)
|
state = auth.SetDisable(state, *u.IsDisable)
|
||||||
}
|
}
|
||||||
if state != aUser.State {
|
if state != aUser.State {
|
||||||
upUser = upUser.SetState(state)
|
upUser = upUser.SetState(state)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package utils
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -18,14 +18,35 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AuthService struct {
|
||||||
|
client *ent.Client
|
||||||
|
c cache.Cache
|
||||||
|
pub *rsa.PublicKey
|
||||||
|
pri *rsa.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAuthService(
|
||||||
|
client *ent.Client,
|
||||||
|
c cache.Cache,
|
||||||
|
pub *rsa.PublicKey,
|
||||||
|
pri *rsa.PrivateKey,
|
||||||
|
) *AuthService {
|
||||||
|
return &AuthService{
|
||||||
|
client: client,
|
||||||
|
c: c,
|
||||||
|
pub: pub,
|
||||||
|
pri: pri,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrTokenInvalid = errors.New("token 无效")
|
ErrTokenInvalid = errors.New("token 无效")
|
||||||
ErrUserDisable = errors.New("用户被禁用")
|
ErrUserDisable = errors.New("用户被禁用")
|
||||||
)
|
)
|
||||||
|
|
||||||
func Auth(ctx context.Context, t yggdrasil.ValidateToken, client *ent.Client, c cache.Cache, pubkey *rsa.PublicKey, tmpInvalid bool) (*model.TokenClaims, error) {
|
func (a *AuthService) Auth(ctx context.Context, t yggdrasil.ValidateToken, tmpInvalid bool) (*model.TokenClaims, error) {
|
||||||
token, err := jwt.ParseWithClaims(t.AccessToken, &model.TokenClaims{}, func(t *jwt.Token) (interface{}, error) {
|
token, err := jwt.ParseWithClaims(t.AccessToken, &model.TokenClaims{}, func(t *jwt.Token) (interface{}, error) {
|
||||||
return pubkey, nil
|
return a.pub, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Auth: %w", errors.Join(err, ErrTokenInvalid))
|
return nil, fmt.Errorf("Auth: %w", errors.Join(err, ErrTokenInvalid))
|
||||||
@ -54,7 +75,7 @@ func Auth(ctx context.Context, t yggdrasil.ValidateToken, client *ent.Client, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tokenID, err := func() (uint64, error) {
|
tokenID, err := func() (uint64, error) {
|
||||||
c := cache.CacheHelp[uint64]{Cache: c}
|
c := cache.CacheHelp[uint64]{Cache: a.c}
|
||||||
key := []byte("auth" + strconv.Itoa(claims.UID))
|
key := []byte("auth" + strconv.Itoa(claims.UID))
|
||||||
t, err := c.Get(key)
|
t, err := c.Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -63,7 +84,7 @@ func Auth(ctx context.Context, t yggdrasil.ValidateToken, client *ent.Client, c
|
|||||||
if t != 0 {
|
if t != 0 {
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
ut, err := client.UserToken.Query().Where(usertoken.HasUserWith(user.ID(claims.UID))).First(ctx)
|
ut, err := a.client.UserToken.Query().Where(usertoken.HasUserWith(user.ID(claims.UID))).First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var ne *ent.NotFoundError
|
var ne *ent.NotFoundError
|
||||||
if errors.As(err, &ne) {
|
if errors.As(err, &ne) {
|
||||||
@ -82,12 +103,12 @@ func Auth(ctx context.Context, t yggdrasil.ValidateToken, client *ent.Client, c
|
|||||||
return claims, nil
|
return claims, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateToken(ctx context.Context, u *ent.User, client *ent.Client, cache cache.Cache, jwtKey *rsa.PrivateKey, clientToken string, uuid string) (string, error) {
|
func (a *AuthService) CreateToken(ctx context.Context, u *ent.User, clientToken string, uuid string) (string, error) {
|
||||||
if IsDisable(u.State) {
|
if IsDisable(u.State) {
|
||||||
return "", fmt.Errorf("CreateToken: %w", ErrUserDisable)
|
return "", fmt.Errorf("CreateToken: %w", ErrUserDisable)
|
||||||
}
|
}
|
||||||
var utoken *ent.UserToken
|
var utoken *ent.UserToken
|
||||||
err := utils.WithTx(ctx, client, func(tx *ent.Tx) error {
|
err := utils.WithTx(ctx, a.client, func(tx *ent.Tx) error {
|
||||||
var err error
|
var err error
|
||||||
utoken, err = tx.User.QueryToken(u).ForUpdateA().First(ctx)
|
utoken, err = tx.User.QueryToken(u).ForUpdateA().First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -108,55 +129,13 @@ func CreateToken(ctx context.Context, u *ent.User, client *ent.Client, cache cac
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("CreateToken: %w", err)
|
return "", fmt.Errorf("CreateToken: %w", err)
|
||||||
}
|
}
|
||||||
err = cache.Del([]byte("auth" + strconv.Itoa(u.ID)))
|
err = a.c.Del([]byte("auth" + strconv.Itoa(u.ID)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("CreateToken: %w", err)
|
return "", fmt.Errorf("CreateToken: %w", err)
|
||||||
}
|
}
|
||||||
t, err := NewJwtToken(jwtKey, strconv.FormatUint(utoken.TokenID, 10), clientToken, uuid, u.ID)
|
t, err := NewJwtToken(a.pri, strconv.FormatUint(utoken.TokenID, 10), clientToken, uuid, u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("CreateToken: %w", err)
|
return "", fmt.Errorf("CreateToken: %w", err)
|
||||||
}
|
}
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewJwtToken(jwtKey *rsa.PrivateKey, tokenID, clientToken, UUID string, userID int) (string, error) {
|
|
||||||
claims := model.TokenClaims{
|
|
||||||
Tid: tokenID,
|
|
||||||
CID: clientToken,
|
|
||||||
UID: userID,
|
|
||||||
RegisteredClaims: jwt.RegisteredClaims{
|
|
||||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * 24 * time.Hour)),
|
|
||||||
Issuer: "authlib-skin",
|
|
||||||
Subject: UUID,
|
|
||||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
|
||||||
jwts, err := token.SignedString(jwtKey)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("newJwtToken: %w", err)
|
|
||||||
}
|
|
||||||
return jwts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsAdmin(state int) bool {
|
|
||||||
return state&1 == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsDisable(state int) bool {
|
|
||||||
return state&2 == 2
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetAdmin(state int, is bool) int {
|
|
||||||
if is {
|
|
||||||
return state | 1
|
|
||||||
}
|
|
||||||
return state & (state ^ 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetDisable(state int, is bool) int {
|
|
||||||
if is {
|
|
||||||
return state | 2
|
|
||||||
}
|
|
||||||
return state & (state ^ 2)
|
|
||||||
}
|
|
52
service/auth/utils.go
Normal file
52
service/auth/utils.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rsa"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func IsAdmin(state int) bool {
|
||||||
|
return state&1 == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsDisable(state int) bool {
|
||||||
|
return state&2 == 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetAdmin(state int, is bool) int {
|
||||||
|
if is {
|
||||||
|
return state | 1
|
||||||
|
}
|
||||||
|
return state & (state ^ 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetDisable(state int, is bool) int {
|
||||||
|
if is {
|
||||||
|
return state | 2
|
||||||
|
}
|
||||||
|
return state & (state ^ 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewJwtToken(jwtKey *rsa.PrivateKey, tokenID, clientToken, UUID string, userID int) (string, error) {
|
||||||
|
claims := model.TokenClaims{
|
||||||
|
Tid: tokenID,
|
||||||
|
CID: clientToken,
|
||||||
|
UID: userID,
|
||||||
|
RegisteredClaims: jwt.RegisteredClaims{
|
||||||
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * 24 * time.Hour)),
|
||||||
|
Issuer: "authlib-skin",
|
||||||
|
Subject: UUID,
|
||||||
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
||||||
|
jwts, err := token.SignedString(jwtKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("NewJwtToken: %w", err)
|
||||||
|
}
|
||||||
|
return jwts, nil
|
||||||
|
}
|
85
service/captcha/captcha.go
Normal file
85
service/captcha/captcha.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package captcha
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CaptchaService struct {
|
||||||
|
config config.Config
|
||||||
|
httpClient *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCaptchaService(config config.Config, httpClient *http.Client) *CaptchaService {
|
||||||
|
return &CaptchaService{
|
||||||
|
config: config,
|
||||||
|
httpClient: httpClient,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CaptchaService) VerifyCaptcha(ctx context.Context, token, ip string) error {
|
||||||
|
if c.config.Captcha.Type != "turnstile" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
bw := &bytes.Buffer{}
|
||||||
|
err := json.NewEncoder(bw).Encode(turnstileResponse{
|
||||||
|
Secret: c.config.Captcha.Secret,
|
||||||
|
Response: token,
|
||||||
|
Remoteip: ip,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("verifyTurnstile: %w", err)
|
||||||
|
}
|
||||||
|
reqs, err := http.NewRequestWithContext(ctx, "POST", "https://challenges.cloudflare.com/turnstile/v0/siteverify", bw)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("verifyTurnstile: %w", err)
|
||||||
|
}
|
||||||
|
reqs.Header.Set("Accept", "*/*")
|
||||||
|
reqs.Header.Set("Content-Type", "application/json")
|
||||||
|
rep, err := c.httpClient.Do(reqs)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("verifyTurnstile: %w", err)
|
||||||
|
}
|
||||||
|
defer rep.Body.Close()
|
||||||
|
|
||||||
|
var t turnstileRet
|
||||||
|
err = json.NewDecoder(rep.Body).Decode(&t)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("verifyTurnstile: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !t.Success {
|
||||||
|
return fmt.Errorf("verifyTurnstile: %w", errors.Join(ErrTurnstile{
|
||||||
|
ErrorCodes: t.ErrorCodes,
|
||||||
|
}, ErrCaptcha))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type turnstileResponse struct {
|
||||||
|
Secret string `json:"secret"`
|
||||||
|
Response string `json:"response"`
|
||||||
|
Remoteip string `json:"remoteip"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type turnstileRet struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
ErrorCodes []string `json:"error-codes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrCaptcha = errors.New("验证码错误")
|
||||||
|
|
||||||
|
type ErrTurnstile struct {
|
||||||
|
ErrorCodes []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrTurnstile) Error() string {
|
||||||
|
return strings.Join(e.ErrorCodes, " ")
|
||||||
|
}
|
1
service/service.go
Normal file
1
service/service.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package service
|
@ -13,7 +13,7 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/db/ent/user"
|
"github.com/xmdhs/authlib-skin/db/ent/user"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/userprofile"
|
"github.com/xmdhs/authlib-skin/db/ent/userprofile"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ func (w *WebService) Reg(ctx context.Context, u model.UserReg, ipPrefix, ip stri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if du.ID == 1 {
|
if du.ID == 1 {
|
||||||
err := tx.User.UpdateOne(du).SetState(utilsService.SetAdmin(0, true)).Exec(ctx)
|
err := tx.User.UpdateOne(du).SetState(auth.SetAdmin(0, true)).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ func (w *WebService) Reg(ctx context.Context, u model.UserReg, ipPrefix, ip stri
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return model.LoginRep{}, fmt.Errorf("Reg: %w", err)
|
return model.LoginRep{}, fmt.Errorf("Reg: %w", err)
|
||||||
}
|
}
|
||||||
jwt, err := utilsService.CreateToken(ctx, du, w.client, w.cache, w.prikey, "web", userUuid)
|
jwt, err := w.authService.CreateToken(ctx, du, "web", userUuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ func (w *WebService) Login(ctx context.Context, l model.Login, ip string) (model
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
||||||
}
|
}
|
||||||
jwt, err := utilsService.CreateToken(ctx, u, w.client, w.cache, w.prikey, "web", u.Edges.Profile.UUID)
|
jwt, err := w.authService.CreateToken(ctx, u, "web", u.Edges.Profile.UUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ func (w *WebService) Info(ctx context.Context, t *model.TokenClaims) (model.User
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return model.UserInfo{}, fmt.Errorf("Info: %w", err)
|
return model.UserInfo{}, fmt.Errorf("Info: %w", err)
|
||||||
}
|
}
|
||||||
isAdmin := utilsService.IsAdmin(u.State)
|
isAdmin := auth.IsAdmin(u.State)
|
||||||
return model.UserInfo{
|
return model.UserInfo{
|
||||||
UID: t.UID,
|
UID: t.UID,
|
||||||
UUID: t.Subject,
|
UUID: t.Subject,
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/db/ent"
|
"github.com/xmdhs/authlib-skin/db/ent"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/migrate"
|
"github.com/xmdhs/authlib-skin/db/ent/migrate"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
var webService *WebService
|
var webService *WebService
|
||||||
@ -34,7 +35,8 @@ func initWebService(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))
|
||||||
webService = NewWebService(config.Default(), c, &http.Client{}, cache.NewFastCache(100000), rsa4)
|
cache := cache.NewFastCache(100000)
|
||||||
|
webService = NewWebService(config.Default(), c, &http.Client{}, cache, rsa4, auth.NewAuthService(c, cache, &rsa4.PublicKey, rsa4))
|
||||||
|
|
||||||
return func() {
|
return func() {
|
||||||
c.User.Delete().Exec(ctx)
|
c.User.Delete().Exec(ctx)
|
||||||
|
@ -9,24 +9,28 @@ import (
|
|||||||
"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/cache"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent"
|
"github.com/xmdhs/authlib-skin/db/ent"
|
||||||
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
"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
|
client *ent.Client
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
cache cache.Cache
|
cache cache.Cache
|
||||||
prikey *rsa.PrivateKey
|
prikey *rsa.PrivateKey
|
||||||
|
authService *auth.AuthService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWebService(c config.Config, e *ent.Client, hc *http.Client, cache cache.Cache, prikey *rsa.PrivateKey) *WebService {
|
func NewWebService(c config.Config, e *ent.Client, hc *http.Client,
|
||||||
|
cache cache.Cache, prikey *rsa.PrivateKey, authService *auth.AuthService) *WebService {
|
||||||
return &WebService{
|
return &WebService{
|
||||||
config: c,
|
config: c,
|
||||||
client: e,
|
client: e,
|
||||||
httpClient: hc,
|
httpClient: hc,
|
||||||
cache: cache,
|
cache: cache,
|
||||||
prikey: prikey,
|
prikey: prikey,
|
||||||
|
authService: authService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"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/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type sessionWithIP struct {
|
type sessionWithIP struct {
|
||||||
@ -19,7 +19,7 @@ type sessionWithIP struct {
|
|||||||
|
|
||||||
func (y *Yggdrasil) SessionJoin(ctx context.Context, s yggdrasil.Session, t *model.TokenClaims, ip string) error {
|
func (y *Yggdrasil) SessionJoin(ctx context.Context, s yggdrasil.Session, t *model.TokenClaims, ip string) error {
|
||||||
if s.SelectedProfile != t.Subject {
|
if s.SelectedProfile != t.Subject {
|
||||||
return fmt.Errorf("SessionJoin: %w", sutils.ErrTokenInvalid)
|
return fmt.Errorf("SessionJoin: %w", auth.ErrTokenInvalid)
|
||||||
}
|
}
|
||||||
err := cache.CacheHelp[sessionWithIP]{Cache: y.cache}.Put([]byte("session"+s.ServerID), sessionWithIP{
|
err := cache.CacheHelp[sessionWithIP]{Cache: y.cache}.Put([]byte("session"+s.ServerID), sessionWithIP{
|
||||||
User: *t,
|
User: *t,
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/db/ent/usertoken"
|
"github.com/xmdhs/authlib-skin/db/ent/usertoken"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
"github.com/xmdhs/authlib-skin/utils/sign"
|
"github.com/xmdhs/authlib-skin/utils/sign"
|
||||||
)
|
)
|
||||||
@ -67,7 +66,7 @@ func (y *Yggdrasil) Authenticate(cxt context.Context, auth yggdrasil.Authenticat
|
|||||||
clientToken = strings.ReplaceAll(uuid.New().String(), "-", "")
|
clientToken = strings.ReplaceAll(uuid.New().String(), "-", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
jwts, err := sutils.CreateToken(cxt, u, y.client, y.cache, y.prikey, clientToken, u.Edges.Profile.UUID)
|
jwts, err := y.authService.CreateToken(cxt, u, clientToken, u.Edges.Profile.UUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -17,19 +17,19 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/db/ent"
|
"github.com/xmdhs/authlib-skin/db/ent"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
"github.com/xmdhs/authlib-skin/service/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Yggdrasil struct {
|
type Yggdrasil struct {
|
||||||
client *ent.Client
|
client *ent.Client
|
||||||
cache cache.Cache
|
cache cache.Cache
|
||||||
config config.Config
|
config config.Config
|
||||||
prikey *rsa.PrivateKey
|
prikey *rsa.PrivateKey
|
||||||
|
authService *auth.AuthService
|
||||||
pubStr func() string
|
pubStr func() string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewYggdrasil(client *ent.Client, cache cache.Cache, c config.Config, prikey *rsa.PrivateKey) *Yggdrasil {
|
func NewYggdrasil(client *ent.Client, cache cache.Cache, c config.Config, prikey *rsa.PrivateKey, authService *auth.AuthService) *Yggdrasil {
|
||||||
return &Yggdrasil{
|
return &Yggdrasil{
|
||||||
client: client,
|
client: client,
|
||||||
cache: cache,
|
cache: cache,
|
||||||
@ -39,6 +39,7 @@ func NewYggdrasil(client *ent.Client, cache cache.Cache, c config.Config, prikey
|
|||||||
derBytes := lo.Must(x509.MarshalPKIXPublicKey(&prikey.PublicKey))
|
derBytes := lo.Must(x509.MarshalPKIXPublicKey(&prikey.PublicKey))
|
||||||
return base64.StdEncoding.EncodeToString(derBytes)
|
return base64.StdEncoding.EncodeToString(derBytes)
|
||||||
}),
|
}),
|
||||||
|
authService: authService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,11 +78,11 @@ func putUint(n uint64, c cache.Cache, key []byte, d time.Duration) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newJwtToken(jwtKey *rsa.PrivateKey, tokenID, clientToken, UUID string, userID int) (string, error) {
|
func newJwtToken(jwtKey *rsa.PrivateKey, tokenID, clientToken, UUID string, userID int) (string, error) {
|
||||||
return sutils.NewJwtToken(jwtKey, tokenID, clientToken, UUID, userID)
|
return auth.NewJwtToken(jwtKey, tokenID, clientToken, UUID, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) Auth(ctx context.Context, t yggdrasil.ValidateToken) (*model.TokenClaims, error) {
|
func (y *Yggdrasil) Auth(ctx context.Context, t yggdrasil.ValidateToken) (*model.TokenClaims, error) {
|
||||||
u, err := sutils.Auth(ctx, t, y.client, y.cache, &y.prikey.PublicKey, true)
|
u, err := y.authService.Auth(ctx, t, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("ValidateToken: %w", err)
|
return nil, fmt.Errorf("ValidateToken: %w", err)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user