Skip to content

Commit 66ed98b

Browse files
authored
Merge pull request #5889 from Turbo87/auth-conn
auth: Reuse existing database connections
2 parents 18382c1 + 3cb531b commit 66ed98b

File tree

9 files changed

+52
-45
lines changed

9 files changed

+52
-45
lines changed

src/auth.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::controllers;
22
use crate::controllers::util::RequestPartsExt;
3-
use crate::middleware::app::RequestApp;
43
use crate::middleware::log_request::CustomMetadataRequestExt;
54
use crate::middleware::session::RequestSession;
65
use crate::models::token::{CrateScope, EndpointScope};
@@ -56,8 +55,12 @@ impl AuthCheck {
5655
}
5756
}
5857

59-
pub fn check<T: RequestPartsExt>(&self, request: &T) -> AppResult<Authentication> {
60-
let auth = authenticate(request)?;
58+
pub fn check<T: RequestPartsExt>(
59+
&self,
60+
request: &T,
61+
conn: &PgConnection,
62+
) -> AppResult<Authentication> {
63+
let auth = authenticate(request, conn)?;
6164

6265
if let Some(token) = auth.api_token() {
6366
if !self.allow_token {
@@ -203,18 +206,16 @@ fn authenticate_via_token<T: RequestPartsExt>(
203206
Ok(Some(TokenAuthentication { user, token }))
204207
}
205208

206-
fn authenticate<T: RequestPartsExt>(req: &T) -> AppResult<Authentication> {
209+
fn authenticate<T: RequestPartsExt>(req: &T, conn: &PgConnection) -> AppResult<Authentication> {
207210
controllers::util::verify_origin(req)?;
208211

209-
let conn = req.app().db_write()?;
210-
211-
match authenticate_via_cookie(req, &conn) {
212+
match authenticate_via_cookie(req, conn) {
212213
Ok(None) => {}
213214
Ok(Some(auth)) => return Ok(Authentication::Cookie(auth)),
214215
Err(err) => return Err(err),
215216
}
216217

217-
match authenticate_via_token(req, &conn) {
218+
match authenticate_via_token(req, conn) {
218219
Ok(None) => {}
219220
Ok(Some(auth)) => return Ok(Authentication::Token(auth)),
220221
Err(err) => return Err(err),

src/controllers/crate_owner_invitation.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use std::collections::{HashMap, HashSet};
1818
/// Handles the `GET /api/v1/me/crate_owner_invitations` route.
1919
pub async fn list(req: ConduitRequest) -> AppResult<Json<Value>> {
2020
conduit_compat(move || {
21-
let auth = AuthCheck::only_cookie().check(&req)?;
21+
let conn = req.app().db_write()?;
22+
let auth = AuthCheck::only_cookie().check(&req, &conn)?;
2223
let user_id = auth.user_id();
2324

2425
let PrivateListResponse {
@@ -57,7 +58,8 @@ pub async fn list(req: ConduitRequest) -> AppResult<Json<Value>> {
5758
/// Handles the `GET /api/private/crate_owner_invitations` route.
5859
pub async fn private_list(req: ConduitRequest) -> AppResult<Json<PrivateListResponse>> {
5960
conduit_compat(move || {
60-
let auth = AuthCheck::only_cookie().check(&req)?;
61+
let conn = req.app().db_write()?;
62+
let auth = AuthCheck::only_cookie().check(&req, &conn)?;
6163

6264
let filter = if let Some(crate_name) = req.query().get("crate_name") {
6365
ListFilter::CrateName(crate_name.clone())
@@ -263,18 +265,19 @@ pub async fn handle_invite(mut req: ConduitRequest) -> AppResult<Json<Value>> {
263265

264266
let crate_invite = crate_invite.crate_owner_invite;
265267

266-
let auth = AuthCheck::default().check(&req)?;
268+
let state = req.app();
269+
let conn = state.db_write()?;
270+
271+
let auth = AuthCheck::default().check(&req, &conn)?;
267272
let user_id = auth.user_id();
268273

269-
let state = req.app();
270-
let conn = &*state.db_write()?;
271274
let config = &state.config;
272275

273-
let invitation = CrateOwnerInvitation::find_by_id(user_id, crate_invite.crate_id, conn)?;
276+
let invitation = CrateOwnerInvitation::find_by_id(user_id, crate_invite.crate_id, &conn)?;
274277
if crate_invite.accepted {
275-
invitation.accept(conn, config)?;
278+
invitation.accept(&conn, config)?;
276279
} else {
277-
invitation.decline(conn)?;
280+
invitation.decline(&conn)?;
278281
}
279282

280283
Ok(Json(json!({ "crate_owner_invitation": crate_invite })))

src/controllers/krate/follow.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ fn follow_target(crate_name: &str, conn: &DieselPooledConn<'_>, user_id: i32) ->
1818
/// Handles the `PUT /crates/:crate_id/follow` route.
1919
pub async fn follow(Path(crate_name): Path<String>, req: ConduitRequest) -> AppResult<Response> {
2020
conduit_compat(move || {
21-
let user_id = AuthCheck::default().check(&req)?.user_id();
2221
let conn = req.app().db_write()?;
22+
let user_id = AuthCheck::default().check(&req, &conn)?.user_id();
2323
let follow = follow_target(&crate_name, &conn, user_id)?;
2424
diesel::insert_into(follows::table)
2525
.values(&follow)
@@ -34,8 +34,8 @@ pub async fn follow(Path(crate_name): Path<String>, req: ConduitRequest) -> AppR
3434
/// Handles the `DELETE /crates/:crate_id/follow` route.
3535
pub async fn unfollow(Path(crate_name): Path<String>, req: ConduitRequest) -> AppResult<Response> {
3636
conduit_compat(move || {
37-
let user_id = AuthCheck::default().check(&req)?.user_id();
3837
let conn = req.app().db_write()?;
38+
let user_id = AuthCheck::default().check(&req, &conn)?.user_id();
3939
let follow = follow_target(&crate_name, &conn, user_id)?;
4040
diesel::delete(&follow).execute(&*conn)?;
4141

@@ -52,8 +52,8 @@ pub async fn following(
5252
conduit_compat(move || {
5353
use diesel::dsl::exists;
5454

55-
let user_id = AuthCheck::only_cookie().check(&req)?.user_id();
5655
let conn = req.app().db_read_prefer_primary()?;
56+
let user_id = AuthCheck::only_cookie().check(&req, &conn)?.user_id();
5757
let follow = follow_target(&crate_name, &conn, user_id)?;
5858
let following =
5959
diesel::select(exists(follows::table.find(follow.id()))).get_result::<bool>(&*conn)?;

src/controllers/krate/owners.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,15 @@ fn modify_owners<B: Read>(
103103
req: &mut Request<B>,
104104
add: bool,
105105
) -> AppResult<Json<Value>> {
106-
let auth = AuthCheck::default()
107-
.with_endpoint_scope(EndpointScope::ChangeOwners)
108-
.for_crate(crate_name)
109-
.check(req)?;
110-
111106
let logins = parse_owners_request(req)?;
112107
let app = req.app();
113108

114109
let conn = app.db_write()?;
110+
let auth = AuthCheck::default()
111+
.with_endpoint_scope(EndpointScope::ChangeOwners)
112+
.for_crate(crate_name)
113+
.check(req, &conn)?;
114+
115115
let user = auth.user();
116116

117117
conn.transaction(|| {

src/controllers/krate/publish.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub async fn publish(mut req: ConduitRequest) -> AppResult<Json<GoodCrate>> {
8282
let auth = AuthCheck::default()
8383
.with_endpoint_scope(endpoint_scope)
8484
.for_crate(&new_crate.name)
85-
.check(&req)?;
85+
.check(&req, &conn)?;
8686

8787
let api_token_id = auth.api_token_id();
8888
let user = auth.user();

src/controllers/krate/search.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ pub async fn search(req: ConduitRequest) -> AppResult<Json<Value>> {
115115
);
116116
}
117117

118+
let conn = req.app().db_read()?;
119+
118120
if let Some(kws) = params.get("all_keywords") {
119121
// Calculating the total number of results with filters is not supported yet.
120122
supports_seek = false;
@@ -188,7 +190,7 @@ pub async fn search(req: ConduitRequest) -> AppResult<Json<Value>> {
188190
// Calculating the total number of results with filters is not supported yet.
189191
supports_seek = false;
190192

191-
let user_id = AuthCheck::default().check(&req)?.user_id();
193+
let user_id = AuthCheck::default().check(&req, &conn)?.user_id();
192194

193195
query = query.filter(
194196
crates::id.eq_any(
@@ -250,7 +252,6 @@ pub async fn search(req: ConduitRequest) -> AppResult<Json<Value>> {
250252
.limit_page_numbers()
251253
.enable_seek(supports_seek)
252254
.gather(&req)?;
253-
let conn = req.app().db_read()?;
254255

255256
let (explicit_page, seek) = match pagination.page.clone() {
256257
Page::Numeric(_) => (true, None),

src/controllers/token.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use serde_json as json;
1111
/// Handles the `GET /me/tokens` route.
1212
pub async fn list(req: ConduitRequest) -> AppResult<Json<Value>> {
1313
conduit_compat(move || {
14-
let auth = AuthCheck::only_cookie().check(&req)?;
1514
let conn = req.app().db_read_prefer_primary()?;
15+
let auth = AuthCheck::only_cookie().check(&req, &conn)?;
1616
let user = auth.user();
1717

1818
let tokens: Vec<ApiToken> = ApiToken::belonging_to(user)
@@ -48,14 +48,15 @@ pub async fn new(mut req: ConduitRequest) -> AppResult<Json<Value>> {
4848
return Err(bad_request("name must have a value"));
4949
}
5050

51-
let auth = AuthCheck::default().check(&req)?;
51+
let conn = req.app().db_write()?;
52+
53+
let auth = AuthCheck::default().check(&req, &conn)?;
5254
if auth.api_token_id().is_some() {
5355
return Err(bad_request(
5456
"cannot use an API token to create a new API token",
5557
));
5658
}
5759

58-
let conn = req.app().db_write()?;
5960
let user = auth.user();
6061

6162
let max_token_per_user = 500;
@@ -77,8 +78,8 @@ pub async fn new(mut req: ConduitRequest) -> AppResult<Json<Value>> {
7778
/// Handles the `DELETE /me/tokens/:id` route.
7879
pub async fn revoke(Path(id): Path<i32>, req: ConduitRequest) -> AppResult<Json<Value>> {
7980
conduit_compat(move || {
80-
let auth = AuthCheck::default().check(&req)?;
8181
let conn = req.app().db_write()?;
82+
let auth = AuthCheck::default().check(&req, &conn)?;
8283
let user = auth.user();
8384
diesel::update(ApiToken::belonging_to(user).find(id))
8485
.set(api_tokens::revoked.eq(true))
@@ -92,12 +93,12 @@ pub async fn revoke(Path(id): Path<i32>, req: ConduitRequest) -> AppResult<Json<
9293
/// Handles the `DELETE /tokens/current` route.
9394
pub async fn revoke_current(req: ConduitRequest) -> AppResult<Response> {
9495
conduit_compat(move || {
95-
let auth = AuthCheck::default().check(&req)?;
96+
let conn = req.app().db_write()?;
97+
let auth = AuthCheck::default().check(&req, &conn)?;
9698
let api_token_id = auth
9799
.api_token_id()
98100
.ok_or_else(|| bad_request("token not provided"))?;
99101

100-
let conn = req.app().db_write()?;
101102
diesel::update(api_tokens::table.filter(api_tokens::id.eq(api_token_id)))
102103
.set(api_tokens::revoked.eq(true))
103104
.execute(&*conn)?;

src/controllers/user/me.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use crate::views::{EncodableMe, EncodablePrivateUser, EncodableVersion, OwnedCra
1515
/// Handles the `GET /me` route.
1616
pub async fn me(req: ConduitRequest) -> AppResult<Json<EncodableMe>> {
1717
conduit_compat(move || {
18-
let user_id = AuthCheck::only_cookie().check(&req)?.user_id();
1918
let conn = req.app().db_read_prefer_primary()?;
19+
let user_id = AuthCheck::only_cookie().check(&req, &conn)?.user_id();
2020

2121
let (user, verified, email, verification_sent): (User, Option<bool>, Option<String>, bool) =
2222
users::table
@@ -59,7 +59,8 @@ pub async fn updates(req: ConduitRequest) -> AppResult<Json<Value>> {
5959
conduit_compat(move || {
6060
use diesel::dsl::any;
6161

62-
let auth = AuthCheck::only_cookie().check(&req)?;
62+
let conn = req.app().db_read_prefer_primary()?;
63+
let auth = AuthCheck::only_cookie().check(&req, &conn)?;
6364
let user = auth.user();
6465

6566
let followed_crates = Follow::belonging_to(user).select(follows::crate_id);
@@ -74,7 +75,6 @@ pub async fn updates(req: ConduitRequest) -> AppResult<Json<Value>> {
7475
users::all_columns.nullable(),
7576
))
7677
.pages_pagination(PaginationOptions::builder().gather(&req)?);
77-
let conn = req.app().db_read_prefer_primary()?;
7878
let data: Paginated<(Version, String, Option<User>)> = query.load(&conn)?;
7979
let more = data.next_page_params().is_some();
8080
let versions = data.iter().map(|(v, _, _)| v).cloned().collect::<Vec<_>>();
@@ -107,8 +107,10 @@ pub async fn update_user(
107107
use self::emails::user_id;
108108
use diesel::insert_into;
109109

110-
let auth = AuthCheck::default().check(&req)?;
110+
let state = req.app().clone();
111+
let conn = state.db_write()?;
111112

113+
let auth = AuthCheck::default().check(&req, &conn)?;
112114
let user = auth.user();
113115

114116
// need to check if current user matches user to be updated
@@ -138,8 +140,6 @@ pub async fn update_user(
138140
return Err(bad_request("empty email rejected"));
139141
}
140142

141-
let state = req.app();
142-
let conn = state.db_write()?;
143143
conn.transaction::<_, BoxedAppError, _>(|| {
144144
let new_email = NewEmail {
145145
user_id: user.id,
@@ -203,10 +203,10 @@ pub async fn regenerate_token_and_send(
203203
use diesel::dsl::sql;
204204
use diesel::update;
205205

206-
let auth = AuthCheck::default().check(&req)?;
207-
208206
let state = req.app();
209207
let conn = state.db_write()?;
208+
209+
let auth = AuthCheck::default().check(&req, &conn)?;
210210
let user = auth.user();
211211

212212
// need to check if current user matches user to be updated
@@ -249,8 +249,8 @@ pub async fn update_email_notifications(mut req: ConduitRequest) -> AppResult<Re
249249
.map(|c| (c.id, c.email_notifications))
250250
.collect();
251251

252-
let user_id = AuthCheck::default().check(&req)?.user_id();
253252
let conn = req.app().db_write()?;
253+
let user_id = AuthCheck::default().check(&req, &conn)?.user_id();
254254

255255
// Build inserts from existing crates belonging to the current user
256256
let to_insert = CrateOwner::by_owner_kind(OwnerKind::User)

src/controllers/version/yank.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,14 @@ fn modify_yank<B>(
4848
return Err(cargo_err(&format_args!("invalid semver: {version}")));
4949
}
5050

51+
let state = req.app();
52+
let conn = state.db_write()?;
53+
5154
let auth = AuthCheck::default()
5255
.with_endpoint_scope(EndpointScope::Yank)
5356
.for_crate(crate_name)
54-
.check(req)?;
57+
.check(req, &conn)?;
5558

56-
let state = req.app();
57-
let conn = state.db_write()?;
5859
let (version, krate) = version_and_crate(&conn, crate_name, version)?;
5960
let api_token_id = auth.api_token_id();
6061
let user = auth.user();

0 commit comments

Comments
 (0)