fix: update repostitory

This commit is contained in:
daniel.w 2024-08-10 09:52:23 +08:00
parent b111cc1210
commit 0d13b0c5f0
31 changed files with 1024 additions and 202 deletions

View File

@ -0,0 +1,45 @@
// Code generated by goctl. DO NOT EDIT.
// Source: permission.proto
package permissionservice
import (
"context"
"ark-permission/gen_result/pb/permission"
"github.com/zeromicro/go-zero/zrpc"
"google.golang.org/grpc"
)
type (
AuthorizationReq = permission.AuthorizationReq
CancelOneTimeTokenReq = permission.CancelOneTimeTokenReq
CancelTokenReq = permission.CancelTokenReq
CreateOneTimeTokenReq = permission.CreateOneTimeTokenReq
CreateOneTimeTokenResp = permission.CreateOneTimeTokenResp
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
DoTokenByUIDReq = permission.DoTokenByUIDReq
OKResp = permission.OKResp
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
RefreshTokenReq = permission.RefreshTokenReq
RefreshTokenResp = permission.RefreshTokenResp
Token = permission.Token
TokenResp = permission.TokenResp
Tokens = permission.Tokens
ValidationTokenReq = permission.ValidationTokenReq
ValidationTokenResp = permission.ValidationTokenResp
PermissionService interface {
}
defaultPermissionService struct {
cli zrpc.Client
}
)
func NewPermissionService(cli zrpc.Client) PermissionService {
return &defaultPermissionService{
cli: cli,
}
}

View File

@ -0,0 +1,51 @@
// Code generated by goctl. DO NOT EDIT.
// Source: permission.proto
package roleservice
import (
"context"
"ark-permission/gen_result/pb/permission"
"github.com/zeromicro/go-zero/zrpc"
"google.golang.org/grpc"
)
type (
AuthorizationReq = permission.AuthorizationReq
CancelOneTimeTokenReq = permission.CancelOneTimeTokenReq
CancelTokenReq = permission.CancelTokenReq
CreateOneTimeTokenReq = permission.CreateOneTimeTokenReq
CreateOneTimeTokenResp = permission.CreateOneTimeTokenResp
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
DoTokenByUIDReq = permission.DoTokenByUIDReq
OKResp = permission.OKResp
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
RefreshTokenReq = permission.RefreshTokenReq
RefreshTokenResp = permission.RefreshTokenResp
Token = permission.Token
TokenResp = permission.TokenResp
Tokens = permission.Tokens
ValidationTokenReq = permission.ValidationTokenReq
ValidationTokenResp = permission.ValidationTokenResp
RoleService interface {
Ping(ctx context.Context, in *OKResp, opts ...grpc.CallOption) (*OKResp, error)
}
defaultRoleService struct {
cli zrpc.Client
}
)
func NewRoleService(cli zrpc.Client) RoleService {
return &defaultRoleService{
cli: cli,
}
}
func (m *defaultRoleService) Ping(ctx context.Context, in *OKResp, opts ...grpc.CallOption) (*OKResp, error) {
client := permission.NewRoleServiceClient(m.cli.Conn())
return client.Ping(ctx, in, opts...)
}

View File

@ -0,0 +1,125 @@
// Code generated by goctl. DO NOT EDIT.
// Source: permission.proto
package tokenservice
import (
"context"
"ark-permission/gen_result/pb/permission"
"github.com/zeromicro/go-zero/zrpc"
"google.golang.org/grpc"
)
type (
AuthorizationReq = permission.AuthorizationReq
CancelOneTimeTokenReq = permission.CancelOneTimeTokenReq
CancelTokenReq = permission.CancelTokenReq
CreateOneTimeTokenReq = permission.CreateOneTimeTokenReq
CreateOneTimeTokenResp = permission.CreateOneTimeTokenResp
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
DoTokenByUIDReq = permission.DoTokenByUIDReq
OKResp = permission.OKResp
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
RefreshTokenReq = permission.RefreshTokenReq
RefreshTokenResp = permission.RefreshTokenResp
Token = permission.Token
TokenResp = permission.TokenResp
Tokens = permission.Tokens
ValidationTokenReq = permission.ValidationTokenReq
ValidationTokenResp = permission.ValidationTokenResp
TokenService interface {
// NewToken 建立一個新的 Token例如AccessToken
NewToken(ctx context.Context, in *AuthorizationReq, opts ...grpc.CallOption) (*TokenResp, error)
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token
RefreshToken(ctx context.Context, in *RefreshTokenReq, opts ...grpc.CallOption) (*RefreshTokenResp, error)
// CancelToken 取消 Token也包含他裡面的 One Time Toke
CancelToken(ctx context.Context, in *CancelTokenReq, opts ...grpc.CallOption) (*OKResp, error)
// CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error)
// CancelTokenByDeviceId 取消 Token
CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error)
// ValidationToken 驗證這個 Token 有沒有效
ValidationToken(ctx context.Context, in *ValidationTokenReq, opts ...grpc.CallOption) (*ValidationTokenResp, error)
// GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error)
// GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
GetUserTokensByUid(ctx context.Context, in *QueryTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error)
// NewOneTimeToken 建立一次性使用例如RefreshToken
NewOneTimeToken(ctx context.Context, in *CreateOneTimeTokenReq, opts ...grpc.CallOption) (*CreateOneTimeTokenResp, error)
// CancelOneTimeToken 取消一次性使用
CancelOneTimeToken(ctx context.Context, in *CancelOneTimeTokenReq, opts ...grpc.CallOption) (*OKResp, error)
}
defaultTokenService struct {
cli zrpc.Client
}
)
func NewTokenService(cli zrpc.Client) TokenService {
return &defaultTokenService{
cli: cli,
}
}
// NewToken 建立一個新的 Token例如AccessToken
func (m *defaultTokenService) NewToken(ctx context.Context, in *AuthorizationReq, opts ...grpc.CallOption) (*TokenResp, error) {
client := permission.NewTokenServiceClient(m.cli.Conn())
return client.NewToken(ctx, in, opts...)
}
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token
func (m *defaultTokenService) RefreshToken(ctx context.Context, in *RefreshTokenReq, opts ...grpc.CallOption) (*RefreshTokenResp, error) {
client := permission.NewTokenServiceClient(m.cli.Conn())
return client.RefreshToken(ctx, in, opts...)
}
// CancelToken 取消 Token也包含他裡面的 One Time Toke
func (m *defaultTokenService) CancelToken(ctx context.Context, in *CancelTokenReq, opts ...grpc.CallOption) (*OKResp, error) {
client := permission.NewTokenServiceClient(m.cli.Conn())
return client.CancelToken(ctx, in, opts...)
}
// CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
func (m *defaultTokenService) CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error) {
client := permission.NewTokenServiceClient(m.cli.Conn())
return client.CancelTokenByUid(ctx, in, opts...)
}
// CancelTokenByDeviceId 取消 Token
func (m *defaultTokenService) CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error) {
client := permission.NewTokenServiceClient(m.cli.Conn())
return client.CancelTokenByDeviceId(ctx, in, opts...)
}
// ValidationToken 驗證這個 Token 有沒有效
func (m *defaultTokenService) ValidationToken(ctx context.Context, in *ValidationTokenReq, opts ...grpc.CallOption) (*ValidationTokenResp, error) {
client := permission.NewTokenServiceClient(m.cli.Conn())
return client.ValidationToken(ctx, in, opts...)
}
// GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
func (m *defaultTokenService) GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error) {
client := permission.NewTokenServiceClient(m.cli.Conn())
return client.GetUserTokensByDeviceId(ctx, in, opts...)
}
// GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
func (m *defaultTokenService) GetUserTokensByUid(ctx context.Context, in *QueryTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error) {
client := permission.NewTokenServiceClient(m.cli.Conn())
return client.GetUserTokensByUid(ctx, in, opts...)
}
// NewOneTimeToken 建立一次性使用例如RefreshToken
func (m *defaultTokenService) NewOneTimeToken(ctx context.Context, in *CreateOneTimeTokenReq, opts ...grpc.CallOption) (*CreateOneTimeTokenResp, error) {
client := permission.NewTokenServiceClient(m.cli.Conn())
return client.NewOneTimeToken(ctx, in, opts...)
}
// CancelOneTimeToken 取消一次性使用
func (m *defaultTokenService) CancelOneTimeToken(ctx context.Context, in *CancelOneTimeTokenReq, opts ...grpc.CallOption) (*OKResp, error) {
client := permission.NewTokenServiceClient(m.cli.Conn())
return client.CancelOneTimeToken(ctx, in, opts...)
}

View File

@ -68,7 +68,13 @@ message CancelTokenReq {
// CancelTokenReq Token // CancelTokenReq Token
message DoTokenByUIDReq { message DoTokenByUIDReq {
repeated string uid = 1; repeated string ids = 1;
string uid = 2;
}
// QueryTokenByUIDReq UID Token
message QueryTokenByUIDReq {
string uid = 1;
} }
// ValidationTokenReq Token // ValidationTokenReq Token
@ -112,6 +118,10 @@ message DoTokenByDeviceIDReq {
} }
message Tokens{ message Tokens{
repeated TokenResp token = 1;
}
message CancelOneTimeTokenReq {
repeated string token = 1; repeated string token = 1;
} }
@ -125,23 +135,29 @@ service TokenService {
rpc RefreshToken(RefreshTokenReq) returns(RefreshTokenResp); rpc RefreshToken(RefreshTokenReq) returns(RefreshTokenResp);
// CancelToken Token One Time Toke // CancelToken Token One Time Toke
rpc CancelToken(CancelTokenReq) returns(OKResp); rpc CancelToken(CancelTokenReq) returns(OKResp);
// CancelTokenByUID Token ( Device Token) One Time Toke
rpc CancelTokenByUid(DoTokenByUIDReq) returns(OKResp);
// CancelTokenByDeviceID Token
rpc CancelTokenByDeviceId(DoTokenByDeviceIDReq) returns(OKResp);
// ValidationToken Token // ValidationToken Token
rpc ValidationToken(ValidationTokenReq) returns(ValidationTokenResp); rpc ValidationToken(ValidationTokenReq) returns(ValidationTokenResp);
// GetUserTokensByDeviceIDs DeviceID Tokens // CancelTokens Token UID token id UID Device ID Token ID UID + Device
rpc CancelTokens(DoTokenByUIDReq) returns(OKResp);
// CancelTokenByDeviceId Token Device Device token Device token
rpc CancelTokenByDeviceId(DoTokenByDeviceIDReq) returns(OKResp);
// GetUserTokensByDeviceId DeviceID Tokens
rpc GetUserTokensByDeviceId(DoTokenByDeviceIDReq) returns(Tokens); rpc GetUserTokensByDeviceId(DoTokenByDeviceIDReq) returns(Tokens);
// GetUserTokensByUID UID Tokens
rpc GetUserTokensByUid(DoTokenByUIDReq) returns(Tokens);
// GetUserTokensByUid UID Tokens
rpc GetUserTokensByUid(QueryTokenByUIDReq) returns(Tokens);
// NewOneTimeToken 使RefreshToken // NewOneTimeToken 使RefreshToken
rpc NewOneTimeToken(CreateOneTimeTokenReq) returns(CreateOneTimeTokenResp); rpc NewOneTimeToken(CreateOneTimeTokenReq) returns(CreateOneTimeTokenResp);
// CancelOneTimeToken 使 // CancelOneTimeToken 使
rpc CancelOneTimeToken(CreateOneTimeTokenReq) returns(CreateOneTimeTokenResp); rpc CancelOneTimeToken(CancelOneTimeTokenReq) returns(OKResp);
} }
//service Role_Service {} service RoleService {
// rpc Ping(OKResp) returns(OKResp);
//service Permission_Service {} }
service PermissionService {}

View File

@ -22,6 +22,7 @@ const (
const ( const (
RedisDelErrorCode = iota + 20 RedisDelErrorCode = iota + 20
RedisPipLineErrorCode RedisPipLineErrorCode
RedisErrorCode
) )
// TokenUnexpectedSigningErr 30001 Token 簽名錯誤 // TokenUnexpectedSigningErr 30001 Token 簽名錯誤
@ -53,5 +54,12 @@ func RedisDelError(msg string) *ers.Err {
func RedisPipLineError(msg string) *ers.Err { func RedisPipLineError(msg string) *ers.Err {
// 看需要建立哪些 Metrics // 看需要建立哪些 Metrics
mts.AppErrorMetrics.AddFailure("redis", "pip_line_error") mts.AppErrorMetrics.AddFailure("redis", "pip_line_error")
return ers.NewErr(code.CloudEPPermission, code.CatInput, TokenClaimErrorCode, msg) return ers.NewErr(code.CloudEPPermission, code.CatInput, RedisPipLineErrorCode, msg)
}
// RedisError 30022 Redis 錯誤
func RedisError(msg string) *ers.Err {
// 看需要建立哪些 Metrics
mts.AppErrorMetrics.AddFailure("redis", "error")
return ers.NewErr(code.CloudEPPermission, code.CatInput, RedisErrorCode, msg)
} }

View File

@ -3,10 +3,30 @@ package repository
import ( import (
"ark-permission/internal/entity" "ark-permission/internal/entity"
"context" "context"
"time"
) )
type TokenRepository interface { type TokenRepository interface {
Create(ctx context.Context, token entity.Token) error Create(ctx context.Context, token entity.Token) error
GetByAccess(ctx context.Context, id string) (entity.Token, error) DeleteOneTimeToken(ctx context.Context, ids []string, tokens []entity.Token) error
CreateOneTimeToken(ctx context.Context, key string, ticket entity.Ticket, dt time.Duration) error
GetByRefresh(ctx context.Context, refreshToken string) (entity.Token, error)
GetAccessTokenByID(ctx context.Context, id string) (entity.Token, error)
GetAccessTokensByUID(ctx context.Context, uid string) ([]entity.Token, error)
GetAccessTokenCountByUID(uid string) (int, error)
GetAccessTokensByDeviceID(ctx context.Context, deviceID string) ([]entity.Token, error)
GetAccessTokenCountByDeviceID(deviceID string) (int, error)
Delete(ctx context.Context, token entity.Token) error Delete(ctx context.Context, token entity.Token) error
DeleteAccessTokenByID(ctx context.Context, id string) error
DeleteAccessTokensByUID(ctx context.Context, uid string) error
DeleteAccessTokensByDeviceID(ctx context.Context, deviceID string) error
DeleteAccessTokenByDeviceIDAndUID(ctx context.Context, deviceID, uid string) error
DeleteUIDToken(ctx context.Context, uid string, ids []string) error
}
type DeviceToken struct {
DeviceID string
TokenID string
} }

View File

@ -33,6 +33,6 @@ func (t *Token) IsExpires() bool {
type UIDToken map[string]int64 type UIDToken map[string]int64
type Ticket struct { type Ticket struct {
Data interface{} `json:"data"` Data any `json:"data"`
Token Token `json:"token"` Token Token `json:"token"`
} }

View File

@ -1,31 +0,0 @@
package logic
import (
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type GetUserTokensByUidLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewGetUserTokensByUidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserTokensByUidLogic {
return &GetUserTokensByUidLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// GetUserTokensByUID 取得目前所對應的 UID 所存在的 Tokens
func (l *GetUserTokensByUidLogic) GetUserTokensByUid(in *permission.DoTokenByUIDReq) (*permission.Tokens, error) {
// todo: add your logic here and delete this line
return &permission.Tokens{}, nil
}

View File

@ -1,31 +0,0 @@
package logic
import (
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type NewOneTimeTokenLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewNewOneTimeTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NewOneTimeTokenLogic {
return &NewOneTimeTokenLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// NewOneTimeToken 建立一次性使用例如RefreshToken
func (l *NewOneTimeTokenLogic) NewOneTimeToken(in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) {
// todo: add your logic here and delete this line
return &permission.CreateOneTimeTokenResp{}, nil
}

View File

@ -1,30 +0,0 @@
package logic
import (
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"context"
"github.com/zeromicro/go-zero/core/logx"
)
type RefreshTokenLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewRefreshTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RefreshTokenLogic {
return &RefreshTokenLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token
func (l *RefreshTokenLogic) RefreshToken(in *permission.RefreshTokenReq) (*permission.RefreshTokenResp, error) {
// todo: add your logic here and delete this line
return &permission.RefreshTokenResp{}, nil
}

View File

@ -0,0 +1,30 @@
package roleservicelogic
import (
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type PingLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewPingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PingLogic {
return &PingLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *PingLogic) Ping(in *permission.OKResp) (*permission.OKResp, error) {
// todo: add your logic here and delete this line
return &permission.OKResp{}, nil
}

View File

@ -1,6 +1,7 @@
package logic package tokenservicelogic
import ( import (
ers "code.30cm.net/wanderland/library-go/errors"
"context" "context"
"ark-permission/gen_result/pb/permission" "ark-permission/gen_result/pb/permission"
@ -23,9 +24,23 @@ func NewCancelOneTimeTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext)
} }
} }
// CancelOneTimeToken 取消一次性使用 type cancelOneTimeTokenReq struct {
func (l *CancelOneTimeTokenLogic) CancelOneTimeToken(in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) { Token []string `json:"token" validate:"required"`
// todo: add your logic here and delete this line }
return &permission.CreateOneTimeTokenResp{}, nil // CancelOneTimeToken 取消一次性使用
func (l *CancelOneTimeTokenLogic) CancelOneTimeToken(in *permission.CancelOneTimeTokenReq) (*permission.OKResp, error) {
// 驗證所需
if err := l.svcCtx.Validate.ValidateAll(&cancelOneTimeTokenReq{
Token: in.GetToken(),
}); err != nil {
return nil, ers.InvalidFormat(err.Error())
}
err := l.svcCtx.TokenRedisRepo.DeleteOneTimeToken(l.ctx, in.GetToken(), nil)
if err != nil {
return nil, err
}
return &permission.OKResp{}, nil
} }

View File

@ -1,4 +1,4 @@
package logic package tokenservicelogic
import ( import (
"context" "context"
@ -23,7 +23,7 @@ func NewCancelTokenByDeviceIdLogic(ctx context.Context, svcCtx *svc.ServiceConte
} }
} }
// CancelTokenByDeviceID 取消 Token // CancelTokenByDeviceId 取消 Token
func (l *CancelTokenByDeviceIdLogic) CancelTokenByDeviceId(in *permission.DoTokenByDeviceIDReq) (*permission.OKResp, error) { func (l *CancelTokenByDeviceIdLogic) CancelTokenByDeviceId(in *permission.DoTokenByDeviceIDReq) (*permission.OKResp, error) {
// todo: add your logic here and delete this line // todo: add your logic here and delete this line

View File

@ -1,6 +1,7 @@
package logic package tokenservicelogic
import ( import (
ers "code.30cm.net/wanderland/library-go/errors"
"context" "context"
"ark-permission/gen_result/pb/permission" "ark-permission/gen_result/pb/permission"
@ -23,9 +24,25 @@ func NewCancelTokenByUidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
} }
} }
// CancelTokenByUID 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke type deleteByTokenIDs struct {
UID string `json:"uid" binding:"required"`
IDs []string `json:"ids" binding:"required"`
}
// CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
func (l *CancelTokenByUidLogic) CancelTokenByUid(in *permission.DoTokenByUIDReq) (*permission.OKResp, error) { func (l *CancelTokenByUidLogic) CancelTokenByUid(in *permission.DoTokenByUIDReq) (*permission.OKResp, error) {
// todo: add your logic here and delete this line // 驗證所需
if err := l.svcCtx.Validate.ValidateAll(&deleteByTokenIDs{
UID: in.GetUid(),
IDs: in.GetIds(),
}); err != nil {
return nil, ers.InvalidFormat(err.Error())
}
err := l.svcCtx.TokenRedisRepo.DeleteUIDToken(l.ctx, in.GetUid(), in.GetIds())
if err != nil {
return nil, err
}
return &permission.OKResp{}, nil return &permission.OKResp{}, nil
} }

View File

@ -1,10 +1,12 @@
package logic package tokenservicelogic
import ( import (
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
ers "code.30cm.net/wanderland/library-go/errors" ers "code.30cm.net/wanderland/library-go/errors"
"context" "context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )

View File

@ -1,11 +1,9 @@
package logic package tokenservicelogic
import ( import (
"context"
"ark-permission/gen_result/pb/permission" "ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc" "ark-permission/internal/svc"
"context"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )
@ -23,9 +21,23 @@ func NewGetUserTokensByDeviceIdLogic(ctx context.Context, svcCtx *svc.ServiceCon
} }
} }
// GetUserTokensByDeviceIDs 取得目前所對應的 DeviceID 所存在的 Tokens // GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
func (l *GetUserTokensByDeviceIdLogic) GetUserTokensByDeviceId(in *permission.DoTokenByDeviceIDReq) (*permission.Tokens, error) { func (l *GetUserTokensByDeviceIdLogic) GetUserTokensByDeviceId(in *permission.DoTokenByDeviceIDReq) (*permission.Tokens, error) {
// todo: add your logic here and delete this line
// ids, err := l.svcCtx.TokenRedisRepo.GetAccessTokensByDeviceID(l.ctx, "")
// if err != nil {
// return nil, error
// }
// tokenIDs := make([]usecase.DeviceToken, 0, len(ids))
// for _, v := range ids {
// tokenIDs = append(tokenIDs, usecase.DeviceToken{
// DeviceID: v.DeviceID,
// TokenID: v.TokenID,
// })
// }
//
// return tokenIDs, nil
return &permission.Tokens{}, nil return &permission.Tokens{}, nil
} }

View File

@ -0,0 +1,57 @@
package tokenservicelogic
import (
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/domain"
"ark-permission/internal/svc"
ers "code.30cm.net/wanderland/library-go/errors"
"context"
"github.com/zeromicro/go-zero/core/logx"
)
type GetUserTokensByUidLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewGetUserTokensByUidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserTokensByUidLogic {
return &GetUserTokensByUidLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
type getUserTokensByUidReq struct {
UID string `json:"uid" validate:"required"`
}
// GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
func (l *GetUserTokensByUidLogic) GetUserTokensByUid(in *permission.QueryTokenByUIDReq) (*permission.Tokens, error) {
if err := l.svcCtx.Validate.ValidateAll(&getUserTokensByUidReq{
UID: in.GetUid(),
}); err != nil {
return nil, ers.InvalidFormat(err.Error())
}
uidTokens, err := l.svcCtx.TokenRedisRepo.GetAccessTokensByUID(l.ctx, in.GetUid())
if err != nil {
return nil, err
}
tokens := make([]*permission.TokenResp, 0, len(uidTokens))
for _, v := range uidTokens {
tokens = append(tokens, &permission.TokenResp{
AccessToken: v.AccessToken,
TokenType: domain.TokenTypeBearer,
ExpiresIn: int32(v.ExpiresIn),
RefreshToken: v.RefreshToken,
})
}
return &permission.Tokens{
Token: tokens,
}, nil
}

View File

@ -0,0 +1,69 @@
package tokenservicelogic
import (
"ark-permission/internal/domain"
"ark-permission/internal/entity"
ers "code.30cm.net/wanderland/library-go/errors"
"context"
"time"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type NewOneTimeTokenLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewNewOneTimeTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NewOneTimeTokenLogic {
return &NewOneTimeTokenLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// NewOneTimeToken 建立一次性使用例如RefreshToken
func (l *NewOneTimeTokenLogic) NewOneTimeToken(in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) {
// 驗證所需
if err := l.svcCtx.Validate.ValidateAll(&refreshTokenReq{
Token: in.GetToken(),
}); err != nil {
return nil, ers.InvalidFormat(err.Error())
}
// 驗證Token
claims, err := parseClaims(l.ctx, in.GetToken(), l.svcCtx.Config.Token.Secret)
if err != nil {
logx.WithCallerSkip(1).WithFields(
logx.Field("func", "parseClaims"),
).Error(err.Error())
return nil, err
}
token, err := l.svcCtx.TokenRedisRepo.GetByAccess(l.ctx, claims.ID())
if err != nil {
logx.WithCallerSkip(1).WithFields(
logx.Field("func", "TokenRedisRepo.GetByAccess"),
logx.Field("claims", claims),
).Error(err.Error())
return nil, err
}
oneTimeToken := generateRefreshToken(in.GetToken())
key := domain.TicketKeyPrefix + oneTimeToken
if err = l.svcCtx.TokenRedisRepo.CreateOneTimeToken(l.ctx, key, entity.Ticket{
Data: claims,
Token: token,
}, time.Minute); err != nil {
return &permission.CreateOneTimeTokenResp{}, err
}
return &permission.CreateOneTimeTokenResp{
OneTimeToken: oneTimeToken,
}, nil
}

View File

@ -1,15 +1,16 @@
package logic package tokenservicelogic
import ( import (
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/domain" "ark-permission/internal/domain"
"ark-permission/internal/entity" "ark-permission/internal/entity"
"ark-permission/internal/svc"
ers "code.30cm.net/wanderland/library-go/errors" ers "code.30cm.net/wanderland/library-go/errors"
"context" "context"
"github.com/google/uuid" "github.com/google/uuid"
"time" "time"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )
@ -37,9 +38,6 @@ type authorizationReq struct {
IsRefreshToken bool `json:"is_refresh_token"` IsRefreshToken bool `json:"is_refresh_token"`
} }
var generateAccessTokenFunc = generateAccessToken
var generateRefreshTokenFunc = generateRefreshToken
// NewToken 建立一個新的 Token例如AccessToken // NewToken 建立一個新的 Token例如AccessToken
func (l *NewTokenLogic) NewToken(in *permission.AuthorizationReq) (*permission.TokenResp, error) { func (l *NewTokenLogic) NewToken(in *permission.AuthorizationReq) (*permission.TokenResp, error) {
// 驗證所需 // 驗證所需
@ -55,13 +53,23 @@ func (l *NewTokenLogic) NewToken(in *permission.AuthorizationReq) (*permission.T
expires := int(in.GetExpires()) expires := int(in.GetExpires())
refreshExpires := int(in.GetExpires()) refreshExpires := int(in.GetExpires())
if expires <= 0 { if expires <= 0 {
expires = int(l.svcCtx.Config.Token.Expired.Seconds()) // 將時間加上 300 秒
sec := time.Duration(l.svcCtx.Config.Token.Expired.Seconds()) * time.Second
newTime := now.Add(sec)
// 獲取 Unix 時間戳
timestamp := newTime.Unix()
expires = int(timestamp)
refreshExpires = expires refreshExpires = expires
} }
// 如果這是一個 Refresh Token 過期時間要比普通的Token 長 // 如果這是一個 Refresh Token 過期時間要比普通的Token 長
if in.GetIsRefreshToken() { if in.GetIsRefreshToken() {
refreshExpires = int(l.svcCtx.Config.Token.RefreshExpires.Seconds()) // 將時間加上 300 秒
sec := time.Duration(l.svcCtx.Config.Token.RefreshExpires.Seconds()) * time.Second
newTime := now.Add(sec)
// 獲取 Unix 時間戳
timestamp := newTime.Unix()
refreshExpires = int(timestamp)
} }
token := entity.Token{ token := entity.Token{

View File

@ -1,4 +1,4 @@
package logic package tokenservicelogic
import ( import (
"ark-permission/internal/entity" "ark-permission/internal/entity"

View File

@ -0,0 +1,133 @@
package tokenservicelogic
import (
"ark-permission/internal/domain"
"ark-permission/internal/entity"
ers "code.30cm.net/wanderland/library-go/errors"
"context"
"time"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type RefreshTokenLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewRefreshTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RefreshTokenLogic {
return &RefreshTokenLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
type refreshReq struct {
RefreshToken string `json:"grant_type" validate:"required"`
DeviceID string `json:"device_id" validate:"required"`
Scope string `json:"scope" validate:"required"`
Expires int64 `json:"expires" validate:"required"`
}
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token
func (l *RefreshTokenLogic) RefreshToken(in *permission.RefreshTokenReq) (*permission.RefreshTokenResp, error) {
// 驗證所需
if err := l.svcCtx.Validate.ValidateAll(&refreshReq{
RefreshToken: in.GetToken(),
Scope: in.GetScope(),
DeviceID: in.GetDeviceId(),
Expires: in.GetExpires(),
}); err != nil {
return nil, ers.InvalidFormat(err.Error())
}
// step 1 拿看看有沒有這個 refresh token
token, err := l.svcCtx.TokenRedisRepo.GetByRefresh(l.ctx, in.Token)
if err != nil {
logx.WithCallerSkip(1).WithFields(
logx.Field("func", "TokenRedisRepo.GetByRefresh"),
logx.Field("req", in),
).Error(err.Error())
return nil, err
}
// 拿到之後替換掉時間以及 refresh token
// refreshToken 建立
now := time.Now().UTC()
sec := time.Duration(l.svcCtx.Config.Token.RefreshExpires.Seconds()) * time.Second
newTime := now.Add(sec)
// 獲取 Unix 時間戳
timestamp := newTime.Unix()
refreshExpires := int(timestamp)
expires := int(in.GetExpires())
if expires <= 0 {
// 將時間加上 300 秒
sec := time.Duration(l.svcCtx.Config.Token.Expired.Seconds()) * time.Second
newTime := now.Add(sec)
// 獲取 Unix 時間戳
timestamp := newTime.Unix()
expires = int(timestamp)
}
newToken := entity.Token{
ID: token.ID,
UID: token.UID,
DeviceID: in.GetDeviceId(),
ExpiresIn: expires,
RefreshExpiresIn: refreshExpires,
AccessCreateAt: now,
RefreshCreateAt: now,
}
claims := claims(map[string]string{
"uid": token.UID,
})
claims.SetRole(domain.DefaultRole)
claims.SetID(token.ID)
claims.SetScope(in.GetScope())
claims.UID()
if in.GetDeviceId() != "" {
claims.SetDeviceID(in.GetDeviceId())
}
newToken.AccessToken, err = generateAccessTokenFunc(newToken, claims, l.svcCtx.Config.Token.Secret)
if err != nil {
logx.WithCallerSkip(1).WithFields(
logx.Field("func", "generateAccessTokenFunc"),
logx.Field("claims", claims),
).Error(err.Error())
return nil, err
}
newToken.RefreshToken = generateRefreshTokenFunc(newToken.AccessToken)
// 刪除掉舊的 token
err = l.svcCtx.TokenRedisRepo.Delete(l.ctx, token)
if err != nil {
logx.WithCallerSkip(1).WithFields(
logx.Field("func", "TokenRedisRepo.Delete"),
logx.Field("req", token),
).Error(err.Error())
return nil, err
}
err = l.svcCtx.TokenRedisRepo.Create(l.ctx, newToken)
if err != nil {
logx.WithCallerSkip(1).WithFields(
logx.Field("func", "TokenRedisRepo.Create"),
logx.Field("token", token),
).Error(err.Error())
return nil, err
}
return &permission.RefreshTokenResp{
Token: newToken.AccessToken,
OneTimeToken: newToken.RefreshToken,
ExpiresIn: int64(expires),
TokenType: domain.TokenTypeBearer,
}, nil
}

View File

@ -1,4 +1,4 @@
package logic package tokenservicelogic
type claims map[string]string type claims map[string]string

View File

@ -1,4 +1,4 @@
package logic package tokenservicelogic
import ( import (
"ark-permission/internal/domain" "ark-permission/internal/domain"
@ -12,6 +12,9 @@ import (
"time" "time"
) )
var generateAccessTokenFunc = generateAccessToken
var generateRefreshTokenFunc = generateRefreshToken
func generateAccessToken(token entity.Token, data any, sign string) (string, error) { func generateAccessToken(token entity.Token, data any, sign string) (string, error) {
claim := entity.Claims{ claim := entity.Claims{
Data: data, Data: data,
@ -40,7 +43,7 @@ func generateRefreshToken(accessToken string) string {
} }
func parseClaims(ctx context.Context, accessToken string, secret string) (claims, error) { func parseClaims(ctx context.Context, accessToken string, secret string) (claims, error) {
claimMap, err := parseToken(ctx, accessToken, secret) claimMap, err := parseToken(accessToken, secret)
if err != nil { if err != nil {
return claims{}, err return claims{}, err
} }
@ -54,7 +57,7 @@ func parseClaims(ctx context.Context, accessToken string, secret string) (claims
return nil, domain.TokenClaimError("get data from claim map error") return nil, domain.TokenClaimError("get data from claim map error")
} }
func parseToken(ctx context.Context, accessToken string, secret string) (jwt.MapClaims, error) { func parseToken(accessToken string, secret string) (jwt.MapClaims, error) {
token, err := jwt.Parse(accessToken, func(token *jwt.Token) (any, error) { token, err := jwt.Parse(accessToken, func(token *jwt.Token) (any, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, domain.TokenUnexpectedSigningErr(fmt.Sprintf("token unexpected signing method: %v", token.Header["alg"])) return nil, domain.TokenUnexpectedSigningErr(fmt.Sprintf("token unexpected signing method: %v", token.Header["alg"]))

View File

@ -0,0 +1,71 @@
package tokenservicelogic
import (
ers "code.30cm.net/wanderland/library-go/errors"
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type ValidationTokenLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewValidationTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ValidationTokenLogic {
return &ValidationTokenLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
type refreshTokenReq struct {
Token string `json:"token" validate:"required"`
}
// ValidationToken 驗證這個 Token 有沒有效
func (l *ValidationTokenLogic) ValidationToken(in *permission.ValidationTokenReq) (*permission.ValidationTokenResp, error) {
// 驗證所需
if err := l.svcCtx.Validate.ValidateAll(&refreshTokenReq{
Token: in.GetToken(),
}); err != nil {
return nil, ers.InvalidFormat(err.Error())
}
claims, err := parseClaims(l.ctx, in.GetToken(), l.svcCtx.Config.Token.Secret)
if err != nil {
logx.WithCallerSkip(1).WithFields(
logx.Field("func", "parseClaims"),
).Error(err.Error())
return nil, err
}
token, err := l.svcCtx.TokenRedisRepo.GetByAccess(l.ctx, claims.ID())
if err != nil {
logx.WithCallerSkip(1).WithFields(
logx.Field("func", "TokenRedisRepo.GetByAccess"),
logx.Field("claims", claims),
).Error(err.Error())
return nil, err
}
return &permission.ValidationTokenResp{
Token: &permission.Token{
Id: token.ID,
Uid: token.UID,
DeviceId: token.DeviceID,
AccessCreateAt: token.AccessCreateAt.Unix(),
AccessToken: token.AccessToken,
ExpiresIn: int32(token.ExpiresIn),
RefreshToken: token.RefreshToken,
RefreshExpiresIn: int32(token.RefreshExpiresIn),
RefreshCreateAt: token.RefreshCreateAt.Unix(),
},
Data: claims,
}, nil
}

View File

@ -1,31 +0,0 @@
package logic
import (
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type ValidationTokenLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewValidationTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ValidationTokenLogic {
return &ValidationTokenLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// ValidationToken 驗證這個 Token 有沒有效
func (l *ValidationTokenLogic) ValidationToken(in *permission.ValidationTokenReq) (*permission.ValidationTokenResp, error) {
// todo: add your logic here and delete this line
return &permission.ValidationTokenResp{}, nil
}

View File

@ -22,6 +22,41 @@ type tokenRepository struct {
store *redis.Redis store *redis.Redis
} }
func (t *tokenRepository) GetAccessTokenCountByUID(uid string) (int, error) {
// TODO implement me
panic("implement me")
}
func (t *tokenRepository) GetAccessTokensByDeviceID(ctx context.Context, deviceID string) ([]entity.Token, error) {
// TODO implement me
panic("implement me")
}
func (t *tokenRepository) GetAccessTokenCountByDeviceID(deviceID string) (int, error) {
// TODO implement me
panic("implement me")
}
func (t *tokenRepository) DeleteAccessTokenByID(ctx context.Context, id string) error {
// TODO implement me
panic("implement me")
}
func (t *tokenRepository) DeleteAccessTokensByUID(ctx context.Context, uid string) error {
// TODO implement me
panic("implement me")
}
func (t *tokenRepository) DeleteAccessTokensByDeviceID(ctx context.Context, deviceID string) error {
// TODO implement me
panic("implement me")
}
func (t *tokenRepository) DeleteAccessTokenByDeviceIDAndUID(ctx context.Context, deviceID, uid string) error {
// TODO implement me
panic("implement me")
}
func NewTokenRepository(param TokenRepositoryParam) repository.TokenRepository { func NewTokenRepository(param TokenRepositoryParam) repository.TokenRepository {
return &tokenRepository{ return &tokenRepository{
store: param.Store, store: param.Store,
@ -62,10 +97,185 @@ func (t *tokenRepository) Create(ctx context.Context, token entity.Token) error
return nil return nil
} }
func (t *tokenRepository) GetByAccess(_ context.Context, id string) (entity.Token, error) { // // GetAccessTokensByDeviceID 透過 Device ID 得到目前未過期的token
// func (t *tokenRepository) GetAccessTokensByDeviceID(ctx context.Context, uid string) ([]repository.DeviceToken, error) {
// data, err := t.store.Hgetall(domain.DeviceTokenRedisKey.With(uid).ToString())
// if err != nil {
// if errors.Is(err, redis.Nil) {
// return nil, nil
// }
//
// return nil, domain.RedisError(fmt.Sprintf("tokenRepository.GetAccessTokensByDeviceID store.HGetAll Device Token error: %v", err.Error()))
// }
//
// ids := make([]repository.DeviceToken, 0, len(data))
// for deviceID, id := range data {
// ids = append(ids, repository.DeviceToken{
// DeviceID: deviceID,
//
// // e0a4f824-41db-4eb2-8e5a-d96966ea1d56-1698083859
// // -11是因為id組成最後11位數是-跟時間戳記
// TokenID: id[:len(id)-11],
// })
// }
// return ids, nil
// }
// GetAccessTokensByUID 透過 uid 得到目前未過期的 token
func (t *tokenRepository) GetAccessTokensByUID(ctx context.Context, uid string) ([]entity.Token, error) {
utKeys, err := t.store.Get(domain.GetUIDTokenRedisKey(uid))
if err != nil {
// 沒有就視為回空
if errors.Is(err, redis.Nil) {
return nil, nil
}
return nil, domain.RedisError(fmt.Sprintf("tokenRepository.GetAccessTokensByUID store.Get GetUIDTokenRedisKey error: %v", err.Error()))
}
uidTokens := make(entity.UIDToken)
err = json.Unmarshal([]byte(utKeys), &uidTokens)
if err != nil {
return nil, ers.ArkInternal(fmt.Sprintf("tokenRepository.GetAccessTokensByUID json.Unmarshal GetUIDTokenRedisKey error: %v", err))
}
now := time.Now().Unix()
var tokens []entity.Token
var deleteToken []string
for id, token := range uidTokens {
if token < now {
deleteToken = append(deleteToken, id)
continue
}
tk, err := t.store.Get(domain.GetAccessTokenRedisKey(id))
if err == nil {
item := entity.Token{}
err = json.Unmarshal([]byte(tk), &item)
if err != nil {
return nil, ers.ArkInternal(fmt.Sprintf("tokenRepository.GetAccessTokensByUID json.Unmarshal GetUIDTokenRedisKey error: %v", err))
}
tokens = append(tokens, item)
}
if errors.Is(err, redis.Nil) {
deleteToken = append(deleteToken, id)
}
}
if len(deleteToken) > 0 {
// 如果失敗也沒關係其他get method撈取時會在判斷是否過期或存在
_ = t.DeleteUIDToken(ctx, uid, deleteToken)
}
return tokens, nil
}
func (t *tokenRepository) DeleteUIDToken(ctx context.Context, uid string, ids []string) error {
uidTokens := make(entity.UIDToken)
tokenKeys, err := t.store.Get(domain.GetUIDTokenRedisKey(uid))
if err != nil {
if !errors.Is(err, redis.Nil) {
return fmt.Errorf("tx.get GetDeviceTokenRedisKey error: %w", err)
}
}
if tokenKeys != "" {
err = json.Unmarshal([]byte(tokenKeys), &uidTokens)
if err != nil {
return fmt.Errorf("json.Unmarshal GetDeviceTokenRedisKey error: %w", err)
}
}
now := time.Now().Unix()
for k, t := range uidTokens {
// 到期就刪除
if t < now {
delete(uidTokens, k)
}
}
for _, id := range ids {
delete(uidTokens, id)
}
b, err := json.Marshal(uidTokens)
if err != nil {
return fmt.Errorf("json.Marshal UIDToken error: %w", err)
}
_, err = t.store.SetnxEx(domain.GetUIDTokenRedisKey(uid), string(b), 86400*30)
if err != nil {
return fmt.Errorf("tx.set GetUIDTokenRedisKey error: %w", err)
}
return nil
}
func (t *tokenRepository) GetAccessTokenByID(_ context.Context, id string) (entity.Token, error) {
return t.get(domain.GetAccessTokenRedisKey(id)) return t.get(domain.GetAccessTokenRedisKey(id))
} }
func (t *tokenRepository) GetByRefresh(ctx context.Context, refreshToken string) (entity.Token, error) {
id, err := t.store.Get(domain.RefreshTokenRedisKey.With(refreshToken).ToString())
if err != nil {
return entity.Token{}, err
}
if errors.Is(err, redis.Nil) || id == "" {
return entity.Token{}, ers.ResourceNotFound("token key not found in redis", domain.RefreshTokenRedisKey.With(refreshToken).ToString())
}
if err != nil {
return entity.Token{}, ers.ArkInternal(fmt.Sprintf("store.GetByRefresh refresh token error: %v", err))
}
return t.GetAccessTokenByID(ctx, id)
}
func (t *tokenRepository) DeleteOneTimeToken(ctx context.Context, ids []string, tokens []entity.Token) error {
err := t.store.Pipelined(func(tx redis.Pipeliner) error {
keys := make([]string, 0, len(ids)+len(tokens))
for _, id := range ids {
keys = append(keys, domain.RefreshTokenRedisKey.With(id).ToString())
}
for _, token := range tokens {
keys = append(keys, domain.RefreshTokenRedisKey.With(token.RefreshToken).ToString())
}
for _, key := range keys {
if err := tx.Del(ctx, key).Err(); err != nil {
return domain.RedisDelError(fmt.Sprintf("store.Del key error: %v", err))
}
}
return nil
})
if err != nil {
return domain.RedisPipLineError(fmt.Sprintf("store.Pipelined error: %v", err))
}
return nil
}
func (t *tokenRepository) CreateOneTimeToken(ctx context.Context, key string, ticket entity.Ticket, expires time.Duration) error {
body, err := json.Marshal(ticket)
if err != nil {
return ers.InvalidFormat("CreateOneTimeToken json.Marshal error:", err.Error())
}
_, err = t.store.SetnxEx(domain.GetTicketRedisKey(key), string(body), int(expires.Seconds()))
if err != nil {
return ers.DBError("CreateOneTimeToken store.set error:", err.Error())
}
return nil
}
func (t *tokenRepository) Delete(ctx context.Context, token entity.Token) error { func (t *tokenRepository) Delete(ctx context.Context, token entity.Token) error {
err := t.store.Pipelined(func(tx redis.Pipeliner) error { err := t.store.Pipelined(func(tx redis.Pipeliner) error {
keys := []string{ keys := []string{

View File

@ -0,0 +1,20 @@
// Code generated by goctl. DO NOT EDIT.
// Source: permission.proto
package server
import (
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
)
type PermissionServiceServer struct {
svcCtx *svc.ServiceContext
permission.UnimplementedPermissionServiceServer
}
func NewPermissionServiceServer(svcCtx *svc.ServiceContext) *PermissionServiceServer {
return &PermissionServiceServer{
svcCtx: svcCtx,
}
}

View File

@ -0,0 +1,28 @@
// Code generated by goctl. DO NOT EDIT.
// Source: permission.proto
package server
import (
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/logic/roleservice"
"ark-permission/internal/svc"
)
type RoleServiceServer struct {
svcCtx *svc.ServiceContext
permission.UnimplementedRoleServiceServer
}
func NewRoleServiceServer(svcCtx *svc.ServiceContext) *RoleServiceServer {
return &RoleServiceServer{
svcCtx: svcCtx,
}
}
func (s *RoleServiceServer) Ping(ctx context.Context, in *permission.OKResp) (*permission.OKResp, error) {
l := roleservicelogic.NewPingLogic(ctx, s.svcCtx)
return l.Ping(in)
}

View File

@ -7,7 +7,7 @@ import (
"context" "context"
"ark-permission/gen_result/pb/permission" "ark-permission/gen_result/pb/permission"
"ark-permission/internal/logic" "ark-permission/internal/logic/tokenservice"
"ark-permission/internal/svc" "ark-permission/internal/svc"
) )
@ -24,60 +24,60 @@ func NewTokenServiceServer(svcCtx *svc.ServiceContext) *TokenServiceServer {
// NewToken 建立一個新的 Token例如AccessToken // NewToken 建立一個新的 Token例如AccessToken
func (s *TokenServiceServer) NewToken(ctx context.Context, in *permission.AuthorizationReq) (*permission.TokenResp, error) { func (s *TokenServiceServer) NewToken(ctx context.Context, in *permission.AuthorizationReq) (*permission.TokenResp, error) {
l := logic.NewNewTokenLogic(ctx, s.svcCtx) l := tokenservicelogic.NewNewTokenLogic(ctx, s.svcCtx)
return l.NewToken(in) return l.NewToken(in)
} }
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token // RefreshToken 更新目前的token 以及裡面包含的一次性 Token
func (s *TokenServiceServer) RefreshToken(ctx context.Context, in *permission.RefreshTokenReq) (*permission.RefreshTokenResp, error) { func (s *TokenServiceServer) RefreshToken(ctx context.Context, in *permission.RefreshTokenReq) (*permission.RefreshTokenResp, error) {
l := logic.NewRefreshTokenLogic(ctx, s.svcCtx) l := tokenservicelogic.NewRefreshTokenLogic(ctx, s.svcCtx)
return l.RefreshToken(in) return l.RefreshToken(in)
} }
// CancelToken 取消 Token也包含他裡面的 One Time Toke // CancelToken 取消 Token也包含他裡面的 One Time Toke
func (s *TokenServiceServer) CancelToken(ctx context.Context, in *permission.CancelTokenReq) (*permission.OKResp, error) { func (s *TokenServiceServer) CancelToken(ctx context.Context, in *permission.CancelTokenReq) (*permission.OKResp, error) {
l := logic.NewCancelTokenLogic(ctx, s.svcCtx) l := tokenservicelogic.NewCancelTokenLogic(ctx, s.svcCtx)
return l.CancelToken(in) return l.CancelToken(in)
} }
// CancelTokenByUID 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke // CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
func (s *TokenServiceServer) CancelTokenByUid(ctx context.Context, in *permission.DoTokenByUIDReq) (*permission.OKResp, error) { func (s *TokenServiceServer) CancelTokenByUid(ctx context.Context, in *permission.DoTokenByUIDReq) (*permission.OKResp, error) {
l := logic.NewCancelTokenByUidLogic(ctx, s.svcCtx) l := tokenservicelogic.NewCancelTokenByUidLogic(ctx, s.svcCtx)
return l.CancelTokenByUid(in) return l.CancelTokenByUid(in)
} }
// CancelTokenByDeviceID 取消 Token // CancelTokenByDeviceId 取消 Token
func (s *TokenServiceServer) CancelTokenByDeviceId(ctx context.Context, in *permission.DoTokenByDeviceIDReq) (*permission.OKResp, error) { func (s *TokenServiceServer) CancelTokenByDeviceId(ctx context.Context, in *permission.DoTokenByDeviceIDReq) (*permission.OKResp, error) {
l := logic.NewCancelTokenByDeviceIdLogic(ctx, s.svcCtx) l := tokenservicelogic.NewCancelTokenByDeviceIdLogic(ctx, s.svcCtx)
return l.CancelTokenByDeviceId(in) return l.CancelTokenByDeviceId(in)
} }
// ValidationToken 驗證這個 Token 有沒有效 // ValidationToken 驗證這個 Token 有沒有效
func (s *TokenServiceServer) ValidationToken(ctx context.Context, in *permission.ValidationTokenReq) (*permission.ValidationTokenResp, error) { func (s *TokenServiceServer) ValidationToken(ctx context.Context, in *permission.ValidationTokenReq) (*permission.ValidationTokenResp, error) {
l := logic.NewValidationTokenLogic(ctx, s.svcCtx) l := tokenservicelogic.NewValidationTokenLogic(ctx, s.svcCtx)
return l.ValidationToken(in) return l.ValidationToken(in)
} }
// GetUserTokensByDeviceIDs 取得目前所對應的 DeviceID 所存在的 Tokens // GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
func (s *TokenServiceServer) GetUserTokensByDeviceId(ctx context.Context, in *permission.DoTokenByDeviceIDReq) (*permission.Tokens, error) { func (s *TokenServiceServer) GetUserTokensByDeviceId(ctx context.Context, in *permission.DoTokenByDeviceIDReq) (*permission.Tokens, error) {
l := logic.NewGetUserTokensByDeviceIdLogic(ctx, s.svcCtx) l := tokenservicelogic.NewGetUserTokensByDeviceIdLogic(ctx, s.svcCtx)
return l.GetUserTokensByDeviceId(in) return l.GetUserTokensByDeviceId(in)
} }
// GetUserTokensByUID 取得目前所對應的 UID 所存在的 Tokens // GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
func (s *TokenServiceServer) GetUserTokensByUid(ctx context.Context, in *permission.DoTokenByUIDReq) (*permission.Tokens, error) { func (s *TokenServiceServer) GetUserTokensByUid(ctx context.Context, in *permission.QueryTokenByUIDReq) (*permission.Tokens, error) {
l := logic.NewGetUserTokensByUidLogic(ctx, s.svcCtx) l := tokenservicelogic.NewGetUserTokensByUidLogic(ctx, s.svcCtx)
return l.GetUserTokensByUid(in) return l.GetUserTokensByUid(in)
} }
// NewOneTimeToken 建立一次性使用例如RefreshToken // NewOneTimeToken 建立一次性使用例如RefreshToken
func (s *TokenServiceServer) NewOneTimeToken(ctx context.Context, in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) { func (s *TokenServiceServer) NewOneTimeToken(ctx context.Context, in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) {
l := logic.NewNewOneTimeTokenLogic(ctx, s.svcCtx) l := tokenservicelogic.NewNewOneTimeTokenLogic(ctx, s.svcCtx)
return l.NewOneTimeToken(in) return l.NewOneTimeToken(in)
} }
// CancelOneTimeToken 取消一次性使用 // CancelOneTimeToken 取消一次性使用
func (s *TokenServiceServer) CancelOneTimeToken(ctx context.Context, in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) { func (s *TokenServiceServer) CancelOneTimeToken(ctx context.Context, in *permission.CancelOneTimeTokenReq) (*permission.OKResp, error) {
l := logic.NewCancelOneTimeTokenLogic(ctx, s.svcCtx) l := tokenservicelogic.NewCancelOneTimeTokenLogic(ctx, s.svcCtx)
return l.CancelOneTimeToken(in) return l.CancelOneTimeToken(in)
} }

View File

@ -1,12 +1,14 @@
package main package main
import ( import (
permissionservice "ark-permission/internal/server/permissionservice"
roleservice "ark-permission/internal/server/roleservice"
tokenservice "ark-permission/internal/server/tokenservice"
"flag" "flag"
"fmt" "fmt"
"ark-permission/gen_result/pb/permission" "ark-permission/gen_result/pb/permission"
"ark-permission/internal/config" "ark-permission/internal/config"
"ark-permission/internal/server"
"ark-permission/internal/svc" "ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/conf" "github.com/zeromicro/go-zero/core/conf"
@ -26,7 +28,9 @@ func main() {
ctx := svc.NewServiceContext(c) ctx := svc.NewServiceContext(c)
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) { s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
permission.RegisterTokenServiceServer(grpcServer, server.NewTokenServiceServer(ctx)) permission.RegisterTokenServiceServer(grpcServer, tokenservice.NewTokenServiceServer(ctx))
permission.RegisterRoleServiceServer(grpcServer, roleservice.NewRoleServiceServer(ctx))
permission.RegisterPermissionServiceServer(grpcServer, permissionservice.NewPermissionServiceServer(ctx))
if c.Mode == service.DevMode || c.Mode == service.TestMode { if c.Mode == service.DevMode || c.Mode == service.TestMode {
reflection.Register(grpcServer) reflection.Register(grpcServer)

View File

@ -20,6 +20,7 @@ type (
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
DoTokenByUIDReq = permission.DoTokenByUIDReq DoTokenByUIDReq = permission.DoTokenByUIDReq
OKResp = permission.OKResp OKResp = permission.OKResp
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
RefreshTokenReq = permission.RefreshTokenReq RefreshTokenReq = permission.RefreshTokenReq
RefreshTokenResp = permission.RefreshTokenResp RefreshTokenResp = permission.RefreshTokenResp
Token = permission.Token Token = permission.Token
@ -35,16 +36,16 @@ type (
RefreshToken(ctx context.Context, in *RefreshTokenReq, opts ...grpc.CallOption) (*RefreshTokenResp, error) RefreshToken(ctx context.Context, in *RefreshTokenReq, opts ...grpc.CallOption) (*RefreshTokenResp, error)
// CancelToken 取消 Token也包含他裡面的 One Time Toke // CancelToken 取消 Token也包含他裡面的 One Time Toke
CancelToken(ctx context.Context, in *CancelTokenReq, opts ...grpc.CallOption) (*OKResp, error) CancelToken(ctx context.Context, in *CancelTokenReq, opts ...grpc.CallOption) (*OKResp, error)
// CancelTokenByUID 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke // CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error) CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error)
// CancelTokenByDeviceID 取消 Token // CancelTokenByDeviceId 取消 Token
CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error) CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error)
// ValidationToken 驗證這個 Token 有沒有效 // ValidationToken 驗證這個 Token 有沒有效
ValidationToken(ctx context.Context, in *ValidationTokenReq, opts ...grpc.CallOption) (*ValidationTokenResp, error) ValidationToken(ctx context.Context, in *ValidationTokenReq, opts ...grpc.CallOption) (*ValidationTokenResp, error)
// GetUserTokensByDeviceIDs 取得目前所對應的 DeviceID 所存在的 Tokens // GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error) GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error)
// GetUserTokensByUID 取得目前所對應的 UID 所存在的 Tokens // GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
GetUserTokensByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error) GetUserTokensByUid(ctx context.Context, in *QueryTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error)
// NewOneTimeToken 建立一次性使用例如RefreshToken // NewOneTimeToken 建立一次性使用例如RefreshToken
NewOneTimeToken(ctx context.Context, in *CreateOneTimeTokenReq, opts ...grpc.CallOption) (*CreateOneTimeTokenResp, error) NewOneTimeToken(ctx context.Context, in *CreateOneTimeTokenReq, opts ...grpc.CallOption) (*CreateOneTimeTokenResp, error)
// CancelOneTimeToken 取消一次性使用 // CancelOneTimeToken 取消一次性使用
@ -80,13 +81,13 @@ func (m *defaultTokenService) CancelToken(ctx context.Context, in *CancelTokenRe
return client.CancelToken(ctx, in, opts...) return client.CancelToken(ctx, in, opts...)
} }
// CancelTokenByUID 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke // CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
func (m *defaultTokenService) CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error) { func (m *defaultTokenService) CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error) {
client := permission.NewTokenServiceClient(m.cli.Conn()) client := permission.NewTokenServiceClient(m.cli.Conn())
return client.CancelTokenByUid(ctx, in, opts...) return client.CancelTokenByUid(ctx, in, opts...)
} }
// CancelTokenByDeviceID 取消 Token // CancelTokenByDeviceId 取消 Token
func (m *defaultTokenService) CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error) { func (m *defaultTokenService) CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error) {
client := permission.NewTokenServiceClient(m.cli.Conn()) client := permission.NewTokenServiceClient(m.cli.Conn())
return client.CancelTokenByDeviceId(ctx, in, opts...) return client.CancelTokenByDeviceId(ctx, in, opts...)
@ -98,14 +99,14 @@ func (m *defaultTokenService) ValidationToken(ctx context.Context, in *Validatio
return client.ValidationToken(ctx, in, opts...) return client.ValidationToken(ctx, in, opts...)
} }
// GetUserTokensByDeviceIDs 取得目前所對應的 DeviceID 所存在的 Tokens // GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
func (m *defaultTokenService) GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error) { func (m *defaultTokenService) GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error) {
client := permission.NewTokenServiceClient(m.cli.Conn()) client := permission.NewTokenServiceClient(m.cli.Conn())
return client.GetUserTokensByDeviceId(ctx, in, opts...) return client.GetUserTokensByDeviceId(ctx, in, opts...)
} }
// GetUserTokensByUID 取得目前所對應的 UID 所存在的 Tokens // GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
func (m *defaultTokenService) GetUserTokensByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error) { func (m *defaultTokenService) GetUserTokensByUid(ctx context.Context, in *QueryTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error) {
client := permission.NewTokenServiceClient(m.cli.Conn()) client := permission.NewTokenServiceClient(m.cli.Conn())
return client.GetUserTokensByUid(ctx, in, opts...) return client.GetUserTokensByUid(ctx, in, opts...)
} }