From f7d7994c4b88af3edcd89fb970ef1fbbaafcfc3f Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Mon, 1 Dec 2025 10:33:57 +0100 Subject: [PATCH] trustpub: Remove workflow path verification from the frontend Unfortunately this wasn't working as intended on production due to CORS issues. We could proxy the requests through our API servers, but for this nice to have feature I'm not sure it's worth the extra complexity for now. --- .../crate/settings/new-trusted-publisher.js | 9 +- .../crate/settings/new-trusted-publisher.gjs | 2 - .../settings/new-trusted-publisher.spec.ts | 88 ------------------- src/config/server.rs | 2 +- .../settings/new-trusted-publisher-test.js | 86 ------------------ 5 files changed, 3 insertions(+), 184 deletions(-) diff --git a/app/controllers/crate/settings/new-trusted-publisher.js b/app/controllers/crate/settings/new-trusted-publisher.js index 92918f09423..498b52b0d44 100644 --- a/app/controllers/crate/settings/new-trusted-publisher.js +++ b/app/controllers/crate/settings/new-trusted-publisher.js @@ -34,15 +34,10 @@ export default class NewTrustedPublisherController extends Controller { } get verificationUrl() { + if (this.publisher !== 'GitHub') return; if (!this.namespace || !this.project || !this.workflow) return; - if (this.publisher === 'GitHub') { - return `https://raw.githubusercontent.com/${this.namespace}/${this.project}/HEAD/.github/workflows/${this.workflow}`; - } - - if (this.publisher === 'GitLab') { - return `https://gitlab.com/${this.namespace}/${this.project}/-/raw/HEAD/${this.workflow}`; - } + return `https://raw.githubusercontent.com/${this.namespace}/${this.project}/HEAD/.github/workflows/${this.workflow}`; } saveConfigTask = task(async () => { diff --git a/app/templates/crate/settings/new-trusted-publisher.gjs b/app/templates/crate/settings/new-trusted-publisher.gjs index f7027ac758b..4e74d5b1a18 100644 --- a/app/templates/crate/settings/new-trusted-publisher.gjs +++ b/app/templates/crate/settings/new-trusted-publisher.gjs @@ -274,8 +274,6 @@ import WorkflowVerification from 'crates-io/components/workflow-verification'; ci/publish.yml. {{/if}} - - {{/let}} diff --git a/e2e/routes/crate/settings/new-trusted-publisher.spec.ts b/e2e/routes/crate/settings/new-trusted-publisher.spec.ts index 77289ba46e0..ee54e1d91f6 100644 --- a/e2e/routes/crate/settings/new-trusted-publisher.spec.ts +++ b/e2e/routes/crate/settings/new-trusted-publisher.spec.ts @@ -505,93 +505,5 @@ test.describe('Route | crate.settings.new-trusted-publisher', { tag: '@routes' } await expect(page).toHaveURL(`/crates/${crate.name}/settings`); await expect(page.locator('[data-test-gitlab-config]')).toHaveCount(0); }); - - test.describe('workflow verification', () => { - test('success case (200 OK)', async ({ msw, page }) => { - let { crate } = await prepare(msw); - - await page.goto(`/crates/${crate.name}/settings/new-trusted-publisher`); - await expect(page).toHaveURL(`/crates/${crate.name}/settings/new-trusted-publisher`); - - // Select GitLab from the publisher dropdown - await page.selectOption('[data-test-publisher]', 'GitLab'); - - await msw.worker.use( - http.head('https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/.gitlab-ci.yml', () => { - return new HttpResponse(null, { status: 200 }); - }), - ); - - await expect(page.locator('[data-test-workflow-verification="initial"]')).toHaveText( - 'The workflow filepath will be verified once all necessary fields are filled.', - ); - - await page.fill('[data-test-namespace]', 'rust-lang'); - await page.fill('[data-test-project]', 'crates.io'); - await page.fill('[data-test-workflow]', '.gitlab-ci.yml'); - - await expect(page.locator('[data-test-workflow-verification="success"]')).toBeVisible(); - - await expect(page.locator('[data-test-workflow-verification="success"]')).toHaveText( - '✓ Workflow file found at https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/.gitlab-ci.yml', - ); - }); - - test('not found case (404)', async ({ msw, page }) => { - let { crate } = await prepare(msw); - - await page.goto(`/crates/${crate.name}/settings/new-trusted-publisher`); - await expect(page).toHaveURL(`/crates/${crate.name}/settings/new-trusted-publisher`); - - // Select GitLab from the publisher dropdown - await page.selectOption('[data-test-publisher]', 'GitLab'); - - await msw.worker.use( - http.head('https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/missing.yml', () => { - return new HttpResponse(null, { status: 404 }); - }), - ); - - await page.fill('[data-test-namespace]', 'rust-lang'); - await page.fill('[data-test-project]', 'crates.io'); - await page.fill('[data-test-workflow]', 'missing.yml'); - - await expect(page.locator('[data-test-workflow-verification="not-found"]')).toBeVisible(); - - await expect(page.locator('[data-test-workflow-verification="not-found"]')).toHaveText( - '⚠ Workflow file not found at https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/missing.yml', - ); - - // Verify form can still be submitted - await page.click('[data-test-add]'); - await expect(page).toHaveURL(`/crates/${crate.name}/settings`); - }); - - test('server error (5xx)', async ({ msw, page }) => { - let { crate } = await prepare(msw); - - await page.goto(`/crates/${crate.name}/settings/new-trusted-publisher`); - await expect(page).toHaveURL(`/crates/${crate.name}/settings/new-trusted-publisher`); - - // Select GitLab from the publisher dropdown - await page.selectOption('[data-test-publisher]', 'GitLab'); - - await msw.worker.use( - http.head('https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/.gitlab-ci.yml', () => { - return new HttpResponse(null, { status: 500 }); - }), - ); - - await page.fill('[data-test-namespace]', 'rust-lang'); - await page.fill('[data-test-project]', 'crates.io'); - await page.fill('[data-test-workflow]', '.gitlab-ci.yml'); - - await expect(page.locator('[data-test-workflow-verification="error"]')).toBeVisible(); - - await expect(page.locator('[data-test-workflow-verification="error"]')).toHaveText( - '⚠ Could not verify workflow file at https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/.gitlab-ci.yml (network error)', - ); - }); - }); }); }); diff --git a/src/config/server.rs b/src/config/server.rs index f458a4dbae7..254ac3c4d7b 100644 --- a/src/config/server.rs +++ b/src/config/server.rs @@ -179,7 +179,7 @@ impl Server { // the `script` in `public/github-redirect.html` let content_security_policy = format!( "default-src 'self'; \ - connect-src 'self' *.ingest.sentry.io https://docs.rs https://play.rust-lang.org https://raw.githubusercontent.com https://gitlab.com {cdn_domain}; \ + connect-src 'self' *.ingest.sentry.io https://docs.rs https://play.rust-lang.org https://raw.githubusercontent.com {cdn_domain}; \ script-src 'self' 'unsafe-eval' 'sha256-n1+BB7Ckjcal1Pr7QNBh/dKRTtBQsIytFodRiIosXdE=' 'sha256-dbf9FMl76C7BnK1CC3eWb3pvsQAUaTYSHAlBy9tNTG0='; \ style-src 'self' 'unsafe-inline' https://code.cdn.mozilla.net; \ font-src https://code.cdn.mozilla.net; \ diff --git a/tests/routes/crate/settings/new-trusted-publisher-test.js b/tests/routes/crate/settings/new-trusted-publisher-test.js index ddf64f8b690..1fd22d67d2f 100644 --- a/tests/routes/crate/settings/new-trusted-publisher-test.js +++ b/tests/routes/crate/settings/new-trusted-publisher-test.js @@ -514,91 +514,5 @@ module('Route | crate.settings.new-trusted-publisher', hooks => { assert.strictEqual(currentURL(), `/crates/${crate.name}/settings`); assert.dom('[data-test-gitlab-config]').exists({ count: 0 }); }); - - module('workflow verification', function () { - test('success case (200 OK)', async function (assert) { - let { crate } = await prepare(this); - - await visit(`/crates/${crate.name}/settings/new-trusted-publisher`); - assert.strictEqual(currentURL(), `/crates/${crate.name}/settings/new-trusted-publisher`); - - // Select GitLab from the publisher dropdown - await fillIn('[data-test-publisher]', 'GitLab'); - - this.worker.use( - http.head('https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/.gitlab-ci.yml', () => { - return new HttpResponse(null, { status: 200 }); - }), - ); - - assert - .dom('[data-test-workflow-verification="initial"]') - .hasText('The workflow filepath will be verified once all necessary fields are filled.'); - - await fillIn('[data-test-namespace]', 'rust-lang'); - await fillIn('[data-test-project]', 'crates.io'); - await fillIn('[data-test-workflow]', '.gitlab-ci.yml'); - - await waitFor('[data-test-workflow-verification="success"]'); - - let expected = '✓ Workflow file found at https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/.gitlab-ci.yml'; - assert.dom('[data-test-workflow-verification="success"]').hasText(expected); - }); - - test('not found case (404)', async function (assert) { - let { crate } = await prepare(this); - - await visit(`/crates/${crate.name}/settings/new-trusted-publisher`); - assert.strictEqual(currentURL(), `/crates/${crate.name}/settings/new-trusted-publisher`); - - // Select GitLab from the publisher dropdown - await fillIn('[data-test-publisher]', 'GitLab'); - - this.worker.use( - http.head('https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/missing.yml', () => { - return new HttpResponse(null, { status: 404 }); - }), - ); - - await fillIn('[data-test-namespace]', 'rust-lang'); - await fillIn('[data-test-project]', 'crates.io'); - await fillIn('[data-test-workflow]', 'missing.yml'); - - await waitFor('[data-test-workflow-verification="not-found"]'); - - let expected = '⚠ Workflow file not found at https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/missing.yml'; - assert.dom('[data-test-workflow-verification="not-found"]').hasText(expected); - - // Verify form can still be submitted - await click('[data-test-add]'); - assert.strictEqual(currentURL(), `/crates/${crate.name}/settings`); - }); - - test('server error (5xx)', async function (assert) { - let { crate } = await prepare(this); - - await visit(`/crates/${crate.name}/settings/new-trusted-publisher`); - assert.strictEqual(currentURL(), `/crates/${crate.name}/settings/new-trusted-publisher`); - - // Select GitLab from the publisher dropdown - await fillIn('[data-test-publisher]', 'GitLab'); - - this.worker.use( - http.head('https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/.gitlab-ci.yml', () => { - return new HttpResponse(null, { status: 500 }); - }), - ); - - await fillIn('[data-test-namespace]', 'rust-lang'); - await fillIn('[data-test-project]', 'crates.io'); - await fillIn('[data-test-workflow]', '.gitlab-ci.yml'); - - await waitFor('[data-test-workflow-verification="error"]'); - - let expected = - '⚠ Could not verify workflow file at https://gitlab.com/rust-lang/crates.io/-/raw/HEAD/.gitlab-ci.yml (network error)'; - assert.dom('[data-test-workflow-verification="error"]').hasText(expected); - }); - }); }); });