summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/guards/mod.rs1
-rw-r--r--src/api/guards/session.rs25
-rw-r--r--src/api/mod.rs2
-rw-r--r--src/api/routes/mod.rs1
-rw-r--r--src/api/routes/test.rs9
-rw-r--r--src/db/mod.rs1
-rw-r--r--src/db/models/auth.rs84
-rw-r--r--src/db/models/mod.rs1
-rw-r--r--src/jobs/startup.rs27
-rw-r--r--src/main.rs21
10 files changed, 162 insertions, 10 deletions
diff --git a/src/api/guards/mod.rs b/src/api/guards/mod.rs
new file mode 100644
index 0000000..f52f1c4
--- /dev/null
+++ b/src/api/guards/mod.rs
@@ -0,0 +1 @@
+pub mod session;
diff --git a/src/api/guards/session.rs b/src/api/guards/session.rs
new file mode 100644
index 0000000..ccd40a2
--- /dev/null
+++ b/src/api/guards/session.rs
@@ -0,0 +1,25 @@
+use std::str::FromStr;
+
+use rocket::{http::Status, outcome::Outcome, request::{self, Request, FromRequest}};
+use sqlx::PgPool;
+use uuid::Uuid;
+use crate::db::models::auth::LoginSession;
+
+
+#[rocket::async_trait]
+impl<'r> FromRequest<'r> for LoginSession {
+    type Error = ();
+
+    async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
+        // At the moment just always look up this one for initial testing
+        let hardcoded_uuid = "557621dd-b98e-409a-9ce7-25b5004caa42";
+
+        if let Some(db) = req.rocket().state::<PgPool>() {
+            if let Some(session) = LoginSession::lookup(&db, Uuid::from_str(hardcoded_uuid).unwrap()).await {
+                return Outcome::Success(session);
+            }
+        }
+
+        Outcome::Error((Status::InternalServerError, ()))
+    }
+}
diff --git a/src/api/mod.rs b/src/api/mod.rs
new file mode 100644
index 0000000..47e142d
--- /dev/null
+++ b/src/api/mod.rs
@@ -0,0 +1,2 @@
+pub mod routes;
+pub mod guards;
diff --git a/src/api/routes/mod.rs b/src/api/routes/mod.rs
new file mode 100644
index 0000000..7b788c2
--- /dev/null
+++ b/src/api/routes/mod.rs
@@ -0,0 +1 @@
+pub mod test;
diff --git a/src/api/routes/test.rs b/src/api/routes/test.rs
new file mode 100644
index 0000000..718c634
--- /dev/null
+++ b/src/api/routes/test.rs
@@ -0,0 +1,9 @@
+use rocket::get;
+use rocket::serde::json::Json;
+
+use crate::db::models::auth::LoginSession;
+
+#[get("/test")]
+pub fn testroute(session: LoginSession) -> Json<LoginSession> {
+    Json(session)
+}
diff --git a/src/db/mod.rs b/src/db/mod.rs
new file mode 100644
index 0000000..c446ac8
--- /dev/null
+++ b/src/db/mod.rs
@@ -0,0 +1 @@
+pub mod models;
diff --git a/src/db/models/auth.rs b/src/db/models/auth.rs
new file mode 100644
index 0000000..b4fa070
--- /dev/null
+++ b/src/db/models/auth.rs
@@ -0,0 +1,84 @@
+use rocket::serde::{self, Serialize};
+use uuid::Uuid;
+use time::OffsetDateTime;
+use sqlx::{postgres::types::PgInterval, Pool, Postgres};
+
+#[derive(Serialize, Debug)]
+#[serde(crate = "rocket::serde")]
+pub struct User {
+    uuid: Uuid,
+    email: String,
+    username: String,
+    display_name: Option<String>,
+    password_hash: Option<String>,
+    #[serde(with="time::serde::rfc3339")]
+    time_created: OffsetDateTime,
+    #[serde(with="time::serde::rfc3339::option")]
+    time_password_changed: Option<OffsetDateTime>,
+    #[serde(with="time::serde::rfc3339::option")]
+    time_email_confirmed: Option<OffsetDateTime>
+}
+
+#[derive(Serialize, Debug)]
+#[serde(crate = "rocket::serde")]
+pub struct LoginSession {
+    uuid: Uuid,
+    #[serde(with="time::serde::rfc3339")]
+    time_created: OffsetDateTime,
+    #[serde(with="time::serde::rfc3339")]
+    time_last_active: OffsetDateTime,
+    #[serde(skip_serializing)]
+    duration: PgInterval,
+    #[serde(with="time::serde::rfc3339::option")]
+    time_logged_out: Option<OffsetDateTime>,
+    ip_address: String,
+    user_agent: String,
+    referer: String,
+    user: User
+}
+
+impl LoginSession {
+    pub async fn lookup(connection: &Pool::<Postgres>, uuid: Uuid) -> Option<LoginSession> {
+        joinrs::query_parsed!(
+            connection = connection,
+            query = r#"
+                select
+                    login_session.*,
+                    user_uuid,
+                    user_display_name,
+                    user_password_hash,
+                    user_time_created,
+                    user_time_password_changed,
+                    user_time_email_confirmed,
+                    user_username::text as username,
+                    user_email::text as email
+                from phtx.login_session
+                    left join phtx."user"
+                        on login_session_user_uuid = user_uuid
+                    where login_session_time_last_active + login_session_duration >= now()
+                        and login_session_uuid = $1
+            "#,
+            params = [uuid],
+            return_type = LoginSession {
+                uuid: login_session_uuid,
+                time_created: login_session_time_created,
+                time_last_active: login_session_time_last_active,
+                duration: login_session_duration,
+                time_logged_out: login_session_time_logged_out,
+                ip_address: login_session_ip_address,
+                user_agent: login_session_user_agent,
+                referer: login_session_referer,
+                user: User {
+                    uuid: user_uuid,
+                    email: email,
+                    username: username,
+                    display_name: user_display_name,
+                    password_hash: user_password_hash,
+                    time_created: user_time_created,
+                    time_password_changed: user_time_password_changed,
+                    time_email_confirmed: user_time_email_confirmed
+                }
+            }
+        ).ok()
+    }
+}
diff --git a/src/db/models/mod.rs b/src/db/models/mod.rs
new file mode 100644
index 0000000..0e4a05d
--- /dev/null
+++ b/src/db/models/mod.rs
@@ -0,0 +1 @@
+pub mod auth;
diff --git a/src/jobs/startup.rs b/src/jobs/startup.rs
index 05eaa94..6ca1849 100644
--- a/src/jobs/startup.rs
+++ b/src/jobs/startup.rs
@@ -1,16 +1,27 @@
 use tokio::runtime;
-use std::{fs, path::Path};
+use std::{fs, path::Path, thread};
+use tokio::sync::mpsc::channel;
 
 use sqlx::{migrate::Migrator, Connection, PgConnection, Row};
 
-pub fn run_startup_jobs() {
-    let runtime = runtime::Builder::new_current_thread()
-        .enable_all()
-        .build().unwrap();
+type JobResult = Result<(), ()>;
 
-    runtime.block_on(async {
-        migrate_db().await
-    })
+pub async fn run_startup_jobs() {
+    let (tx, mut rx) = channel::<JobResult>(1);
+
+    thread::spawn(move || {
+        let runtime = runtime::Builder::new_current_thread()
+            .enable_all()
+            .build().unwrap();
+
+        runtime.block_on(async {
+            migrate_db().await;
+
+            tx.send(Ok(())).await.unwrap()
+        });
+    });
+
+    rx.recv().await;
 }
 
 async fn migrate_db() {
diff --git a/src/main.rs b/src/main.rs
index ba41b2d..01f6eed 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,23 @@
+use rocket::routes;
+use sqlx::PgPool;
+
 mod jobs;
+mod db;
+mod api;
 
-fn main() {
+#[rocket::main]
+async fn main() -> Result<(), rocket::Error> {
     println!("{}_{} starting up", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
-    jobs::startup::run_startup_jobs();
+
+    jobs::startup::run_startup_jobs().await;
+
+    let db_pool = PgPool::connect("postgres://localhost/photoxide").await.unwrap();
+
+    let _rocket = rocket::build()
+        .manage(db_pool)
+        .mount("/", routes![api::routes::test::testroute])
+        .launch()
+        .await?;
+
+    Ok(())
 }