Merge pull request #4 from RaspberryProgramming/ownership_registraton
Added ownership registration page.
This commit is contained in:
commit
1d97eb1b78
|
|
@ -65,9 +65,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.80"
|
version = "0.1.81"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -169,9 +169,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.104"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490"
|
checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
|
@ -246,9 +246,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
version = "0.20.9"
|
version = "0.20.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
|
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"darling_macro",
|
"darling_macro",
|
||||||
|
|
@ -256,9 +256,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling_core"
|
name = "darling_core"
|
||||||
version = "0.20.9"
|
version = "0.20.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
|
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fnv",
|
"fnv",
|
||||||
"ident_case",
|
"ident_case",
|
||||||
|
|
@ -270,9 +270,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling_macro"
|
name = "darling_macro"
|
||||||
version = "0.20.9"
|
version = "0.20.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
|
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -674,9 +674,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "0.14.29"
|
version = "0.14.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33"
|
checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
|
|
@ -1277,11 +1277,12 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "request-mirror"
|
name = "request-mirror"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
|
"regex",
|
||||||
"rocket",
|
"rocket",
|
||||||
"rocket_dyn_templates",
|
"rocket_dyn_templates",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -1497,18 +1498,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.203"
|
version = "1.0.204"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
|
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.203"
|
version = "1.0.204"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -1621,9 +1622,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.68"
|
version = "2.0.70"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9"
|
checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -1790,9 +1791,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.22.14"
|
version = "0.22.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
|
checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -1925,9 +1926,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.9.1"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439"
|
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"rand",
|
"rand",
|
||||||
|
|
@ -1936,9 +1937,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid-macro-internal"
|
name = "uuid-macro-internal"
|
||||||
version = "1.9.1"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3ff64d5cde1e2cb5268bdb497235b6bd255ba8244f910dbc3574e59593de68c"
|
checksum = "ee1cd046f83ea2c4e920d6ee9f7c3537ef928d75dce5d84a87c2c5d6b3999a3a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "request-mirror"
|
name = "request-mirror"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
@ -9,6 +9,7 @@ edition = "2021"
|
||||||
chrono = "0.4.34"
|
chrono = "0.4.34"
|
||||||
diesel = { version = "2.1.4", features = ["postgres", "chrono"] }
|
diesel = { version = "2.1.4", features = ["postgres", "chrono"] }
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
|
regex = "1.10.5"
|
||||||
rocket = { version = "0.5.1", features = ["tls"] }
|
rocket = { version = "0.5.1", features = ["tls"] }
|
||||||
serde = { version = "1.0.197", features = ["derive"] }
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
serde_json = "1.0.114"
|
serde_json = "1.0.114"
|
||||||
|
|
|
||||||
45
src/lib.rs
45
src/lib.rs
|
|
@ -6,10 +6,18 @@ use diesel::prelude::*;
|
||||||
use std::env;
|
use std::env;
|
||||||
use dotenvy::dotenv;
|
use dotenvy::dotenv;
|
||||||
use models::{
|
use models::{
|
||||||
Client, NewClient, NewHistoryRecord, NewPairRecord, PairType
|
Client,
|
||||||
|
NewClient,
|
||||||
|
NewHistoryRecord,
|
||||||
|
NewPairRecord,
|
||||||
|
PairType,
|
||||||
|
Ownership
|
||||||
};
|
};
|
||||||
use schema::{
|
use schema::{
|
||||||
clients, history, pair_records
|
clients,
|
||||||
|
history,
|
||||||
|
pair_records,
|
||||||
|
ownership
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Establishes diesel Postgres connection that can be used to iteract with the database
|
/// Establishes diesel Postgres connection that can be used to iteract with the database
|
||||||
|
|
@ -88,3 +96,36 @@ pub fn create_pair_record(conn: &mut PgConnection, history_id: i64, pair_type: P
|
||||||
.values(&new_pair_record)
|
.values(&new_pair_record)
|
||||||
.execute(conn).unwrap()
|
.execute(conn).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new ownership record in the database
|
||||||
|
/// Pass the owner_id and client_id
|
||||||
|
pub fn create_owner_record(conn: &mut PgConnection, owner_id: String, client_id: String) -> usize {
|
||||||
|
let new_ownership_record = Ownership {
|
||||||
|
owner_id,
|
||||||
|
client_id
|
||||||
|
};
|
||||||
|
|
||||||
|
diesel::insert_into(ownership::table)
|
||||||
|
.values(&new_ownership_record)
|
||||||
|
.execute(conn).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// retrieve a Vec of ownership relationships which client_id owns
|
||||||
|
pub fn get_ownerships(client_id: &str, connection: &mut PgConnection) -> Vec<Ownership> {
|
||||||
|
ownership::dsl::ownership
|
||||||
|
.filter(ownership::owner_id.eq(client_id))
|
||||||
|
.select(Ownership::as_select())
|
||||||
|
.load(connection)
|
||||||
|
.expect("Error loading history records")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns boolean for whether the given ownership exists between client_id and owner_id
|
||||||
|
pub fn ownership_exists(client_id: &str, owner_id: &str, connection: &mut PgConnection) -> bool {
|
||||||
|
let ownerships = ownership::dsl::ownership
|
||||||
|
.filter(ownership::client_id.eq(client_id).and(ownership::owner_id.eq(owner_id)))
|
||||||
|
.select(Ownership::as_select())
|
||||||
|
.load(connection)
|
||||||
|
.expect("Error loading history records");
|
||||||
|
|
||||||
|
ownerships.len() > 0
|
||||||
|
}
|
||||||
|
|
|
||||||
98
src/main.rs
98
src/main.rs
|
|
@ -13,22 +13,33 @@ use uuid::Uuid;
|
||||||
use request_mirror::models::*;
|
use request_mirror::models::*;
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use request_mirror::*;
|
use request_mirror::*;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
/// Contains information about a request
|
||||||
#[derive(Serialize, Debug, Clone)]
|
#[derive(Serialize, Debug, Clone)]
|
||||||
struct RequestInfo {
|
pub struct RequestInfo {
|
||||||
header: Vec<Pair>,
|
header: Vec<Pair>,
|
||||||
cookies: Vec<Pair>,
|
cookies: Vec<Pair>,
|
||||||
query: Vec<Pair>
|
query: Vec<Pair>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
impl RequestInfo {
|
||||||
enum Error {
|
/// Find query pair with given key
|
||||||
TooLarge,
|
pub fn find_query_key(&self, key: &str) -> Option<&Pair> {
|
||||||
Io(std::io::Error),
|
|
||||||
|
for pair in self.query.iter() {
|
||||||
|
if pair.key == key {
|
||||||
|
return Some(pair);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Contains string representation of body of a request
|
||||||
#[derive(Serialize, Debug, Clone)]
|
#[derive(Serialize, Debug, Clone)]
|
||||||
struct RequestBody(String);
|
pub struct RequestBody(String);
|
||||||
|
|
||||||
// Always use a limit to prevent DoS attacks.
|
// Always use a limit to prevent DoS attacks.
|
||||||
const LIMIT: u64 = 256;
|
const LIMIT: u64 = 256;
|
||||||
|
|
@ -257,12 +268,28 @@ fn history_req(cookies: &CookieJar<'_>) -> Template {
|
||||||
let connection = &mut establish_connection();
|
let connection = &mut establish_connection();
|
||||||
|
|
||||||
// Query the database for history records
|
// Query the database for history records
|
||||||
let results = history::dsl::history
|
let mut results = history::dsl::history
|
||||||
.filter(history::client_id.eq(client_id.to_string()))
|
.filter(history::client_id.eq(client_id.to_string()))
|
||||||
.select(HistoryRecord::as_select())
|
.select(HistoryRecord::as_select())
|
||||||
.load(connection)
|
.load(connection)
|
||||||
.expect("Error loading clients");
|
.expect("Error loading clients");
|
||||||
|
|
||||||
|
// Get ownership relationships
|
||||||
|
let ownerships: Vec<Ownership> = get_ownerships(client_id, connection);
|
||||||
|
|
||||||
|
// Add any records that owned clients have
|
||||||
|
for ownership in ownerships {
|
||||||
|
let mut owned_records: Vec<HistoryRecord> = history::dsl::history
|
||||||
|
.filter(history::client_id.eq(ownership.client_id.to_string()))
|
||||||
|
.select(HistoryRecord::as_select())
|
||||||
|
.load(connection)
|
||||||
|
.expect("Error loading history records");
|
||||||
|
|
||||||
|
results.append(&mut owned_records);
|
||||||
|
}
|
||||||
|
|
||||||
|
results.sort_unstable_by_key(|item| item.id);
|
||||||
|
|
||||||
/// Template Context
|
/// Template Context
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct Context {
|
struct Context {
|
||||||
|
|
@ -302,13 +329,19 @@ fn history_details(history_id: i64, cookies: &CookieJar<'_>) -> Template {
|
||||||
|
|
||||||
let client_id = cookies.get("mirror-id").unwrap().value();
|
let client_id = cookies.get("mirror-id").unwrap().value();
|
||||||
|
|
||||||
let connection = &mut establish_connection();
|
let connection: &mut PgConnection = &mut establish_connection();
|
||||||
|
|
||||||
|
// Get owned client ids
|
||||||
|
let owned_clients: Vec<String> = get_ownerships(client_id, connection)
|
||||||
|
.iter()
|
||||||
|
.map(|x|x.client_id.to_string())
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
// Query history table where the history id is what was in the route. Also filter client_ids.
|
// Query history table where the history id is what was in the route. Also filter client_ids.
|
||||||
// If this record has a different client_id nothing will be returned
|
// If this record has a different client_id nothing will be returned
|
||||||
let results: Vec<HistoryRecord> = history::dsl::history
|
let results: Vec<HistoryRecord> = history::dsl::history
|
||||||
.filter(history::id.eq(&history_id))
|
.filter(history::id.eq(&history_id))
|
||||||
.filter(history::client_id.eq(client_id.to_string()))
|
.filter(history::client_id.eq(client_id.to_string()).or(history::client_id.eq_any(owned_clients)))
|
||||||
.select(HistoryRecord::as_select())
|
.select(HistoryRecord::as_select())
|
||||||
.load(connection)
|
.load(connection)
|
||||||
.expect("Error loading history records");
|
.expect("Error loading history records");
|
||||||
|
|
@ -322,8 +355,6 @@ fn history_details(history_id: i64, cookies: &CookieJar<'_>) -> Template {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let connection = &mut establish_connection();
|
|
||||||
|
|
||||||
// Query all Pair Records for this history_id
|
// Query all Pair Records for this history_id
|
||||||
let pairs: Vec<PairRecord> = pair_records::dsl::pair_records
|
let pairs: Vec<PairRecord> = pair_records::dsl::pair_records
|
||||||
.filter(pair_records::history_id.eq(history_id))
|
.filter(pair_records::history_id.eq(history_id))
|
||||||
|
|
@ -381,6 +412,48 @@ fn history_details(history_id: i64, cookies: &CookieJar<'_>) -> Template {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/ownership_registration")]
|
||||||
|
fn ownership_registration(info: RequestInfo, cookies: &CookieJar<'_>) -> Template {
|
||||||
|
|
||||||
|
let client_id = cookies.get("mirror-id").unwrap().value().to_string();
|
||||||
|
let owner_id_pair = info.find_query_key("owner_id");
|
||||||
|
let mut disp_owner_reg = false;
|
||||||
|
let re = Regex::new(r"^[{]?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}]?$").unwrap();
|
||||||
|
let connection: &mut PgConnection = &mut establish_connection();
|
||||||
|
let ownerships: Vec<Ownership> = get_ownerships(&client_id, connection);
|
||||||
|
|
||||||
|
let owner_id = match owner_id_pair {
|
||||||
|
Some(v) => v.value.to_string(),
|
||||||
|
None => "".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
if
|
||||||
|
owner_id_pair.is_some() &&
|
||||||
|
re.is_match(&owner_id) &&
|
||||||
|
owner_id != client_id &&
|
||||||
|
!ownership_exists(&client_id, &owner_id, connection)
|
||||||
|
{
|
||||||
|
create_owner_record(connection, owner_id.clone(), client_id.clone());
|
||||||
|
disp_owner_reg = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Context{
|
||||||
|
client_id: String,
|
||||||
|
owner_id: String,
|
||||||
|
disp_owner_reg: bool,
|
||||||
|
ownerships: Vec<Ownership>
|
||||||
|
}
|
||||||
|
|
||||||
|
Template::render("ownership_registration", Context {
|
||||||
|
client_id,
|
||||||
|
owner_id,
|
||||||
|
disp_owner_reg,
|
||||||
|
ownerships
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// 404 Response
|
/// 404 Response
|
||||||
#[catch(404)]
|
#[catch(404)]
|
||||||
fn not_found(req: &Request) -> Template {
|
fn not_found(req: &Request) -> Template {
|
||||||
|
|
@ -402,7 +475,8 @@ fn rocket() -> _ {
|
||||||
test_get,
|
test_get,
|
||||||
test_post,
|
test_post,
|
||||||
history_req,
|
history_req,
|
||||||
history_details
|
history_details,
|
||||||
|
ownership_registration
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
.register("/", catchers![not_found])
|
.register("/", catchers![not_found])
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use serde::Serialize;
|
||||||
use crate::schema::{
|
use crate::schema::{
|
||||||
clients,
|
clients,
|
||||||
history,
|
history,
|
||||||
|
ownership,
|
||||||
pair_records
|
pair_records
|
||||||
};
|
};
|
||||||
use diesel::pg::Pg;
|
use diesel::pg::Pg;
|
||||||
|
|
@ -58,6 +59,16 @@ pub struct NewHistoryRecord<'a> {
|
||||||
pub timestamp: NaiveDateTime
|
pub timestamp: NaiveDateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used to store ownership relationship between two clients
|
||||||
|
/// This structure is used for allowing separate clients to view history records of other clients
|
||||||
|
#[derive(Queryable, Selectable, Insertable, Debug, Serialize)]
|
||||||
|
#[diesel(table_name = ownership)]
|
||||||
|
#[diesel(check_for_backend(Pg))]
|
||||||
|
pub struct Ownership {
|
||||||
|
pub owner_id: String,
|
||||||
|
pub client_id: String
|
||||||
|
}
|
||||||
|
|
||||||
/// Pair Records are used to store attributes of a request. This includes a body record, header, query and cookie record.
|
/// Pair Records are used to store attributes of a request. This includes a body record, header, query and cookie record.
|
||||||
/// Each has a key and value.
|
/// Each has a key and value.
|
||||||
#[derive(Queryable, Selectable, Debug, Serialize)]
|
#[derive(Queryable, Selectable, Debug, Serialize)]
|
||||||
|
|
@ -105,3 +116,10 @@ pub struct Pair {
|
||||||
pub struct ErrorContext {
|
pub struct ErrorContext {
|
||||||
pub error_msg: String
|
pub error_msg: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Provides error context for
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
TooLarge,
|
||||||
|
Io(std::io::Error),
|
||||||
|
}
|
||||||
|
|
@ -8,18 +8,11 @@
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="d-flex flex-column">
|
<body class="d-flex flex-column">
|
||||||
<nav id="navbar" class="navbar navbar-expand-lg bg-body-tertiary mb-2">
|
<nav id="navbar" class="navbar navbar-expand-lg bg-body-tertiary mb-5">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="/">Request Mirror</a>
|
<a class="navbar-brand" href="/">Request Mirror</a>
|
||||||
<button
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
|
||||||
class="navbar-toggler"
|
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
type="button"
|
|
||||||
data-bs-toggle="collapse"
|
|
||||||
data-bs-target="#navbarSupportedContent"
|
|
||||||
aria-controls="navbarSupportedContent"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-label="Toggle navigation"
|
|
||||||
>
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
|
@ -33,6 +26,9 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/history">History</a>
|
<a class="nav-link" href="/history">History</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/ownership_registration">Ownership Registration</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,8 @@
|
||||||
<nav id="navbar" class="navbar navbar-expand-lg bg-body-tertiary mb-5">
|
<nav id="navbar" class="navbar navbar-expand-lg bg-body-tertiary mb-5">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="/">Request Mirror</a>
|
<a class="navbar-brand" href="/">Request Mirror</a>
|
||||||
<button
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
|
||||||
class="navbar-toggler"
|
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
type="button"
|
|
||||||
data-bs-toggle="collapse"
|
|
||||||
data-bs-target="#navbarSupportedContent"
|
|
||||||
aria-controls="navbarSupportedContent"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-label="Toggle navigation"
|
|
||||||
>
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
|
@ -34,6 +27,9 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/history">History</a>
|
<a class="nav-link" href="/history">History</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/ownership_registration">Ownership Registration</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,8 @@
|
||||||
<nav id="navbar" class="navbar navbar-expand-lg bg-body-tertiary mb-5">
|
<nav id="navbar" class="navbar navbar-expand-lg bg-body-tertiary mb-5">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="/">Request Mirror</a>
|
<a class="navbar-brand" href="/">Request Mirror</a>
|
||||||
<button
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
|
||||||
class="navbar-toggler"
|
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
type="button"
|
|
||||||
data-bs-toggle="collapse"
|
|
||||||
data-bs-target="#navbarSupportedContent"
|
|
||||||
aria-controls="navbarSupportedContent"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-label="Toggle navigation"
|
|
||||||
>
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
|
@ -33,6 +26,9 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/history">History</a>
|
<a class="nav-link" href="/history">History</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/ownership_registration">Ownership Registration</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="d-flex flex-column">
|
||||||
|
<nav id="navbar" class="navbar navbar-expand-lg bg-body-tertiary mb-5">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand" href="/">Request Mirror</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
|
||||||
|
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" aria-current="page" href="/">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/test">Test Page</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/history">History</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/ownership_registration">Ownership Registration</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div id="body" class="p-5">
|
||||||
|
<h3>Your Client ID: {{client_id}}</h3>
|
||||||
|
|
||||||
|
<form target="/owner_registration">
|
||||||
|
<h5>Ownership Registration</h5>
|
||||||
|
<input type="text" name="owner_id">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{{#if disp_owner_reg}}
|
||||||
|
<p>Registered new owner {{owner_id}} for {{client_id}}</p>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<h3>Owned Clients</h3>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Client ID</th>
|
||||||
|
</tr>
|
||||||
|
{{#each ownerships}}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{client_id}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
|
||||||
|
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -11,15 +11,8 @@
|
||||||
<nav id="navbar" class="navbar navbar-expand-lg bg-body-tertiary mb-5">
|
<nav id="navbar" class="navbar navbar-expand-lg bg-body-tertiary mb-5">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="/">Request Mirror</a>
|
<a class="navbar-brand" href="/">Request Mirror</a>
|
||||||
<button
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
|
||||||
class="navbar-toggler"
|
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
type="button"
|
|
||||||
data-bs-toggle="collapse"
|
|
||||||
data-bs-target="#navbarSupportedContent"
|
|
||||||
aria-controls="navbarSupportedContent"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-label="Toggle navigation"
|
|
||||||
>
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
|
@ -33,6 +26,9 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/history">History</a>
|
<a class="nav-link" href="/history">History</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/ownership_registration">Ownership Registration</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue