99 lines
2.0 KiB
Go
99 lines
2.0 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"git.nobla.cn/golang/aeus-admin/models"
|
|
"git.nobla.cn/golang/aeus-admin/pb"
|
|
"git.nobla.cn/golang/aeus-admin/types"
|
|
"git.nobla.cn/golang/aeus/pkg/errors"
|
|
jwt "github.com/golang-jwt/jwt/v5"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type (
|
|
authOptions struct {
|
|
db *gorm.DB
|
|
secret []byte
|
|
method string
|
|
ttl int64
|
|
}
|
|
|
|
AuthOption func(o *authOptions)
|
|
|
|
AuthService struct {
|
|
opts *authOptions
|
|
}
|
|
)
|
|
|
|
func WithAuthDB(db *gorm.DB) AuthOption {
|
|
return func(o *authOptions) {
|
|
o.db = db
|
|
}
|
|
}
|
|
|
|
func WithAuthSecret(secret []byte) AuthOption {
|
|
return func(o *authOptions) {
|
|
o.secret = secret
|
|
}
|
|
}
|
|
|
|
func WithAuthMethod(method string) AuthOption {
|
|
return func(o *authOptions) {
|
|
o.method = method
|
|
}
|
|
}
|
|
|
|
func WithAuthTTL(ttl int64) AuthOption {
|
|
return func(o *authOptions) {
|
|
o.ttl = ttl
|
|
}
|
|
}
|
|
|
|
func (s *AuthService) Login(ctx context.Context, req *pb.LoginRequest) (res *pb.LoginResponse, err error) {
|
|
model := &models.User{}
|
|
tx := s.opts.db.WithContext(ctx)
|
|
if err = req.Validate(); err != nil {
|
|
return nil, errors.Format(errors.Invalid, err.Error())
|
|
}
|
|
if err = model.FindOne(tx, "uid=?", req.Username); err != nil {
|
|
return
|
|
}
|
|
if model.Password != req.Password {
|
|
err = errors.ErrAccessDenied
|
|
return
|
|
}
|
|
claims := types.Claims{
|
|
Uid: model.Uid,
|
|
Role: model.Role,
|
|
IssuedAt: time.Now().Unix(),
|
|
ExpirationAt: time.Now().Add(time.Second * time.Duration(s.opts.ttl)).Unix(),
|
|
}
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
res = &pb.LoginResponse{}
|
|
if res.Token, err = token.SignedString(s.opts.secret); err == nil {
|
|
res.Uid = model.Uid
|
|
res.Username = model.Username
|
|
res.Expires = s.opts.ttl
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *AuthService) Logout(ctx context.Context, req *pb.LogoutRequest) (res *pb.LogoutResponse, err error) {
|
|
|
|
return
|
|
}
|
|
|
|
func NewAuthService(cbs ...AuthOption) *AuthService {
|
|
opts := &authOptions{
|
|
ttl: 7200,
|
|
}
|
|
for _, cb := range cbs {
|
|
cb(opts)
|
|
}
|
|
return &AuthService{
|
|
opts: opts,
|
|
}
|
|
}
|