Skip to content

Commit ef8b87f

Browse files
committed
[server] Move some admin rpcs to non EE
1 parent 096d3eb commit ef8b87f

File tree

2 files changed

+196
-288
lines changed

2 files changed

+196
-288
lines changed

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

Lines changed: 0 additions & 263 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,9 @@ import {
1212
AdminGetListRequest,
1313
User,
1414
Team,
15-
TeamMemberInfo,
1615
AdminGetListResult,
1716
Permission,
1817
AdminBlockUserRequest,
19-
AdminModifyRoleOrPermissionRequest,
20-
RoleOrPermission,
21-
AdminModifyPermanentWorkspaceFeatureFlagRequest,
22-
UserFeatureSettings,
23-
AdminGetWorkspacesRequest,
24-
WorkspaceAndInstance,
2518
GetWorkspaceTimeoutResult,
2619
WorkspaceTimeoutDuration,
2720
SetWorkspaceTimeoutResult,
@@ -38,7 +31,6 @@ import {
3831
StartPrebuildResult,
3932
ClientHeaderFields,
4033
FindPrebuildsParams,
41-
TeamMemberRole,
4234
WORKSPACE_TIMEOUT_DEFAULT_SHORT,
4335
PrebuildEvent,
4436
OpenPrebuildContext,
@@ -56,7 +48,6 @@ import { log, LogContext } from "@gitpod/gitpod-protocol/lib/util/logging";
5648
import { LicenseValidationResult } from "@gitpod/gitpod-protocol/lib/license-protocol";
5749
import { PrebuildManager } from "../prebuilds/prebuild-manager";
5850
import { GuardedCostCenter, ResourceAccessGuard, ResourceAccessOp } from "../../../src/auth/resource-access";
59-
import { BlockedRepository } from "@gitpod/gitpod-protocol/lib/blocked-repositories-protocol";
6051
import { CostCenterJSON, ListUsageRequest, ListUsageResponse } from "@gitpod/gitpod-protocol/lib/usage";
6152
import {
6253
CostCenter,
@@ -429,260 +420,6 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
429420
return this.censorUser(targetUser);
430421
}
431422

432-
async adminVerifyUser(ctx: TraceContext, userId: string): Promise<User> {
433-
await this.guardAdminAccess("adminVerifyUser", { id: userId }, Permission.ADMIN_USERS);
434-
try {
435-
const user = await this.userDB.findUserById(userId);
436-
if (!user) {
437-
throw new ResponseError(ErrorCodes.NOT_FOUND, `No user with id ${userId} found.`);
438-
}
439-
this.verificationService.markVerified(user);
440-
await this.userDB.updateUserPartial(user);
441-
return user;
442-
} catch (e) {
443-
throw new ResponseError(ErrorCodes.INTERNAL_SERVER_ERROR, e.toString());
444-
}
445-
}
446-
447-
async adminDeleteUser(ctx: TraceContext, userId: string): Promise<void> {
448-
traceAPIParams(ctx, { userId });
449-
450-
await this.guardAdminAccess("adminDeleteUser", { id: userId }, Permission.ADMIN_USERS);
451-
452-
try {
453-
await this.userDeletionService.deleteUser(userId);
454-
} catch (e) {
455-
throw new ResponseError(ErrorCodes.INTERNAL_SERVER_ERROR, e.toString());
456-
}
457-
}
458-
459-
async adminGetBlockedRepositories(
460-
ctx: TraceContext,
461-
req: AdminGetListRequest<BlockedRepository>,
462-
): Promise<AdminGetListResult<BlockedRepository>> {
463-
traceAPIParams(ctx, { req: censor(req, "searchTerm") }); // searchTerm may contain PII
464-
465-
await this.guardAdminAccess("adminGetBlockedRepositories", { req }, Permission.ADMIN_USERS);
466-
467-
try {
468-
const res = await this.blockedRepostoryDB.findAllBlockedRepositories(
469-
req.offset,
470-
req.limit,
471-
req.orderBy,
472-
req.orderDir === "asc" ? "ASC" : "DESC",
473-
req.searchTerm,
474-
);
475-
return res;
476-
} catch (e) {
477-
throw new ResponseError(ErrorCodes.INTERNAL_SERVER_ERROR, e.toString());
478-
}
479-
}
480-
481-
async adminCreateBlockedRepository(
482-
ctx: TraceContext,
483-
urlRegexp: string,
484-
blockUser: boolean,
485-
): Promise<BlockedRepository> {
486-
traceAPIParams(ctx, { urlRegexp, blockUser });
487-
488-
await this.guardAdminAccess("adminCreateBlockedRepository", { urlRegexp, blockUser }, Permission.ADMIN_USERS);
489-
490-
return await this.blockedRepostoryDB.createBlockedRepository(urlRegexp, blockUser);
491-
}
492-
493-
async adminDeleteBlockedRepository(ctx: TraceContext, id: number): Promise<void> {
494-
traceAPIParams(ctx, { id });
495-
496-
await this.guardAdminAccess("adminDeleteBlockedRepository", { id }, Permission.ADMIN_USERS);
497-
498-
await this.blockedRepostoryDB.deleteBlockedRepository(id);
499-
}
500-
501-
async adminModifyRoleOrPermission(ctx: TraceContext, req: AdminModifyRoleOrPermissionRequest): Promise<User> {
502-
traceAPIParams(ctx, { req });
503-
504-
await this.guardAdminAccess("adminModifyRoleOrPermission", { req }, Permission.ADMIN_USERS);
505-
506-
const target = await this.userDB.findUserById(req.id);
507-
if (!target) {
508-
throw new ResponseError(ErrorCodes.NOT_FOUND, "not found");
509-
}
510-
511-
const rolesOrPermissions = new Set((target.rolesOrPermissions || []) as string[]);
512-
req.rpp.forEach((e) => {
513-
if (e.add) {
514-
rolesOrPermissions.add(e.r as string);
515-
} else {
516-
rolesOrPermissions.delete(e.r as string);
517-
}
518-
});
519-
target.rolesOrPermissions = Array.from(rolesOrPermissions.values()) as RoleOrPermission[];
520-
521-
await this.userDB.storeUser(target);
522-
// For some reason, neither returning the result of `this.userDB.storeUser(target)` nor returning `target` work.
523-
// The response never arrives the caller.
524-
// Returning the following works at the cost of an additional DB query:
525-
return this.censorUser((await this.userDB.findUserById(req.id))!);
526-
}
527-
528-
async adminModifyPermanentWorkspaceFeatureFlag(
529-
ctx: TraceContext,
530-
req: AdminModifyPermanentWorkspaceFeatureFlagRequest,
531-
): Promise<User> {
532-
traceAPIParams(ctx, { req });
533-
534-
await this.guardAdminAccess("adminModifyPermanentWorkspaceFeatureFlag", { req }, Permission.ADMIN_USERS);
535-
const target = await this.userDB.findUserById(req.id);
536-
if (!target) {
537-
throw new ResponseError(ErrorCodes.NOT_FOUND, "not found");
538-
}
539-
540-
const featureSettings: UserFeatureSettings = target.featureFlags || {};
541-
const featureFlags = new Set(featureSettings.permanentWSFeatureFlags || []);
542-
543-
req.changes.forEach((e) => {
544-
if (e.add) {
545-
featureFlags.add(e.featureFlag);
546-
} else {
547-
featureFlags.delete(e.featureFlag);
548-
}
549-
});
550-
featureSettings.permanentWSFeatureFlags = Array.from(featureFlags);
551-
target.featureFlags = featureSettings;
552-
553-
await this.userDB.storeUser(target);
554-
// For some reason, returning the result of `this.userDB.storeUser(target)` does not work. The response never arrives the caller.
555-
// Returning `target` instead (which should be equivalent).
556-
return this.censorUser(target);
557-
}
558-
559-
async adminGetTeamMembers(ctx: TraceContext, teamId: string): Promise<TeamMemberInfo[]> {
560-
await this.guardAdminAccess("adminGetTeamMembers", { teamId }, Permission.ADMIN_WORKSPACES);
561-
562-
const team = await this.teamDB.findTeamById(teamId);
563-
if (!team) {
564-
throw new ResponseError(ErrorCodes.NOT_FOUND, "Team not found");
565-
}
566-
const members = await this.teamDB.findMembersByTeam(team.id);
567-
return members;
568-
}
569-
570-
async adminGetTeams(ctx: TraceContext, req: AdminGetListRequest<Team>): Promise<AdminGetListResult<Team>> {
571-
await this.guardAdminAccess("adminGetTeams", { req }, Permission.ADMIN_WORKSPACES);
572-
573-
return await this.teamDB.findTeams(
574-
req.offset,
575-
req.limit,
576-
req.orderBy,
577-
req.orderDir === "asc" ? "ASC" : "DESC",
578-
req.searchTerm as string,
579-
);
580-
}
581-
582-
async adminGetTeamById(ctx: TraceContext, id: string): Promise<Team | undefined> {
583-
await this.guardAdminAccess("adminGetTeamById", { id }, Permission.ADMIN_WORKSPACES);
584-
return await this.teamDB.findTeamById(id);
585-
}
586-
587-
async adminSetTeamMemberRole(
588-
ctx: TraceContext,
589-
teamId: string,
590-
userId: string,
591-
role: TeamMemberRole,
592-
): Promise<void> {
593-
await this.guardAdminAccess("adminSetTeamMemberRole", { teamId, userId, role }, Permission.ADMIN_WORKSPACES);
594-
return this.teamDB.setTeamMemberRole(userId, teamId, role);
595-
}
596-
597-
async adminGetWorkspaces(
598-
ctx: TraceContext,
599-
req: AdminGetWorkspacesRequest,
600-
): Promise<AdminGetListResult<WorkspaceAndInstance>> {
601-
traceAPIParams(ctx, { req });
602-
603-
await this.guardAdminAccess("adminGetWorkspaces", { req }, Permission.ADMIN_WORKSPACES);
604-
605-
return await this.workspaceDb
606-
.trace(ctx)
607-
.findAllWorkspaceAndInstances(
608-
req.offset,
609-
req.limit,
610-
req.orderBy,
611-
req.orderDir === "asc" ? "ASC" : "DESC",
612-
req,
613-
);
614-
}
615-
616-
async adminGetWorkspace(ctx: TraceContext, workspaceId: string): Promise<WorkspaceAndInstance> {
617-
traceAPIParams(ctx, { workspaceId });
618-
619-
await this.guardAdminAccess("adminGetWorkspace", { id: workspaceId }, Permission.ADMIN_WORKSPACES);
620-
621-
const result = await this.workspaceDb.trace(ctx).findWorkspaceAndInstance(workspaceId);
622-
if (!result) {
623-
throw new ResponseError(ErrorCodes.NOT_FOUND, "not found");
624-
}
625-
return result;
626-
}
627-
628-
async adminForceStopWorkspace(ctx: TraceContext, workspaceId: string): Promise<void> {
629-
traceAPIParams(ctx, { workspaceId });
630-
631-
await this.guardAdminAccess("adminForceStopWorkspace", { id: workspaceId }, Permission.ADMIN_WORKSPACES);
632-
633-
const workspace = await this.workspaceDb.trace(ctx).findById(workspaceId);
634-
if (workspace) {
635-
await this.internalStopWorkspace(ctx, workspace, "stopped by admin", StopWorkspacePolicy.IMMEDIATELY, true);
636-
}
637-
}
638-
639-
async adminRestoreSoftDeletedWorkspace(ctx: TraceContext, workspaceId: string): Promise<void> {
640-
traceAPIParams(ctx, { workspaceId });
641-
642-
await this.guardAdminAccess(
643-
"adminRestoreSoftDeletedWorkspace",
644-
{ id: workspaceId },
645-
Permission.ADMIN_WORKSPACES,
646-
);
647-
648-
await this.workspaceDb.trace(ctx).transaction(async (db) => {
649-
const ws = await db.findById(workspaceId);
650-
if (!ws) {
651-
throw new ResponseError(ErrorCodes.NOT_FOUND, `No workspace with id '${workspaceId}' found.`);
652-
}
653-
if (!ws.softDeleted) {
654-
return;
655-
}
656-
if (!!ws.contentDeletedTime) {
657-
throw new ResponseError(ErrorCodes.NOT_FOUND, "The workspace content was already garbage-collected.");
658-
}
659-
// @ts-ignore
660-
ws.softDeleted = null;
661-
ws.softDeletedTime = "";
662-
ws.pinned = true;
663-
await db.store(ws);
664-
});
665-
}
666-
667-
async adminGetProjectsBySearchTerm(
668-
ctx: TraceContext,
669-
req: AdminGetListRequest<Project>,
670-
): Promise<AdminGetListResult<Project>> {
671-
await this.guardAdminAccess("adminGetProjectsBySearchTerm", { req }, Permission.ADMIN_PROJECTS);
672-
return await this.projectDB.findProjectsBySearchTerm(
673-
req.offset,
674-
req.limit,
675-
req.orderBy,
676-
req.orderDir === "asc" ? "ASC" : "DESC",
677-
req.searchTerm as string,
678-
);
679-
}
680-
681-
async adminGetProjectById(ctx: TraceContext, id: string): Promise<Project | undefined> {
682-
await this.guardAdminAccess("adminGetProjectById", { id }, Permission.ADMIN_PROJECTS);
683-
return await this.projectDB.findProjectById(id);
684-
}
685-
686423
protected async findPrebuiltWorkspace(
687424
parentCtx: TraceContext,
688425
user: User,

0 commit comments

Comments
 (0)