package permission

import (
	"context"
	"strings"

	"github.com/samber/lo"
	"google.golang.org/grpc"

	bffclusterv1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/bff/cluster_management/v1beta1"
	bffv1beta2 "github.com/tidbcloud/tidb-management-service/api/spec/bff/cluster_management/v1beta2"
	openapicommonv1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/common/v1beta1"
	openapidedicatedv1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/dedicated/v1beta1"
	openapifsv1beta2 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/fs/v1beta2"
	openapingv1beta2 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/nextgen/v1beta2"
	openapiserverlessv1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/serverless/v1beta1"
	openapizerov1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/zero/v1beta1"
	tidbmgmtservicev1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_mgmt_service/v1"
	permissionckr "github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/pkg/apimiddleware/authorization/permission/checker"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/pkg/common"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/grpc/metadata"
)

// NewPermissionCheckInterceptor is a grpc.UnaryServerInterceptor that checks if the user has the permission to access the resource.
// It parses the request body message and checks the permission using request meta.
// The request meta is generated by upstream service, such as mgmt portal.
func NewPermissionCheckInterceptor(checkCtx *permissionckr.CheckContext) grpc.UnaryServerInterceptor {
	return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
		// Get the permission checker.
		checker, ok := methodToCheckerMap[info.FullMethod]
		if !ok {
			// For tidb_cloud_open_api and bff APIs, return error if no checker is found.
			if strings.HasPrefix(info.FullMethod, "/tidb_cloud_open_api") || strings.HasPrefix(info.FullMethod, "/bff") {
				return nil, bizerr.New(bizerr.ErrCodePermission, "permission checker for method %s not found", info.FullMethod)
			}
			// For other APIs (including internalapi, proxy, core, etc.), skip permission check if no checker is found.
			// Set IsCheckPermission to true in request meta to indicate that permission check is skipped.
			ctx = metadata.AppendToIncomingMeta(ctx, &metadata.RequestMeta{IsCheckPermission: lo.ToPtr(true)})
			// Skip permission check.
			return handler(ctx, req)
		}

		// Check permission.
		ctx, req, err := checker.Check(ctx, checkCtx, req, info)
		if err != nil {
			return nil, err
		}

		// Call the handler.
		return handler(ctx, req)
	}
}

// methodToCheckerMap is a checker **register** for each method.
var methodToCheckerMap = map[string]permissionckr.Checker{
	// console API
	bffclusterv1beta1.ClusterService_GetCluster_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	bffclusterv1beta1.ClusterService_ListClusters_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	bffclusterv1beta1.ClusterService_AdvancedModifyDedicatedCluster_FullMethodName: permissionckr.NewClusterPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*bffclusterv1beta1.AdvancedModifyDedicatedClusterRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetCluster().GetClusterId(), nil
		},
	),
	bffclusterv1beta1.ClusterService_EstimatePrice_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	bffclusterv1beta1.ClusterService_CheckModificationRisks_FullMethodName: permissionckr.NewClusterPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*bffclusterv1beta1.CheckModificationRisksRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetCluster().GetClusterId(), nil
		},
	),

	// one console API
	bffv1beta2.RegionService_ListRegions_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	bffv1beta2.RegionService_ListCloudProviders_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	bffv1beta2.TiDBService_ListTidbs_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	bffv1beta2.TiDBService_GetTidb_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	bffv1beta2.TiDBService_GetClusterInventory_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	bffv1beta2.TiDBService_BindTags_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	bffv1beta2.TiDBService_UnbindTags_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	bffv1beta2.TiDBService_MoveTiDB_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	bffv1beta2.TiDBService_BatchMoveTiDBs_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	bffv1beta2.TiDBService_GetProjectMigrationTask_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	bffv1beta2.TiDBService_ApproveProjectMigrationTask_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),

	// Dedicated cluster service
	openapidedicatedv1beta1.ClusterService_CreateCluster_FullMethodName: permissionckr.NewCreateClusterPermissionChecker(
		func(req any) (map[string]string, error) {
			r, ok := req.(*openapidedicatedv1beta1.CreateClusterRequest)
			if !ok {
				return nil, bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetCluster().GetLabels(), nil
		},
	),
	openapidedicatedv1beta1.ClusterService_ListClusters_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.ClusterService_GetCluster_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	"/tidb_cloud_open_api.dedicated.v1beta1.ClusterService/BindTags": permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	"/tidb_cloud_open_api.dedicated.v1beta1.ClusterService/UnbindTags": permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.ClusterService_DeleteCluster_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.ClusterService_UpdateCluster_FullMethodName: permissionckr.NewClusterPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.UpdateClusterRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetCluster().GetClusterId(), nil
		},
	),
	openapidedicatedv1beta1.ClusterService_PauseCluster_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.ClusterService_ResumeCluster_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.ClusterService_ResetRootPassword_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.ClusterService_GetNodeInstance_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.ClusterService_ListNodeInstances_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.ClusterService_ShowNodeQuota_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapidedicatedv1beta1.ClusterService_GetLogRedactionPolicy_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.ClusterService_UpdateLogRedactionPolicy_FullMethodName: permissionckr.NewClusterPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.UpdateLogRedactionPolicyRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetLogRedactionPolicy().GetClusterId(), nil
		},
	),

	// Dedicated region service
	openapidedicatedv1beta1.RegionService_ListRegions_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.RegionService_GetRegion_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.RegionService_ListNodeSpecs_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.RegionService_GetNodeSpec_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.RegionService_ShowCloudProviders_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),

	// Dedicated private link service
	openapidedicatedv1beta1.PrivateEndpointConnectionService_GetPrivateLinkService_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		permissionckr.StdTidbGroupIdExtractor,
	),
	openapidedicatedv1beta1.PrivateEndpointConnectionService_CreatePrivateEndpointConnection_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		func(req any) (string, string, error) {
			r, ok := req.(*openapidedicatedv1beta1.CreatePrivateEndpointConnectionRequest)
			if !ok {
				return "", "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			tidbGroupIdStr := r.GetPrivateEndpointConnection().GetTidbNodeGroupId()
			if tidbGroupIdStr == "" {
				return "", "", bizerr.New(bizerr.ErrCodeParams, "tidb node group id is required")
			}
			return r.GetClusterId(), tidbGroupIdStr, nil
		},
	),
	// ListPrivateLinkConnections can list all connections under a project, across different clusters and TiDB groups.
	openapidedicatedv1beta1.PrivateEndpointConnectionService_ListPrivateEndpointConnections_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.PrivateEndpointConnectionService_GetPrivateEndpointConnection_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		permissionckr.StdTidbGroupIdExtractor,
	),
	openapidedicatedv1beta1.PrivateEndpointConnectionService_DeletePrivateEndpointConnection_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		permissionckr.StdTidbGroupIdExtractor,
	),

	// Dedicated vpc peering service
	openapidedicatedv1beta1.NetworkContainerService_CreateNetworkContainer_FullMethodName: permissionckr.NewProjectIdChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.CreateNetworkContainerRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetNetworkContainer().GetLabels()[common.ProjectIDLabelKey], nil
		},
	),
	openapidedicatedv1beta1.NetworkContainerService_CreateVpcPeering_FullMethodName: permissionckr.NewProjectIdChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.CreateVpcPeeringRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetVpcPeering().GetLabels()[common.ProjectIDLabelKey], nil
		},
	),
	openapidedicatedv1beta1.NetworkContainerService_ListNetworkContainers_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.NetworkContainerService_ListVpcPeerings_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.NetworkContainerService_GetNetworkContainer_FullMethodName: permissionckr.CheckFunc(
		permissionckr.NetworkContainerIdChecker,
	),
	openapidedicatedv1beta1.NetworkContainerService_DeleteNetworkContainer_FullMethodName: permissionckr.CheckFunc(
		permissionckr.NetworkContainerIdChecker,
	),
	openapidedicatedv1beta1.NetworkContainerService_GetVpcPeering_FullMethodName: permissionckr.CheckFunc(
		permissionckr.VpcPeeringIdChecker,
	),
	openapidedicatedv1beta1.NetworkContainerService_DeleteVpcPeering_FullMethodName: permissionckr.CheckFunc(
		permissionckr.VpcPeeringIdChecker,
	),

	// Dedicated database AuditLog  service
	openapidedicatedv1beta1.DatabaseAuditLogService_GetAuditLogConfig_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.DatabaseAuditLogService_UpdateAuditLogConfig_FullMethodName: permissionckr.NewClusterPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.UpdateAuditLogConfigRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetAuditLogConfig().GetClusterId(), nil
		},
	),
	openapidedicatedv1beta1.DatabaseAuditLogService_CreateAuditLogFilterRule_FullMethodName: permissionckr.NewClusterPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.CreateAuditLogFilterRuleRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetAuditLogFilterRule().GetClusterId(), nil
		},
	),
	openapidedicatedv1beta1.DatabaseAuditLogService_GetAuditLogFilterRule_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.DatabaseAuditLogService_ListAuditLogFilterRules_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.DatabaseAuditLogService_DeleteAuditLogFilterRule_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.DatabaseAuditLogService_ReplaceAuditLogFilterRule_FullMethodName: permissionckr.NewClusterPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.ReplaceAuditLogFilterRuleRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetAuditLogFilterRule().GetClusterId(), nil
		},
	),
	openapidedicatedv1beta1.DatabaseAuditLogService_ShowObjectStorageAccessIamPrincipal_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.DatabaseAuditLogService_QueryAuditLogFiles_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapidedicatedv1beta1.DatabaseAuditLogService_GenerateAuditLogFileDownloadAddress_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),

	// Dedicated customer managed encryption key service
	openapidedicatedv1beta1.CustomerManagedEncryptionKeyService_CreateCustomerManagedEncryptionKey_FullMethodName: permissionckr.NewProjectIdChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.CreateCustomerManagedEncryptionKeyRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetCustomerManagedEncryptionKey().GetProjectId(), nil
		},
	),
	openapidedicatedv1beta1.CustomerManagedEncryptionKeyService_GetCustomerManagedEncryptionKey_FullMethodName: permissionckr.CheckFunc(
		permissionckr.CmekIdChecker,
	),
	openapidedicatedv1beta1.CustomerManagedEncryptionKeyService_ListCustomerManagedEncryptionKeys_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.CustomerManagedEncryptionKeyService_DeleteCustomerManagedEncryptionKey_FullMethodName: permissionckr.CheckFunc(
		permissionckr.CmekIdChecker,
	),
	openapidedicatedv1beta1.CustomerManagedEncryptionKeyService_ShowCmekAccessIamPrincipal_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),

	// Dedicated tidb node group service
	openapidedicatedv1beta1.TidbNodeGroupService_CreateTidbNodeGroup_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		func(req any) (string, string, error) {
			r, ok := req.(*openapidedicatedv1beta1.CreateTidbNodeGroupRequest)
			if !ok {
				return "", "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetTidbNodeGroup().GetClusterId(), "", nil
		},
	),
	openapidedicatedv1beta1.TidbNodeGroupService_GetTidbNodeGroup_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		permissionckr.StdTidbGroupIdExtractor,
	),
	openapidedicatedv1beta1.TidbNodeGroupService_ListTidbNodeGroups_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	), // only check cluster permission
	openapidedicatedv1beta1.TidbNodeGroupService_UpdateTidbNodeGroup_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		func(req any) (string, string, error) {
			r, ok := req.(*openapidedicatedv1beta1.UpdateTidbNodeGroupRequest)
			if !ok {
				return "", "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			tidbGroupIdStr := r.GetTidbNodeGroup().GetTidbNodeGroupId()
			if tidbGroupIdStr == "" {
				return "", "", bizerr.New(bizerr.ErrCodeParams, "tidb node group id is required")
			}
			return r.GetTidbNodeGroup().GetClusterId(), tidbGroupIdStr, nil
		},
	),
	openapidedicatedv1beta1.TidbNodeGroupService_DeleteTidbNodeGroup_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		permissionckr.StdTidbGroupIdExtractor,
	),
	openapidedicatedv1beta1.TidbNodeGroupService_GetPublicEndpointSetting_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		permissionckr.StdTidbGroupIdExtractor,
	),
	openapidedicatedv1beta1.TidbNodeGroupService_UpdatePublicEndpointSetting_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		func(req any) (string, string, error) {
			r, ok := req.(*openapidedicatedv1beta1.UpdatePublicEndpointSettingRequest)
			if !ok {
				return "", "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			tidbGroupIdStr := r.GetPublicEndpointSetting().GetTidbNodeGroupId()
			if tidbGroupIdStr == "" {
				return "", "", bizerr.New(bizerr.ErrCodeParams, "tidb node group id is required")
			}
			return r.GetClusterId(), tidbGroupIdStr, nil
		},
	),
	openapidedicatedv1beta1.TidbNodeGroupService_GetPrivateLinkIPAddressTypeSetting_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		permissionckr.StdTidbGroupIdExtractor,
	),
	openapidedicatedv1beta1.TidbNodeGroupService_UpdatePrivateLinkIPAddressTypeSetting_FullMethodName: permissionckr.NewTidbGroupPermissionChecker(
		permissionckr.StdTidbGroupIdExtractor,
	),

	// Dedicated maintenance window service
	openapidedicatedv1beta1.MaintenanceService_ListMaintenanceTasks_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.MaintenanceService_UpdateMaintenanceTask_FullMethodName: permissionckr.NewMaintenanceTaskIdChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.UpdateMaintenanceTaskRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetMaintenanceTask().GetMaintenanceTaskId(), nil
		},
	),
	openapidedicatedv1beta1.MaintenanceService_GetMaintenanceTask_FullMethodName: permissionckr.NewMaintenanceTaskIdChecker(
		permissionckr.StdMaintenanceTaskIdExtractor,
	),
	openapidedicatedv1beta1.MaintenanceService_GetMaintenanceWindow_FullMethodName: permissionckr.NewProjectIdChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.GetMaintenanceWindowRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			mwID := r.GetMaintenanceWindowId()
			if mwID == "" {
				return "", bizerr.New(bizerr.ErrCodeParams, "maintenance window id is required")
			}
			if !strings.HasPrefix(mwID, "project-") {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid maintenance window id format")
			}
			projectID := strings.TrimPrefix(mwID, "project-")
			if projectID == "" {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid maintenance window id format")
			}
			return projectID, nil
		},
	),
	openapidedicatedv1beta1.MaintenanceService_ListMaintenanceWindows_FullMethodName: permissionckr.NewProjectIdChecker(
		permissionckr.StdProjectIdExtractor,
	),
	openapidedicatedv1beta1.MaintenanceService_UpdateMaintenanceWindow_FullMethodName: permissionckr.NewProjectIdChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapidedicatedv1beta1.UpdateMaintenanceWindowRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			if r.GetMaintenanceWindow() == nil {
				return "", bizerr.New(bizerr.ErrCodeParams, "maintenance window is required")
			}
			mwID := r.GetMaintenanceWindow().GetMaintenanceWindowId()
			if mwID == "" {
				return "", bizerr.New(bizerr.ErrCodeParams, "maintenance window id is required")
			}
			if !strings.HasPrefix(mwID, "project-") {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid maintenance window id format")
			}
			projectID := strings.TrimPrefix(mwID, "project-")
			if projectID == "" {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid maintenance window id format")
			}
			return projectID, nil
		},
	),

	// Serverless cluster service
	// v1beta1
	openapiserverlessv1beta1.ClusterService_CreateCluster_FullMethodName: permissionckr.NewCreateClusterPermissionChecker(
		func(req any) (map[string]string, error) {
			r, ok := req.(*openapiserverlessv1beta1.CreateClusterRequest)
			if !ok {
				return nil, bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetCluster().GetLabels(), nil
		},
	),
	openapiserverlessv1beta1.ClusterService_ClaimClusterFromZero_FullMethodName: permissionckr.NewCreateClusterPermissionChecker(
		func(req any) (map[string]string, error) {
			r, ok := req.(*openapiserverlessv1beta1.ClaimClusterFromZeroRequest)
			if !ok {
				return nil, bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetCluster().GetLabels(), nil
		},
	),
	openapiserverlessv1beta1.ClusterService_ListClusters_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ClusterService_GetCluster_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	"/tidb_cloud_open_api.serverless.v1beta1.ClusterService/BindTags": permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	"/tidb_cloud_open_api.serverless.v1beta1.ClusterService/UnbindTags": permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapiserverlessv1beta1.ClusterService_DeleteCluster_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapiserverlessv1beta1.ClusterService_PartialUpdateCluster_FullMethodName: permissionckr.NewClusterPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapiserverlessv1beta1.PartialUpdateClusterRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetCluster().GetClusterId(), nil
		},
	),
	openapiserverlessv1beta1.ClusterService_ChangeRootPassword_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapiserverlessv1beta1.ClusterService_RotateRootPassword_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapiserverlessv1beta1.ClusterService_RedeemRootPassword_FullMethodName: permissionckr.NewClusterPermissionChecker(
		permissionckr.StdClusterIdExtractor,
	),
	openapiserverlessv1beta1.ClusterService_ListRegions_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ClusterService_ListCloudProviders_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ClusterService_BatchCreateClusters_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ClusterService_BatchGetClusters_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ClusterService_BatchDeleteClusters_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ClusterService_TakeoverClusterFromPool_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ShadowPoolService_CreateShadowPool_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ShadowPoolService_ListShadowPools_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ShadowPoolService_GetShadowPool_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ShadowPoolService_DeleteShadowPool_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ShadowPoolService_UpdateShadowPool_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ShadowPoolService_ReplaceShadowPoolInitSqls_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapiserverlessv1beta1.ShadowPoolService_ReplaceShadowPoolInstanceDemand_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),

	// internal api
	tidbmgmtservicev1.ClusterService_DeleteCluster_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ApikeyChecker,
	),
	tidbmgmtservicev1.ClusterService_CleanClusters_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ApikeyChecker,
	),
	tidbmgmtservicev1.ClusterService_CreateClusterWithClusterConfiguration_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	tidbmgmtservicev1.BackupService_OverrideFlexibleBackupRetention_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ApikeyChecker,
	),
	tidbmgmtservicev1.FsRegionService_CreateFsRegion_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ApikeyChecker,
	),
	tidbmgmtservicev1.FsRegionService_UpdateFsRegion_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ApikeyChecker,
	),
	tidbmgmtservicev1.FsRegionService_ListFsRegions_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ApikeyChecker,
	),
	tidbmgmtservicev1.FsRegionService_GetFsRegion_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ApikeyChecker,
	),

	// nextgen api
	openapingv1beta2.TidbService_CreateTidb_FullMethodName: permissionckr.ComposeCheckers(
		permissionckr.NewProjectIdChecker(
			func(req any) (string, error) {
				r, ok := req.(*openapingv1beta2.CreateTidbRequest)
				if !ok {
					return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
				}
				if r.GetTidb() == nil {
					return "", bizerr.New(bizerr.ErrCodeParams, "tidb is required")
				}
				if r.GetTidb().GetLabels() == nil {
					return "", nil
				}
				return r.GetTidb().GetLabels()[common.ProjectIDLabelKey], nil
			},
		),
		permissionckr.NewOptionalBYOCResourcePoolPermissionChecker(
			func(req any) (string, bool, error) {
				r, ok := req.(*openapingv1beta2.CreateTidbRequest)
				if !ok || r.GetTidb() == nil {
					return "", false, bizerr.New(bizerr.ErrCodeParams, "tidb is required")
				}
				return r.GetTidb().GetResourcePoolId(),
					r.GetTidb().GetServicePlan() == openapicommonv1beta1.ServicePlan_BYOC,
					nil
			},
		),
	),
	openapingv1beta2.TidbService_ListTidbs_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.TidbService_GetTidb_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_ResumeTidb_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_BindTags_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_UnbindTags_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_UpdateTidb_FullMethodName: permissionckr.NewTidbPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapingv1beta2.UpdateTidbRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetTidb().GetTidbId(), nil
		},
	),
	openapingv1beta2.TidbService_DeleteTidb_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_ResetRootPassword_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_EstimatePrice_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.TidbService_CalculateMinRcu_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.TidbService_ListPremiumReservedCapacityOptions_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.TidbService_ListBackupPolicies_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_GetBackupSetting_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_UpdateBackupSetting_FullMethodName: permissionckr.NewTidbPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapingv1beta2.UpdateBackupSettingRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetBackupSetting().GetTidbId(), nil
		},
	),
	openapingv1beta2.TidbService_CreateTidbBackup_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_ListTidbBackups_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_DeleteTidbBackup_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_RestoreTidb_FullMethodName: permissionckr.ComposeCheckers(
		permissionckr.NewProjectIdChecker(
			func(req any) (string, error) {
				r, ok := req.(*openapingv1beta2.RestoreTidbRequest)
				if !ok {
					return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
				}
				if r.GetTidb() == nil {
					return "", bizerr.New(bizerr.ErrCodeParams, "tidb is required")
				}
				if r.GetTidb().GetLabels() == nil {
					return "", nil
				}
				return r.GetTidb().GetLabels()[common.ProjectIDLabelKey], nil
			},
		),
		permissionckr.NewOptionalBYOCResourcePoolPermissionChecker(
			func(req any) (string, bool, error) {
				r, ok := req.(*openapingv1beta2.RestoreTidbRequest)
				if !ok || r.GetTidb() == nil {
					return "", false, bizerr.New(bizerr.ErrCodeParams, "tidb is required")
				}
				return r.GetTidb().GetResourcePoolId(),
					r.GetTidb().GetServicePlan() == openapicommonv1beta1.ServicePlan_BYOC,
					nil
			},
		),
	),
	openapingv1beta2.TidbService_RestoreStatus_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_GetRestoreStatus_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_ValidateClassicBackup_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.TidbService_GetCloudProviderInfo_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.TidbService_GetCaCertificateDownloadUrl_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.BackupService_ListBackups_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.BackupService_DeleteBackup_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.BackupService_ListDeletedTidbs_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.ExportService_ListExports_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.ExportService_GetExport_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.ExportService_CreateExport_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.ExportService_DeleteExport_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.ExportService_CancelExport_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.PublicConnectionSettingService_GetPublicConnectionSetting_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.PublicConnectionSettingService_UpdatePublicConnectionSetting_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.ByocVpcPeeringService_ListVpcPeerings_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.ByocVpcPeeringService_GetVpcPeering_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.ByocVpcPeeringService_GetVpcPeeringAllowlistSetting_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.ByocVpcPeeringService_UpdateVpcPeeringAllowlistSetting_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.PlanReplayerService_GetPlanReplayerStatus_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.PlanReplayerService_UpdatePlanReplayerStatus_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.RegionService_ListRegions_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.RegionService_ListCloudProviders_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.RegionService_ListOpsAuditLogSettings_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.RegionService_ListRegionCapacities_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.RegionService_ListNodeSpecs_FullMethodName: permissionckr.NewOrganizationPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapingv1beta2.ListNodeSpecsRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetOrganizationId(), nil
		},
	),
	openapingv1beta2.RegionService_PlanResourcePoolCidr_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.RegionService_ValidateResourcePoolCidr_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.RegionService_ListByocVcpuPools_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.RegionService_GetByocSharedComponentScaleConstraints_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ResourcePoolIdChecker,
	),
	openapingv1beta2.RegionService_UpdateByocVcpuPool_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ResourcePoolIdChecker,
	),
	openapingv1beta2.RegionService_ScaleByocSharedComponents_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ResourcePoolIdChecker,
	),
	openapingv1beta2.ResourcePoolService_CreateResourcePool_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.ResourcePoolService_ListResourcePools_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.ResourcePoolService_GetResourcePool_FullMethodName: permissionckr.NewResourcePoolPermissionChecker(
		permissionckr.StdResourcePoolIDExtractor,
	),
	openapingv1beta2.ResourcePoolService_UpdateResourcePool_FullMethodName: permissionckr.NewResourcePoolPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapingv1beta2.UpdateResourcePoolRequest)
			if !ok || r.GetResourcePool() == nil {
				return "", bizerr.New(bizerr.ErrCodeParams, "resource_pool is required")
			}
			return r.GetResourcePool().GetResourcePoolId(), nil
		},
	),
	openapingv1beta2.ResourcePoolService_DeleteResourcePool_FullMethodName: permissionckr.NewResourcePoolPermissionChecker(
		permissionckr.StdResourcePoolIDExtractor,
	),
	openapingv1beta2.ResourcePoolService_ResumeResourcePool_FullMethodName: permissionckr.NewResourcePoolPermissionChecker(
		permissionckr.StdResourcePoolIDExtractor,
	),
	openapingv1beta2.ResourcePoolService_GetResourcePoolCapacityConstraints_FullMethodName: permissionckr.NewResourcePoolPermissionChecker(
		permissionckr.StdResourcePoolIDExtractor,
	),
	openapingv1beta2.ResourcePoolService_ResizeResourcePoolCapacity_FullMethodName: permissionckr.NewResourcePoolPermissionChecker(
		permissionckr.StdResourcePoolIDExtractor,
	),
	openapingv1beta2.ResourcePoolService_UpsertResourcePoolCloudResourceTags_FullMethodName: permissionckr.NewResourcePoolPermissionChecker(
		permissionckr.StdResourcePoolIDExtractor,
	),
	openapingv1beta2.PrivateEndpointConnectionService_GetPrivateLinkService_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.PrivateEndpointConnectionService_CreatePrivateEndpointConnection_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.PrivateEndpointConnectionService_ListPrivateEndpointConnections_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.PrivateEndpointConnectionService_GetPrivateEndpointConnection_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.PrivateEndpointConnectionService_DeletePrivateEndpointConnection_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.DatabaseAuditLogService_GetAuditLogSetting_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.DatabaseAuditLogService_UpdateAuditLogSetting_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.DatabaseAuditLogService_CreateAuditLogFilterRule_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.DatabaseAuditLogService_GetAuditLogFilterRule_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.DatabaseAuditLogService_ListAuditLogFilterRules_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.DatabaseAuditLogService_DeleteAuditLogFilterRule_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.DatabaseAuditLogService_UpdateAuditLogFilterRule_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.LogRedactionPolicyService_GetLogRedactionPolicy_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.LogRedactionPolicyService_UpdateLogRedactionPolicy_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),
	openapingv1beta2.QuotaService_ListQuotas_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.CustomerManagedEncryptionKeyService_GetCustomerManagedEncryptionKey_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.CustomerManagedEncryptionKeyService_VerifyCmekAccessIamPrincipal_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.CustomerManagedEncryptionKeyService_GetCmekAccessIamPrincipal_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.CustomerManagedEncryptionKeyService_ListCustomerManagedEncryptionKeys_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapingv1beta2.TidbService_UpdateTidbDualLayerEncryption_FullMethodName: permissionckr.NewTidbPermissionChecker(
		func(req any) (string, error) {
			r, ok := req.(*openapingv1beta2.UpdateTidbDualLayerEncryptionRequest)
			if !ok {
				return "", bizerr.New(bizerr.ErrCodeParams, "invalid request: req=%v", req)
			}
			return r.GetTidbDualLayerEncryption().GetTidbId(), nil
		},
	),
	openapingv1beta2.TidbService_GetTidbDualLayerEncryption_FullMethodName: permissionckr.NewTidbPermissionChecker(
		permissionckr.StdTidbIdExtractor,
	),

	// zero api checker
	openapizerov1beta1.ZeroInstanceService_AllocateZeroInstance_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ZeroPermissionCheckerFunc,
	),
	openapizerov1beta1.ZeroInstanceService_GetZeroInstance_FullMethodName: permissionckr.CheckFunc(
		permissionckr.ZeroPermissionCheckerFunc,
	),

	// fs api
	openapifsv1beta2.RegionService_ListRegions_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
	openapifsv1beta2.RegionService_GetRegion_FullMethodName: permissionckr.CheckFunc(
		permissionckr.DefaultPermissionCheckerFunc,
	),
}
