Skip to content

Commit

Permalink
[server]: add seats to the licensor.enabled call
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon Emms committed Mar 7, 2022
1 parent 449e489 commit 967a303
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 29 deletions.
4 changes: 3 additions & 1 deletion components/server/ee/src/user/user-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ export class UserServiceEE extends UserService {
return this.eligibilityService.getDefaultWorkspaceTimeout(user, date);
}

const userCount = await this.userDb.getUserCount(true);

// the self-hosted case
if (!this.licenseEvaluator.isEnabled(Feature.FeatureSetTimeout)) {
if (!this.licenseEvaluator.isEnabled(Feature.FeatureSetTimeout, userCount)) {
return "30m";
}

Expand Down
51 changes: 27 additions & 24 deletions components/server/ee/src/workspace/gitpod-server-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,10 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
}
}

protected requireEELicense(feature: Feature) {
if (!this.licenseEvaluator.isEnabled(feature)) {
protected async requireEELicense(feature: Feature) {
const userCount = await this.userDB.getUserCount(true);

if (!this.licenseEvaluator.isEnabled(feature, userCount)) {
throw new ResponseError(ErrorCodes.EE_LICENSE_REQUIRED, "enterprise license required");
}
}
Expand Down Expand Up @@ -181,7 +183,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
traceAPIParams(ctx, { workspaceId, duration });
traceWI(ctx, { workspaceId });

this.requireEELicense(Feature.FeatureSetTimeout);
await this.requireEELicense(Feature.FeatureSetTimeout);
const user = this.checkUser("setWorkspaceTimeout");

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

this.requireEELicense(Feature.FeatureWorkspaceSharing);
await this.requireEELicense(Feature.FeatureWorkspaceSharing);
this.checkAndBlockUser('controlAdmission');

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

this.requireEELicense(Feature.FeatureSnapshot);
await this.requireEELicense(Feature.FeatureSnapshot);
const user = this.checkAndBlockUser("takeSnapshot");

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

this.requireEELicense(Feature.FeatureSnapshot);
await this.requireEELicense(Feature.FeatureSnapshot);
const user = this.checkAndBlockUser("waitForSnapshot");

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

this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);

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

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

this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);

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

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

this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);

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

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

this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);

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

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

this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);

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

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

this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);

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

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

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

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

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

async adminGetTeamById(ctx: TraceContext, id: string): Promise<Team | undefined> {
this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);
await this.guardAdminAccess("adminGetTeamById", { id }, Permission.ADMIN_WORKSPACES);
return await this.teamDB.findTeamById(id);
}

async adminSetTeamMemberRole(ctx: TraceContext, teamId: string, userId: string, role: TeamMemberRole): Promise<void> {
this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);
await this.guardAdminAccess("adminSetTeamMemberRole", { teamId, userId, role }, Permission.ADMIN_WORKSPACES);
return this.teamDB.setTeamMemberRole(userId, teamId, role);
}

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

this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);

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

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

this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);

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

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

this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);

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

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

this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);

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

Expand All @@ -643,13 +645,13 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
}

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

async adminGetProjectById(ctx: TraceContext, id: string): Promise<Project | undefined> {
this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);
await this.guardAdminAccess("adminGetProjectById", { id }, Permission.ADMIN_PROJECTS);
return await this.projectDB.findProjectById(id);
}
Expand Down Expand Up @@ -800,7 +802,8 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
default:
}
if (feature) {
return this.licenseEvaluator.isEnabled(feature);
const userCount = await this.userDB.getUserCount(true);
return this.licenseEvaluator.isEnabled(feature, userCount);
}
return false;
}
Expand Down Expand Up @@ -1561,7 +1564,7 @@ export class GitpodServerEEImpl extends GitpodServerImpl {

async adminFindPrebuilds(ctx: TraceContext, params: FindPrebuildsParams): Promise<PrebuildWithStatus[]> {
traceAPIParams(ctx, { params });
this.requireEELicense(Feature.FeatureAdminDashboard);
await this.requireEELicense(Feature.FeatureAdminDashboard);
await this.guardAdminAccess("adminFindPrebuilds", { params }, Permission.ADMIN_PROJECTS);

return this.projectsService.findPrebuilds(params);
Expand Down
13 changes: 9 additions & 4 deletions components/server/ee/src/workspace/workspace-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,20 @@ import { ResponseError } from 'vscode-jsonrpc';
import { ErrorCodes } from '@gitpod/gitpod-protocol/lib/messaging/error';
import { HostContextProvider } from '../../../src/auth/host-context-provider';
import { RepoURL } from '../../../src/repohost';
import { UserDB } from '@gitpod/gitpod-db/lib';

@injectable()
export class WorkspaceFactoryEE extends WorkspaceFactory {

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

protected requireEELicense(feature: Feature) {
if (!this.licenseEvaluator.isEnabled(feature)) {
@inject(UserDB) protected readonly userDB: UserDB;

protected async requireEELicense(feature: Feature) {
const userCount = await this.userDB.getUserCount(true);

if (!this.licenseEvaluator.isEnabled(feature, userCount)) {
throw new ResponseError(ErrorCodes.EE_LICENSE_REQUIRED, "enterprise license required");
}
}
Expand All @@ -40,7 +45,7 @@ export class WorkspaceFactoryEE extends WorkspaceFactory {
}

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

try {
Expand Down Expand Up @@ -196,7 +201,7 @@ export class WorkspaceFactoryEE extends WorkspaceFactory {
}

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

try {
Expand Down

0 comments on commit 967a303

Please sign in to comment.