Skip to content

Commit

Permalink
[auth] RequestContext: add missing runWithSubjectId (#19235)
Browse files Browse the repository at this point in the history
  • Loading branch information
geropl authored Dec 11, 2023
1 parent 1e4e606 commit 6f64417
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 50 deletions.
44 changes: 24 additions & 20 deletions components/server/src/code-sync/code-sync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { Config } from "../config";
import { CachingBlobServiceClientProvider } from "../util/content-service-sugar";
import { Authorizer } from "../authorization/authorizer";
import { FGAFunctionAccessGuard } from "../auth/resource-access";
import { runWithSubjectId } from "../util/request-context";
import { SubjectId } from "../auth/subject-id";

// By default: 5 kind of resources * 20 revs * 1Mb = 100Mb max in the content service for user data.
const defaultRevLimit = 20;
Expand Down Expand Up @@ -106,31 +108,33 @@ export class CodeSyncService {
}

const userId = req.user.id;
try {
await UserRateLimiter.instance(this.config.rateLimiter).consume(userId, accessCodeSyncStorage);
} catch (e) {
if (e instanceof Error) {
throw e;
await runWithSubjectId(SubjectId.fromUserId(userId), async () => {
try {
await UserRateLimiter.instance(this.config.rateLimiter).consume(userId, accessCodeSyncStorage);
} catch (e) {
if (e instanceof Error) {
throw e;
}
res.setHeader("Retry-After", String(Math.round(e.msBeforeNext / 1000)) || 1);
res.status(429).send("Too Many Requests");
return;
}

const functionGuard = (req.user as WithFunctionAccessGuard).functionGuard;
if (!!functionGuard) {
// If we authorize with scopes, there is a FunctionGuard
const guard = new FGAFunctionAccessGuard(userId, functionGuard);
if (!(await guard.canAccess(accessCodeSyncStorage))) {
res.sendStatus(403);
return;
}
}
res.setHeader("Retry-After", String(Math.round(e.msBeforeNext / 1000)) || 1);
res.status(429).send("Too Many Requests");
return;
}

const functionGuard = (req.user as WithFunctionAccessGuard).functionGuard;
if (!!functionGuard) {
// If we authorize with scopes, there is a FunctionGuard
const guard = new FGAFunctionAccessGuard(userId, functionGuard);
if (!(await guard.canAccess(accessCodeSyncStorage))) {
if (!(await this.authorizer.hasPermissionOnUser(userId, "code_sync", userId))) {
res.sendStatus(403);
return;
}
}

if (!(await this.authorizer.hasPermissionOnUser(userId, "code_sync", userId))) {
res.sendStatus(403);
return;
}
});

return next();
});
Expand Down
65 changes: 35 additions & 30 deletions components/server/src/user/user-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,39 +401,44 @@ export class UserController {
return;
}
const sessionId = req.body.sessionId;
const resourceGuard = new FGAResourceAccessGuard(user.id, new OwnerResourceGuard(user.id));
const server = this.createGitpodServer(user, resourceGuard);
try {
await server.sendHeartBeat({}, { wasClosed: true, instanceId: instanceID });
/** no await */ server
.trackEvent(
{},
{
event: "ide_close_signal",
properties: {
sessionId,
instanceId: instanceID,
clientKind: "supervisor-frontend",

await runWithSubjectId(SubjectId.fromUserId(user.id), async () => {
const resourceGuard = new FGAResourceAccessGuard(user.id, new OwnerResourceGuard(user.id));
const server = this.createGitpodServer(user, resourceGuard);
try {
await server.sendHeartBeat({}, { wasClosed: true, instanceId: instanceID });
/** no await */ server
.trackEvent(
{},
{
event: "ide_close_signal",
properties: {
sessionId,
instanceId: instanceID,
clientKind: "supervisor-frontend",
},
},
},
)
.catch((err) => log.warn(logCtx, "workspacePageClose: failed to track ide close signal", err));
res.sendStatus(200);
} catch (e) {
if (ApplicationError.hasErrorCode(e)) {
res.status(e.code).send(e.message);
log.warn(
logCtx,
`workspacePageClose: server sendHeartBeat respond with code: ${e.code}, message: ${e.message}`,
);
)
.catch((err) =>
log.warn(logCtx, "workspacePageClose: failed to track ide close signal", err),
);
res.sendStatus(200);
} catch (e) {
if (ApplicationError.hasErrorCode(e)) {
res.status(e.code).send(e.message);
log.warn(
logCtx,
`workspacePageClose: server sendHeartBeat respond with code: ${e.code}, message: ${e.message}`,
);
return;
}
log.error(logCtx, "workspacePageClose failed", e);
res.sendStatus(500);
return;
} finally {
server.dispose();
}
log.error(logCtx, "workspacePageClose failed", e);
res.sendStatus(500);
return;
} finally {
server.dispose();
}
});
},
);
if (this.config.enableLocalApp) {
Expand Down

0 comments on commit 6f64417

Please sign in to comment.