Repository navigation
fix(gitlab): merge request calls use the bound remote's host #34556
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -281,3 +281,58 @@ it.effect.each(["read", "decode"] as const)( | |
| else assert.propertyVal(error.cause, "_tag", "SchemaError"); | ||
| }), | ||
| ); | ||
|
|
||
| it.effect("sends merge request calls to the bound remote's host", () => | ||
| Effect.gen(function* () { | ||
| const hosts: Array<string | undefined> = []; | ||
| const provider = yield* GitLabSourceControlProvider.make.pipe( | ||
| Effect.provide( | ||
| GitLabCli.layer.pipe( | ||
| Layer.provideMerge( | ||
| TestSourceControlHost.layer({ | ||
| process: { | ||
| run: (input) => { | ||
| hosts.push(input.env?.GITLAB_HOST); | ||
| return Effect.succeed( | ||
| processOutput(input.args[0] === "mr" ? "[]" : '{"default_branch":"main"}'), | ||
| ); | ||
| }, | ||
| }, | ||
| }), | ||
| ), | ||
| ), | ||
| ), | ||
| ); | ||
| const context = { | ||
| provider: { | ||
| kind: SourceControlProviderKind.make("gitlab"), | ||
| name: "GitLab Self-Hosted", | ||
| baseUrl: "https://gitlab.example.test", | ||
| }, | ||
| remoteName: "work", | ||
| remoteUrl: "git@gitlab.example.test:group/project.git", | ||
| }; | ||
|
|
||
| yield* provider.listChangeRequests({ | ||
| cwd: "/repo", | ||
| context, | ||
| headSelector: "feature", | ||
| state: "open", | ||
| }); | ||
| yield* provider.getDefaultBranch({ cwd: "/repo", context }); | ||
| yield* provider.createChangeRequest({ | ||
| cwd: "/repo", | ||
| context, | ||
| baseRefName: "main", | ||
| headSelector: "feature", | ||
| title: "Feature", | ||
| bodyFile: "/tmp/body.md", | ||
| }); | ||
|
|
||
| assert.deepStrictEqual(hosts, [ | ||
| "gitlab.example.test", | ||
| "gitlab.example.test", | ||
| "gitlab.example.test", | ||
| ]); | ||
|
Comment on lines
+332
to
+336
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cover view and checkout host propagation. Removing the host from either As per coding guidelines, “Backend behavior changes ship with focused tests for that behavior.”
|
||
| }), | ||
| ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -166,6 +166,9 @@ export const discovery = { | |
| "Install the GitLab command-line tool (`glab`) from https://gitlab.com/gitlab-org/cli or your package manager (for example `brew install glab`).", | ||
| } satisfies SourceControlCliDiscoverySpec; | ||
|
|
||
| const contextHost = (context: SourceControlProvider.SourceControlProviderContext | undefined) => | ||
| context === undefined ? undefined : new URL(context.provider.baseUrl).host; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preserve compatibility with glab’s port matching. For an HTTPS remote on port
|
||
|
|
||
| export const make = Effect.gen(function* () { | ||
| const gitlab = yield* GitLabCli.GitLabCli; | ||
| const { git } = yield* SourceControlHost.SourceControlHost; | ||
|
|
@@ -234,6 +237,7 @@ export const make = Effect.gen(function* () { | |
| return gitlab | ||
| .listMergeRequests({ | ||
| cwd: input.cwd, | ||
| host: contextHost(input.context), | ||
| headSelector: input.headSelector, | ||
| ...(source ? { source } : {}), | ||
| state: input.state, | ||
|
|
@@ -259,7 +263,7 @@ export const make = Effect.gen(function* () { | |
| }, | ||
| ), | ||
| getChangeRequest: Effect.fn("GitLabSourceControlProvider.getChangeRequest")(function (input) { | ||
| return gitlab.getMergeRequest(input).pipe( | ||
| return gitlab.getMergeRequest({ ...input, host: contextHost(input.context) }).pipe( | ||
| Effect.map(toChangeRequest), | ||
| Effect.mapError( | ||
| (error) => | ||
|
|
@@ -283,6 +287,7 @@ export const make = Effect.gen(function* () { | |
| return gitlab | ||
| .createMergeRequest({ | ||
| cwd: input.cwd, | ||
| host: contextHost(input.context), | ||
| baseBranch: input.baseRefName, | ||
| headSelector: input.headSelector, | ||
| ...(source ? { source } : {}), | ||
|
|
@@ -347,7 +352,7 @@ export const make = Effect.gen(function* () { | |
| ); | ||
| }), | ||
| getDefaultBranch: Effect.fn("GitLabSourceControlProvider.getDefaultBranch")(function (input) { | ||
| return gitlab.getDefaultBranch(input).pipe( | ||
| return gitlab.getDefaultBranch({ ...input, host: contextHost(input.context) }).pipe( | ||
| Effect.mapError( | ||
| (error) => | ||
| new SourceControlProviderError({ | ||
|
|
@@ -363,7 +368,7 @@ export const make = Effect.gen(function* () { | |
| }), | ||
| checkoutChangeRequest: Effect.fn("GitLabSourceControlProvider.checkoutChangeRequest")( | ||
| function (input) { | ||
| return gitlab.checkoutMergeRequest(input).pipe( | ||
| return gitlab.checkoutMergeRequest({ ...input, host: contextHost(input.context) }).pipe( | ||
| Effect.mapError( | ||
| (error) => | ||
| new SourceControlProviderError({ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script executed:
rg -n -C 4 'SourceControlHost\.of|input\.env|process\.env|GITLAB_TOKEN|OAUTH_TOKEN' apps/server packages/source-control-coreRepository: pingdotgg/t3code
Length of output: 41602
Script executed:
Repository: pingdotgg/t3code
Length of output: 41580
Script executed:
Repository: pingdotgg/t3code
Length of output: 25639
Web query:
gitlab glab cli GITLAB_HOST GITLAB_TOKEN OAUTH_TOKEN token host config source code credentials environmentResult:
Script executed:
Repository: pingdotgg/t3code
Length of output: 25633
Script executed:
Repository: pingdotgg/t3code
Length of output: 15501
Script executed:
Repository: pingdotgg/t3code
Length of output: 24927
Script executed:
Repository: pingdotgg/t3code
Length of output: 9396
Protect ambient tokens from untrusted remote hosts.
If a checkout binds an attacker-controlled
gitlab-labeled remote, a merge-request lookup can pass that host asGITLAB_HOST. glab then treats it as trusted and can send an inheritedGITLAB_TOKENorOAUTH_TOKENto it. Require a trusted host-to-token association before forwarding ambient credentials, while preserving authentication for configured hosts.Script executed:
Repository: pingdotgg/t3code
Length of output: 15852
Script executed:
Repository: pingdotgg/t3code
Length of output: 38494
Script executed:
Repository: pingdotgg/t3code
Length of output: 35955
Script executed:
Repository: pingdotgg/t3code
Length of output: 8702
Script executed:
Repository: pingdotgg/t3code
Length of output: 6635
Script executed:
Repository: pingdotgg/t3code
Length of output: 13525
Select the repository explicitly for GitLab.com.
With glab v1.43.0,
GITLAB_HOST=gitlab.comdoes not filter remotes. If an authenticated self-hostedupstreamhas priority, these calls can list or create merge requests on the wrong host. Use an explicit repository selector for the MR commands, and select the host and repository explicitly for the API calls.