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