Minor changes lumped together

* claim.rng is now seeded from 16 bytes
+ passing Member to auth::login_get_jwt
* Better error loggin on jwt::insert call

+ Moar meta config-caching fixes
Basically lazy static sucks and we have to start accessing meta::basic_config
though a proxy function which forces the initialization on startup
! We should probably init this prior to listening for connections to avoid connection issues

+ New /neighbors/list endpoint which has already passed required checks
This commit is contained in:
shockrah 2021-05-08 02:03:58 -07:00
parent 1c366611d9
commit cdb956a85c
2 changed files with 62 additions and 13 deletions

View File

@ -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<String> {
@ -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<hyper::Body>, user: Member) {
pub async fn login_get_jwt(p: &Pool, response: &mut hyper::Response<hyper::Body>, 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<hyper::Body>, 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;
}
}
}

View File

@ -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<String>
}
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<String> = 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<Body>) {
// 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<Body>) {
// 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);
}
}
}