Skip to content

Commit e825fd4

Browse files
authored
Merge pull request #11697 from Turbo87/use-encrypted-tokens
Use encrypted GitHub OAuth access tokens
2 parents 9ca17a3 + d9aab69 commit e825fd4

File tree

25 files changed

+74
-133
lines changed

25 files changed

+74
-133
lines changed

crates/crates_io_database/src/models/user.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub struct User {
2424
#[serde(skip)]
2525
pub gh_access_token: SecretString,
2626
#[serde(skip)]
27-
pub gh_encrypted_token: Option<Vec<u8>>,
27+
pub gh_encrypted_token: Vec<u8>,
2828
pub account_lock_reason: Option<String>,
2929
pub account_lock_until: Option<DateTime<Utc>>,
3030
pub is_admin: bool,
@@ -96,7 +96,7 @@ pub struct NewUser<'a> {
9696
pub name: Option<&'a str>,
9797
pub gh_avatar: Option<&'a str>,
9898
pub gh_access_token: &'a str,
99-
pub gh_encrypted_token: Option<&'a [u8]>,
99+
pub gh_encrypted_token: &'a [u8],
100100
}
101101

102102
impl NewUser<'_> {

crates/crates_io_database/src/schema.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ diesel::table! {
881881
/// Whether or not the user wants to receive notifications when a package they own is published
882882
publish_notifications -> Bool,
883883
/// Encrypted GitHub access token
884-
gh_encrypted_token -> Nullable<Bytea>,
884+
gh_encrypted_token -> Bytea,
885885
}
886886
}
887887

crates/crates_io_database_dump/src/dump-db.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ publish_notifications = "private"
235235
gh_encrypted_token = "private"
236236
[users.column_defaults]
237237
gh_access_token = "''"
238+
gh_encrypted_token = "''"
238239

239240
[version_downloads]
240241
dependencies = ["versions"]

crates/crates_io_database_dump/src/snapshots/crates_io_database_dump__tests__sql_scripts@import.sql.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ BEGIN;
2424
-- Set defaults for non-nullable columns not included in the dump.
2525

2626
ALTER TABLE "users" ALTER COLUMN "gh_access_token" SET DEFAULT '';
27+
ALTER TABLE "users" ALTER COLUMN "gh_encrypted_token" SET DEFAULT '';
2728

2829
-- Truncate all tables.
2930

@@ -67,6 +68,7 @@ BEGIN;
6768
-- Drop the defaults again.
6869

6970
ALTER TABLE "users" ALTER COLUMN "gh_access_token" DROP DEFAULT;
71+
ALTER TABLE "users" ALTER COLUMN "gh_encrypted_token" DROP DEFAULT;
7072

7173
-- Reenable triggers on each table.
7274

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE users ALTER COLUMN gh_encrypted_token DROP NOT NULL;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE users ALTER COLUMN gh_encrypted_token SET NOT NULL;

src/bin/crates-admin/encrypt_github_tokens.rs

Lines changed: 0 additions & 108 deletions
This file was deleted.

src/bin/crates-admin/main.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ mod default_versions;
66
mod delete_crate;
77
mod delete_version;
88
mod dialoguer;
9-
mod encrypt_github_tokens;
109
mod enqueue_job;
1110
mod migrate;
1211
mod populate;
@@ -22,7 +21,6 @@ enum Command {
2221
BackfillOgImages(backfill_og_images::Opts),
2322
DeleteCrate(delete_crate::Opts),
2423
DeleteVersion(delete_version::Opts),
25-
EncryptGithubTokens(encrypt_github_tokens::Opts),
2624
Populate(populate::Opts),
2725
RenderReadmes(render_readmes::Opts),
2826
TransferCrates(transfer_crates::Opts),
@@ -53,7 +51,6 @@ async fn main() -> anyhow::Result<()> {
5351
Command::BackfillOgImages(opts) => backfill_og_images::run(opts).await,
5452
Command::DeleteCrate(opts) => delete_crate::run(opts).await,
5553
Command::DeleteVersion(opts) => delete_version::run(opts).await,
56-
Command::EncryptGithubTokens(opts) => encrypt_github_tokens::run(opts).await,
5754
Command::Populate(opts) => populate::run(opts).await,
5855
Command::RenderReadmes(opts) => render_readmes::run(opts).await,
5956
Command::TransferCrates(opts) => transfer_crates::run(opts).await,

src/controllers/crate_owner_invitation.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ async fn prepare_list(
166166
// Only allow crate owners to query pending invitations for their crate.
167167
let krate: Crate = Crate::by_name(&crate_name).first(conn).await?;
168168
let owners = krate.owners(conn).await?;
169-
if Rights::get(user, &*state.github, &owners).await? != Rights::Full {
169+
let encryption = &state.config.gh_token_encryption;
170+
if Rights::get(user, &*state.github, &owners, encryption).await? != Rights::Full {
170171
let detail = "only crate owners can query pending invitations for their crate";
171172
return Err(forbidden(detail));
172173
}

src/controllers/helpers/authorization.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::models::{Owner, User};
2+
use crate::util::gh_token_encryption::GitHubTokenEncryption;
23
use crates_io_github::{GitHubClient, GitHubError};
3-
use oauth2::AccessToken;
4-
use secrecy::ExposeSecret;
54

65
/// Access rights to the crate (publishing and ownership management)
76
/// NOTE: The order of these variants matters!
@@ -25,8 +24,11 @@ impl Rights {
2524
user: &User,
2625
gh_client: &dyn GitHubClient,
2726
owners: &[Owner],
27+
encryption: &GitHubTokenEncryption,
2828
) -> Result<Self, GitHubError> {
29-
let token = AccessToken::new(user.gh_access_token.expose_secret().to_string());
29+
let token = encryption
30+
.decrypt(&user.gh_encrypted_token)
31+
.map_err(GitHubError::Other)?;
3032

3133
let mut best = Self::None;
3234
for owner in owners {

0 commit comments

Comments
 (0)