Skip to content

Commit b94fa7f

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

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
}
@@ -800,7 +802,8 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
800802
default:
801803
}
802804
if (feature) {
803-
return this.licenseEvaluator.isEnabled(feature);
805+
const userCount = await this.userDB.getUserCount(true);
806+
return this.licenseEvaluator.isEnabled(feature, userCount);
804807
}
805808
return false;
806809
}
@@ -1561,7 +1564,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
15611564

15621565
async adminFindPrebuilds(ctx: TraceContext, params: FindPrebuildsParams): Promise<PrebuildWithStatus[]> {
15631566
traceAPIParams(ctx, { params });
1564-
this.requireEELicense(Feature.FeatureAdminDashboard);
1567+
await this.requireEELicense(Feature.FeatureAdminDashboard);
15651568
await this.guardAdminAccess("adminFindPrebuilds", { params }, Permission.ADMIN_PROJECTS);
15661569

15671570
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
@@ -16,15 +16,20 @@ import { ResponseError } from 'vscode-jsonrpc';
1616
import { ErrorCodes } from '@gitpod/gitpod-protocol/lib/messaging/error';
1717
import { HostContextProvider } from '../../../src/auth/host-context-provider';
1818
import { RepoURL } from '../../../src/repohost';
19+
import { UserDB } from '@gitpod/gitpod-db/lib';
1920

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

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

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

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

4651
try {
@@ -196,7 +201,7 @@ export class WorkspaceFactoryEE extends WorkspaceFactory {
196201
}
197202

198203
protected async createForPrebuiltWorkspace(ctx: TraceContext, user: User, context: PrebuiltWorkspaceContext, normalizedContextURL: string): Promise<Workspace> {
199-
this.requireEELicense(Feature.FeaturePrebuild);
204+
await this.requireEELicense(Feature.FeaturePrebuild);
200205
const span = TraceContext.startSpan("createForPrebuiltWorkspace", ctx);
201206

202207
try {

0 commit comments

Comments
 (0)