Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/ide/code/leeway.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ RUN sudo apt-get update \
&& sudo apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*

ENV GP_CODE_COMMIT 07fe931b77d75daa0ba73f05e5e282c0f1dc1482
ENV GP_CODE_COMMIT b16a98d1506fc5008773b4694d0553847d441674
RUN mkdir gp-code \
&& cd gp-code \
&& git init \
Expand Down
2 changes: 1 addition & 1 deletion components/server/ee/src/workspace/gitpod-server-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ export class GitpodServerEEImpl<C extends GitpodClient, S extends GitpodServer>
}

await this.guardAccess({kind: "workspaceInstance", subject: instance, workspaceOwnerID: workspace.ownerId, workspaceIsShared: workspace.shareable || false}, "get");
await this.guardAccess({kind: "snapshot", subject: undefined, workspaceOwnerID: workspace.ownerId}, "create");
await this.guardAccess({kind: "snapshot", subject: undefined, workspaceOwnerID: workspace.ownerId, workspaceID: workspace.id }, "create");

const client = await this.workspaceManagerClientProvider.get(instance.region);
const request = new TakeSnapshotRequest();
Expand Down
35 changes: 32 additions & 3 deletions components/server/src/auth/resource-access.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import { suite, test } from "mocha-typescript";
import * as chai from 'chai';
const expect = chai.expect;
import { TokenResourceGuard, ScopedResourceGuard, GuardedResource } from "./resource-access";
import { TokenResourceGuard, ScopedResourceGuard, GuardedResource, ResourceAccessOp } from "./resource-access";

@suite class TestResourceAccess {

Expand Down Expand Up @@ -62,6 +62,8 @@ import { TokenResourceGuard, ScopedResourceGuard, GuardedResource } from "./reso
const tests: {
name: string
guard: TokenResourceGuard
resource?: GuardedResource,
operation?: ResourceAccessOp,
expectation: boolean
}[] = [
{
Expand Down Expand Up @@ -100,11 +102,38 @@ import { TokenResourceGuard, ScopedResourceGuard, GuardedResource } from "./reso
"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "workspace", subjectID: "*", operations: ["get"]}),
]),
expectation: true,
}
},
{
name: "snaphshot create",
guard: new TokenResourceGuard(workspaceResource.subject.ownerId, [
"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "snapshot", subjectID: ScopedResourceGuard.SNAPSHOT_WORKSPACE_SUBJECT_ID_PREFIX + workspaceResource.subject.id, operations: ["create"]}),
]),
resource: { kind: "snapshot", subject: undefined, workspaceID: workspaceResource.subject.id, workspaceOwnerID: workspaceResource.subject.ownerId},
operation: "create",
expectation: true,
},
{
name: "snaphshot create missing prefix fails",
guard: new TokenResourceGuard(workspaceResource.subject.ownerId, [
"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "snapshot", subjectID: workspaceResource.subject.id, operations: ["create"]}),
]),
resource: { kind: "snapshot", subject: undefined, workspaceID: workspaceResource.subject.id, workspaceOwnerID: workspaceResource.subject.ownerId},
operation: "create",
expectation: false,
},
{
name: "snaphshot create other user fails",
guard: new TokenResourceGuard(workspaceResource.subject.ownerId, [
"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "snapshot", subjectID: workspaceResource.subject.id, operations: ["create"]}),
]),
resource: { kind: "snapshot", subject: undefined, workspaceID: workspaceResource.subject.id, workspaceOwnerID: "other_owner"},
operation: "create",
expectation: false,
},
]

await Promise.all(tests.map(async t => {
const res = await t.guard.canAccess(workspaceResource, "get")
const res = await t.guard.canAccess(t.resource || workspaceResource, t.operation || "get")
expect(res).to.be.eq(t.expectation, `"${t.name}" expected canAccess(...) === ${t.expectation}, but was ${res}`);
}))
}
Expand Down
14 changes: 12 additions & 2 deletions components/server/src/auth/resource-access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface GuardedSnapshot {
kind: "snapshot";
subject: Snapshot | undefined;
workspaceOwnerID: string;
workspaceID?: string;
}

export interface GuardedUserStorage {
Expand Down Expand Up @@ -172,6 +173,9 @@ export class ScopedResourceGuard implements ResourceAccessGuard {
}

export namespace ScopedResourceGuard {

export const SNAPSHOT_WORKSPACE_SUBJECT_ID_PREFIX = 'ws-'

export interface ResourceScope {
kind: GuardedResourceKind;
subjectID: string;
Expand Down Expand Up @@ -229,7 +233,13 @@ export namespace ScopedResourceGuard {
case "gitpodToken":
return resource.subject.tokenHash;
case "snapshot":
return resource.subject ? resource.subject.id : undefined;
if (resource.subject) {
return resource.subject.id;
}
if (resource.workspaceID) {
return SNAPSHOT_WORKSPACE_SUBJECT_ID_PREFIX + resource.workspaceID;
}
return undefined;
case "token":
return resource.subject.value;
case "user":
Expand Down Expand Up @@ -308,4 +318,4 @@ export namespace TokenResourceGuard {
return true;
}

}
}
2 changes: 1 addition & 1 deletion components/server/src/workspace/workspace-starter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ export class WorkspaceStarter {

"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "workspace", subjectID: workspace.id, operations: ["get", "update"]}),
"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "workspaceInstance", subjectID: instance.id, operations: ["get", "update", "delete"]}),
"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "snapshot", subjectID: "*", operations: ["create", "get"]}),
"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "snapshot", subjectID: ScopedResourceGuard.SNAPSHOT_WORKSPACE_SUBJECT_ID_PREFIX + workspace.id, operations: ["create"]}),
"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "gitpodToken", subjectID: "*", operations: ["create"]}),
"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "userStorage", subjectID: "*", operations: ["create", "get", "update"]}),
"resource:"+ScopedResourceGuard.marshalResourceScope({kind: "token", subjectID: "*", operations: ["get"]}),
Expand Down