Skip to content

Commit ab2df09

Browse files
committed
fix: use custom authenticated user extractor
1 parent 25a0901 commit ab2df09

File tree

10 files changed

+52
-108
lines changed

10 files changed

+52
-108
lines changed

rustytime/src/handlers/admin/mod.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
use aide::NoApi;
22
use axum::extract::Path;
33
use axum::{
4-
Extension,
54
extract::State,
65
http::StatusCode,
76
response::{IntoResponse, Response},
87
};
98

109
use crate::models::user::User;
1110
use crate::state::AppState;
11+
use crate::utils::auth::AuthenticatedUser;
1212
use crate::{db_query, get_db_conn};
1313

1414
pub async fn change_user_admin_level(
1515
State(app_state): State<AppState>,
1616
Path((user_id, new_level)): Path<(i32, i16)>,
17-
user: NoApi<Option<Extension<User>>>,
17+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
1818
) -> Result<StatusCode, Response> {
19-
let current_user = user
20-
.0
21-
.expect("User should be authenticated since middleware validated authentication")
22-
.0;
2319

2420
if !current_user.is_owner() {
2521
return Err((StatusCode::FORBIDDEN, "No permission").into_response());

rustytime/src/handlers/data/import.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use axum::extract::State;
44
use axum::http::StatusCode;
55
use axum::response::IntoResponse;
66
use axum::response::Response;
7-
use axum::{Extension, Json};
7+
use axum::Json;
88
use schemars::JsonSchema;
99
use serde::Deserialize;
1010
use serde::Serialize;
@@ -14,9 +14,9 @@ use tracing::{error, info};
1414
use crate::db_query;
1515
use crate::jobs::import::enqueue_import;
1616
use crate::models::import_job::{ImportJob, ImportJobStatus};
17-
use crate::models::user::User;
1817
use crate::state::AppState;
1918
use crate::utils::session::SessionManager;
19+
use crate::utils::auth::AuthenticatedUser;
2020

2121
#[derive(Deserialize, JsonSchema)]
2222
pub struct ImportQuery {
@@ -65,12 +65,8 @@ pub async fn import_heartbeats(
6565
State(app_state): State<AppState>,
6666
Query(query): Query<ImportQuery>,
6767
cookies: NoApi<Cookies>,
68-
user: NoApi<Option<Extension<User>>>,
68+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
6969
) -> Result<Json<ImportStartResponse>, Response> {
70-
let current_user = user
71-
.0
72-
.expect("User should be authenticated since middleware validated authentication")
73-
.0;
7470

7571
let Some(session_id) = SessionManager::get_session_from_cookies(&cookies) else {
7672
return Err((StatusCode::UNAUTHORIZED, "User session is invalid").into_response());
@@ -153,13 +149,8 @@ pub async fn import_heartbeats(
153149

154150
pub async fn import_status(
155151
State(app_state): State<AppState>,
156-
user: NoApi<Option<Extension<User>>>,
152+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
157153
) -> Result<Json<ImportStatusResponse>, Response> {
158-
let current_user = user
159-
.0
160-
.expect("User should be authenticated since middleware validated authentication")
161-
.0;
162-
163154
let user_id = current_user.id;
164155

165156
let job = db_query!(

rustytime/src/handlers/data/project_aliases.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use crate::models::project_alias::{NewProjectAlias, ProjectAlias as ProjectAliasModel};
2-
use crate::models::user::User;
32
use crate::state::AppState;
3+
use crate::utils::auth::AuthenticatedUser;
44
use crate::{db_query, get_db_conn};
55
use aide::NoApi;
66
use axum::Json;
77
use axum::extract::Path;
88
use axum::{
9-
Extension,
109
extract::State,
1110
http::StatusCode,
1211
response::{IntoResponse, Response},
@@ -35,13 +34,8 @@ pub struct ProjectAliasesResponse {
3534
/// Handler for the project aliases
3635
pub async fn project_aliases(
3736
State(app_state): State<AppState>,
38-
user: NoApi<Option<Extension<User>>>,
37+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
3938
) -> Result<Json<ProjectAliasesResponse>, Response> {
40-
// get current user
41-
let current_user = user
42-
.0
43-
.expect("User should be authenticated since middleware validated authentication")
44-
.0;
4539

4640
// get database connection
4741
let mut conn = get_db_conn!(app_state);
@@ -78,13 +72,9 @@ pub async fn project_aliases(
7872

7973
pub async fn add_project_alias(
8074
State(app_state): State<AppState>,
81-
user: NoApi<Option<Extension<User>>>,
75+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
8276
Path((id, alias_id)): Path<(i32, i32)>,
8377
) -> Result<StatusCode, Response> {
84-
let current_user = user
85-
.0
86-
.expect("User should be authenticated since middleware validated authentication")
87-
.0;
8878

8979
let mut conn = get_db_conn!(app_state);
9080

@@ -104,13 +94,9 @@ pub async fn add_project_alias(
10494

10595
pub async fn delete_project_alias(
10696
State(app_state): State<AppState>,
107-
user: NoApi<Option<Extension<User>>>,
97+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
10898
Path(id): Path<i32>,
10999
) -> Result<StatusCode, Response> {
110-
let current_user = user
111-
.0
112-
.expect("User should be authenticated since middleware validated authentication")
113-
.0;
114100

115101
let mut conn = get_db_conn!(app_state);
116102

rustytime/src/handlers/data/projects.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use crate::models::project::Project as ProjectModel;
2-
use crate::models::user::User;
32
use crate::state::AppState;
3+
use crate::utils::auth::AuthenticatedUser;
44
use crate::{db_query, get_db_conn};
55
use aide::NoApi;
66
use axum::Json;
77
use axum::extract::Path;
88
use axum::{
9-
Extension,
109
extract::State,
1110
http::StatusCode,
1211
response::{IntoResponse, Response},
@@ -33,13 +32,8 @@ pub struct RepoUrlRequest {
3332
/// Handler for the projects list
3433
pub async fn projects_list(
3534
State(app_state): State<AppState>,
36-
user: NoApi<Option<Extension<User>>>,
35+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
3736
) -> Result<Json<ProjectsListResponse>, Response> {
38-
// get current user
39-
let current_user = user
40-
.0
41-
.expect("User should be authenticated since middleware validated authentication")
42-
.0;
4337

4438
// get database connection
4539
let mut conn = get_db_conn!(app_state);
@@ -61,15 +55,10 @@ pub async fn projects_list(
6155

6256
pub async fn set_project_repo(
6357
State(app_state): State<AppState>,
64-
user: NoApi<Option<Extension<User>>>,
58+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
6559
Path(project_id): Path<i32>,
6660
repo_url: Json<RepoUrlRequest>,
6761
) -> Result<Response, Response> {
68-
// get current user
69-
let current_user = user
70-
.0
71-
.expect("User should be authenticated since middleware validated authentication")
72-
.0;
7362

7463
// get database connection
7564
let mut conn = get_db_conn!(app_state);

rustytime/src/handlers/page/admin.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::models::user::{PartialUser, User};
1818
use crate::state::AppState;
1919
use crate::utils::cache::CachedAdminStats;
2020
use crate::utils::session::{ImpersonationContext, SessionManager};
21+
use crate::utils::auth::AuthenticatedUser;
2122
use crate::{db_query, get_db_conn};
2223

2324
#[derive(Deserialize, JsonSchema)]
@@ -54,13 +55,8 @@ pub struct AdminDashboardResponse {
5455
pub async fn admin_dashboard(
5556
State(app_state): State<AppState>,
5657
Query(query): Query<AdminQuery>,
57-
user: NoApi<Option<Extension<User>>>,
58+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
5859
) -> Result<Json<AdminDashboardResponse>, Response> {
59-
// check if user is an admin
60-
let current_user = user
61-
.0
62-
.expect("User should be authenticated since middleware validated authentication")
63-
.0;
6460

6561
if !current_user.is_admin() {
6662
return Err((StatusCode::FORBIDDEN, "No permission").into_response());
@@ -145,14 +141,10 @@ pub async fn impersonate_user(
145141
Path(user_id): Path<i64>,
146142
cookies: NoApi<Cookies>,
147143
impersonation: NoApi<Option<Extension<ImpersonationContext>>>,
148-
user: NoApi<Option<Extension<User>>>,
144+
NoApi(AuthenticatedUser(session_user)): NoApi<AuthenticatedUser>,
149145
) -> Result<StatusCode, Response> {
150146
let cookies = cookies.0;
151147
let impersonation = impersonation.0;
152-
let session_user = user
153-
.0
154-
.expect("User should be authenticated since middleware validated authentication")
155-
.0;
156148

157149
let Some(session_id) = SessionManager::get_session_from_cookies(&cookies) else {
158150
return Err((StatusCode::UNAUTHORIZED, "Session missing").into_response());

rustytime/src/handlers/page/dashboard.rs

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use crate::models::heartbeat::{TimeRange, UsageStat};
2-
use crate::models::user::User;
32
use crate::state::AppState;
43
use crate::utils::cache::{CachedDashboardStats, DashboardCacheKey};
54
use crate::utils::session::SessionManager;
65
use crate::utils::time::{TimeFormat, human_readable_duration};
6+
use crate::utils::auth::AuthenticatedUser;
77
use crate::{db_query, get_db_conn, models::heartbeat::Heartbeat};
88
use aide::NoApi;
99
use axum::{
10-
Extension,
1110
extract::{Query, State},
1211
http::StatusCode,
1312
response::{IntoResponse, Json, Response},
@@ -45,33 +44,21 @@ pub struct DashboardResponse {
4544
pub async fn dashboard(
4645
State(app_state): State<AppState>,
4746
cookies: NoApi<Cookies>,
48-
user: Option<Extension<User>>,
47+
NoApi(AuthenticatedUser(user)): NoApi<AuthenticatedUser>,
4948
Query(query): Query<DashboardQuery>,
5049
) -> Result<Json<DashboardResponse>, Response> {
5150
let cookies = cookies.0;
52-
// check if user is authenticated
53-
if user.is_none() {
54-
return Err((
55-
StatusCode::INTERNAL_SERVER_ERROR,
56-
"User should be authenticated since middleware validated authentication",
57-
)
58-
.into_response());
59-
}
60-
let user = user.unwrap().0;
6151

6252
// get user's session info
63-
let session_id = SessionManager::get_session_from_cookies(&cookies)
64-
.expect("Session should exist since middleware validated authentication");
53+
let Some(session_id) = SessionManager::get_session_from_cookies(&cookies) else {
54+
return Err((StatusCode::UNAUTHORIZED, "Session missing").into_response());
55+
};
6556

6657
let Some(session_data) = db_query!(
6758
SessionManager::validate_session(&app_state.db_pool, session_id).await,
6859
"Session validation error"
6960
) else {
70-
return Err((
71-
StatusCode::INTERNAL_SERVER_ERROR,
72-
"User should be authenticated since middleware validated authentication",
73-
)
74-
.into_response());
61+
return Err((StatusCode::UNAUTHORIZED, "Session invalid").into_response());
7562
};
7663

7764
let user_timezone = user.timezone.clone();

rustytime/src/handlers/page/imports.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use aide::NoApi;
22
use axum::Json;
33
use axum::extract::Query;
44
use axum::{
5-
Extension, extract::State, http::StatusCode, response::IntoResponse, response::Response,
5+
extract::State, http::StatusCode, response::IntoResponse, response::Response,
66
};
77
use schemars::JsonSchema;
88
use serde::{Deserialize, Serialize};
@@ -11,6 +11,7 @@ use crate::db_query;
1111
use crate::models::import_job::ImportJob;
1212
use crate::models::user::User;
1313
use crate::state::AppState;
14+
use crate::utils::auth::AuthenticatedUser;
1415

1516
#[derive(Deserialize, JsonSchema)]
1617
pub struct ImportsQuery {
@@ -52,12 +53,8 @@ pub struct AdminImportsResponse {
5253
pub async fn admin_imports(
5354
State(app_state): State<AppState>,
5455
Query(query): Query<ImportsQuery>,
55-
user: NoApi<Option<Extension<User>>>,
56+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
5657
) -> Result<Json<AdminImportsResponse>, Response> {
57-
let current_user = user
58-
.0
59-
.expect("User should be authenticated since middleware validated authentication")
60-
.0;
6158

6259
if !current_user.is_admin() {
6360
return Err((StatusCode::FORBIDDEN, "No permission").into_response());

rustytime/src/handlers/page/projects.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use crate::models::project::Project as ProjectModel;
2-
use crate::models::user::User;
32
use crate::state::AppState;
43
use crate::utils::time::{TimeFormat, human_readable_duration};
4+
use crate::utils::auth::AuthenticatedUser;
55
use crate::{db_query, get_db_conn};
66
use aide::NoApi;
77
use axum::Json;
88
use axum::{
9-
Extension,
109
extract::State,
1110
http::StatusCode,
1211
response::{IntoResponse, Response},
@@ -34,13 +33,8 @@ pub struct ProjectsDashboardResponse {
3433
/// Handler for the projects dashboard page
3534
pub async fn projects_dashboard(
3635
State(app_state): State<AppState>,
37-
user: NoApi<Option<Extension<User>>>,
36+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
3837
) -> Result<Json<ProjectsDashboardResponse>, Response> {
39-
// get current user
40-
let current_user = user
41-
.0
42-
.expect("User should be authenticated since middleware validated authentication")
43-
.0;
4438

4539
// get database connection
4640
let mut conn = get_db_conn!(app_state);

rustytime/src/handlers/page/settings.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ use std::env;
33
use crate::models::user::User;
44
use crate::state::AppState;
55
use crate::utils::session::SessionManager;
6+
use crate::utils::auth::AuthenticatedUser;
67
use crate::{db_query, get_db_conn};
78
use aide::NoApi;
89
use axum::Json;
910
use axum::extract::State;
1011
use axum::response::Redirect;
1112
use axum::{
12-
Extension,
1313
http::StatusCode,
1414
response::{IntoResponse, Response},
1515
};
@@ -42,14 +42,9 @@ pub struct UpdateSettingsResponse {
4242
pub async fn settings_page(
4343
State(app_state): State<AppState>,
4444
cookies: NoApi<Cookies>,
45-
user: NoApi<Option<Extension<User>>>,
45+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
4646
) -> Result<Json<SettingsResponse>, Response> {
4747
let cookies = cookies.0;
48-
// get current user
49-
let current_user = user
50-
.0
51-
.expect("User should be authenticated since middleware validated authentication")
52-
.0;
5348

5449
let frontend_url =
5550
env::var("FRONTEND_URL").unwrap_or_else(|_| "http://localhost:5173".to_string());
@@ -87,13 +82,9 @@ pub async fn settings_page(
8782
/// Handler for updating user settings
8883
pub async fn update_settings(
8984
State(app_state): State<AppState>,
90-
user: NoApi<Option<Extension<User>>>,
85+
NoApi(AuthenticatedUser(current_user)): NoApi<AuthenticatedUser>,
9186
Json(request): Json<UpdateSettingsRequest>,
9287
) -> Result<Json<UpdateSettingsResponse>, Response> {
93-
let current_user = user
94-
.0
95-
.expect("User should be authenticated since middleware validated authentication")
96-
.0;
9788

9889
let mut conn = get_db_conn!(app_state);
9990

0 commit comments

Comments
 (0)