diff --git a/json-api/src/auth.rs b/json-api/src/auth.rs index 40fda73..7bd20a4 100644 --- a/json-api/src/auth.rs +++ b/json-api/src/auth.rs @@ -1,6 +1,7 @@ use serde::{Serialize, Deserialize}; use bcrypt::{self, BcryptResult}; use mysql_async::Pool; +use hyper::StatusCode; use std::collections::HashMap; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -111,7 +112,7 @@ pub fn generate_secret() -> String { } pub fn generate_cookie() -> String { - return rng_secret(32) + return rng_secret(16) } pub fn encrypt_secret(raw: &str) -> BcryptResult { @@ -198,7 +199,6 @@ pub async fn wall_entry<'path, 'pool, 'params>( } if let Some(jwt) = jwt { - // get the headers here return valid_jwt(pool, path, jwt).await; } if let Some((id, secret)) = login_params_from_qs(params) { @@ -232,7 +232,7 @@ pub async fn wall_entry<'path, 'pool, 'params>( } } -pub async fn login_get_jwt(response: &mut hyper::Response, user: Member) { +pub async fn login_get_jwt(p: &Pool, response: &mut hyper::Response, user: Member) { // Login data has already been validated at this point // Required data such as 'id' and 'secret' are there and validated use jsonwebtoken::{ @@ -254,7 +254,13 @@ pub async fn login_get_jwt(response: &mut hyper::Response, user: Me response.headers_mut().insert("Content-Type", HeaderValue::from_static("application/json")); - http::set_json_body(response, serde_json::json!({"jwt": encoded})); + match db::jwt::insert(p, id, &claim.rng).await { + Ok(_) => http::set_json_body(response, serde_json::json!({"jwt": encoded})), + Err(e) => { + eprintln!("/login 500 {}", e); + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + } + } } diff --git a/json-api/src/meta.rs b/json-api/src/meta.rs index b21bfeb..0f14cbd 100644 --- a/json-api/src/meta.rs +++ b/json-api/src/meta.rs @@ -1,28 +1,71 @@ // Basic handler for getting meta data about the server use std::env::var; +use std::collections::HashMap; +use crate::http::set_json_body; -use hyper::{Response, Body}; -use serde_json::to_string; -use serde::Serialize; +use mysql_async::Pool; +use hyper::{Response, Body, StatusCode}; +use serde_json::{json, to_string}; +use serde::{Serialize, Deserialize}; +use lazy_static::lazy_static; - -#[derive( Serialize)] +#[derive(Debug, Serialize)] pub struct Config { pub name: String, pub description: String, pub url: String, pub wsurl: String, + pub tags: Vec +} + +lazy_static! { + // NOTE: this object must be access by proxy through get_config() + #[derive(Deserialize, Serialize)] + static ref BASIC_CONFIG: Config = { + let tags = var("SERVER_TAGS").unwrap(); + let tags: Vec = match serde_json::from_str(tags.as_str()).expect("Unable to parse tags") { + Some(tags) => tags, + None => vec![] + }; + + let cfg = Config { + name: var("SERVER_NAME").unwrap_or("No name".into()), + description: var("SERVER_DESCRIPTION").unwrap_or("No description".into()), + url: var("PUBLIC_URL").unwrap(), + wsurl: var("PUBLIC_WS_URL").unwrap(), + tags + }; + cfg + }; } pub fn get_config() -> Config { + // We have to do this (for now) because lazy_static silently hides the actual fields + // we care about Config { - name: var("SERVER_NAME").unwrap_or("No name".into()), - description: var("SERVER_DESCRIPTION").unwrap_or("No description".into()), - url: var("PUBLIC_URL").unwrap(), - wsurl: var("PUBLIC_WS_URL").unwrap() + name: BASIC_CONFIG.name.clone(), + description: BASIC_CONFIG.description.clone(), + url: BASIC_CONFIG.url.clone(), + wsurl: BASIC_CONFIG.wsurl.clone(), + tags: BASIC_CONFIG.tags.clone() } } pub async fn server_meta(response: &mut Response) { + // NOTE: This route _is_ open but we should do something to rate limit the + // number of requests we service as it could be ripe for abuse *response.body_mut() = Body::from(to_string(&get_config()).unwrap()); } + +pub async fn server_neighbors(p: &Pool, response: &mut Response) { + // This method refers to what servers have been added as **related** by the admins + // It returns a list of servers meta objects which converted to JSON + match db::Neighbor::get_all(p).await { + Ok(neighbors) => set_json_body(response, json!({"neighbors": neighbors})), + Err(e) => { + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + eprintln!("500 /neighbors/list {}", e); + } + } +} +