From 09a3f096c72b061f0a670e79d49f5121adefd983 Mon Sep 17 00:00:00 2001 From: Stefan Schwarz Date: Sat, 15 Aug 2020 09:10:47 +0200 Subject: [PATCH] work --- Cargo.lock | 1 + Cargo.toml | 3 +- src/db.rs | 100 ++++++++++++++++++++++++++++++++++++++++--- src/main.rs | 20 ++++----- src/routes.rs | 18 ++++++++ src/routes/mod.rs | 9 ---- src/templates.rs | 25 +++-------- templates/index.html | 93 +++++++++++----------------------------- 8 files changed, 154 insertions(+), 115 deletions(-) create mode 100644 src/routes.rs delete mode 100644 src/routes/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 61ea221..412c1bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1054,6 +1054,7 @@ dependencies = [ name = "macnickenson" version = "0.1.0" dependencies = [ + "anyhow", "argh", "askama", "askama_tide", diff --git a/Cargo.toml b/Cargo.toml index c0c3af3..7f1ec49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,9 +5,10 @@ authors = ["Stefan Schwarz "] edition = "2018" [dependencies] +anyhow = "1.0" argh = "0.1.3" -askama = { version = "0.10", features = ["with-tide"]} askama_tide = "0.10" +askama = { version = "0.10", features = ["with-tide"]} async-std = { version = "1.6", features = ["attributes"] } chrono = "0.4" sqlx = { version = "0.4.0-beta.1", features = ["mysql", "chrono", "macros"] } diff --git a/src/db.rs b/src/db.rs index 274d266..c7e0e36 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,11 +1,99 @@ use chrono::{DateTime, Utc}; +use sqlx::database::HasArguments; +use std::net::IpAddr; + +type QueryAs<'q, T> = + sqlx::query::QueryAs<'q, sqlx::MySql, T, >::Arguments>; #[derive(sqlx::FromRow, Debug)] pub struct Entry { - id: i32, - macaddr: String, - nickname: String, - descr: String, - privacy: i8, - created: DateTime, + pub id: i32, + pub macaddr: String, + pub nickname: String, + pub descr: String, + pub privacy: PrivacyLevel, + pub created: DateTime, + pub present: bool, +} + +#[derive(sqlx::Type, Debug, Clone, Copy)] +#[repr(i8)] +pub enum PrivacyLevel { + ShowUserAndDevice = 0, + ShowUser = 1, + ShowAnonymous = 2, + HideUser = 3, + DontLog = 4, +} + +impl<'q> Entry { + pub fn all() -> QueryAs<'q, Self> { + sqlx::query_as("SELECT * FROM mac_to_nick") + } + + pub fn for_user(user: &'q str) -> QueryAs<'q, Self> { + sqlx::query_as( + " +SELECT + mtn.*, + IF(al.iplong != NULL, TRUE, FALSE) present +FROM + mac_to_nick mtn, + alive_hosts al +WHERE + al.macaddr = mtn.macaddr + AND nickname = ? +GROUP BY + mtn.macaddr +", + ) + .bind(user) + } +} + +impl PrivacyLevel { + pub fn as_u8(&self) -> u8 { + *self as u8 + } + + pub fn selected(&self, level: &PrivacyLevel) -> &'static str { + if *self as u8 == *level as u8 { + "selected" + } else { + "" + } + } +} + +#[derive(sqlx::FromRow, Debug)] +pub struct AliveDevice { + pub macaddr: String, + pub iplong: i32, +} + +impl<'q> AliveDevice { + pub fn unassinged() -> QueryAs<'q, Self> { + sqlx::query_as( + " +SELECT DISTINCT + al.macaddr macaddr, + al.iplong iplong +FROM + alive_hosts al, + mac_to_nick mtn +WHERE + mtn.nickname IS NULL + AND al.erfda > NOW() - INTERVAL 24 DAY +", + ) + } + + pub fn ip(&self) -> IpAddr { + IpAddr::from([ + (self.iplong >> 24 & 0xff) as u8, + (self.iplong >> 16 & 0xff) as u8, + (self.iplong >> 8 & 0xff) as u8, + (self.iplong & 0xff) as u8, + ]) + } } diff --git a/src/main.rs b/src/main.rs index aa00845..da72abb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,13 @@ struct Config { /// listen address #[argh(option, default = "\"[::1]:8080\".to_string()")] listen: String, + + /// database dsn + #[argh( + option, + default = "\"mysql://administration:foosinn123@127.0.0.1/administration\".to_string()" + )] + dsn: String, } #[derive(Clone)] @@ -24,12 +31,7 @@ pub type Request = tide::Request; async fn main() -> Result<(), io::Error> { let config: Config = argh::from_env(); - let dsn = "mysql://administration:foosinn123@127.0.0.1/administration"; - let pool = MySqlPool::connect(dsn) - .await - .map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))?; - let mut conn = pool - .acquire() + let pool = MySqlPool::connect(&config.dsn) .await .map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))?; @@ -38,11 +40,5 @@ async fn main() -> Result<(), io::Error> { app.at("/healthz").get(routes::healthz); app.at("/static").serve_dir("static/")?; - let entries: Vec = sqlx::query_as("select * from mac_to_nick") - .fetch_all(&mut conn) - .await - .map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))?; - - entries.into_iter().for_each(|e| println!("{:?}", e)); app.listen(config.listen).await } diff --git a/src/routes.rs b/src/routes.rs new file mode 100644 index 0000000..42ea35f --- /dev/null +++ b/src/routes.rs @@ -0,0 +1,18 @@ +use crate::db; +use crate::templates; + +pub async fn healthz(_request: crate::Request) -> tide::Result { + Ok("ok".into()) +} + +pub async fn index(request: crate::Request) -> tide::Result { + let my = db::Entry::for_user("foosinn") + .fetch_all(&request.state().pool) + .await + .map_err(|err| dbg!(err))?; + let unassinged = db::AliveDevice::unassinged() + .fetch_all(&request.state().pool) + .await + .map_err(|err| dbg!(err))?; + Ok(templates::IndexTemplate::new(my, unassinged).into()) +} diff --git a/src/routes/mod.rs b/src/routes/mod.rs deleted file mode 100644 index d75ed22..0000000 --- a/src/routes/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -use crate::templates; - -pub async fn healthz(_request: crate::Request) -> tide::Result { - Ok("ok".into()) -} - -pub async fn index(request: crate::Request) -> tide::Result { - Ok(templates::IndexTemplate::new().into()) -} diff --git a/src/templates.rs b/src/templates.rs index 3c030ca..7123ca5 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -3,26 +3,13 @@ use askama::Template; #[derive(Template, Default)] #[template(path = "index.html")] -pub struct IndexTemplate<'a> { - devices: Vec>, +pub struct IndexTemplate { + my: Vec, + unassinged: Vec, } -pub struct Device<'a> { - pub macaddr: &'a str, - pub nickname: &'a str, - pub descr: &'a str, - pub privacy: PrivacyLevel, -} - -#[repr(u8)] -pub enum PrivacyLevel { - Public = 1, - Private = 2, - Internal = 3, -} - -impl<'a> IndexTemplate<'a> { - pub fn new() -> Self { - Self::default() +impl IndexTemplate { + pub fn new(my: Vec, unassinged: Vec) -> Self { + Self { my, unassinged } } } diff --git a/templates/index.html b/templates/index.html index 81f3ef4..d349ba3 100644 --- a/templates/index.html +++ b/templates/index.html @@ -18,15 +18,28 @@

Your Devices:

-
-
macaddr: "00:18:e7:34:11:1c"
+ {% for device in my %} +
+
{{ device.macaddr }}
+ value="{{ device.descr }}"/>
@@ -34,23 +47,14 @@
-
-
macaddr: "90:78:41:bd:10:23"
-
nickname: "Neptun"
-
descr: "Neptun"
-
-
-
macaddr: "10:0b:a9:ad:9f:30"
-
nickname: "Wu"
-
descr: "x220"
-
+ {% endfor %}

Unregistred Devices:

- -
- -
macaddr: "f0:d5:bf:cc:a2:f9"
+ {% for device in unassinged %} +
+
{{ device.macaddr }}
+
{{ device.ip() }}
@@ -59,54 +63,7 @@
-
- -
macaddr: "6a:f4:a2:c4:e2:2e"
-
nickname: "Mondschauer93"
-
descr: "Smartphone"
- -
-
-
macaddr: "f8:ff:c2:20:b6:0d"
-
nickname: "idefix"
-
descr: "MacBook"
- -
-
-
macaddr: "30:57:14:db:34:d3"
-
nickname: "idefix"
-
descr: "IPhone"
- -
-
-
macaddr: "98:01:a7:b6:48:5b"
-
nickname: "idefix"
-
descr: "UbuntuBook"
- -
-
-
macaddr: "f4:db:e3:3f:7e:18"
-
nickname: "raphii"
-
descr: "iPhone 11"
- -
-
-
macaddr: "70:48:0f:98:de:23"
-
nickname: "raphii"
-
descr: "iPad Pro"
- -
-
-
macaddr: "e0:cc:f8:6a:d1:d4"
-
nickname: "stoneos"
-
descr: "xiaomi mi10"
- -
-
-
macaddr: "74:e5:f9:86:98:8b"
-
nickname: "ptflea"
-
descr: "computer"
-
+ {% endfor %}
footer