Skip to content

Commit 6c439d1

Browse files
committed
impl
1 parent 171daca commit 6c439d1

File tree

5 files changed

+60
-6
lines changed

5 files changed

+60
-6
lines changed

components/dashboard/src/service/json-rpc-organization-client.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import {
4141
import { getGitpodService } from "./service";
4242
import { converter } from "./public-api";
4343
import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
44-
import { OrgMemberRole } from "@gitpod/gitpod-protocol";
44+
import { OrgMemberRole, RoleRestrictions } from "@gitpod/gitpod-protocol";
4545

4646
export class JsonRpcOrganizationClient implements PromiseClient<typeof OrganizationService> {
4747
async createOrganization(
@@ -251,13 +251,32 @@ export class JsonRpcOrganizationClient implements PromiseClient<typeof Organizat
251251
"updateRestrictedEditorNames is required to be true to update restrictedEditorNames",
252252
);
253253
}
254+
const roleRestrictions: RoleRestrictions = {};
255+
if (request.updateRoleRestrictions) {
256+
for (const roleRestriction of request?.roleRestrictions ?? []) {
257+
if (!roleRestriction.role) {
258+
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "role is required");
259+
}
260+
const role = converter.fromOrgMemberRole(roleRestriction.role);
261+
const permissions = roleRestriction?.permissions?.map((p) => converter.fromOrganizationPermission(p));
262+
263+
roleRestrictions[role] = permissions;
264+
}
265+
} else if (request.roleRestrictions && Object.keys(request.roleRestrictions).length > 0) {
266+
throw new ApplicationError(
267+
ErrorCodes.BAD_REQUEST,
268+
"updateRoleRestrictions is required to be true to update roleRestrictions",
269+
);
270+
}
271+
254272
await getGitpodService().server.updateOrgSettings(request.organizationId, {
255273
...update,
256274
defaultRole: request.defaultRole as OrgMemberRole,
257275
timeoutSettings: {
258276
inactivity: converter.toDurationString(request.timeoutSettings?.inactivity),
259277
denyUserTimeouts: request.timeoutSettings?.denyUserTimeouts,
260278
},
279+
roleRestrictions,
261280
});
262281
return new UpdateOrganizationSettingsResponse();
263282
}

components/gitpod-protocol/src/teams-projects-protocol.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ export interface OrganizationSettings {
231231

232232
// the default organization-wide timeout settings for workspaces
233233
timeoutSettings?: TimeoutSettings;
234+
235+
roleRestrictions?: RoleRestrictions;
234236
}
235237

236238
export type TimeoutSettings = {
@@ -241,12 +243,17 @@ export type TimeoutSettings = {
241243
denyUserTimeouts?: boolean;
242244
};
243245

246+
export const VALID_ORG_MEMBER_ROLES = ["owner", "member", "collaborator"] as const;
247+
244248
export type TeamMemberRole = OrgMemberRole;
245-
export type OrgMemberRole = "owner" | "member" | "collaborator";
249+
export type OrgMemberRole = typeof VALID_ORG_MEMBER_ROLES[number];
250+
251+
export type OrgMemberPermission = "start_arbitrary_repositories";
252+
export type RoleRestrictions = Partial<Record<OrgMemberRole, OrgMemberPermission[]>>;
246253

247254
export namespace TeamMemberRole {
248-
export function isValid(role: any): role is TeamMemberRole {
249-
return role === "owner" || role === "member" || role === "collaborator";
255+
export function isValid(role: unknown): role is TeamMemberRole {
256+
return VALID_ORG_MEMBER_ROLES.includes(role as TeamMemberRole);
250257
}
251258
}
252259

components/public-api/typescript-common/src/public-api-converter.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ import {
4343
import { AuditLog as AuditLogProtocol } from "@gitpod/gitpod-protocol/lib/audit-log";
4444
import {
4545
OrgMemberInfo,
46-
OrgMemberRole,
4746
OrganizationSettings as OrganizationSettingsProtocol,
4847
PartialProject,
4948
PrebuildSettings as PrebuildSettingsProtocol,
5049
PrebuildWithStatus,
5150
Project,
5251
ProjectSettings,
5352
Organization as ProtocolOrganization,
53+
OrgMemberPermission,
54+
OrgMemberRole,
5455
} from "@gitpod/gitpod-protocol/lib/teams-projects-protocol";
5556
import type { DeepPartial } from "@gitpod/gitpod-protocol/lib/util/deep-partial";
5657
import { parseGoDurationToMs } from "@gitpod/gitpod-protocol/lib/util/timeutil";
@@ -108,6 +109,7 @@ import {
108109
import {
109110
Organization,
110111
OrganizationMember,
112+
OrganizationPermission,
111113
OrganizationRole,
112114
OrganizationSettings,
113115
} from "@gitpod/public-api/lib/gitpod/v1/organization_pb";
@@ -1394,6 +1396,15 @@ export class PublicAPIConverter {
13941396
});
13951397
}
13961398

1399+
fromOrganizationPermission = (permission: OrganizationPermission): OrgMemberPermission => {
1400+
switch (permission) {
1401+
case OrganizationPermission.START_ARBITRARY_REPOS:
1402+
return "start_arbitrary_repositories";
1403+
default:
1404+
throw new Error(`unknown org member permission ${permission}`);
1405+
}
1406+
}
1407+
13971408
toSuggestedRepository(r: SuggestedRepositoryProtocol): SuggestedRepository {
13981409
return new SuggestedRepository({
13991410
url: r.url,

components/server/src/api/organization-service-api.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,23 @@ export class OrganizationServiceAPI implements ServiceImpl<typeof OrganizationSe
293293
update.timeoutSettings.inactivity = this.apiConverter.toDurationString(req.timeoutSettings.inactivity);
294294
}
295295

296+
if (req.roleRestrictions.length > 0) {
297+
if (!req.updateRoleRestrictions) {
298+
throw new ApplicationError(
299+
ErrorCodes.BAD_REQUEST,
300+
"updateRoleRestrictions is required to be true when updating roleRestrictions",
301+
);
302+
}
303+
304+
update.roleRestrictions = update.roleRestrictions ?? {};
305+
for (const roleRestriction of req.roleRestrictions) {
306+
const role = this.apiConverter.fromOrgMemberRole(roleRestriction.role);
307+
const permissions = roleRestriction.permissions.map((p) =>
308+
this.apiConverter.fromOrganizationPermission(p),
309+
);
310+
update.roleRestrictions[role] = permissions;
311+
}
312+
}
296313
if (Object.keys(update).length === 0) {
297314
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "nothing to update");
298315
}

components/server/src/orgs/organization-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
import { BUILTIN_INSTLLATION_ADMIN_USER_ID, TeamDB, UserDB } from "@gitpod/gitpod-db/lib";
88
import {
99
OrgMemberInfo,
10-
OrgMemberRole,
1110
Organization,
1211
OrganizationSettings,
1312
TeamMemberRole,
1413
TeamMembershipInvite,
1514
WorkspaceTimeoutDuration,
15+
OrgMemberRole,
1616
} from "@gitpod/gitpod-protocol";
1717
import { IAnalyticsWriter } from "@gitpod/gitpod-protocol/lib/analytics";
1818
import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";

0 commit comments

Comments
 (0)