chore: add feature matrix

This commit is contained in:
Steven 2023-09-22 08:15:18 +08:00
parent 92fba82927
commit d0a25e3ab2
5 changed files with 53 additions and 12 deletions

View File

@ -34,7 +34,7 @@ func NewAPIV2Service(secret string, profile *profile.Profile, store *store.Store
), ),
) )
apiv2pb.RegisterSubscriptionServiceServer(grpcServer, NewSubscriptionService(profile, store, licenseService)) apiv2pb.RegisterSubscriptionServiceServer(grpcServer, NewSubscriptionService(profile, store, licenseService))
apiv2pb.RegisterWorkspaceServiceServer(grpcServer, NewWorkspaceService(profile, store)) apiv2pb.RegisterWorkspaceServiceServer(grpcServer, NewWorkspaceService(profile, store, licenseService))
apiv2pb.RegisterUserServiceServer(grpcServer, NewUserService(secret, store)) apiv2pb.RegisterUserServiceServer(grpcServer, NewUserService(secret, store))
apiv2pb.RegisterUserSettingServiceServer(grpcServer, NewUserSettingService(store)) apiv2pb.RegisterUserSettingServiceServer(grpcServer, NewUserSettingService(store))
apiv2pb.RegisterShortcutServiceServer(grpcServer, NewShortcutService(secret, store)) apiv2pb.RegisterShortcutServiceServer(grpcServer, NewShortcutService(secret, store))

View File

@ -6,6 +6,7 @@ import (
apiv2pb "github.com/boojack/slash/proto/gen/api/v2" apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
storepb "github.com/boojack/slash/proto/gen/store" storepb "github.com/boojack/slash/proto/gen/store"
"github.com/boojack/slash/server/profile" "github.com/boojack/slash/server/profile"
"github.com/boojack/slash/server/service/license"
"github.com/boojack/slash/store" "github.com/boojack/slash/store"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
@ -16,13 +17,15 @@ type WorkspaceService struct {
Profile *profile.Profile Profile *profile.Profile
Store *store.Store Store *store.Store
LicenseService *license.LicenseService
} }
// NewWorkspaceService creates a new WorkspaceService. // NewWorkspaceService creates a new WorkspaceService.
func NewWorkspaceService(profile *profile.Profile, store *store.Store) *WorkspaceService { func NewWorkspaceService(profile *profile.Profile, store *store.Store, licenseService *license.LicenseService) *WorkspaceService {
return &WorkspaceService{ return &WorkspaceService{
Profile: profile, Profile: profile,
Store: store, Store: store,
LicenseService: licenseService,
} }
} }
@ -117,6 +120,10 @@ func (s *WorkspaceService) UpdateWorkspaceSetting(ctx context.Context, request *
return nil, status.Errorf(codes.Internal, "failed to update workspace setting: %v", err) return nil, status.Errorf(codes.Internal, "failed to update workspace setting: %v", err)
} }
} else if path == "custom_style" { } else if path == "custom_style" {
if !s.LicenseService.IsFeatureEnabled(license.FeatureTypeCustomeStyle) {
return nil, status.Errorf(codes.PermissionDenied, "feature custom style is not available")
}
if _, err := s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{ if _, err := s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE, Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE,
Value: &storepb.WorkspaceSetting_CustomStyle{ Value: &storepb.WorkspaceSetting_CustomStyle{

View File

@ -112,7 +112,11 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
return s, nil return s, nil
} }
func (s *Server) Start(_ context.Context) error { func (s *Server) Start(ctx context.Context) error {
// Load subscription.
if _, err := s.licenseService.LoadSubscription(ctx); err != nil {
println("failed to load subscription", err)
}
// Start gRPC server. // Start gRPC server.
listen, err := net.Listen("tcp", fmt.Sprintf(":%d", s.Profile.Port+1)) listen, err := net.Listen("tcp", fmt.Sprintf(":%d", s.Profile.Port+1))
if err != nil { if err != nil {

View File

@ -0,0 +1,21 @@
package license
type FeatureType string
const (
// Accounts.
// FeatureTypeUnlimitedAccounts allows the user to create unlimited accounts.
FeatureTypeUnlimitedAccounts FeatureType = "unlimited_accounts"
// Customization.
// FeatureTypeCustomStyle allows the user to customize the style.
FeatureTypeCustomeStyle FeatureType = "custom_style"
)
// FeatureMatrix is a matrix of features in [Free, Pro].
var FeatureMatrix = map[FeatureType][2]bool{
FeatureTypeUnlimitedAccounts: {false, true},
FeatureTypeCustomeStyle: {false, true},
}

View File

@ -15,7 +15,8 @@ import (
type LicenseService struct { type LicenseService struct {
Profile *profile.Profile Profile *profile.Profile
Store *store.Store Store *store.Store
CachedSubscription *apiv2pb.Subscription
cachedSubscription *apiv2pb.Subscription
} }
// NewLicenseService creates a new LicenseService. // NewLicenseService creates a new LicenseService.
@ -23,7 +24,7 @@ func NewLicenseService(profile *profile.Profile, store *store.Store) *LicenseSer
return &LicenseService{ return &LicenseService{
Profile: profile, Profile: profile,
Store: store, Store: store,
CachedSubscription: &apiv2pb.Subscription{ cachedSubscription: &apiv2pb.Subscription{
Plan: apiv2pb.PlanType_FREE, Plan: apiv2pb.PlanType_FREE,
}, },
} }
@ -66,7 +67,7 @@ func (s *LicenseService) LoadSubscription(ctx context.Context) (*apiv2pb.Subscri
} }
subscription.StartedTime = timestamppb.New(startedTime) subscription.StartedTime = timestamppb.New(startedTime)
} }
s.CachedSubscription = subscription s.cachedSubscription = subscription
return subscription, nil return subscription, nil
} }
@ -92,3 +93,11 @@ func (s *LicenseService) UpdateSubscription(ctx context.Context, licenseKey stri
} }
return s.LoadSubscription(ctx) return s.LoadSubscription(ctx)
} }
func (s *LicenseService) IsFeatureEnabled(feature FeatureType) bool {
matrix, ok := FeatureMatrix[feature]
if !ok {
return false
}
return matrix[s.cachedSubscription.Plan-1]
}