Improve security

This commit is contained in:
2026-06-12 19:22:07 +02:00
parent 0820ce6ef7
commit b457b8abaa
31 changed files with 1266 additions and 169 deletions
+38 -13
View File
@@ -1,7 +1,8 @@
use actix_web::{web, HttpRequest, Responder};
use actix_web::{web, HttpRequest, HttpResponse, Responder};
use diesel::prelude::*;
use crate::{
auth::extractor::AuthUser,
database::establish_connection,
error::AppError,
json_serialization::feed_info::{FeedInfo, FeedInfoList},
@@ -12,10 +13,15 @@ use crate::{
pub async fn list_feeds(
path: web::Path<JsonUser>,
req: HttpRequest,
) -> Result<impl Responder, AppError> {
auth_user: AuthUser,
) -> Result<HttpResponse, AppError> {
let request = req.clone();
let req_user_id = path.user_id;
if auth_user.0 != req_user_id {
return Ok(HttpResponse::Forbidden().finish());
}
let mut connection = establish_connection();
let feeds = feed::table
.filter(user_id.eq(req_user_id))
@@ -27,15 +33,19 @@ pub async fn list_feeds(
.map(|(id, title, url)| FeedInfo { id, title, url })
.collect();
Ok(FeedInfoList { feeds: feed_list }.respond_to(&request))
Ok(FeedInfoList { feeds: feed_list }
.respond_to(&request)
.map_into_boxed_body())
}
#[cfg(test)]
mod tests {
use actix_service::Service;
use actix_web::http::StatusCode;
use actix_web::{test, web, App};
use actix_web::{test, web, App, HttpMessage};
use super::list_feeds;
use crate::auth::extractor::AuthUser;
use crate::database::establish_connection;
use crate::test_helpers::{delete_feed, delete_user, insert_feed, insert_user};
@@ -45,8 +55,14 @@ mod tests {
let user = insert_user(&mut connection, "secret");
let feed = insert_feed(&mut connection, user.id);
let user_id = user.id;
let app = test::init_service(
App::new().route("/feeds/{user_id}", web::get().to(list_feeds)),
App::new()
.wrap_fn(move |req, srv| {
req.extensions_mut().insert(AuthUser(user_id));
srv.call(req)
})
.route("/feeds/{user_id}", web::get().to(list_feeds)),
)
.await;
let req = test::TestRequest::get()
@@ -69,8 +85,14 @@ mod tests {
let mut connection = establish_connection();
let user = insert_user(&mut connection, "secret");
let user_id = user.id;
let app = test::init_service(
App::new().route("/feeds/{user_id}", web::get().to(list_feeds)),
App::new()
.wrap_fn(move |req, srv| {
req.extensions_mut().insert(AuthUser(user_id));
srv.call(req)
})
.route("/feeds/{user_id}", web::get().to(list_feeds)),
)
.await;
let req = test::TestRequest::get()
@@ -87,25 +109,28 @@ mod tests {
}
#[actix_web::test]
async fn list_feeds_does_not_return_other_users_feeds() {
async fn list_feeds_rejects_requests_for_another_user() {
let mut connection = establish_connection();
let user_a = insert_user(&mut connection, "secret");
let user_b = insert_user(&mut connection, "secret");
let feed_b = insert_feed(&mut connection, user_b.id);
let user_a_id = user_a.id;
let app = test::init_service(
App::new().route("/feeds/{user_id}", web::get().to(list_feeds)),
App::new()
.wrap_fn(move |req, srv| {
req.extensions_mut().insert(AuthUser(user_a_id));
srv.call(req)
})
.route("/feeds/{user_id}", web::get().to(list_feeds)),
)
.await;
let req = test::TestRequest::get()
.uri(&format!("/feeds/{}", user_a.id))
.uri(&format!("/feeds/{}", user_b.id))
.to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(StatusCode::OK, resp.status());
let body = test::read_body(resp).await;
let body_str = String::from_utf8(body.to_vec()).unwrap();
assert!(!body_str.contains(&feed_b.title));
assert_eq!(StatusCode::FORBIDDEN, resp.status());
delete_feed(&mut connection, feed_b.id);
delete_user(&mut connection, user_a.id);