Skip to content

Commit e6ca1b3

Browse files
committed
fix: use extractor for db connections
1 parent ab2df09 commit e6ca1b3

File tree

17 files changed

+98
-130
lines changed

17 files changed

+98
-130
lines changed

rustytime/src/handlers/admin/mod.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,23 @@
11
use aide::NoApi;
22
use axum::extract::Path;
33
use axum::{
4-
extract::State,
54
http::StatusCode,
65
response::{IntoResponse, Response},
76
};
87

8+
use crate::db_query;
99
use crate::models::user::User;
10-
use crate::state::AppState;
11-
use crate::utils::auth::AuthenticatedUser;
12-
use crate::{db_query, get_db_conn};
10+
use crate::utils::extractors::{AuthenticatedUser, DbConnection};
1311

1412
pub async fn change_user_admin_level(
15-
State(app_state): State<AppState>,
1613
Path((user_id, new_level)): Path<(i32, i16)>,
1714
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
15+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
1816
) -> Result<StatusCode, Response> {
19-
2017
if !current_user.is_owner() {
2118
return Err((StatusCode::FORBIDDEN, "No permission").into_response());
2219
}
2320

24-
let mut conn = get_db_conn!(app_state);
25-
2621
let Some(target_user) = db_query!(
2722
User::get_by_id(&mut conn, user_id),
2823
"Failed to fetch target user"

rustytime/src/handlers/api/user.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use aide::NoApi;
12
use axum::extract::ConnectInfo;
23
use axum::extract::{Json, Path, State};
34
use axum::http::StatusCode;
@@ -10,13 +11,13 @@ use std::net::IpAddr;
1011
use std::net::SocketAddr;
1112

1213
use crate::db::connection::DbPool;
13-
use crate::get_db_conn;
1414
use crate::models::heartbeat::Heartbeat;
1515
use crate::models::heartbeat::*;
1616
use crate::models::project::get_or_create_project_id;
1717
use crate::schema::heartbeats;
1818
use crate::state::AppState;
1919
use crate::utils::auth::{get_user_id_from_api_key, get_valid_api_key};
20+
use crate::utils::extractors::DbConnection;
2021
use crate::utils::http::extract_client_ip_from_headers;
2122
use crate::utils::time::{TimeFormat, human_readable_duration};
2223
use std::collections::{HashMap, hash_map};
@@ -132,6 +133,7 @@ pub async fn create_heartbeats(
132133
pub async fn get_statusbar_today(
133134
State(app_state): State<AppState>,
134135
Path(id): Path<String>,
136+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
135137
headers: axum::http::HeaderMap,
136138
uri: axum::http::Uri,
137139
) -> Result<Json<serde_json::Value>, Response> {
@@ -164,8 +166,6 @@ pub async fn get_statusbar_today(
164166
.unwrap()
165167
.and_utc();
166168

167-
let mut conn = get_db_conn!(app_state);
168-
169169
match Heartbeat::get_user_duration_seconds(
170170
&mut conn,
171171
DurationInput {

rustytime/src/handlers/data/import.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use aide::NoApi;
2+
use axum::Json;
23
use axum::extract::Query;
34
use axum::extract::State;
45
use axum::http::StatusCode;
56
use axum::response::IntoResponse;
67
use axum::response::Response;
7-
use axum::Json;
88
use schemars::JsonSchema;
99
use serde::Deserialize;
1010
use serde::Serialize;
@@ -15,8 +15,8 @@ use crate::db_query;
1515
use crate::jobs::import::enqueue_import;
1616
use crate::models::import_job::{ImportJob, ImportJobStatus};
1717
use crate::state::AppState;
18+
use crate::utils::extractors::AuthenticatedUser;
1819
use crate::utils::session::SessionManager;
19-
use crate::utils::auth::AuthenticatedUser;
2020

2121
#[derive(Deserialize, JsonSchema)]
2222
pub struct ImportQuery {
@@ -67,7 +67,6 @@ pub async fn import_heartbeats(
6767
cookies: NoApi<Cookies>,
6868
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
6969
) -> Result<Json<ImportStartResponse>, Response> {
70-
7170
let Some(session_id) = SessionManager::get_session_from_cookies(&cookies) else {
7271
return Err((StatusCode::UNAUTHORIZED, "User session is invalid").into_response());
7372
};

rustytime/src/handlers/data/project_aliases.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1+
use crate::db_query;
12
use crate::models::project_alias::{NewProjectAlias, ProjectAlias as ProjectAliasModel};
2-
use crate::state::AppState;
3-
use crate::utils::auth::AuthenticatedUser;
4-
use crate::{db_query, get_db_conn};
3+
use crate::utils::extractors::{AuthenticatedUser, DbConnection};
54
use aide::NoApi;
65
use axum::Json;
76
use axum::extract::Path;
87
use axum::{
9-
extract::State,
108
http::StatusCode,
119
response::{IntoResponse, Response},
1210
};
@@ -33,13 +31,9 @@ pub struct ProjectAliasesResponse {
3331

3432
/// Handler for the project aliases
3533
pub async fn project_aliases(
36-
State(app_state): State<AppState>,
3734
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
35+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
3836
) -> Result<Json<ProjectAliasesResponse>, Response> {
39-
40-
// get database connection
41-
let mut conn = get_db_conn!(app_state);
42-
4337
// get all project aliases
4438
let alias_records = db_query!(
4539
ProjectAliasModel::list_user_project_aliases(&mut conn, current_user.id),
@@ -71,13 +65,10 @@ pub async fn project_aliases(
7165
}
7266

7367
pub async fn add_project_alias(
74-
State(app_state): State<AppState>,
7568
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
7669
Path((id, alias_id)): Path<(i32, i32)>,
70+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
7771
) -> Result<StatusCode, Response> {
78-
79-
let mut conn = get_db_conn!(app_state);
80-
8172
let new_alias = NewProjectAlias {
8273
user_id: current_user.id,
8374
project_id: alias_id,
@@ -93,13 +84,10 @@ pub async fn add_project_alias(
9384
}
9485

9586
pub async fn delete_project_alias(
96-
State(app_state): State<AppState>,
9787
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
9888
Path(id): Path<i32>,
89+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
9990
) -> Result<StatusCode, Response> {
100-
101-
let mut conn = get_db_conn!(app_state);
102-
10391
db_query!(
10492
ProjectAliasModel::delete_project_alias(&mut conn, current_user.id, id),
10593
"Failed to delete project alias"

rustytime/src/handlers/data/projects.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1+
use crate::db_query;
12
use crate::models::project::Project as ProjectModel;
2-
use crate::state::AppState;
3-
use crate::utils::auth::AuthenticatedUser;
4-
use crate::{db_query, get_db_conn};
3+
use crate::utils::extractors::{AuthenticatedUser, DbConnection};
54
use aide::NoApi;
65
use axum::Json;
76
use axum::extract::Path;
87
use axum::{
9-
extract::State,
108
http::StatusCode,
119
response::{IntoResponse, Response},
1210
};
@@ -31,13 +29,9 @@ pub struct RepoUrlRequest {
3129

3230
/// Handler for the projects list
3331
pub async fn projects_list(
34-
State(app_state): State<AppState>,
3532
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
33+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
3634
) -> Result<Json<ProjectsListResponse>, Response> {
37-
38-
// get database connection
39-
let mut conn = get_db_conn!(app_state);
40-
4135
// get all projects
4236
let projects = db_query!(
4337
ProjectModel::list_user_projects(&mut conn, current_user.id),
@@ -54,15 +48,11 @@ pub async fn projects_list(
5448
}
5549

5650
pub async fn set_project_repo(
57-
State(app_state): State<AppState>,
5851
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
52+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
5953
Path(project_id): Path<i32>,
6054
repo_url: Json<RepoUrlRequest>,
6155
) -> Result<Response, Response> {
62-
63-
// get database connection
64-
let mut conn = get_db_conn!(app_state);
65-
6656
// validate the url if provided
6757
if let Some(url) = &repo_url.repo_url {
6858
let parsed = url::Url::parse(url).map_err(|_| {

rustytime/src/handlers/github.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ use serde::{Deserialize, Serialize};
1515
use std::env;
1616
use tower_cookies::Cookies;
1717

18-
use crate::state::AppState;
18+
use crate::models::session::Session;
1919
use crate::utils::session::SessionManager;
20-
use crate::{get_db_conn, models::session::Session};
2120
use crate::{models::user::User, utils::env::is_production_env};
21+
use crate::{state::AppState, utils::extractors::DbConnection};
2222
use axum::Json;
2323
use tracing::error;
2424

@@ -137,6 +137,7 @@ pub async fn login(
137137
pub async fn callback(
138138
State(app_state): State<AppState>,
139139
cookies: NoApi<Cookies>,
140+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
140141
Query(params): Query<AuthRequest>,
141142
) -> Result<Redirect, Response> {
142143
let cookies = cookies.0;
@@ -202,9 +203,6 @@ pub async fn callback(
202203
}
203204
};
204205

205-
// get database connection
206-
let mut conn = get_db_conn!(app_state);
207-
208206
let (user, session) = match conn.transaction::<_, diesel::result::Error, _>(|conn| {
209207
// create or update user in database
210208
let user = User::create_or_update(
@@ -253,6 +251,7 @@ pub async fn callback(
253251
pub async fn verify_session(
254252
State(app_state): State<AppState>,
255253
Query(params): Query<serde_json::Value>,
254+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
256255
cookies: NoApi<Cookies>,
257256
) -> Result<Json<VerifySessionResponse>, Response> {
258257
let cookies = cookies.0;
@@ -272,7 +271,6 @@ pub async fn verify_session(
272271
match SessionManager::validate_session(&app_state.db_pool, session_id).await {
273272
Ok(Some(session_data)) => {
274273
// get user details
275-
let mut conn = get_db_conn!(app_state);
276274
let user = crate::schema::users::table
277275
.find(session_data.user_id)
278276
.first::<User>(&mut conn)
@@ -333,15 +331,12 @@ pub async fn verify_session(
333331

334332
/// Handler to log out the user
335333
pub async fn logout(
336-
State(app_state): State<AppState>,
334+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
337335
cookies: NoApi<Cookies>,
338336
) -> Result<Response, Response> {
339337
let cookies = cookies.0;
340338
// get session from cookie
341339
if let Some(session_id) = SessionManager::get_session_from_cookies(&cookies) {
342-
// delete session from database
343-
let mut conn = get_db_conn!(app_state);
344-
345340
diesel::delete(
346341
crate::schema::sessions::table.filter(crate::schema::sessions::id.eq(session_id)),
347342
)

rustytime/src/handlers/homepage.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use crate::state::AppState;
2-
use axum::{extract::State, response::Redirect};
1+
use axum::response::Redirect;
2+
33
/// Handler for the homepage
4-
pub async fn home_page(State(_app_state): State<AppState>) -> Result<Redirect, Redirect> {
4+
pub async fn home_page() -> Result<Redirect, Redirect> {
55
let frontend_url =
66
std::env::var("FRONTEND_URL").unwrap_or_else(|_| "http://localhost:5173".to_string());
77
Ok(Redirect::to(&frontend_url))

rustytime/src/handlers/page/admin.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ use schemars::JsonSchema;
1212
use serde::{Deserialize, Serialize};
1313
use tower_cookies::Cookies;
1414

15+
use crate::db_query;
1516
use crate::models::heartbeat::Heartbeat;
1617
use crate::models::session::Session;
1718
use crate::models::user::{PartialUser, User};
1819
use crate::state::AppState;
1920
use crate::utils::cache::CachedAdminStats;
21+
use crate::utils::extractors::{AuthenticatedUser, DbConnection};
2022
use crate::utils::session::{ImpersonationContext, SessionManager};
21-
use crate::utils::auth::AuthenticatedUser;
22-
use crate::{db_query, get_db_conn};
2323

2424
#[derive(Deserialize, JsonSchema)]
2525
pub struct AdminQuery {
@@ -56,8 +56,8 @@ pub async fn admin_dashboard(
5656
State(app_state): State<AppState>,
5757
Query(query): Query<AdminQuery>,
5858
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
59+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
5960
) -> Result<Json<AdminDashboardResponse>, Response> {
60-
6161
if !current_user.is_admin() {
6262
return Err((StatusCode::FORBIDDEN, "No permission").into_response());
6363
}
@@ -70,8 +70,6 @@ pub async fn admin_dashboard(
7070
let daily_activity = if let Some(cached) = cached {
7171
cached.daily_activity
7272
} else {
73-
let mut conn = get_db_conn!(app_state);
74-
7573
let raw_daily_activity = db_query!(
7674
Heartbeat::get_daily_activity_last_week(&mut conn),
7775
"Failed to fetch daily activity"
@@ -87,8 +85,6 @@ pub async fn admin_dashboard(
8785
raw_daily_activity
8886
};
8987

90-
let mut conn = get_db_conn!(app_state);
91-
9288
let total_heartbeats = db_query!(Heartbeat::total_heartbeat_count_estimate(&mut conn));
9389
let total_users = db_query!(User::count_total_users(&mut conn, false));
9490
let heartbeats_last_hour = db_query!(Heartbeat::count_heartbeats_last_hour(&mut conn));
@@ -142,6 +138,7 @@ pub async fn impersonate_user(
142138
cookies: NoApi<Cookies>,
143139
impersonation: NoApi<Option<Extension<ImpersonationContext>>>,
144140
NoApi(AuthenticatedUser(session_user)): NoApi<AuthenticatedUser>,
141+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
145142
) -> Result<StatusCode, Response> {
146143
let cookies = cookies.0;
147144
let impersonation = impersonation.0;
@@ -150,8 +147,6 @@ pub async fn impersonate_user(
150147
return Err((StatusCode::UNAUTHORIZED, "Session missing").into_response());
151148
};
152149

153-
let mut conn = get_db_conn!(app_state);
154-
155150
let Some(session_data) = db_query!(
156151
SessionManager::validate_session(&app_state.db_pool, session_id).await,
157152
"Failed to validate session"

rustytime/src/handlers/page/dashboard.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
use crate::db_query;
2+
use crate::models::heartbeat::Heartbeat;
13
use crate::models::heartbeat::{TimeRange, UsageStat};
24
use crate::state::AppState;
35
use crate::utils::cache::{CachedDashboardStats, DashboardCacheKey};
6+
use crate::utils::extractors::{AuthenticatedUser, DbConnection};
47
use crate::utils::session::SessionManager;
58
use crate::utils::time::{TimeFormat, human_readable_duration};
6-
use crate::utils::auth::AuthenticatedUser;
7-
use crate::{db_query, get_db_conn, models::heartbeat::Heartbeat};
89
use aide::NoApi;
910
use axum::{
1011
extract::{Query, State},
@@ -45,6 +46,7 @@ pub async fn dashboard(
4546
State(app_state): State<AppState>,
4647
cookies: NoApi<Cookies>,
4748
NoApi(AuthenticatedUser(user)): NoApi<AuthenticatedUser>,
49+
NoApi(DbConnection(mut conn)): NoApi<DbConnection>,
4850
Query(query): Query<DashboardQuery>,
4951
) -> Result<Json<DashboardResponse>, Response> {
5052
let cookies = cookies.0;
@@ -72,8 +74,6 @@ pub async fn dashboard(
7274
let (total_heartbeats, dashboard_stats) = if let Some(cached) = cached {
7375
(cached.heartbeat_count, cached.stats)
7476
} else {
75-
let mut conn = get_db_conn!(app_state);
76-
7777
let total_heartbeats = db_query!(
7878
Heartbeat::get_user_heartbeat_count_by_range(
7979
&mut conn,

0 commit comments

Comments
 (0)