refactor: Move User guard to the model The User model didn't have the FromRequest 'constructor' for the guard. This felt off. Now some Request knowledge leaks to the model, but still it seems better.
Dependencies
- [2]
Y52KSJEFrocket: User sign up guard forwards over failures When no user can be found, the User implementation of FromRequest was failing, which is a mistake. This meant that no other routes were tried and thus assigning policies to routes failed. This changes fixes that by forwarding instead. To be frank, this is over forwarding, and can still be improved on. - [3]
Z63HIZPStesting: Move tests to specific directory Tests I didn't really write until today, as I mostly didn't really know how to set it up. This is now partially mitigated, just by forcing myself to do it. There's a few problems still in the code; the database is shared with the dev application for instance. Though as a start I'll take it. - [4]
RJ75MX6Yroutes: Move user routes to controllers module The last routes to move, the src directory now only has a main.rs file and directories. - [5]
E4OBIIUBtemplates: Fix navigation mocks Cleans up the directory structure for templates and fixes the navigation bugs in the applications too. Includes a context! macro which is lifted from upstream, but is currently unreleased. When rocket_dyn_templates is updates, it could be DRY'ed out. - [*]
TWIZ7QV4db: Add interface to add a project Right now a project has a name, and an owner which is hardcoded to 1. This is because basically I'm speedrunning to implement push/pull of Pijul and then revisit to add depth to features and tests. Model code is now split into files properly too.
Change contents
- edit in src/models/users.rs at line 55[7.3371][7.3371]
}}static COOKIE_USER_ID_KEY: &str = "user_id";use rocket::http::{CookieJar, Status};use rocket::request::{FromRequest, Outcome};use rocket::Request;#[rocket::async_trait]impl<'r> FromRequest<'r> for User {type Error = ();async fn from_request(request: &'r Request<'_>) -> Outcome<User, ()> {let db: &State<Database> = match request.guard().await {Outcome::Success(db) => db,_ => return Outcome::Failure((Status::Unauthorized, ())),};let cookies = request.cookies();let some_id = match get_user_id_from_cookie(cookies) {Some(id) => id,None => return Outcome::Forward(()),};match User::find(db, some_id).await {Ok(u) => Outcome::Success(u),Err(_e) => Outcome::Forward(()), // TODO this is a failure} - edit in src/models/users.rs at line 86[7.3379]
fn get_user_id_from_cookie(jar: &CookieJar) -> Option<i32> {match jar.get_private(COOKIE_USER_ID_KEY) {Some(id) => Some(id.value().parse::<i32>().ok()?),None => None,}} - replacement in src/controllers/users.rs at line 3
http::{Cookie, CookieJar, Status},request,request::{FromRequest, Outcome},http::{Cookie, CookieJar}, - replacement in src/controllers/users.rs at line 5
Request, Route, State,Route, State, - edit in src/controllers/users.rs at line 11[4.362]→[4.362:363](∅→∅),[4.363]→[3.2738:2874](∅→∅),[3.2874]→[4.437:518](∅→∅),[4.437]→[4.437:518](∅→∅),[4.518]→[2.98:368](∅→∅),[2.368]→[4.735:868](∅→∅),[4.735]→[4.735:868](∅→∅),[4.868]→[2.369:418](∅→∅),[2.418]→[4.941:952](∅→∅),[4.941]→[4.941:952](∅→∅)
// TODO decide if this controller file is the place for this guard to be at?// Feels like a constructor for a model, thus needs moving#[rocket::async_trait]impl<'r> FromRequest<'r> for User {type Error = ();async fn from_request(request: &'r Request<'_>) -> request::Outcome<User, ()> {let db: &State<Database> = match request.guard().await {Outcome::Success(db) => db,_ => return Outcome::Failure((Status::Unauthorized, ())),};let cookies = request.cookies();let some_id = match get_user_id_from_cookie(cookies) {Some(id) => id,None => return Outcome::Forward(()),}; - edit in src/controllers/users.rs at line 12[4.953]→[4.953:1041](∅→∅),[4.1041]→[2.419:490](∅→∅),[2.490]→[4.1110:1129](∅→∅),[4.1110]→[4.1110:1129](∅→∅)
match User::find(db, some_id).await {Ok(u) => Outcome::Success(u),Err(_e) => Outcome::Forward(()), // TODO this is a failure}}} - edit in src/controllers/users.rs at line 110
fn get_user_id_from_cookie(jar: &CookieJar) -> Option<i32> {match jar.get_private(COOKIE_USER_ID_KEY) {Some(id) => Some(id.value().parse::<i32>().ok()?),None => None,}}