Skip to content

Commit d7b16df

Browse files
authored
trustpub: Disallow config creation if email is not verified (#11351)
1 parent 99fdebe commit d7b16df

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/controllers/trustpub/github_configs/create/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::auth::AuthCheck;
33
use crate::controllers::krate::load_crate;
44
use crate::controllers::trustpub::github_configs::emails::ConfigCreatedEmail;
55
use crate::controllers::trustpub::github_configs::json;
6-
use crate::util::errors::{AppResult, bad_request};
6+
use crate::util::errors::{AppResult, bad_request, forbidden};
77
use axum::Json;
88
use crates_io_database::models::OwnerKind;
99
use crates_io_database::models::trustpub::NewGitHubConfig;
@@ -61,8 +61,14 @@ pub async fn create_trustpub_github_config(
6161
.load::<(i32, String, String, bool)>(&mut conn)
6262
.await?;
6363

64-
if !user_owners.iter().any(|owner| owner.0 == auth_user.id) {
65-
return Err(bad_request("You are not an owner of this crate"));
64+
let (_, _, _, email_verified) = user_owners
65+
.iter()
66+
.find(|(id, _, _, _)| *id == auth_user.id)
67+
.ok_or_else(|| bad_request("You are not an owner of this crate"))?;
68+
69+
if !email_verified {
70+
let message = "You must verify your email address to create a Trusted Publishing config";
71+
return Err(forbidden(message));
6672
}
6773

6874
// Lookup `repository_owner_id` via GitHub API

src/controllers/trustpub/github_configs/create/tests.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::tests::builders::CrateBuilder;
22
use crate::tests::util::{RequestHelper, Response, TestApp};
33
use anyhow::anyhow;
44
use bytes::Bytes;
5-
use crates_io_database::schema::trustpub_configs_github;
5+
use crates_io_database::schema::{emails, trustpub_configs_github};
66
use crates_io_github::{GitHubError, GitHubUser, MockGitHubClient};
77
use diesel::prelude::*;
88
use diesel_async::RunQueryDsl;
@@ -370,3 +370,38 @@ async fn test_github_error() -> anyhow::Result<()> {
370370

371371
Ok(())
372372
}
373+
374+
#[tokio::test(flavor = "multi_thread")]
375+
async fn test_unverified_email() -> anyhow::Result<()> {
376+
let (app, _client, cookie_client) = TestApp::full()
377+
.with_github(simple_github_mock())
378+
.with_user()
379+
.await;
380+
381+
let mut conn = app.db_conn().await;
382+
383+
diesel::update(emails::table.filter(emails::user_id.eq(cookie_client.as_model().id)))
384+
.set(emails::verified.eq(false))
385+
.execute(&mut conn)
386+
.await?;
387+
388+
CrateBuilder::new(CRATE_NAME, cookie_client.as_model().id)
389+
.build(&mut conn)
390+
.await?;
391+
392+
let body = serde_json::to_vec(&json!({
393+
"github_config": {
394+
"crate": CRATE_NAME,
395+
"repository_owner": "rust-lang",
396+
"repository_name": "foo-rs",
397+
"workflow_filename": "publish.yml",
398+
"environment": null,
399+
}
400+
}))?;
401+
402+
let response = cookie_client.put::<()>(URL, body).await;
403+
assert_eq!(response.status(), StatusCode::FORBIDDEN);
404+
assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"You must verify your email address to create a Trusted Publishing config"}]}"#);
405+
406+
Ok(())
407+
}

0 commit comments

Comments
 (0)