Skip to content

Commit

Permalink
feat(auth): add LoggedInRepository as abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
H1ghBre4k3r committed Aug 30, 2023
1 parent ca5db4b commit 42f026c
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 59 deletions.
4 changes: 2 additions & 2 deletions src/hooks/user.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use leptos::*;

use crate::model::{Session, User};
use crate::{model::User, repository::LoggedInRepository};

use super::use_identity;

Expand All @@ -15,5 +15,5 @@ pub async fn use_user(cx: Scope) -> Option<User> {
return None;
};

Session::find_user_via_session(&session_id).await
LoggedInRepository::find_user_via_session(&session_id).await
}
56 changes: 5 additions & 51 deletions src/model/session.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use leptos::*;
use serde::{Deserialize, Serialize};
use surrealdb::sql::Thing;

use crate::{hooks::use_database, repository::SessionRepository};
use crate::repository::{LoggedInRepository, SessionRepository};

use super::User;

Expand All @@ -12,21 +11,9 @@ pub struct Session {
pub user_id: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct LoggenInRelation {
user_id: String,
session_id: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct LoggedInModel {
id: Thing,
users: Vec<Thing>,
}

impl Session {
pub async fn find_by_id(id: &str) -> Option<Session> {
let Some(user) = Self::find_user_via_session(id).await else {
let Some(user) = LoggedInRepository::find_user_via_session(id).await else {
return None;
};

Expand All @@ -36,50 +23,17 @@ impl Session {
})
}

pub async fn find_user_via_session(session_id: &str) -> Option<User> {
let db = use_database().await;

let Ok(mut response) = db
.query(format!(
"select id, <-logged_in<-user as users from {session_id};"
))
.await
else {
return None;
};

let Ok(Some(result)): Result<Option<LoggedInModel>, surrealdb::Error> = response.take(0)
else {
return None;
};

let Some(user) = result.users.get(0) else {
return None;
};

User::get_by_id(user.id.clone()).await
}

pub async fn new(user: &User) -> Option<Session> {
let Some(session) = SessionRepository::create().await.ok().flatten() else {
return None;
};

let session_id = session.id().expect("session from DB should have ID");

let db = use_database().await;

if let Err(e) = db
.query(format!("RELATE {}->logged_in->{}", user.id, session_id))
if LoggedInRepository::attach_user_to_session(&user.id, &session_id)
.await
.is_err()
{
error!(
"Error creating a relation between user ({}) and session ({}): {e:?}",
user.id, session_id
);
if let Err(e) = SessionRepository::delete(&session_id).await {
error!("Error deleting session ({session_id}): {e:?}");
};
return None;
};

Expand All @@ -90,7 +44,7 @@ impl Session {
}

pub async fn destroy(session_id: &str) {
if let Err(e) = SessionRepository::delete(&session_id).await {
if let Err(e) = SessionRepository::delete(session_id).await {
error!("Error deleting session ({session_id}): {e:?}");
};
}
Expand Down
75 changes: 75 additions & 0 deletions src/repository/logged_in.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use leptos::*;

use serde::{Deserialize, Serialize};
use surrealdb::sql::Thing;

use crate::{hooks::use_database, model::User, repository::SessionRepository};

use super::UserRepository;

pub struct LoggedInRepository {}

#[derive(Debug, Serialize, Deserialize)]
struct LoggenInRelation {
user_id: String,
session_id: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct LoggedInModel {
id: Thing,
users: Vec<Thing>,
}

impl LoggedInRepository {
const TABLE: &str = "logged_in";

Check warning on line 25 in src/repository/logged_in.rs

View workflow job for this annotation

GitHub Actions / Build & Test (nightly)

`&` without an explicit lifetime name cannot be used here

pub async fn find_user_via_session(session_id: &str) -> Option<User> {
let db = use_database().await;

let Ok(mut response) = db
.query(format!(
"select id, <-{relation}<-{user_table} as users from {session_id};",
relation = Self::TABLE,
user_table = UserRepository::TABLE
))
.await
else {
return None;
};

let Ok(Some(result)): Result<Option<LoggedInModel>, surrealdb::Error> = response.take(0)
else {
return None;
};

let Some(user) = result.users.get(0) else {
return None;
};

User::get_by_id(user.id.clone()).await
}

pub async fn attach_user_to_session(user: &str, session: &str) -> Result<(), ()> {
let db = use_database().await;

if let Err(e) = db
.query(format!(
"RELATE {user}->{table}->{session}",
table = Self::TABLE
))
.await
{
error!(
"Error creating a relation between user ({}) and session ({}): {e:?}",
user, session
);
if let Err(e) = SessionRepository::delete(session).await {
error!("Error deleting session ({session}): {e:?}");
};
return Err(());
};

Ok(())
}
}
2 changes: 2 additions & 0 deletions src/repository/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ cfg_if! {
if #[cfg(feature = "ssr")] {
mod user;
mod session;
mod logged_in;

pub use self::user::*;
pub use self::session::*;
pub use self::logged_in::*;
}
}
2 changes: 1 addition & 1 deletion src/repository/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct UserRepository {
}

impl UserRepository {
const TABLE: &str = "user";
pub const TABLE: &str = "user";

Check warning on line 16 in src/repository/user.rs

View workflow job for this annotation

GitHub Actions / Build & Test (nightly)

`&` without an explicit lifetime name cannot be used here

Check warning on line 16 in src/repository/user.rs

View workflow job for this annotation

GitHub Actions / Build & Test (nightly)

`&` without an explicit lifetime name cannot be used here

pub fn id(&self) -> Option<String> {
self.id.as_ref().map(|id| format!("{}:{}", id.tb, id.id))
Expand Down
9 changes: 4 additions & 5 deletions src/views/impressum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ pub fn ImpressumView(cx: Scope) -> impl IntoView {
view! { cx,
<section class="impressum">
<div>
<h1>Impressum</h1>
<h2 id="m3">Verantwortlicher</h2>

<h1>"Datenschutzerklärung"</h1>
<h2 id="m4158">"Präambel"</h2>
<p>"Mit der folgenden Datenschutzerklärung möchten wir Sie darüber aufklären, welche Arten Ihrer personenbezogenen Daten (nachfolgend auch kurz als \"Daten\" bezeichnet) wir zu welchen Zwecken und in welchem Umfang im Rahmen der Bereitstellung unserer Applikation verarbeiten."</p>
Expand All @@ -16,7 +13,7 @@ pub fn ImpressumView(cx: Scope) -> impl IntoView {
<h2>"Inhaltsübersicht"</h2>
<ul class="index">
<li><a class="index-link" href="#m4158">"Präambel"</a></li>
<li><a class="index-link" href="#m3">"Verantwortlicher"</a></li>
<li><a class="index-link" href="#m3">"Kontakt"</a></li>
<li><a class="index-link" href="#mOverview">"Übersicht der Verarbeitungen"</a></li>
<li><a class="index-link" href="#m2427">"Maßgebliche Rechtsgrundlagen"</a></li>
<li><a class="index-link" href="#m27">"Sicherheitsmaßnahmen"</a></li>
Expand All @@ -32,7 +29,9 @@ pub fn ImpressumView(cx: Scope) -> impl IntoView {
<li><a class="index-link" href="#m328">Plugins und eingebettete Funktionen sowie Inhalte</a></li>
<li><a class="index-link" href="#m15">Änderung und Aktualisierung der Datenschutzerklärung</a></li>
</ul>
<h2 id="m3">Verantwortlicher</h2>
<h2 id="m3">"Kontakt"</h2>
E-Mail-Adresse:
<p><a href="mailto:[email protected]">"[email protected]"</a></p>
<h2 id="m2427">Maßgebliche Rechtsgrundlagen</h2>
<p><strong>Maßgebliche Rechtsgrundlagen nach der DSGVO: </strong>Im Folgenden erhalten Sie eine Übersicht der Rechtsgrundlagen der DSGVO, auf deren Basis wir personenbezogene Daten verarbeiten. Bitte nehmen Sie zur Kenntnis, dass neben den Regelungen der DSGVO nationale Datenschutzvorgaben in Ihrem bzw. unserem Wohn- oder Sitzland gelten können. Sollten ferner im Einzelfall speziellere Rechtsgrundlagen maßgeblich sein, teilen wir Ihnen diese in der Datenschutzerklärung mit.</p>
<ul>
Expand Down

0 comments on commit 42f026c

Please sign in to comment.