This commit is contained in:
wwweww
2026-02-23 20:36:21 +08:00
parent 4898aecd3b
commit fdbcde13b2
52 changed files with 11263 additions and 194 deletions
+5 -1
View File
@@ -3,7 +3,7 @@ ListenOn: 0.0.0.0:9001
Prometheus:
Host: 0.0.0.0
Port: 9001
Port: 4001
Path: /metrics
DataSource: "${DB_URI}?sslmode=disable"
@@ -13,3 +13,7 @@ CacheConf:
Type: cluster
Pass: "${REDIS_PASSWORD}"
User: "default"
Jwt:
SecretKey: "${JWT_SECRET_KEY}"
Issuer: "juwan-user-rpc"
+6
View File
@@ -5,8 +5,14 @@ import (
"github.com/zeromicro/go-zero/zrpc"
)
type JwtConfig struct {
SecretKey string `json:"secretKey"`
Issuer string `json:"issuer"`
}
type Config struct {
zrpc.RpcServerConf
DataSource string `json:"dataSource"`
CacheConf cache.CacheConf
Jwt JwtConfig `json:"jwt"`
}
@@ -0,0 +1,30 @@
package logic
import (
"context"
"juwan-backend/app/users/rpc/internal/svc"
"juwan-backend/app/users/rpc/pb"
"github.com/zeromicro/go-zero/core/logx"
)
type CheckPermissionLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewCheckPermissionLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CheckPermissionLogic {
return &CheckPermissionLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *CheckPermissionLogic) CheckPermission(in *pb.CheckPermissionReq) (*pb.CheckPermissionResp, error) {
// todo: add your logic here and delete this line
return &pb.CheckPermissionResp{}, nil
}
@@ -5,6 +5,7 @@ import (
"juwan-backend/app/users/rpc/internal/svc"
"juwan-backend/app/users/rpc/pb"
"juwan-backend/common/converter"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -23,8 +24,19 @@ func NewGetUserByUsernameLogic(ctx context.Context, svcCtx *svc.ServiceContext)
}
}
func (l *GetUserByUsernameLogic) GetUserByUsername(in *pb.GetUsersByIdReq) (*pb.GetUsersByIdResp, error) {
func (l *GetUserByUsernameLogic) GetUserByUsername(in *pb.GetUserByUsernameReq) (*pb.GetUserByUsernameResp, error) {
// todo: add your logic here and delete this line
return &pb.GetUsersByIdResp{}, nil
user, err := l.svcCtx.UsersModel.FindOneByUsername(l.ctx, in.Username)
pbUsers := &pb.Users{}
converter.StructToStruct(user, pbUsers)
if err == nil || user != nil {
return &pb.GetUserByUsernameResp{
Users: pbUsers,
}, nil
}
if err.Error() != "not found" {
return nil, err
}
return &pb.GetUserByUsernameResp{}, nil
}
@@ -0,0 +1,30 @@
package logic
import (
"context"
"juwan-backend/app/users/rpc/internal/svc"
"juwan-backend/app/users/rpc/pb"
"github.com/zeromicro/go-zero/core/logx"
)
type LoginLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
return &LoginLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *LoginLogic) Login(in *pb.LoginReq) (*pb.LoginResp, error) {
// todo: add your logic here and delete this line
return &pb.LoginResp{}, nil
}
@@ -0,0 +1,30 @@
package logic
import (
"context"
"juwan-backend/app/users/rpc/internal/svc"
"juwan-backend/app/users/rpc/pb"
"github.com/zeromicro/go-zero/core/logx"
)
type ValidateTokenLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewValidateTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ValidateTokenLogic {
return &ValidateTokenLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *ValidateTokenLogic) ValidateToken(in *pb.ValidateTokenReq) (*pb.ValidateTokenResp, error) {
// todo: add your logic here and delete this line
return &pb.ValidateTokenResp{}, nil
}
@@ -53,3 +53,18 @@ func (s *UsercenterServer) SearchUsers(ctx context.Context, in *pb.SearchUsersRe
l := logic.NewSearchUsersLogic(ctx, s.svcCtx)
return l.SearchUsers(in)
}
func (s *UsercenterServer) Login(ctx context.Context, in *pb.LoginReq) (*pb.LoginResp, error) {
l := logic.NewLoginLogic(ctx, s.svcCtx)
return l.Login(in)
}
func (s *UsercenterServer) ValidateToken(ctx context.Context, in *pb.ValidateTokenReq) (*pb.ValidateTokenResp, error) {
l := logic.NewValidateTokenLogic(ctx, s.svcCtx)
return l.ValidateToken(in)
}
func (s *UsercenterServer) CheckPermission(ctx context.Context, in *pb.CheckPermissionReq) (*pb.CheckPermissionResp, error) {
l := logic.NewCheckPermissionLogic(ctx, s.svcCtx)
return l.CheckPermission(in)
}
@@ -4,6 +4,7 @@ import (
"context"
"juwan-backend/app/users/rpc/internal/config"
"juwan-backend/app/users/rpc/internal/models"
"juwan-backend/app/users/rpc/internal/utils"
"time"
"github.com/redis/go-redis/v9"
@@ -15,6 +16,7 @@ type ServiceContext struct {
Config config.Config
UsersModel models.UsersModel
RedisCluster *redis.ClusterClient
JwtManager *utils.JwtManager
}
func NewServiceContext(c config.Config) *ServiceContext {
@@ -39,9 +41,13 @@ func NewServiceContext(c config.Config) *ServiceContext {
}
}
// Initialize JWT Manager
jwtManager := utils.NewJwtManager(redisCluster, c.Jwt.SecretKey, c.Jwt.Issuer)
return &ServiceContext{
Config: c,
UsersModel: models.NewUsersModel(conn, c.CacheConf),
RedisCluster: redisCluster,
JwtManager: jwtManager,
}
}
+90
View File
@@ -0,0 +1,90 @@
package utils
import (
"encoding/base64"
"encoding/json"
"fmt"
"time"
"github.com/golang-jwt/jwt/v4"
)
// JWKS (JSON Web Key Set) 结构
type JWKSKey struct {
Kty string `json:"kty"`
Use string `json:"use"`
Kid string `json:"kid"`
N string `json:"n,omitempty"`
E string `json:"e,omitempty"`
K string `json:"k,omitempty"` // 对称密钥
Alg string `json:"alg"`
}
type JWKS struct {
Keys []JWKSKey `json:"keys"`
}
// GenerateJWKSFromSecret 从密钥生成 JWKS(用于对称加密 HS256)
func GenerateJWKSFromSecret(secretKey string, keyID string) *JWKS {
// 对于 HS256,将密钥进行 base64 编码
encodedSecret := base64.RawURLEncoding.EncodeToString([]byte(secretKey))
return &JWKS{
Keys: []JWKSKey{
{
Kty: "oct",
Use: "sig",
Kid: keyID,
K: encodedSecret,
Alg: "HS256",
},
},
}
}
// GenerateJWKSEndpoint 生成可以被 Envoy 使用的 JWKS JSON
// 此端点应在 user-rpc 中暴露,URL 为 /.well-known/jwks.json
func GenerateJWKSEndpoint(secretKey string, keyID string) (string, error) {
if secretKey == "" {
return "", fmt.Errorf("secret key cannot be empty")
}
jwks := GenerateJWKSFromSecret(secretKey, keyID)
jsonData, err := json.MarshalIndent(jwks, "", " ")
if err != nil {
return "", err
}
return string(jsonData), nil
}
// TokenPayload 令牌负载
type TokenMetadata struct {
IssuedAt time.Time
ExpiresAt time.Time
Subject string // userId
Issuer string
Audience string
}
// ExtractTokenMetadata 从 token 中提取元数据(不验证签名)
func ExtractTokenMetadata(tokenString string) (*TokenMetadata, error) {
token, _, err := new(jwt.Parser).ParseUnverified(tokenString, &Claims{})
if err != nil {
return nil, err
}
claims, ok := token.Claims.(*Claims)
if !ok {
return nil, fmt.Errorf("invalid token claims type")
}
return &TokenMetadata{
IssuedAt: claims.IssuedAt.Time,
ExpiresAt: claims.ExpiresAt.Time,
Subject: claims.UserId,
Issuer: claims.Issuer,
Audience: "", // 如果需要,可以增加到 Claims 中
}, nil
}
+218 -5
View File
@@ -1,8 +1,14 @@
package utils
import (
"context"
"encoding/json"
"errors"
"fmt"
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/redis/go-redis/v9"
)
type TokenPayload struct {
@@ -10,11 +16,16 @@ type TokenPayload struct {
IsAdmin bool
}
type Claims struct {
TokenPayload
jwt.RegisteredClaims
}
const (
tokenCachePrefixUser = "jwt:user:"
tokenCachePrefixToken = "jwt:token:"
tokenCacheTTL = 60 * 24 * time.Hour
tokenLifetime = 5 * 24 * time.Hour
tokenCacheTTL = 30 * 24 * time.Hour
tokenLifetime = 7 * 24 * time.Hour
)
var (
@@ -22,9 +33,211 @@ var (
errInvalidToken = errors.New("invalid token claims")
errTokenNotInCache = errors.New("token not found in cache")
errNoRedisClient = errors.New("redis client not configured")
// errExpiredToken = errors.New("token expired")
)
func NewToken(payload TokenPayload) (string, error) {
return "", nil
type JwtManager struct {
redisCluster *redis.ClusterClient
secretKey string
issuer string
}
func NewJwtManager(redisCluster *redis.ClusterClient, secretKey, issuer string) *JwtManager {
return &JwtManager{
redisCluster: redisCluster,
secretKey: secretKey,
issuer: issuer,
}
}
// New 生成新的 JWT token
func (m *JwtManager) New(ctx context.Context, payload *TokenPayload) (string, error) {
if m.redisCluster == nil {
return "", errNoRedisClient
}
now := time.Now()
expiresAt := now.Add(tokenLifetime)
claims := &Claims{
TokenPayload: *payload,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(expiresAt),
IssuedAt: jwt.NewNumericDate(now),
Issuer: m.issuer,
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString([]byte(m.secretKey))
if err != nil {
return "", err
}
// 存储 token 到 RedisTTL 为 30 天
userKey := tokenCachePrefixUser + payload.UserId
tokenKey := tokenCachePrefixToken + tokenString
tokenData, _ := json.Marshal(payload)
// 同时存储两个 key:用户 -> token 和 token -> payload
pipe := m.redisCluster.Pipeline()
pipe.Set(ctx, userKey, tokenString, tokenCacheTTL)
pipe.Set(ctx, tokenKey, string(tokenData), tokenCacheTTL)
_, err = pipe.Exec(ctx)
if err != nil {
return "", err
}
return tokenString, nil
}
// Valid 验证 token 有效性,支持自动换票
func (m *JwtManager) Valid(ctx context.Context, tokenString string) (*TokenPayload, error) {
if m.redisCluster == nil {
return nil, errNoRedisClient
}
if tokenString == "" {
return nil, errMissingToken
}
// 检查 token 是否在 Redis 中
tokenKey := tokenCachePrefixToken + tokenString
tokenData, err := m.redisCluster.Get(ctx, tokenKey).Result()
if err != nil && err != redis.Nil {
return nil, err
}
var payload TokenPayload
if err == redis.Nil {
return nil, errTokenNotInCache
}
err = json.Unmarshal([]byte(tokenData), &payload)
if err != nil {
return nil, errInvalidToken
}
// 解析 JWT 并验证签名和过期时间
token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(m.secretKey), nil
})
if err != nil {
return nil, err
}
claims, ok := token.Claims.(*Claims)
if !ok || !token.Valid {
return nil, errInvalidToken
}
return &claims.TokenPayload, nil
}
// Renew 换票逻辑:如果 token 过期但 Redis 中还存在,则生成新 token
func (m *JwtManager) Renew(ctx context.Context, tokenString string) (string, error) {
if m.redisCluster == nil {
return "", errNoRedisClient
}
// 检查 token 是否在 Redis 中(不检查过期时间)
tokenKey := tokenCachePrefixToken + tokenString
tokenData, err := m.redisCluster.Get(ctx, tokenKey).Result()
if err != nil {
if err == redis.Nil {
return "", errTokenNotInCache
}
return "", err
}
var payload TokenPayload
err = json.Unmarshal([]byte(tokenData), &payload)
if err != nil {
return "", errInvalidToken
}
// 删除旧 token 记录
userKey := tokenCachePrefixUser + payload.UserId
m.redisCluster.Del(ctx, tokenKey, userKey)
// 生成新 token
return m.New(ctx, &payload)
}
// extract payload from token without validating expiration (used for auto-renewal)
func (m *JwtManager) Extract(ctx context.Context, tokenString string) (*TokenPayload, error) {
token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(m.secretKey), nil
})
if err != nil {
return nil, err
}
claims, ok := token.Claims.(*Claims)
if !ok {
return nil, errInvalidToken
}
return &claims.TokenPayload, nil
}
// check if token exists in Redis (i.e. is valid and not revoked)
func (m *JwtManager) Exists(ctx context.Context, tokenString string) (bool, error) {
if m.redisCluster == nil {
return false, errNoRedisClient
}
tokenKey := tokenCachePrefixToken + tokenString
exists, err := m.redisCluster.Exists(ctx, tokenKey).Result()
if err != nil {
return false, err
}
return exists > 0, nil
}
// extract payload from JWT claims
func (m *JwtManager) ClaimsToPayload(claims *Claims) *TokenPayload {
return &claims.TokenPayload
}
// revoke token by deleting both user -> token and token -> payload keys from Redis
func (m *JwtManager) Revoke(ctx context.Context, tokenString string) error {
if m.redisCluster == nil {
return errNoRedisClient
}
payload, err := m.Extract(ctx, tokenString)
if err != nil {
return err
}
userKey := tokenCachePrefixUser + payload.UserId
tokenKey := tokenCachePrefixToken + tokenString
pipe := m.redisCluster.Pipeline()
pipe.Del(ctx, userKey)
pipe.Del(ctx, tokenKey)
_, err = pipe.Exec(ctx)
return err
}
func (m *JwtManager) GetUserToken(ctx context.Context, userID string) (string, error) {
if m.redisCluster == nil {
return "", errNoRedisClient
}
userKey := tokenCachePrefixUser + userID
token, err := m.redisCluster.Get(ctx, userKey).Result()
if err != nil {
if err == redis.Nil {
return "", fmt.Errorf("user %s has no token", userID)
}
return "", err
}
return token, nil
}
+375 -12
View File
@@ -906,6 +906,334 @@ func (x *GetUserByUsernameResp) GetUsers() *Users {
return nil
}
type LoginReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
Passwd string `protobuf:"bytes,2,opt,name=passwd,proto3" json:"passwd,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *LoginReq) Reset() {
*x = LoginReq{}
mi := &file_users_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *LoginReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LoginReq) ProtoMessage() {}
func (x *LoginReq) ProtoReflect() protoreflect.Message {
mi := &file_users_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LoginReq.ProtoReflect.Descriptor instead.
func (*LoginReq) Descriptor() ([]byte, []int) {
return file_users_proto_rawDescGZIP(), []int{13}
}
func (x *LoginReq) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *LoginReq) GetPasswd() string {
if x != nil {
return x.Passwd
}
return ""
}
type LoginResp struct {
state protoimpl.MessageState `protogen:"open.v1"`
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *LoginResp) Reset() {
*x = LoginResp{}
mi := &file_users_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *LoginResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LoginResp) ProtoMessage() {}
func (x *LoginResp) ProtoReflect() protoreflect.Message {
mi := &file_users_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LoginResp.ProtoReflect.Descriptor instead.
func (*LoginResp) Descriptor() ([]byte, []int) {
return file_users_proto_rawDescGZIP(), []int{14}
}
func (x *LoginResp) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
type ValidateTokenReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` // JWT token
UserId string `protobuf:"bytes,2,opt,name=userId,proto3" json:"userId,omitempty"` // 用户ID
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ValidateTokenReq) Reset() {
*x = ValidateTokenReq{}
mi := &file_users_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ValidateTokenReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ValidateTokenReq) ProtoMessage() {}
func (x *ValidateTokenReq) ProtoReflect() protoreflect.Message {
mi := &file_users_proto_msgTypes[15]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ValidateTokenReq.ProtoReflect.Descriptor instead.
func (*ValidateTokenReq) Descriptor() ([]byte, []int) {
return file_users_proto_rawDescGZIP(), []int{15}
}
func (x *ValidateTokenReq) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
func (x *ValidateTokenReq) GetUserId() string {
if x != nil {
return x.UserId
}
return ""
}
type ValidateTokenResp struct {
state protoimpl.MessageState `protogen:"open.v1"`
Valid bool `protobuf:"varint,1,opt,name=valid,proto3" json:"valid,omitempty"` // token 是否有效(不在黑名单中)
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` // 验证失败原因
UserId string `protobuf:"bytes,3,opt,name=userId,proto3" json:"userId,omitempty"` // 用户ID
RoleType int64 `protobuf:"varint,4,opt,name=roleType,proto3" json:"roleType,omitempty"` // 用户角色
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ValidateTokenResp) Reset() {
*x = ValidateTokenResp{}
mi := &file_users_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ValidateTokenResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ValidateTokenResp) ProtoMessage() {}
func (x *ValidateTokenResp) ProtoReflect() protoreflect.Message {
mi := &file_users_proto_msgTypes[16]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ValidateTokenResp.ProtoReflect.Descriptor instead.
func (*ValidateTokenResp) Descriptor() ([]byte, []int) {
return file_users_proto_rawDescGZIP(), []int{16}
}
func (x *ValidateTokenResp) GetValid() bool {
if x != nil {
return x.Valid
}
return false
}
func (x *ValidateTokenResp) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
func (x *ValidateTokenResp) GetUserId() string {
if x != nil {
return x.UserId
}
return ""
}
func (x *ValidateTokenResp) GetRoleType() int64 {
if x != nil {
return x.RoleType
}
return 0
}
type CheckPermissionReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserId string `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` // 用户ID
Resource string `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"` // 资源 ID
Action string `protobuf:"bytes,3,opt,name=action,proto3" json:"action,omitempty"` // 操作类型: read/write/delete
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CheckPermissionReq) Reset() {
*x = CheckPermissionReq{}
mi := &file_users_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckPermissionReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckPermissionReq) ProtoMessage() {}
func (x *CheckPermissionReq) ProtoReflect() protoreflect.Message {
mi := &file_users_proto_msgTypes[17]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckPermissionReq.ProtoReflect.Descriptor instead.
func (*CheckPermissionReq) Descriptor() ([]byte, []int) {
return file_users_proto_rawDescGZIP(), []int{17}
}
func (x *CheckPermissionReq) GetUserId() string {
if x != nil {
return x.UserId
}
return ""
}
func (x *CheckPermissionReq) GetResource() string {
if x != nil {
return x.Resource
}
return ""
}
func (x *CheckPermissionReq) GetAction() string {
if x != nil {
return x.Action
}
return ""
}
type CheckPermissionResp struct {
state protoimpl.MessageState `protogen:"open.v1"`
Allowed bool `protobuf:"varint,1,opt,name=allowed,proto3" json:"allowed,omitempty"` // 是否有权限
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` // 拒绝原因
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CheckPermissionResp) Reset() {
*x = CheckPermissionResp{}
mi := &file_users_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckPermissionResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckPermissionResp) ProtoMessage() {}
func (x *CheckPermissionResp) ProtoReflect() protoreflect.Message {
mi := &file_users_proto_msgTypes[18]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckPermissionResp.ProtoReflect.Descriptor instead.
func (*CheckPermissionResp) Descriptor() ([]byte, []int) {
return file_users_proto_rawDescGZIP(), []int{18}
}
func (x *CheckPermissionResp) GetAllowed() bool {
if x != nil {
return x.Allowed
}
return false
}
func (x *CheckPermissionResp) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
var File_users_proto protoreflect.FileDescriptor
const file_users_proto_rawDesc = "" +
@@ -987,7 +1315,27 @@ const file_users_proto_rawDesc = "" +
"\x14GetUserByUsernameReq\x12\x1a\n" +
"\busername\x18\x01 \x01(\tR\busername\"8\n" +
"\x15GetUserByUsernameResp\x12\x1f\n" +
"\x05users\x18\x01 \x01(\v2\t.pb.UsersR\x05users2\xdf\x02\n" +
"\x05users\x18\x01 \x01(\v2\t.pb.UsersR\x05users\">\n" +
"\bLoginReq\x12\x1a\n" +
"\busername\x18\x01 \x01(\tR\busername\x12\x16\n" +
"\x06passwd\x18\x02 \x01(\tR\x06passwd\"!\n" +
"\tLoginResp\x12\x14\n" +
"\x05token\x18\x01 \x01(\tR\x05token\"@\n" +
"\x10ValidateTokenReq\x12\x14\n" +
"\x05token\x18\x01 \x01(\tR\x05token\x12\x16\n" +
"\x06userId\x18\x02 \x01(\tR\x06userId\"w\n" +
"\x11ValidateTokenResp\x12\x14\n" +
"\x05valid\x18\x01 \x01(\bR\x05valid\x12\x18\n" +
"\amessage\x18\x02 \x01(\tR\amessage\x12\x16\n" +
"\x06userId\x18\x03 \x01(\tR\x06userId\x12\x1a\n" +
"\broleType\x18\x04 \x01(\x03R\broleType\"`\n" +
"\x12CheckPermissionReq\x12\x16\n" +
"\x06userId\x18\x01 \x01(\tR\x06userId\x12\x1a\n" +
"\bresource\x18\x02 \x01(\tR\bresource\x12\x16\n" +
"\x06action\x18\x03 \x01(\tR\x06action\"I\n" +
"\x13CheckPermissionResp\x12\x18\n" +
"\aallowed\x18\x01 \x01(\bR\aallowed\x12\x18\n" +
"\amessage\x18\x02 \x01(\tR\amessage2\x87\x04\n" +
"\n" +
"usercenter\x12-\n" +
"\bAddUsers\x12\x0f.pb.AddUsersReq\x1a\x10.pb.AddUsersResp\x126\n" +
@@ -995,7 +1343,10 @@ const file_users_proto_rawDesc = "" +
"\bDelUsers\x12\x0f.pb.DelUsersReq\x1a\x10.pb.DelUsersResp\x129\n" +
"\fGetUsersById\x12\x13.pb.GetUsersByIdReq\x1a\x14.pb.GetUsersByIdResp\x12H\n" +
"\x11GetUserByUsername\x12\x18.pb.GetUserByUsernameReq\x1a\x19.pb.GetUserByUsernameResp\x126\n" +
"\vSearchUsers\x12\x12.pb.SearchUsersReq\x1a\x13.pb.SearchUsersRespB\x06Z\x04./pbb\x06proto3"
"\vSearchUsers\x12\x12.pb.SearchUsersReq\x1a\x13.pb.SearchUsersResp\x12$\n" +
"\x05Login\x12\f.pb.LoginReq\x1a\r.pb.LoginResp\x12<\n" +
"\rValidateToken\x12\x14.pb.ValidateTokenReq\x1a\x15.pb.ValidateTokenResp\x12B\n" +
"\x0fCheckPermission\x12\x16.pb.CheckPermissionReq\x1a\x17.pb.CheckPermissionRespB\x06Z\x04./pbb\x06proto3"
var (
file_users_proto_rawDescOnce sync.Once
@@ -1009,7 +1360,7 @@ func file_users_proto_rawDescGZIP() []byte {
return file_users_proto_rawDescData
}
var file_users_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
var file_users_proto_msgTypes = make([]protoimpl.MessageInfo, 19)
var file_users_proto_goTypes = []any{
(*Users)(nil), // 0: pb.Users
(*AddUsersReq)(nil), // 1: pb.AddUsersReq
@@ -1024,6 +1375,12 @@ var file_users_proto_goTypes = []any{
(*SearchUsersResp)(nil), // 10: pb.SearchUsersResp
(*GetUserByUsernameReq)(nil), // 11: pb.GetUserByUsernameReq
(*GetUserByUsernameResp)(nil), // 12: pb.GetUserByUsernameResp
(*LoginReq)(nil), // 13: pb.LoginReq
(*LoginResp)(nil), // 14: pb.LoginResp
(*ValidateTokenReq)(nil), // 15: pb.ValidateTokenReq
(*ValidateTokenResp)(nil), // 16: pb.ValidateTokenResp
(*CheckPermissionReq)(nil), // 17: pb.CheckPermissionReq
(*CheckPermissionResp)(nil), // 18: pb.CheckPermissionResp
}
var file_users_proto_depIdxs = []int32{
0, // 0: pb.GetUsersByIdResp.users:type_name -> pb.Users
@@ -1035,14 +1392,20 @@ var file_users_proto_depIdxs = []int32{
7, // 6: pb.usercenter.GetUsersById:input_type -> pb.GetUsersByIdReq
11, // 7: pb.usercenter.GetUserByUsername:input_type -> pb.GetUserByUsernameReq
9, // 8: pb.usercenter.SearchUsers:input_type -> pb.SearchUsersReq
2, // 9: pb.usercenter.AddUsers:output_type -> pb.AddUsersResp
4, // 10: pb.usercenter.UpdateUsers:output_type -> pb.UpdateUsersResp
6, // 11: pb.usercenter.DelUsers:output_type -> pb.DelUsersResp
8, // 12: pb.usercenter.GetUsersById:output_type -> pb.GetUsersByIdResp
12, // 13: pb.usercenter.GetUserByUsername:output_type -> pb.GetUserByUsernameResp
10, // 14: pb.usercenter.SearchUsers:output_type -> pb.SearchUsersResp
9, // [9:15] is the sub-list for method output_type
3, // [3:9] is the sub-list for method input_type
13, // 9: pb.usercenter.Login:input_type -> pb.LoginReq
15, // 10: pb.usercenter.ValidateToken:input_type -> pb.ValidateTokenReq
17, // 11: pb.usercenter.CheckPermission:input_type -> pb.CheckPermissionReq
2, // 12: pb.usercenter.AddUsers:output_type -> pb.AddUsersResp
4, // 13: pb.usercenter.UpdateUsers:output_type -> pb.UpdateUsersResp
6, // 14: pb.usercenter.DelUsers:output_type -> pb.DelUsersResp
8, // 15: pb.usercenter.GetUsersById:output_type -> pb.GetUsersByIdResp
12, // 16: pb.usercenter.GetUserByUsername:output_type -> pb.GetUserByUsernameResp
10, // 17: pb.usercenter.SearchUsers:output_type -> pb.SearchUsersResp
14, // 18: pb.usercenter.Login:output_type -> pb.LoginResp
16, // 19: pb.usercenter.ValidateToken:output_type -> pb.ValidateTokenResp
18, // 20: pb.usercenter.CheckPermission:output_type -> pb.CheckPermissionResp
12, // [12:21] is the sub-list for method output_type
3, // [3:12] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
@@ -1059,7 +1422,7 @@ func file_users_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_users_proto_rawDesc), len(file_users_proto_rawDesc)),
NumEnums: 0,
NumMessages: 13,
NumMessages: 19,
NumExtensions: 0,
NumServices: 1,
},
+114
View File
@@ -25,6 +25,9 @@ const (
Usercenter_GetUsersById_FullMethodName = "/pb.usercenter/GetUsersById"
Usercenter_GetUserByUsername_FullMethodName = "/pb.usercenter/GetUserByUsername"
Usercenter_SearchUsers_FullMethodName = "/pb.usercenter/SearchUsers"
Usercenter_Login_FullMethodName = "/pb.usercenter/Login"
Usercenter_ValidateToken_FullMethodName = "/pb.usercenter/ValidateToken"
Usercenter_CheckPermission_FullMethodName = "/pb.usercenter/CheckPermission"
)
// UsercenterClient is the client API for Usercenter service.
@@ -38,6 +41,9 @@ type UsercenterClient interface {
GetUsersById(ctx context.Context, in *GetUsersByIdReq, opts ...grpc.CallOption) (*GetUsersByIdResp, error)
GetUserByUsername(ctx context.Context, in *GetUserByUsernameReq, opts ...grpc.CallOption) (*GetUserByUsernameResp, error)
SearchUsers(ctx context.Context, in *SearchUsersReq, opts ...grpc.CallOption) (*SearchUsersResp, error)
Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*LoginResp, error)
ValidateToken(ctx context.Context, in *ValidateTokenReq, opts ...grpc.CallOption) (*ValidateTokenResp, error)
CheckPermission(ctx context.Context, in *CheckPermissionReq, opts ...grpc.CallOption) (*CheckPermissionResp, error)
}
type usercenterClient struct {
@@ -108,6 +114,36 @@ func (c *usercenterClient) SearchUsers(ctx context.Context, in *SearchUsersReq,
return out, nil
}
func (c *usercenterClient) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*LoginResp, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(LoginResp)
err := c.cc.Invoke(ctx, Usercenter_Login_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *usercenterClient) ValidateToken(ctx context.Context, in *ValidateTokenReq, opts ...grpc.CallOption) (*ValidateTokenResp, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ValidateTokenResp)
err := c.cc.Invoke(ctx, Usercenter_ValidateToken_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *usercenterClient) CheckPermission(ctx context.Context, in *CheckPermissionReq, opts ...grpc.CallOption) (*CheckPermissionResp, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CheckPermissionResp)
err := c.cc.Invoke(ctx, Usercenter_CheckPermission_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// UsercenterServer is the server API for Usercenter service.
// All implementations must embed UnimplementedUsercenterServer
// for forward compatibility.
@@ -119,6 +155,9 @@ type UsercenterServer interface {
GetUsersById(context.Context, *GetUsersByIdReq) (*GetUsersByIdResp, error)
GetUserByUsername(context.Context, *GetUserByUsernameReq) (*GetUserByUsernameResp, error)
SearchUsers(context.Context, *SearchUsersReq) (*SearchUsersResp, error)
Login(context.Context, *LoginReq) (*LoginResp, error)
ValidateToken(context.Context, *ValidateTokenReq) (*ValidateTokenResp, error)
CheckPermission(context.Context, *CheckPermissionReq) (*CheckPermissionResp, error)
mustEmbedUnimplementedUsercenterServer()
}
@@ -147,6 +186,15 @@ func (UnimplementedUsercenterServer) GetUserByUsername(context.Context, *GetUser
func (UnimplementedUsercenterServer) SearchUsers(context.Context, *SearchUsersReq) (*SearchUsersResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method SearchUsers not implemented")
}
func (UnimplementedUsercenterServer) Login(context.Context, *LoginReq) (*LoginResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method Login not implemented")
}
func (UnimplementedUsercenterServer) ValidateToken(context.Context, *ValidateTokenReq) (*ValidateTokenResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method ValidateToken not implemented")
}
func (UnimplementedUsercenterServer) CheckPermission(context.Context, *CheckPermissionReq) (*CheckPermissionResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method CheckPermission not implemented")
}
func (UnimplementedUsercenterServer) mustEmbedUnimplementedUsercenterServer() {}
func (UnimplementedUsercenterServer) testEmbeddedByValue() {}
@@ -276,6 +324,60 @@ func _Usercenter_SearchUsers_Handler(srv interface{}, ctx context.Context, dec f
return interceptor(ctx, in, info, handler)
}
func _Usercenter_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(LoginReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UsercenterServer).Login(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Usercenter_Login_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UsercenterServer).Login(ctx, req.(*LoginReq))
}
return interceptor(ctx, in, info, handler)
}
func _Usercenter_ValidateToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ValidateTokenReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UsercenterServer).ValidateToken(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Usercenter_ValidateToken_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UsercenterServer).ValidateToken(ctx, req.(*ValidateTokenReq))
}
return interceptor(ctx, in, info, handler)
}
func _Usercenter_CheckPermission_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CheckPermissionReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UsercenterServer).CheckPermission(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Usercenter_CheckPermission_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UsercenterServer).CheckPermission(ctx, req.(*CheckPermissionReq))
}
return interceptor(ctx, in, info, handler)
}
// Usercenter_ServiceDesc is the grpc.ServiceDesc for Usercenter service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -307,6 +409,18 @@ var Usercenter_ServiceDesc = grpc.ServiceDesc{
MethodName: "SearchUsers",
Handler: _Usercenter_SearchUsers_Handler,
},
{
MethodName: "Login",
Handler: _Usercenter_Login_Handler,
},
{
MethodName: "ValidateToken",
Handler: _Usercenter_ValidateToken_Handler,
},
{
MethodName: "CheckPermission",
Handler: _Usercenter_CheckPermission_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "users.proto",
+24
View File
@@ -16,17 +16,23 @@ import (
type (
AddUsersReq = pb.AddUsersReq
AddUsersResp = pb.AddUsersResp
CheckPermissionReq = pb.CheckPermissionReq
CheckPermissionResp = pb.CheckPermissionResp
DelUsersReq = pb.DelUsersReq
DelUsersResp = pb.DelUsersResp
GetUserByUsernameReq = pb.GetUserByUsernameReq
GetUserByUsernameResp = pb.GetUserByUsernameResp
GetUsersByIdReq = pb.GetUsersByIdReq
GetUsersByIdResp = pb.GetUsersByIdResp
LoginReq = pb.LoginReq
LoginResp = pb.LoginResp
SearchUsersReq = pb.SearchUsersReq
SearchUsersResp = pb.SearchUsersResp
UpdateUsersReq = pb.UpdateUsersReq
UpdateUsersResp = pb.UpdateUsersResp
Users = pb.Users
ValidateTokenReq = pb.ValidateTokenReq
ValidateTokenResp = pb.ValidateTokenResp
Usercenter interface {
// -----------------------users-----------------------
@@ -36,6 +42,9 @@ type (
GetUsersById(ctx context.Context, in *GetUsersByIdReq, opts ...grpc.CallOption) (*GetUsersByIdResp, error)
GetUserByUsername(ctx context.Context, in *GetUserByUsernameReq, opts ...grpc.CallOption) (*GetUserByUsernameResp, error)
SearchUsers(ctx context.Context, in *SearchUsersReq, opts ...grpc.CallOption) (*SearchUsersResp, error)
Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*LoginResp, error)
ValidateToken(ctx context.Context, in *ValidateTokenReq, opts ...grpc.CallOption) (*ValidateTokenResp, error)
CheckPermission(ctx context.Context, in *CheckPermissionReq, opts ...grpc.CallOption) (*CheckPermissionResp, error)
}
defaultUsercenter struct {
@@ -79,3 +88,18 @@ func (m *defaultUsercenter) SearchUsers(ctx context.Context, in *SearchUsersReq,
client := pb.NewUsercenterClient(m.cli.Conn())
return client.SearchUsers(ctx, in, opts...)
}
func (m *defaultUsercenter) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*LoginResp, error) {
client := pb.NewUsercenterClient(m.cli.Conn())
return client.Login(ctx, in, opts...)
}
func (m *defaultUsercenter) ValidateToken(ctx context.Context, in *ValidateTokenReq, opts ...grpc.CallOption) (*ValidateTokenResp, error) {
client := pb.NewUsercenterClient(m.cli.Conn())
return client.ValidateToken(ctx, in, opts...)
}
func (m *defaultUsercenter) CheckPermission(ctx context.Context, in *CheckPermissionReq, opts ...grpc.CallOption) (*CheckPermissionResp, error) {
client := pb.NewUsercenterClient(m.cli.Conn())
return client.CheckPermission(ctx, in, opts...)
}