Added QoL error handling
This commit is contained in:
parent
a53ad775dc
commit
2bca9bba60
@ -318,7 +318,7 @@ async fn relate_member(registration_token: String) -> Result<(), ServerFnError>
|
|||||||
let user = Session::fetch_current_user().await?;
|
let user = Session::fetch_current_user().await?;
|
||||||
let member_id = Member::fetch_from_registration_token(registration_token).await?;
|
let member_id = Member::fetch_from_registration_token(registration_token).await?;
|
||||||
|
|
||||||
user.relate_member(member_id.id).await?;
|
user.relate_member(&member_id.id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,6 +326,6 @@ async fn relate_member(registration_token: String) -> Result<(), ServerFnError>
|
|||||||
async fn delete_member_relation(member_id: String) -> Result<(), ServerFnError> {
|
async fn delete_member_relation(member_id: String) -> Result<(), ServerFnError> {
|
||||||
let user = Session::fetch_current_user().await?;
|
let user = Session::fetch_current_user().await?;
|
||||||
|
|
||||||
user.remove_relation(member_id).await?;
|
user.remove_relation(&member_id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ impl Member {
|
|||||||
pub async fn fetch_all() -> Result<Vec<Self>, surrealdb::Error> {
|
pub async fn fetch_all() -> Result<Vec<Self>, surrealdb::Error> {
|
||||||
let mut res = DB.query("SELECT id, name.first, name.full, hours, groups, diploma, registration_token FROM member").await?;
|
let mut res = DB.query("SELECT id, name.first, name.full, hours, groups, diploma, registration_token FROM member").await?;
|
||||||
|
|
||||||
|
res = res.check()?;
|
||||||
|
|
||||||
let members: Vec<Self> = res.take(0)?;
|
let members: Vec<Self> = res.take(0)?;
|
||||||
|
|
||||||
Ok(members)
|
Ok(members)
|
||||||
@ -47,6 +49,8 @@ impl Member {
|
|||||||
.bind(("registration_token", registration_token))
|
.bind(("registration_token", registration_token))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
res = res.check()?;
|
||||||
|
|
||||||
match res.take(0)? {
|
match res.take(0)? {
|
||||||
Some(m) => Ok(m),
|
Some(m) => Ok(m),
|
||||||
None => Err(crate::Error::NoDocument),
|
None => Err(crate::Error::NoDocument),
|
||||||
@ -61,6 +65,8 @@ impl Member {
|
|||||||
.bind(("user_id", user_id))
|
.bind(("user_id", user_id))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
res = res.check()?;
|
||||||
|
|
||||||
let members: Vec<Self> = res.take(0)?;
|
let members: Vec<Self> = res.take(0)?;
|
||||||
|
|
||||||
Ok(members)
|
Ok(members)
|
||||||
|
@ -24,6 +24,8 @@ impl Session {
|
|||||||
.bind(("user_id", user_id))
|
.bind(("user_id", user_id))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
res = res.check()?;
|
||||||
|
|
||||||
let session: Option<Self> = res.take(0)?;
|
let session: Option<Self> = res.take(0)?;
|
||||||
|
|
||||||
match session {
|
match session {
|
||||||
@ -67,6 +69,8 @@ impl Session {
|
|||||||
.bind(("session_token", session_token))
|
.bind(("session_token", session_token))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
res = res.check()?;
|
||||||
|
|
||||||
let user: Option<User> = res.take(0)?;
|
let user: Option<User> = res.take(0)?;
|
||||||
|
|
||||||
match user {
|
match user {
|
||||||
@ -111,10 +115,13 @@ impl Session {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_session(user_id: String) -> Result<(), crate::Error> {
|
pub async fn delete_session(user_id: String) -> Result<(), crate::Error> {
|
||||||
DB.query("DELETE ONLY session WHERE user = type::thing('user', $user_id)")
|
let res = DB
|
||||||
|
.query("DELETE ONLY session WHERE user = type::thing('user', $user_id)")
|
||||||
.bind(("user_id", user_id))
|
.bind(("user_id", user_id))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
res.check()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,10 @@ use serde::{Deserialize, Serialize};
|
|||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
use crate::util::surrealdb::{thing_to_string, DB};
|
use crate::util::surrealdb::{thing_to_string, DB};
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
use surrealdb::sql::statements::{BeginStatement, CommitStatement};
|
use surrealdb::sql::{
|
||||||
|
statements::{BeginStatement, CommitStatement},
|
||||||
|
Thing,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
|
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
@ -37,6 +40,8 @@ impl User {
|
|||||||
.query(CommitStatement::default())
|
.query(CommitStatement::default())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
res = res.check()?;
|
||||||
|
|
||||||
let user: Option<Self> = res.take(0)?;
|
let user: Option<Self> = res.take(0)?;
|
||||||
|
|
||||||
match user {
|
match user {
|
||||||
@ -45,36 +50,40 @@ impl User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn relate_member(&self, member_id: String) -> Result<(), crate::Error> {
|
pub async fn relate_member(&self, member_id: &str) -> Result<(), crate::Error> {
|
||||||
let mut res = DB
|
let res = DB
|
||||||
.query("
|
.query("
|
||||||
IF (SELECT * FROM ONLY user_to_member WHERE in = type::thing('user', $user_id) AND out = type::thing('member', $member_id) LIMIT 1) == NONE {
|
IF (SELECT id FROM ONLY user_to_member WHERE in = $user AND out = $member LIMIT 1) == NONE {
|
||||||
RELATE ONLY (type::thing('user', $user_id))->user_to_member->(type::thing('member', $member_id));
|
RELATE ONLY $user->user_to_member->$member;
|
||||||
} ELSE {
|
} ELSE {
|
||||||
THROW 'Relation already exists'
|
THROW 'Relation already exists'
|
||||||
};
|
};
|
||||||
")
|
")
|
||||||
.bind(("user_id", self.id.to_string()))
|
.bind(("user", Thing::from(("user", self.id.as_str()))))
|
||||||
.bind(("member_id", member_id))
|
.bind(("member", Thing::from(("member", member_id))))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if res.take_errors().len() != 0 {
|
res.check()?;
|
||||||
return Err(crate::Error::NoDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_relation(&self, member_id: String) -> Result<(), crate::Error> {
|
pub async fn remove_relation(&self, member_id: &str) -> Result<(), crate::Error> {
|
||||||
let mut res = DB
|
let res = DB
|
||||||
.query("DELETE type::thing('user', $user_id)->user_to_member WHERE out = type::thing('member', $member_id)")
|
.query(
|
||||||
.bind(("user_id", self.id.clone()))
|
"
|
||||||
.bind(("member_id", member_id))
|
IF (SELECT count() FROM user_to_member WHERE in = $user GROUP ALL)[0].count == 1 {
|
||||||
|
THROW 'At least one relation is required'
|
||||||
|
} ELSE {
|
||||||
|
DELETE $user->user_to_member WHERE out = $member
|
||||||
|
};
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.bind(("user", Thing::from(("user", self.id.as_str()))))
|
||||||
|
.bind(("member", Thing::from(("member", member_id))))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if res.take_errors().len() != 0 {
|
res.check()?;
|
||||||
return Err(crate::Error::NoDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -85,9 +94,12 @@ impl User {
|
|||||||
) -> Result<String, crate::Error> {
|
) -> Result<String, crate::Error> {
|
||||||
let mut res = DB
|
let mut res = DB
|
||||||
.query("SELECT VALUE id FROM user WHERE email = $email AND crypto::argon2::compare(password, $password)")
|
.query("SELECT VALUE id FROM user WHERE email = $email AND crypto::argon2::compare(password, $password)")
|
||||||
.bind(("email", email)).bind(("password", password))
|
.bind(("email", email))
|
||||||
|
.bind(("password", password))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
res = res.check()?;
|
||||||
|
|
||||||
let id: Option<String> = res.take(0)?;
|
let id: Option<String> = res.take(0)?;
|
||||||
|
|
||||||
match id {
|
match id {
|
||||||
@ -98,11 +110,13 @@ impl User {
|
|||||||
|
|
||||||
pub async fn change_email(&self, new_email: String) -> Result<String, crate::Error> {
|
pub async fn change_email(&self, new_email: String) -> Result<String, crate::Error> {
|
||||||
let mut res = DB
|
let mut res = DB
|
||||||
.query("UPDATE type::thing('user', $user_id) SET email = $email RETURN VALUE email")
|
.query("UPDATE $user SET email = $email RETURN VALUE email")
|
||||||
.bind(("user_id", self.id.to_string()))
|
.bind(("user", Thing::from(("user", self.id.as_str()))))
|
||||||
.bind(("email", new_email))
|
.bind(("email", new_email))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
res = res.check()?;
|
||||||
|
|
||||||
let email: Option<String> = res.take(0)?;
|
let email: Option<String> = res.take(0)?;
|
||||||
|
|
||||||
match email {
|
match email {
|
||||||
@ -116,26 +130,24 @@ impl User {
|
|||||||
old_password: String,
|
old_password: String,
|
||||||
new_password: String,
|
new_password: String,
|
||||||
) -> Result<(), crate::Error> {
|
) -> Result<(), crate::Error> {
|
||||||
let mut res = DB
|
let res = DB
|
||||||
.query(
|
.query(
|
||||||
"
|
"
|
||||||
LET $user = (SELECT * FROM ONLY type::thing('user', $user_id));
|
LET $user = (SELECT * FROM ONLY $user);
|
||||||
|
|
||||||
IF crypto::argon2::compare($user.password, $old_password) {
|
IF crypto::argon2::compare($user.password, $old_password) {
|
||||||
UPDATE type::thing('user', $user_id) SET password = crypto::argon2::generate($new_password)
|
UPDATE $user SET password = crypto::argon2::generate($new_password)
|
||||||
} ELSE {
|
} ELSE {
|
||||||
THROW 'Password dit not match'
|
THROW 'Password dit not match'
|
||||||
};
|
};
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.bind(("user_id", self.id.to_string()))
|
.bind(("user", Thing::from(("user", self.id.as_str()))))
|
||||||
.bind(("old_password", old_password))
|
.bind(("old_password", old_password))
|
||||||
.bind(("new_password", new_password))
|
.bind(("new_password", new_password))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if res.take_errors().len() != 0 {
|
res.check()?;
|
||||||
return Err(crate::Error::NoDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user