Skip to content

Release/2022.07.1 #11843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
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 WORKSPACE.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defaultArgs:
localAppVersion: unknown
codeCommit: 3fef802aa6bfd601cf182315ba949931401772f8
codeQuality: stable
intellijDownloadUrl: "https://download.jetbrains.com/idea/ideaIU-2022.1.4.tar.gz"
intellijDownloadUrl: "https://download.jetbrains.com/idea/ideaIU-2022.2.tar.gz"
golandDownloadUrl: "https://download.jetbrains.com/go/goland-2022.1.4.tar.gz"
pycharmDownloadUrl: "https://download.jetbrains.com/python/pycharm-professional-2022.1.4.tar.gz"
phpstormDownloadUrl: "https://download.jetbrains.com/webide/PhpStorm-2022.1.4.tar.gz"
Expand Down
92 changes: 60 additions & 32 deletions components/server/ee/src/prebuilds/github-enterprise-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class GitHubEnterpriseApp {
}
if (!user) {
res.statusCode = 401;
res.send("Unauthorized: Cannot find user.");
res.send("Unauthorized: Cannot find authorized user.");
span.finish();
await this.webhookEvents.updateEvent(event.id, { status: "dismissed_unauthorized" });
return;
Expand All @@ -82,7 +82,7 @@ export class GitHubEnterpriseApp {
ctx: TraceContext,
payload: GitHubEnterprisePushPayload,
req: express.Request,
): Promise<User> {
): Promise<User | undefined> {
const span = TraceContext.startSpan("GitHubEnterpriseApp.findUser", ctx);
try {
let host = req.header("X-Github-Enterprise-Host");
Expand All @@ -95,38 +95,39 @@ export class GitHubEnterpriseApp {
if (!hostContext) {
throw new Error("Unsupported GitHub Enterprise host: " + host);
}
const { authProviderId } = hostContext.authProvider;
const authId = payload.sender.id;
const user = await this.userDB.findUserByIdentity({ authProviderId, authId });
if (!user) {
throw new Error(`No user found with identity ${authProviderId}/${authId}.`);
} else if (!!user.blocked) {
throw new Error(`Blocked user ${user.id} tried to start prebuild.`);
}
const gitpodIdentity = user.identities.find(
(i) => i.authProviderId === TokenService.GITPOD_AUTH_PROVIDER_ID,
);
if (!gitpodIdentity) {
throw new Error(`User ${user.id} has no identity for '${TokenService.GITPOD_AUTH_PROVIDER_ID}'.`);
const cloneURL = payload.repository.clone_url;
const projectOwners = await this.findProjectOwners(cloneURL);
if (!projectOwners) {
throw new Error("No project found.");
}
// Verify the webhook signature
const signature = req.header("X-Hub-Signature-256");
const body = (req as any).rawBody;
const tokenEntries = (await this.userDB.findTokensForIdentity(gitpodIdentity)).filter((tokenEntry) => {
return tokenEntry.token.scopes.includes(GitHubService.PREBUILD_TOKEN_SCOPE);
});
const signingToken = tokenEntries.find((tokenEntry) => {
const sig =
"sha256=" +
createHmac("sha256", user.id + "|" + tokenEntry.token.value)
.update(body)
.digest("hex");
return timingSafeEqual(Buffer.from(sig), Buffer.from(signature ?? ""));
});
if (!signingToken) {
throw new Error(`User ${user.id} has no token matching the payload signature.`);
for (const user of projectOwners.users) {
const gitpodIdentity = user.identities.find(
(i) => i.authProviderId === TokenService.GITPOD_AUTH_PROVIDER_ID,
);
if (!gitpodIdentity) {
continue;
}
// Verify the webhook signature
const signature = req.header("X-Hub-Signature-256");
const body = (req as any).rawBody;
const tokenEntries = (await this.userDB.findTokensForIdentity(gitpodIdentity)).filter((tokenEntry) => {
return tokenEntry.token.scopes.includes(GitHubService.PREBUILD_TOKEN_SCOPE);
});
const signatureMatched = tokenEntries.some((tokenEntry) => {
const sig =
"sha256=" +
createHmac("sha256", user.id + "|" + tokenEntry.token.value)
.update(body)
.digest("hex");
return timingSafeEqual(Buffer.from(sig), Buffer.from(signature ?? ""));
});
if (signatureMatched) {
if (!!user.blocked) {
throw new Error(`Blocked user ${user.id} tried to start prebuild.`);
}
return user;
}
}
return user;
} finally {
span.finish();
}
Expand Down Expand Up @@ -255,6 +256,33 @@ export class GitHubEnterpriseApp {
return { user: webhookInstaller };
}

protected async findProjectOwners(cloneURL: string): Promise<{ users: User[]; project: Project } | undefined> {
const project = await this.projectDB.findProjectByCloneUrl(cloneURL);
if (project) {
if (project.userId) {
const user = await this.userDB.findUserById(project.userId);
if (user) {
return { users: [user], project };
}
} else if (project.teamId) {
const users = [];
const owners = (await this.teamDB.findMembersByTeam(project.teamId || "")).filter(
(m) => m.role === "owner",
);
const hostContext = this.hostContextProvider.get(new URL(cloneURL).host);
const authProviderId = hostContext?.authProvider.authProviderId;
for (const teamMember of owners) {
const user = await this.userDB.findUserById(teamMember.userId);
if (user && user.identities.some((i) => i.authProviderId === authProviderId)) {
users.push(user);
}
}
return { users, project };
}
}
return undefined;
}

protected getBranchFromRef(ref: string): string | undefined {
const headsPrefix = "refs/heads/";
if (ref.startsWith(headsPrefix)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,17 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
WorkspaceImageRepository: fmt.Sprintf("%s/workspace-images", registryName),
}

workspaceImage := ctx.Config.Workspace.WorkspaceImage
if workspaceImage == "" {
workspaceImage = ctx.ImageName(common.ThirdPartyContainerRepo(ctx.Config.Repository, ""), workspace.DefaultWorkspaceImage, workspace.DefaultWorkspaceImageVersion)
}

imgcfg := config.ServiceConfig{
Orchestrator: orchestrator,
RefCache: config.RefCacheConfig{
Interval: util.Duration(time.Hour * 6).String(),
Refs: []string{
ctx.ImageName(common.ThirdPartyContainerRepo(ctx.Config.Repository, ""), workspace.DefaultWorkspaceImage, workspace.DefaultWorkspaceImageVersion),
workspaceImage,
},
},
Service: config.Service{
Expand Down
5 changes: 5 additions & 0 deletions install/kots/manifests/kots-preflight.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ spec:
collectorName: database
image: eu.gcr.io/gitpod-core-dev/build/kots-config-check/database:sje-kots-config-check.9
name: database
namespace: '{{repl Namespace }}'
args:
- '{{repl ConfigOption "db_incluster" }}' # DB_IN_CLUSTER_ENABLED
- '{{repl ConfigOption "db_cloudsql_enabled" }}' # DB_CLOUDSQL_ENABLED
Expand All @@ -24,6 +25,7 @@ spec:
collectorName: "kernel"
image: alpine/semver
name: kernel
namespace: '{{repl Namespace }}'
command:
- /bin/sh
- -c
Expand All @@ -33,6 +35,7 @@ spec:
collectorName: registry
image: eu.gcr.io/gitpod-core-dev/build/kots-config-check/registry:sje-kots-registry-check.16
name: registry
namespace: '{{repl Namespace }}'
args:
- '{{repl ConfigOption "reg_incluster" }}' # REG_IN_CLUSTER_ENABLED
- '{{repl ConfigOption "reg_username" }}' # REG_USERNAME
Expand All @@ -49,6 +52,7 @@ spec:
collectorName: storage
image: eu.gcr.io/gitpod-core-dev/build/kots-config-check/storage:sje-kots-storage-check.9
name: storage
namespace: '{{repl Namespace }}'
args:
- '{{repl ConfigOption "store_provider" }}' # STORE_PROVIDER
- '{{repl ConfigOption "store_region" }}' # STORE_LOCATION
Expand All @@ -65,6 +69,7 @@ spec:
collectorName: ping-registry
image: alpine/curl
name: ping-registry
namespace: '{{repl Namespace }}'
command:
- /bin/sh
- -c
Expand Down
4 changes: 4 additions & 0 deletions install/kots/manifests/kots-support-bundle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ spec:
collectorName: database
image: eu.gcr.io/gitpod-core-dev/build/kots-config-check/database:sje-kots-config-check.9
name: database
namespace: '{{repl Namespace }}'
args:
- '{{repl ConfigOption "db_incluster" }}' # DB_IN_CLUSTER_ENABLED
- '{{repl ConfigOption "db_cloudsql_enabled" }}' # DB_CLOUDSQL_ENABLED
Expand All @@ -24,6 +25,7 @@ spec:
collectorName: registry
image: eu.gcr.io/gitpod-core-dev/build/kots-config-check/registry:sje-kots-registry-check.16
name: registry
namespace: '{{repl Namespace }}'
args:
- '{{repl ConfigOption "reg_incluster" }}' # REG_IN_CLUSTER_ENABLED
- '{{repl ConfigOption "reg_username" }}' # REG_USERNAME
Expand All @@ -40,6 +42,7 @@ spec:
collectorName: storage
image: eu.gcr.io/gitpod-core-dev/build/kots-config-check/storage:sje-kots-storage-check.9
name: storage
namespace: '{{repl Namespace }}'
args:
- '{{repl ConfigOption "store_provider" }}' # STORE_PROVIDER
- '{{repl ConfigOption "store_region" }}' # STORE_LOCATION
Expand All @@ -55,6 +58,7 @@ spec:
collectorName: ping-registry
image: alpine/curl
name: ping-registry
namespace: '{{repl Namespace }}'
command:
- /bin/sh
- -c
Expand Down