// Module handles creating invites for potentially new users use diesel::{self, prelude::*}; use rocket_contrib::json::Json; use chrono::{Duration, Utc}; use rand::random; use crate::auth::{join, AuthResult, AuthErr}; use crate::DBConn; use crate::models::{User, Invite}; use crate::schema; /* TODO: both the generation and usage endpoints for invites need the following * meaningful responses * authentication */ #[get("/generate")] pub fn generate_invite(conn: DBConn) -> Json { let dt = Utc::now() + Duration::minutes(30); // TODO:[maybe] ensure no collisions by doing a quick database check here let mut new_invite = Invite { id: random::(), // hopefully there won't ever be collision with this size of pool uses: 1, // default/hardcorded for now expires: dt.timestamp() as u64 }; // Next we cache this invite let result = diesel::insert_into(schema::invites::table) .values(&new_invite) .execute(&conn.0); // Finally we attempt to return _something_ match result { Ok(_val) => { Json(new_invite) } Err(_e) => { new_invite.id = 0; new_invite.expires = 0; new_invite.uses = 0; Json(new_invite) } } } // GET doesn't really like having data in its body for whatever reason // Problem: invite/joining system is gonna have to get a redesign #[get("/join//")] pub fn use_invite(hash: u64, name: String, conn: DBConn) -> AuthResult, AuthErr>{ join(conn, hash, name) } #[cfg(test)] mod invite_tests { use super::*; use rocket; use rocket::local::Client; use rocket::http::Status; use serde_json; #[test] fn request_invite() { let rocket = rocket::ignite() .mount("/invite", routes![generate_invite]) .attach(DBConn::fairing()); let client = Client::new(rocket).expect("Invalid rocket instance"); let mut response = client.get("/invite/generate").dispatch(); assert_eq!(response.status(), Status::Ok); match response.body_string() { Some(val) => { let invite: Result = serde_json::from_str(&val); match invite { Ok(val) => { println!("{:#?}", val) } Err(e) => { panic!("{}", e) } } } None => { println!("bro wtf"); } } } #[test] fn use_invite() { let app = rocket::ignite() .mount("/invite", routes![generate_invite, use_invite]) .attach(DBConn::fairing()); // We assume in this test that invite generation is fine let client = Client::new(app).expect("Invalid rocket instance"); let mut r = client.get("/invite/generate").dispatch(); let invite: Invite = serde_json::from_str(&r.body_string().unwrap()).unwrap(); // TODO: for some reason we can't use a regular struct so figure that out at some point let mut response = client.get(format!("/invite/{}", invite.id)).dispatch(); let body: String = response.body_string().unwrap(); println!("{}", body); } }