mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-07 08:54:42 +00:00
fix(hub): retain local execution grants
This commit is contained in:
@@ -116,6 +116,29 @@ describe("Hub relationship", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("Hub enrollment cannot widen the daemon's locally granted scopes", async () => {
|
||||
relationship = await HubRelationshipHarness.start();
|
||||
relationship.returnEnrollmentScopes(["hub.execution.*", "*"]);
|
||||
|
||||
await relationship.beginConnect().result;
|
||||
relationship.connectLatestSocket();
|
||||
const responses = relationship.sendHubRequestOnLatest({
|
||||
type: "daemon.get_status.request",
|
||||
requestId: "scope-escalation",
|
||||
});
|
||||
|
||||
expect(relationship.relationshipFile()?.relationship.scopes).toEqual(["hub.execution.*"]);
|
||||
expect(responses).toContainEqual({
|
||||
type: "rpc_error",
|
||||
payload: {
|
||||
requestId: "scope-escalation",
|
||||
requestType: "daemon.get_status.request",
|
||||
error: "Session is not authorized for daemon.get_status.request",
|
||||
code: "access_denied",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test("a lost enrollment response reuses the exact ceremony", async () => {
|
||||
relationship = await HubRelationshipHarness.start();
|
||||
relationship.holdEnrollment();
|
||||
|
||||
@@ -343,7 +343,7 @@ export class HubRelationshipController implements HubRelationshipManagement {
|
||||
const active: ActiveRecord = {
|
||||
version: 1,
|
||||
state: "active",
|
||||
relationship: { ...pending.relationship, scopes: enrollment.scopes },
|
||||
relationship: pending.relationship,
|
||||
credential: pending.credential,
|
||||
transport: { kind: "direct_websocket", webSocketUrl: enrollment.webSocketUrl },
|
||||
};
|
||||
|
||||
@@ -318,6 +318,7 @@ class InMemoryHubRelationships implements HubRelationshipRemote {
|
||||
private enrollmentObserved = deferred<void>();
|
||||
private socketObserved = deferred<void>();
|
||||
private enrollmentRejection: 401 | 403 | null = null;
|
||||
private enrollmentScopes = ["hub.execution.*"];
|
||||
private revokeFailures = 0;
|
||||
private readonly relationships = new Set<string>();
|
||||
readonly enrollmentSnapshots: RelationshipInvocationSnapshot[] = [];
|
||||
@@ -333,6 +334,10 @@ class InMemoryHubRelationships implements HubRelationshipRemote {
|
||||
this.enrollmentRejection = statusCode;
|
||||
}
|
||||
|
||||
returnEnrollmentScopes(scopes: string[]): void {
|
||||
this.enrollmentScopes = scopes.slice();
|
||||
}
|
||||
|
||||
async enroll(input: HubEnrollment): Promise<HubEnrollmentResult> {
|
||||
this.enrollmentSnapshots.push(this.captureRelationship());
|
||||
this.enrollments.push({ ...input, scopes: input.scopes.slice() });
|
||||
@@ -415,7 +420,7 @@ class InMemoryHubRelationships implements HubRelationshipRemote {
|
||||
private enrollmentResult(input: HubEnrollment): HubEnrollmentResult {
|
||||
return {
|
||||
daemonId: input.daemonId,
|
||||
scopes: ["hub.execution.*"],
|
||||
scopes: this.enrollmentScopes.slice(),
|
||||
webSocketUrl: SOCKET_URL,
|
||||
};
|
||||
}
|
||||
@@ -579,6 +584,10 @@ export class HubRelationshipHarness {
|
||||
this.remote.completeEnrollment();
|
||||
}
|
||||
|
||||
returnEnrollmentScopes(scopes: string[]): void {
|
||||
this.remote.returnEnrollmentScopes(scopes);
|
||||
}
|
||||
|
||||
loseEnrollmentResponse(): void {
|
||||
this.remote.loseEnrollmentResponse();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user