Skip to content

Commit ddac704

Browse files
authored
Merge pull request #10267 from Turbo87/session-crate
Extract `crates_io_session` crate
2 parents 2f73baf + f302ddd commit ddac704

File tree

8 files changed

+48
-30
lines changed

8 files changed

+48
-30
lines changed

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ aws-ip-ranges = "=0.963.0"
4949
aws-sdk-cloudfront = "=1.57.0"
5050
aws-sdk-sqs = "=1.51.0"
5151
axum = { version = "=0.7.9", features = ["macros", "matched-path"] }
52-
axum-extra = { version = "=0.9.6", features = ["cookie-signed", "erased-json", "query", "typed-header"] }
52+
axum-extra = { version = "=0.9.6", features = ["erased-json", "query", "typed-header"] }
5353
base64 = "=0.22.1"
5454
bigdecimal = { version = "=0.4.7", features = ["serde"] }
5555
bon = "=3.3.1"
@@ -63,6 +63,7 @@ crates_io_github = { path = "crates/crates_io_github" }
6363
crates_io_index = { path = "crates/crates_io_index" }
6464
crates_io_markdown = { path = "crates/crates_io_markdown" }
6565
crates_io_pagerduty = { path = "crates/crates_io_pagerduty" }
66+
crates_io_session = { path = "crates/crates_io_session" }
6667
crates_io_tarball = { path = "crates/crates_io_tarball" }
6768
crates_io_team_repo = { path = "crates/crates_io_team_repo" }
6869
crates_io_worker = { path = "crates/crates_io_worker" }
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "crates_io_session"
3+
version = "0.0.0"
4+
license = "MIT OR Apache-2.0"
5+
edition = "2021"
6+
7+
[lints]
8+
workspace = true
9+
10+
[dependencies]
11+
axum = { version = "=0.7.9", features = ["macros"] }
12+
axum-extra = { version = "=0.9.6", features = ["cookie-signed"] }
13+
base64 = "=0.22.1"
14+
cookie = { version = "=0.18.1", features = ["secure"] }
15+
parking_lot = "=0.12.3"
16+
17+
[dev-dependencies]

src/middleware/session.rs renamed to crates/crates_io_session/src/lib.rs

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
1-
use crate::controllers::util::RequestPartsExt;
21
use axum::extract::{Extension, FromRequestParts, Request};
32
use axum::middleware::Next;
43
use axum::response::{IntoResponse, Response};
54
use axum_extra::extract::SignedCookieJar;
65
use base64::{engine::general_purpose, Engine};
76
use cookie::time::Duration;
87
use cookie::{Cookie, SameSite};
9-
use derive_more::Deref;
108
use parking_lot::RwLock;
119
use std::collections::HashMap;
1210
use std::sync::Arc;
1311

1412
static COOKIE_NAME: &str = "cargo_session";
1513
static MAX_AGE_DAYS: i64 = 90;
1614

17-
#[derive(Clone, FromRequestParts, Deref)]
15+
#[derive(Clone, FromRequestParts)]
1816
#[from_request(via(Extension))]
1917
pub struct SessionExtension(Arc<RwLock<Session>>);
2018

@@ -24,18 +22,18 @@ impl SessionExtension {
2422
}
2523

2624
pub fn get(&self, key: &str) -> Option<String> {
27-
let session = self.read();
25+
let session = self.0.read();
2826
session.data.get(key).cloned()
2927
}
3028

3129
pub fn insert(&self, key: String, value: String) -> Option<String> {
32-
let mut session = self.write();
30+
let mut session = self.0.write();
3331
session.dirty = true;
3432
session.data.insert(key, value)
3533
}
3634

3735
pub fn remove(&self, key: &str) -> Option<String> {
38-
let mut session = self.write();
36+
let mut session = self.0.write();
3937
session.dirty = true;
4038
session.data.remove(key)
4139
}
@@ -54,7 +52,7 @@ pub async fn attach_session(jar: SignedCookieJar, mut req: Request, next: Next)
5452
let response = next.run(req).await;
5553

5654
// Check if the session data was mutated
57-
let session = session.read();
55+
let session = session.0.read();
5856
if session.dirty {
5957
// Return response with additional `Set-Cookie` header
6058
let encoded = encode(&session.data);
@@ -83,18 +81,6 @@ impl Session {
8381
}
8482
}
8583

86-
pub trait RequestSession {
87-
fn session(&self) -> &SessionExtension;
88-
}
89-
90-
impl<T: RequestPartsExt> RequestSession for T {
91-
fn session(&self) -> &SessionExtension {
92-
self.extensions()
93-
.get::<SessionExtension>()
94-
.expect("missing cookie session")
95-
}
96-
}
97-
9884
pub fn decode(cookie: Cookie<'_>) -> HashMap<String, String> {
9985
let mut ret = HashMap::new();
10086
let bytes = general_purpose::STANDARD

src/auth.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use crate::controllers;
22
use crate::controllers::util::RequestPartsExt;
33
use crate::middleware::log_request::RequestLogExt;
4-
use crate::middleware::session::RequestSession;
54
use crate::models::token::{CrateScope, EndpointScope};
65
use crate::models::{ApiToken, User};
76
use crate::util::errors::{
87
account_locked, forbidden, internal, AppResult, InsecurelyGeneratedTokenRevoked,
98
};
109
use crate::util::token::HashedToken;
1110
use chrono::Utc;
11+
use crates_io_session::SessionExtension;
1212
use diesel_async::AsyncPgConnection;
1313
use http::header;
1414
use http::request::Parts;
@@ -176,11 +176,12 @@ async fn authenticate_via_cookie(
176176
parts: &Parts,
177177
conn: &mut AsyncPgConnection,
178178
) -> AppResult<Option<CookieAuthentication>> {
179-
let user_id_from_session = parts
180-
.session()
181-
.get("user_id")
182-
.and_then(|s| s.parse::<i32>().ok());
179+
let session = parts
180+
.extensions()
181+
.get::<SessionExtension>()
182+
.expect("missing cookie session");
183183

184+
let user_id_from_session = session.get("user_id").and_then(|s| s.parse::<i32>().ok());
184185
let Some(id) = user_id_from_session else {
185186
return Ok(None);
186187
};

src/controllers/session.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ use oauth2::{AuthorizationCode, CsrfToken, Scope, TokenResponse};
1111
use crate::app::AppState;
1212
use crate::email::Emails;
1313
use crate::middleware::log_request::RequestLogExt;
14-
use crate::middleware::session::SessionExtension;
1514
use crate::models::{NewUser, User};
1615
use crate::schema::users;
1716
use crate::util::diesel::is_read_only_error;
1817
use crate::util::errors::{bad_request, server_error, AppResult};
1918
use crate::views::EncodableMe;
2019
use crates_io_github::GithubUser;
20+
use crates_io_session::SessionExtension;
2121

2222
/// Begin authentication flow.
2323
///

src/middleware.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ pub mod log_request;
88
pub mod normalize_path;
99
pub mod real_ip;
1010
mod require_user_agent;
11-
pub mod session;
1211
mod static_or_continue;
1312
mod update_metrics;
1413

@@ -59,7 +58,10 @@ pub fn apply_axum_middleware(state: AppState, router: Router<()>) -> Router {
5958
state.config.cargo_compat_status_code_config,
6059
cargo_compat::middleware,
6160
))
62-
.layer(from_fn_with_state(state.clone(), session::attach_session))
61+
.layer(from_fn_with_state(
62+
state.clone(),
63+
crates_io_session::attach_session,
64+
))
6365
.layer(from_fn_with_state(
6466
state.clone(),
6567
require_user_agent::require_user_agent,

src/tests/util.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
//! `MockCookieUser` and `MockTokenUser` provide an `as_model` function which returns a reference
2020
//! to the underlying database model value (`User` and `ApiToken` respectively).
2121
22-
use crate::middleware::session;
2322
use crate::models::{ApiToken, CreatedApiToken, User};
2423
use crate::tests::{
2524
CategoryListResponse, CategoryResponse, CrateList, CrateResponse, GoodCrate, OwnerResp,
@@ -72,7 +71,7 @@ pub fn encode_session_header(session_key: &cookie::Key, user_id: i32) -> String
7271
map.insert("user_id".into(), user_id.to_string());
7372

7473
// encode the map into a cookie value string
75-
let encoded = session::encode(&map);
74+
let encoded = crates_io_session::encode(&map);
7675

7776
// put the cookie into a signed cookie jar
7877
let cookie = Cookie::build((cookie_name, encoded));

0 commit comments

Comments
 (0)