fix(clone): a CodeCommit region borrows saved key IDs; Clone runs in the background

An IAM SSH key ID logs in to every region of its AWS account, but a login
was saved per host, so a repo in a region with no key ID of its own was
refused. Clone now tries the key IDs saved for the other CodeCommit regions
(each with its own key; the first ls-remote accepts, or the only one) and
keeps that user in the clone's origin.

Files → New → Clone repository steps aside for its progress chip as soon
as the clone starts; a failure asking for a login reopens the form.
This commit is contained in:
2026-11-02 10:00:09 +07:00
parent 8d0477e0f7
commit e4ecd116a2
6 changed files with 126 additions and 20 deletions
+39 -1
View File
@@ -5,7 +5,7 @@
* ECREDENTIALS for a remote wanting a login), `/api/me/git` (key made once,
* only the public half returned, 0600 on disk; named keys beside the default
* ones, SSH logins per alias tied to one key, which a clone then offers
* alone), and the member (S3) path of
* alone; a CodeCommit region with no login borrowing another region's), and the member (S3) path of
* `server/lib/git-identity.js` with run-as and git stubbed — what reaches
* git's argv, and that a login typed without "remember" leaves the member's
* store as it was.
@@ -650,6 +650,44 @@ describe("several accounts: named keys and SSH logins per alias", () => {
});
});
describe("CodeCommit: a region with no login borrows another region's", () => {
it("clones as the first saved CodeCommit user the remote accepts, and keeps that user in origin", async () => {
const bare = path.join(ROOT, "bare.git");
const R = "git-codecommit.ap-southeast-2.amazonaws.com";
const saved = [
["git-codecommit.ap-southeast-1.amazonaws.com", "APKAONE"],
["git-codecommit.us-east-1.amazonaws.com", "APKATWO"],
];
for (const [host, user] of saved) {
assert.equal((await request("PUT", "/api/me/git/ssh-user", { host, user })).status, 200);
}
// The test forge stands in for the region: APKAONE is refused (no such
// repo behind it), APKATWO is the account that owns the repo.
const rules = [
[`url.file://${ROOT}/nowhere.git.insteadOf`, `ssh://APKAONE@${R}/v1/repos/r`],
[`url.file://${bare}.insteadOf`, `ssh://APKATWO@${R}/v1/repos/r`],
];
for (const [k, v] of rules) execFileSync("git", ["config", "--global", "--add", k, v]);
try {
const r = await request("POST", "/api/lanes/clone", {
url: `ssh://${R}/v1/repos/r`,
parent: WORK,
name: "borrowed-login",
});
assert.equal(r.status, 201, JSON.stringify(r.body));
const origin = execFileSync(
"git",
["-C", path.join(WORK, "borrowed-login"), "config", "remote.origin.url"],
{ encoding: "utf8" }
).trim();
assert.equal(origin, `ssh://APKATWO@${R}/v1/repos/r`);
} finally {
for (const [k] of rules) execFileSync("git", ["config", "--global", "--unset-all", k]);
for (const [host] of saved) await request("DELETE", `/api/me/git/ssh-user/${host}`);
}
});
});
describe("git-identity, member account (S3, stubbed)", () => {
const runAs = require("../lib/run-as");
const worktree = require("../lib/worktree");