
! This route needs way more testing as its currently failing the prelim test listed right now ! Some more misc changes in testing/mod.rs that aren't imporant at all to anyone It's just an extra comment
119 lines
4.3 KiB
Rust
119 lines
4.3 KiB
Rust
// Basic handler for getting meta data about the server
|
|
use std::collections::HashMap;
|
|
use crate::http::set_json_body;
|
|
use db::Neighbor;
|
|
|
|
use mysql_async::Pool;
|
|
use hyper::{Response, Body, StatusCode};
|
|
use hyper::body::to_bytes;
|
|
use hyper::body::Bytes;
|
|
use serde_json::{json, to_string, Result as JsonResult};
|
|
use serde::{Serialize, Deserialize};
|
|
use lazy_static::lazy_static;
|
|
|
|
#[derive(Debug, Deserialize, 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 = {
|
|
use std::fs::File;
|
|
use std::io::BufReader;
|
|
match File::open("config.json") {
|
|
Ok(file) => {
|
|
let reader = BufReader::new(file);
|
|
let rr: JsonResult<Config> = serde_json::from_reader(reader);
|
|
match rr {
|
|
Ok(meta) => meta,
|
|
Err(e) => panic!("{}", e)
|
|
}
|
|
|
|
},
|
|
Err(e) => panic!("{}", e)
|
|
}
|
|
};
|
|
}
|
|
|
|
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: 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::neighbors::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);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
pub async fn add_neighbor(p: &Pool, response: &mut Response<Body>, body: Body) {
|
|
let body: Bytes = to_bytes(body).await.unwrap_or(Bytes::new());
|
|
let json: JsonResult<Neighbor> = serde_json::from_slice(&body);
|
|
if let Ok(neighbor) = json {
|
|
// Before we try adding the new neighbor, make sure there isn't already
|
|
// an entry with the same url
|
|
if let Ok(row) = db::neighbors::get(p, &neighbor.url).await {
|
|
match row.is_some() {
|
|
true => *response.status_mut() = StatusCode::CONFLICT,
|
|
false => if let Err(e) = db::neighbors::add_neighbor(p, neighbor).await {
|
|
eprintln!("{}", e);
|
|
}
|
|
};
|
|
} else {
|
|
eprintln!();
|
|
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
|
}
|
|
} else {
|
|
*response.status_mut() = StatusCode::BAD_REQUEST;
|
|
}
|
|
}
|
|
|
|
pub async fn update_neighbor(p: &Pool, response: &mut Response<Body>, params: HashMap<String, String>, body: Body) {
|
|
// First collect the target url from the map and try to parse the body
|
|
let target = params.get("url");
|
|
let body: Bytes = to_bytes(body).await.unwrap_or(Bytes::new());
|
|
let s: String = String::from_utf8_lossy(&body).to_string();
|
|
let json: JsonResult<Neighbor> = serde_json::from_str(&s);
|
|
|
|
println!("\tjson result: {:?}", json);
|
|
println!("\tbody {}", s);
|
|
// Verify query string parameter **and** body before attempting to reach database
|
|
match (target, json) {
|
|
(Some(target_url), Ok(neighbor)) => {
|
|
// Only return a 500 if something happened on db-lib's end
|
|
if let Err(e) = db::neighbors::update(p, target_url, neighbor).await {
|
|
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
|
eprintln!("/neighbor/update [DB-LIB] {}", e);
|
|
}
|
|
// Nothing to do on success 200 is already set by hyper
|
|
},
|
|
_ => *response.status_mut() = StatusCode::BAD_REQUEST
|
|
}
|
|
}
|