feat/all-pa #3

Merged
daniel.w merged 5 commits from feat/all-pa into main 2024-08-18 14:09:52 +00:00
16 changed files with 444 additions and 62 deletions
Showing only changes of commit 016035887c - Show all commits

View File

@ -16,11 +16,19 @@ type (
AuthorizationReq = permission.AuthorizationReq
CancelOneTimeTokenReq = permission.CancelOneTimeTokenReq
CancelTokenReq = permission.CancelTokenReq
CheckPermissionByRoleReq = permission.CheckPermissionByRoleReq
CreateOneTimeTokenReq = permission.CreateOneTimeTokenReq
CreateOneTimeTokenResp = permission.CreateOneTimeTokenResp
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
DoTokenByUIDReq = permission.DoTokenByUIDReq
GetPermissionStatusByPathReq = permission.GetPermissionStatusByPathReq
ListPermissionResp = permission.ListPermissionResp
ListPermissionStatusResp = permission.ListPermissionStatusResp
NoneReq = permission.NoneReq
OKResp = permission.OKResp
PermissionItem = permission.PermissionItem
PermissionResp = permission.PermissionResp
PermissionStatusItem = permission.PermissionStatusItem
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
RefreshTokenReq = permission.RefreshTokenReq
RefreshTokenResp = permission.RefreshTokenResp
@ -31,6 +39,14 @@ type (
ValidationTokenResp = permission.ValidationTokenResp
PermissionService interface {
// ListPermissionStatus 取得狀態
ListPermissionStatus(ctx context.Context, in *NoneReq, opts ...grpc.CallOption) (*ListPermissionStatusResp, error)
// ListPermission 取得完整權限
ListPermission(ctx context.Context, in *NoneReq, opts ...grpc.CallOption) (*ListPermissionResp, error)
// CheckPermissionByRole 透過角色 ID 來檢視權限
CheckPermissionByRole(ctx context.Context, in *CheckPermissionByRoleReq, opts ...grpc.CallOption) (*PermissionResp, error)
// GetPermissionStatusByPath 透過資源拿取角色的狀態
GetPermissionStatusByPath(ctx context.Context, in *GetPermissionStatusByPathReq, opts ...grpc.CallOption) (*PermissionStatusItem, error)
}
defaultPermissionService struct {
@ -43,3 +59,27 @@ func NewPermissionService(cli zrpc.Client) PermissionService {
cli: cli,
}
}
// ListPermissionStatus 取得狀態
func (m *defaultPermissionService) ListPermissionStatus(ctx context.Context, in *NoneReq, opts ...grpc.CallOption) (*ListPermissionStatusResp, error) {
client := permission.NewPermissionServiceClient(m.cli.Conn())
return client.ListPermissionStatus(ctx, in, opts...)
}
// ListPermission 取得完整權限
func (m *defaultPermissionService) ListPermission(ctx context.Context, in *NoneReq, opts ...grpc.CallOption) (*ListPermissionResp, error) {
client := permission.NewPermissionServiceClient(m.cli.Conn())
return client.ListPermission(ctx, in, opts...)
}
// CheckPermissionByRole 透過角色 ID 來檢視權限
func (m *defaultPermissionService) CheckPermissionByRole(ctx context.Context, in *CheckPermissionByRoleReq, opts ...grpc.CallOption) (*PermissionResp, error) {
client := permission.NewPermissionServiceClient(m.cli.Conn())
return client.CheckPermissionByRole(ctx, in, opts...)
}
// GetPermissionStatusByPath 透過資源拿取角色的狀態
func (m *defaultPermissionService) GetPermissionStatusByPath(ctx context.Context, in *GetPermissionStatusByPathReq, opts ...grpc.CallOption) (*PermissionStatusItem, error) {
client := permission.NewPermissionServiceClient(m.cli.Conn())
return client.GetPermissionStatusByPath(ctx, in, opts...)
}

View File

@ -16,11 +16,19 @@ type (
AuthorizationReq = permission.AuthorizationReq
CancelOneTimeTokenReq = permission.CancelOneTimeTokenReq
CancelTokenReq = permission.CancelTokenReq
CheckPermissionByRoleReq = permission.CheckPermissionByRoleReq
CreateOneTimeTokenReq = permission.CreateOneTimeTokenReq
CreateOneTimeTokenResp = permission.CreateOneTimeTokenResp
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
DoTokenByUIDReq = permission.DoTokenByUIDReq
GetPermissionStatusByPathReq = permission.GetPermissionStatusByPathReq
ListPermissionResp = permission.ListPermissionResp
ListPermissionStatusResp = permission.ListPermissionStatusResp
NoneReq = permission.NoneReq
OKResp = permission.OKResp
PermissionItem = permission.PermissionItem
PermissionResp = permission.PermissionResp
PermissionStatusItem = permission.PermissionStatusItem
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
RefreshTokenReq = permission.RefreshTokenReq
RefreshTokenResp = permission.RefreshTokenResp

View File

@ -16,11 +16,19 @@ type (
AuthorizationReq = permission.AuthorizationReq
CancelOneTimeTokenReq = permission.CancelOneTimeTokenReq
CancelTokenReq = permission.CancelTokenReq
CheckPermissionByRoleReq = permission.CheckPermissionByRoleReq
CreateOneTimeTokenReq = permission.CreateOneTimeTokenReq
CreateOneTimeTokenResp = permission.CreateOneTimeTokenResp
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
DoTokenByUIDReq = permission.DoTokenByUIDReq
GetPermissionStatusByPathReq = permission.GetPermissionStatusByPathReq
ListPermissionResp = permission.ListPermissionResp
ListPermissionStatusResp = permission.ListPermissionStatusResp
NoneReq = permission.NoneReq
OKResp = permission.OKResp
PermissionItem = permission.PermissionItem
PermissionResp = permission.PermissionResp
PermissionStatusItem = permission.PermissionStatusItem
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
RefreshTokenReq = permission.RefreshTokenReq
RefreshTokenResp = permission.RefreshTokenResp

View File

@ -10,6 +10,6 @@ RedisCluster:
Type: cluster
Token:
Expired: 300
RefreshExpires: 86500
Expired: 300s
RefreshExpires: 86500s
Secret: gg88g88

View File

@ -6,6 +6,8 @@ option go_package="./permission";
// OKResp
message OKResp {}
// NoneReq
message NoneReq {}
// AuthorizationReq
message AuthorizationReq {
@ -156,8 +158,72 @@ service TokenService {
}
// --------------------------------------------------------------------------------
enum PermissionStatus {
PERMISSION_STATUS_NONE = 0; //
PERMISSION_STATUS_OPEN = 1;
PERMISSION_STATUS_CLOSE = 2;
}
message PermissionStatusItem {
int64 id =1;
int64 parent_id =2;
string name =3;
PermissionStatus status = 4;
bool approval = 5;
}
message ListPermissionStatusResp {
repeated PermissionStatusItem data = 1;
}
message PermissionItem{
int64 id = 1;
string name = 2;
string http_method = 3;
string http_path = 4;
optional PermissionItem parent= 5;
repeated PermissionItem children =6;
repeated int64 path_ids=7;
}
message ListPermissionResp {
repeated PermissionItem data = 1;
}
message CheckPermissionByRoleReq {
string role = 1;
string path = 2;
string method = 3;
}
message PermissionResp {
bool allow = 1;
string permission_name =2;
bool plain_code =3;
}
message GetPermissionStatusByPathReq {
string path = 2;
string method = 3;
}
service PermissionService {
// ListPermissionStatus
rpc ListPermissionStatus(NoneReq)returns(ListPermissionStatusResp);
// ListPermission
rpc ListPermission(NoneReq)returns(ListPermissionResp);
// CheckPermissionByRole ID
rpc CheckPermissionByRole(CheckPermissionByRoleReq)returns(PermissionResp);
// GetPermissionStatusByPath
rpc GetPermissionStatusByPath(GetPermissionStatusByPathReq)returns(PermissionStatusItem);
}
service RoleService {
rpc Ping(OKResp) returns(OKResp);
}
service PermissionService {}

34
go.mod
View File

@ -7,6 +7,10 @@ require (
github.com/go-playground/validator/v10 v10.22.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/google/uuid v1.6.0
github.com/mitchellh/mapstructure v1.5.0
github.com/open-policy-agent/opa v0.67.1
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.9.0
github.com/zeromicro/go-zero v1.7.0
go.uber.org/mock v0.4.0
google.golang.org/grpc v1.65.0
@ -14,16 +18,19 @@ require (
)
require (
github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/agnivade/levenshtein v1.1.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/fatih/color v1.17.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
@ -31,12 +38,14 @@ require (
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
@ -49,25 +58,32 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/openzipkin/zipkin-go v0.4.3 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/redis/go-redis/v9 v9.6.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/yashtewari/glob-intersection v0.2.0 // indirect
go.etcd.io/etcd/api/v3 v3.5.15 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect
go.etcd.io/etcd/client/v3 v3.5.15 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 // indirect
go.opentelemetry.io/otel/exporters/zipkin v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/automaxprocs v1.5.3 // indirect
@ -93,5 +109,5 @@ require (
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

View File

@ -13,6 +13,7 @@ import (
// full code 12009 只會有 系統以及錯誤碼category 是給系統判定用的
// 目前 Scope 以及分類要系統共用,係向的錯誤各自服務實作就好
// token error 方面
const (
TokenUnexpectedSigningErrorCode = iota + 1
TokenValidateErrorCode
@ -25,6 +26,11 @@ const (
RedisErrorCode
)
const (
PermissionNotFoundCode = iota + 30
PermissionGetDataErrorCode
)
// TokenUnexpectedSigningErr 30001 Token 簽名錯誤
func TokenUnexpectedSigningErr(msg string) *ers.Err {
mts.AppErrorMetrics.AddFailure("token", "token_unexpected_sign")
@ -63,3 +69,15 @@ func RedisError(msg string) *ers.Err {
mts.AppErrorMetrics.AddFailure("redis", "error")
return ers.NewErr(code.CloudEPPermission, code.CatInput, RedisErrorCode, msg)
}
// PermissionNotFoundError 30030 權限錯誤
func PermissionNotFoundError(msg string) *ers.Err {
// 看需要建立哪些 Metrics
return ers.NewErr(code.CloudEPPermission, code.Forbidden, PermissionNotFoundCode, msg)
}
// PermissionGetDataError 30031 解析權限時錯誤
func PermissionGetDataError(msg string) *ers.Err {
// 看需要建立哪些 Metrics
return ers.NewErr(code.CloudEPPermission, code.InvalidFormat, PermissionGetDataErrorCode, msg)
}

View File

@ -0,0 +1,8 @@
package domain
type PermissionType int8
const (
PermissionTypeBackendUser PermissionType = iota + 1
PermissionTypeFrontendUser
)

View File

@ -0,0 +1,45 @@
package usecase
import (
"context"
)
type OpaUseCase interface {
// CheckRBACPermission 確認有無權限
CheckRBACPermission(ctx context.Context, req CheckReq) (CheckOPAResp, error)
// LoadPolicy 將 Policy 從其他地方加載到 opa 的 policy 當中
LoadPolicy(ctx context.Context, input []Policy) error
GetPolicy(ctx context.Context) []map[string]any
}
type CheckReq struct {
ID string
Roles []string
Path string
Method string
}
type Grant struct {
ID string
Path string
Method string
}
type Policy struct {
Methods []string `json:"methods"`
Name string `json:"name"`
Path string `json:"path"`
Role string `json:"role"`
}
type RuleRequest struct {
Method string `json:"method"`
Path string `json:"path"`
Policies []Policy `json:"policies"`
Roles []string `json:"roles"`
}
type CheckOPAResp struct {
Allow bool `json:"allow"`
Request RuleRequest `json:"request"`
}

View File

@ -0,0 +1,22 @@
package entity
import "ark-permission/internal/domain"
type Permission struct {
ID int64 `gorm:"column:id"`
Parent int64 `gorm:"column:parent"`
Name string `gorm:"column:name"`
HTTPMethod string `gorm:"column:http_method"`
HTTPPath string `gorm:"column:http_path"`
Status int `gorm:"column:status"`
Type domain.PermissionType `gorm:"column:type"`
CreateTime int64 `gorm:"column:create_time;autoCreateTime"`
UpdateTime int64 `gorm:"column:update_time;autoUpdateTime"`
}
func (c *Permission) TableName() string {
return "permission"
}

View File

@ -1,7 +1,7 @@
package middleware
import (
ers "ark-permission/internal/lib/error"
ers "code.30cm.net/wanderland/library-go/errors"
"context"
"errors"
"time"

View File

@ -0,0 +1,31 @@
package permissionservicelogic
import (
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type CheckPermissionByRoleLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewCheckPermissionByRoleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CheckPermissionByRoleLogic {
return &CheckPermissionByRoleLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// CheckPermissionByRole 透過角色 ID 來檢視權限
func (l *CheckPermissionByRoleLogic) CheckPermissionByRole(in *permission.CheckPermissionByRoleReq) (*permission.PermissionResp, error) {
// todo: add your logic here and delete this line
return &permission.PermissionResp{}, nil
}

View File

@ -0,0 +1,31 @@
package permissionservicelogic
import (
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type GetPermissionStatusByPathLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewGetPermissionStatusByPathLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPermissionStatusByPathLogic {
return &GetPermissionStatusByPathLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// GetPermissionStatusByPath 透過資源拿取角色的狀態
func (l *GetPermissionStatusByPathLogic) GetPermissionStatusByPath(in *permission.GetPermissionStatusByPathReq) (*permission.PermissionStatusItem, error) {
// todo: add your logic here and delete this line
return &permission.PermissionStatusItem{}, nil
}

View File

@ -0,0 +1,31 @@
package permissionservicelogic
import (
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type ListPermissionLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewListPermissionLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListPermissionLogic {
return &ListPermissionLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// ListPermission 取得完整權限
func (l *ListPermissionLogic) ListPermission(in *permission.NoneReq) (*permission.ListPermissionResp, error) {
// todo: add your logic here and delete this line
return &permission.ListPermissionResp{}, nil
}

View File

@ -0,0 +1,31 @@
package permissionservicelogic
import (
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type ListPermissionStatusLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewListPermissionStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListPermissionStatusLogic {
return &ListPermissionStatusLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// ListPermissionStatus 取得狀態
func (l *ListPermissionStatusLogic) ListPermissionStatus(in *permission.NoneReq) (*permission.ListPermissionStatusResp, error) {
// todo: add your logic here and delete this line
return &permission.ListPermissionStatusResp{}, nil
}

View File

@ -4,7 +4,10 @@
package server
import (
"context"
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/logic/permissionservice"
"ark-permission/internal/svc"
)
@ -18,3 +21,27 @@ func NewPermissionServiceServer(svcCtx *svc.ServiceContext) *PermissionServiceSe
svcCtx: svcCtx,
}
}
// ListPermissionStatus 取得狀態
func (s *PermissionServiceServer) ListPermissionStatus(ctx context.Context, in *permission.NoneReq) (*permission.ListPermissionStatusResp, error) {
l := permissionservicelogic.NewListPermissionStatusLogic(ctx, s.svcCtx)
return l.ListPermissionStatus(in)
}
// ListPermission 取得完整權限
func (s *PermissionServiceServer) ListPermission(ctx context.Context, in *permission.NoneReq) (*permission.ListPermissionResp, error) {
l := permissionservicelogic.NewListPermissionLogic(ctx, s.svcCtx)
return l.ListPermission(in)
}
// CheckPermissionByRole 透過角色 ID 來檢視權限
func (s *PermissionServiceServer) CheckPermissionByRole(ctx context.Context, in *permission.CheckPermissionByRoleReq) (*permission.PermissionResp, error) {
l := permissionservicelogic.NewCheckPermissionByRoleLogic(ctx, s.svcCtx)
return l.CheckPermissionByRole(in)
}
// GetPermissionStatusByPath 透過資源拿取角色的狀態
func (s *PermissionServiceServer) GetPermissionStatusByPath(ctx context.Context, in *permission.GetPermissionStatusByPathReq) (*permission.PermissionStatusItem, error) {
l := permissionservicelogic.NewGetPermissionStatusByPathLogic(ctx, s.svcCtx)
return l.GetPermissionStatusByPath(in)
}