Skip to content

Commit bcf6c99

Browse files
author
Simon Emms
committed
[server]: add seats to the licensor.enabled call
1 parent ebb90c6 commit bcf6c99

File tree

3 files changed

+39
-29
lines changed

3 files changed

+39
-29
lines changed

components/server/ee/src/user/user-service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ export class UserServiceEE extends UserService {
2828
return this.eligibilityService.getDefaultWorkspaceTimeout(user, date);
2929
}
3030

31+
const userCount = await this.userDb.getUserCount(true);
32+
3133
// the self-hosted case
32-
if (!this.licenseEvaluator.isEnabled(Feature.FeatureSetTimeout)) {
34+
if (!this.licenseEvaluator.isEnabled(Feature.FeatureSetTimeout, userCount)) {
3335
return "30m";
3436
}
3537

components/server/ee/src/workspace/gitpod-server-impl.ts

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,10 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
152152
}
153153
}
154154

155-
protected requireEELicense(feature: Feature) {
156-
if (!this.licenseEvaluator.isEnabled(feature)) {
155+
protected async requireEELicense(feature: Feature) {
156+
const userCount = await this.userDB.getUserCount(true);
157+
158+
if (!this.licenseEvaluator.isEnabled(feature, userCount)) {
157159
throw new ResponseError(ErrorCodes.EE_LICENSE_REQUIRED, "enterprise license required");
158160
}
159161
}
@@ -181,7 +183,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
181183
traceAPIParams(ctx, { workspaceId, duration });
182184
traceWI(ctx, { workspaceId });
183185

184-
this.requireEELicense(Feature.FeatureSetTimeout);
186+
await this.requireEELicense(Feature.FeatureSetTimeout);
185187
const user = this.checkUser("setWorkspaceTimeout");
186188

187189
if (!WorkspaceTimeoutValues.includes(duration)) {
@@ -281,7 +283,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
281283
traceAPIParams(ctx, { workspaceId, level });
282284
traceWI(ctx, { workspaceId });
283285

284-
this.requireEELicense(Feature.FeatureWorkspaceSharing);
286+
await this.requireEELicense(Feature.FeatureWorkspaceSharing);
285287
this.checkAndBlockUser('controlAdmission');
286288

287289
const lvlmap = new Map<string, AdmissionLevel>();
@@ -317,7 +319,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
317319
const { workspaceId, dontWait } = options;
318320
traceWI(ctx, { workspaceId });
319321

320-
this.requireEELicense(Feature.FeatureSnapshot);
322+
await this.requireEELicense(Feature.FeatureSnapshot);
321323
const user = this.checkAndBlockUser("takeSnapshot");
322324

323325
const workspace = await this.guardSnaphotAccess(ctx, user.id, workspaceId);
@@ -371,7 +373,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
371373
async waitForSnapshot(ctx: TraceContext, snapshotId: string): Promise<void> {
372374
traceAPIParams(ctx, { snapshotId });
373375

374-
this.requireEELicense(Feature.FeatureSnapshot);
376+
await this.requireEELicense(Feature.FeatureSnapshot);
375377
const user = this.checkAndBlockUser("waitForSnapshot");
376378

377379
const snapshot = await this.workspaceDb.trace(ctx).findSnapshotById(snapshotId);
@@ -415,7 +417,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
415417
async adminGetUsers(ctx: TraceContext, req: AdminGetListRequest<User>): Promise<AdminGetListResult<User>> {
416418
traceAPIParams(ctx, { req: censor(req, "searchTerm") }); // searchTerm may contain PII
417419

418-
this.requireEELicense(Feature.FeatureAdminDashboard);
420+
await this.requireEELicense(Feature.FeatureAdminDashboard);
419421

420422
await this.guardAdminAccess("adminGetUsers", { req }, Permission.ADMIN_USERS);
421423

@@ -431,7 +433,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
431433
async adminGetUser(ctx: TraceContext, userId: string): Promise<User> {
432434
traceAPIParams(ctx, { userId });
433435

434-
this.requireEELicense(Feature.FeatureAdminDashboard);
436+
await this.requireEELicense(Feature.FeatureAdminDashboard);
435437

436438
await this.guardAdminAccess("adminGetUser", { id: userId }, Permission.ADMIN_USERS);
437439

@@ -451,7 +453,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
451453
async adminBlockUser(ctx: TraceContext, req: AdminBlockUserRequest): Promise<User> {
452454
traceAPIParams(ctx, { req });
453455

454-
this.requireEELicense(Feature.FeatureAdminDashboard);
456+
await this.requireEELicense(Feature.FeatureAdminDashboard);
455457

456458
await this.guardAdminAccess("adminBlockUser", { req }, Permission.ADMIN_USERS);
457459

@@ -478,7 +480,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
478480
async adminDeleteUser(ctx: TraceContext, userId: string): Promise<void> {
479481
traceAPIParams(ctx, { userId });
480482

481-
this.requireEELicense(Feature.FeatureAdminDashboard);
483+
await this.requireEELicense(Feature.FeatureAdminDashboard);
482484

483485
await this.guardAdminAccess("adminDeleteUser", { id: userId }, Permission.ADMIN_USERS);
484486

@@ -492,7 +494,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
492494
async adminModifyRoleOrPermission(ctx: TraceContext, req: AdminModifyRoleOrPermissionRequest): Promise<User> {
493495
traceAPIParams(ctx, { req });
494496

495-
this.requireEELicense(Feature.FeatureAdminDashboard);
497+
await this.requireEELicense(Feature.FeatureAdminDashboard);
496498

497499
await this.guardAdminAccess("adminModifyRoleOrPermission", { req }, Permission.ADMIN_USERS);
498500

@@ -521,7 +523,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
521523
async adminModifyPermanentWorkspaceFeatureFlag(ctx: TraceContext, req: AdminModifyPermanentWorkspaceFeatureFlagRequest): Promise<User> {
522524
traceAPIParams(ctx, { req });
523525

524-
this.requireEELicense(Feature.FeatureAdminDashboard);
526+
await this.requireEELicense(Feature.FeatureAdminDashboard);
525527

526528
await this.guardAdminAccess("adminModifyPermanentWorkspaceFeatureFlag", { req }, Permission.ADMIN_USERS);
527529
const target = await this.userDB.findUserById(req.id);
@@ -549,7 +551,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
549551
}
550552

551553
async adminGetTeamMembers(ctx: TraceContext, teamId: string): Promise<TeamMemberInfo[]> {
552-
this.requireEELicense(Feature.FeatureAdminDashboard);
554+
await this.requireEELicense(Feature.FeatureAdminDashboard);
553555
await this.guardAdminAccess("adminGetTeamMembers", { teamId }, Permission.ADMIN_WORKSPACES);
554556

555557
const team = await this.teamDB.findTeamById(teamId);
@@ -561,28 +563,28 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
561563
}
562564

563565
async adminGetTeams(ctx: TraceContext, req: AdminGetListRequest<Team>): Promise<AdminGetListResult<Team>> {
564-
this.requireEELicense(Feature.FeatureAdminDashboard);
566+
await this.requireEELicense(Feature.FeatureAdminDashboard);
565567
await this.guardAdminAccess("adminGetTeams", { req }, Permission.ADMIN_WORKSPACES);
566568

567569
return await this.teamDB.findTeams(req.offset, req.limit, req.orderBy, req.orderDir === "asc" ? "ASC" : "DESC", req.searchTerm as string);
568570
}
569571

570572
async adminGetTeamById(ctx: TraceContext, id: string): Promise<Team | undefined> {
571-
this.requireEELicense(Feature.FeatureAdminDashboard);
573+
await this.requireEELicense(Feature.FeatureAdminDashboard);
572574
await this.guardAdminAccess("adminGetTeamById", { id }, Permission.ADMIN_WORKSPACES);
573575
return await this.teamDB.findTeamById(id);
574576
}
575577

576578
async adminSetTeamMemberRole(ctx: TraceContext, teamId: string, userId: string, role: TeamMemberRole): Promise<void> {
577-
this.requireEELicense(Feature.FeatureAdminDashboard);
579+
await this.requireEELicense(Feature.FeatureAdminDashboard);
578580
await this.guardAdminAccess("adminSetTeamMemberRole", { teamId, userId, role }, Permission.ADMIN_WORKSPACES);
579581
return this.teamDB.setTeamMemberRole(userId, teamId, role);
580582
}
581583

582584
async adminGetWorkspaces(ctx: TraceContext, req: AdminGetWorkspacesRequest): Promise<AdminGetListResult<WorkspaceAndInstance>> {
583585
traceAPIParams(ctx, { req });
584586

585-
this.requireEELicense(Feature.FeatureAdminDashboard);
587+
await this.requireEELicense(Feature.FeatureAdminDashboard);
586588

587589
await this.guardAdminAccess("adminGetWorkspaces", { req }, Permission.ADMIN_WORKSPACES);
588590

@@ -592,7 +594,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
592594
async adminGetWorkspace(ctx: TraceContext, workspaceId: string): Promise<WorkspaceAndInstance> {
593595
traceAPIParams(ctx, { workspaceId });
594596

595-
this.requireEELicense(Feature.FeatureAdminDashboard);
597+
await this.requireEELicense(Feature.FeatureAdminDashboard);
596598

597599
await this.guardAdminAccess("adminGetWorkspace", { id: workspaceId }, Permission.ADMIN_WORKSPACES);
598600

@@ -606,7 +608,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
606608
async adminForceStopWorkspace(ctx: TraceContext, workspaceId: string): Promise<void> {
607609
traceAPIParams(ctx, { workspaceId });
608610

609-
this.requireEELicense(Feature.FeatureAdminDashboard);
611+
await this.requireEELicense(Feature.FeatureAdminDashboard);
610612

611613
await this.guardAdminAccess("adminForceStopWorkspace", { id: workspaceId }, Permission.ADMIN_WORKSPACES);
612614

@@ -619,7 +621,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
619621
async adminRestoreSoftDeletedWorkspace(ctx: TraceContext, workspaceId: string): Promise<void> {
620622
traceAPIParams(ctx, { workspaceId });
621623

622-
this.requireEELicense(Feature.FeatureAdminDashboard);
624+
await this.requireEELicense(Feature.FeatureAdminDashboard);
623625

624626
await this.guardAdminAccess("adminRestoreSoftDeletedWorkspace", { id: workspaceId }, Permission.ADMIN_WORKSPACES);
625627

@@ -643,13 +645,13 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
643645
}
644646

645647
async adminGetProjectsBySearchTerm(ctx: TraceContext, req: AdminGetListRequest<Project>): Promise<AdminGetListResult<Project>> {
646-
this.requireEELicense(Feature.FeatureAdminDashboard);
648+
await this.requireEELicense(Feature.FeatureAdminDashboard);
647649
await this.guardAdminAccess("adminGetProjectsBySearchTerm", { req }, Permission.ADMIN_PROJECTS);
648650
return await this.projectDB.findProjectsBySearchTerm(req.offset, req.limit, req.orderBy, req.orderDir === "asc" ? "ASC" : "DESC", req.searchTerm as string);
649651
}
650652

651653
async adminGetProjectById(ctx: TraceContext, id: string): Promise<Project | undefined> {
652-
this.requireEELicense(Feature.FeatureAdminDashboard);
654+
await this.requireEELicense(Feature.FeatureAdminDashboard);
653655
await this.guardAdminAccess("adminGetProjectById", { id }, Permission.ADMIN_PROJECTS);
654656
return await this.projectDB.findProjectById(id);
655657
}
@@ -780,7 +782,8 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
780782
default:
781783
}
782784
if (feature) {
783-
return this.licenseEvaluator.isEnabled(feature);
785+
const userCount = await this.userDB.getUserCount(true);
786+
return this.licenseEvaluator.isEnabled(feature, userCount);
784787
}
785788
return false;
786789
}
@@ -1543,7 +1546,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
15431546

15441547
async adminFindPrebuilds(ctx: TraceContext, params: FindPrebuildsParams): Promise<PrebuildWithStatus[]> {
15451548
traceAPIParams(ctx, { params });
1546-
this.requireEELicense(Feature.FeatureAdminDashboard);
1549+
await this.requireEELicense(Feature.FeatureAdminDashboard);
15471550
await this.guardAdminAccess("adminFindPrebuilds", { params }, Permission.ADMIN_PROJECTS);
15481551

15491552
return this.projectsService.findPrebuilds(params);

components/server/ee/src/workspace/workspace-factory.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,20 @@ import { Feature } from '@gitpod/licensor/lib/api';
1515
import { ResponseError } from 'vscode-jsonrpc';
1616
import { ErrorCodes } from '@gitpod/gitpod-protocol/lib/messaging/error';
1717
import { HostContextProvider } from '../../../src/auth/host-context-provider';
18+
import { UserDB } from '@gitpod/gitpod-db/lib';
1819

1920
@injectable()
2021
export class WorkspaceFactoryEE extends WorkspaceFactory {
2122

2223
@inject(LicenseEvaluator) protected readonly licenseEvaluator: LicenseEvaluator;
2324
@inject(HostContextProvider) protected readonly hostContextProvider: HostContextProvider;
2425

25-
protected requireEELicense(feature: Feature) {
26-
if (!this.licenseEvaluator.isEnabled(feature)) {
26+
@inject(UserDB) protected readonly userDB: UserDB;
27+
28+
protected async requireEELicense(feature: Feature) {
29+
const userCount = await this.userDB.getUserCount(true);
30+
31+
if (!this.licenseEvaluator.isEnabled(feature, userCount)) {
2732
throw new ResponseError(ErrorCodes.EE_LICENSE_REQUIRED, "enterprise license required");
2833
}
2934
}
@@ -39,7 +44,7 @@ export class WorkspaceFactoryEE extends WorkspaceFactory {
3944
}
4045

4146
protected async createForStartPrebuild(ctx: TraceContext, user: User, context: StartPrebuildContext, normalizedContextURL: string): Promise<Workspace> {
42-
this.requireEELicense(Feature.FeaturePrebuild);
47+
await this.requireEELicense(Feature.FeaturePrebuild);
4348
const span = TraceContext.startSpan("createForStartPrebuild", ctx);
4449

4550
try {
@@ -177,7 +182,7 @@ export class WorkspaceFactoryEE extends WorkspaceFactory {
177182
}
178183

179184
protected async createForPrebuiltWorkspace(ctx: TraceContext, user: User, context: PrebuiltWorkspaceContext, normalizedContextURL: string): Promise<Workspace> {
180-
this.requireEELicense(Feature.FeaturePrebuild);
185+
await this.requireEELicense(Feature.FeaturePrebuild);
181186
const span = TraceContext.startSpan("createForPrebuiltWorkspace", ctx);
182187

183188
try {

0 commit comments

Comments
 (0)