yggdrasil/src/util/structs/Account.rs

109 lines
3.3 KiB
Rust

/*
* Yggdrasil: Minecraft authentication server
* Copyright (C) 2023 0xf8.dev@proton.me
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use structs::Profile::{Profile, ProfileRaw};
use crate::*;
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Account {
pub id: i64,
pub email: String,
pub password_hash: String,
pub language: String,
pub country: String,
pub selected_profile: Option<Profile>,
}
impl Account {
pub async fn from_id(db: &Database, id: i64) -> Option<Self> {
let record = sqlx::query_as!(AccountRaw, "SELECT * FROM accounts WHERE id = $1", id)
.fetch_one(&db.pool)
.await;
match record {
Ok(r) => Some(r.complete(db).await),
Err(_) => None
}
}
pub async fn from_email(db: &Database, email: String) -> Option<Self> {
let record = sqlx::query_as!(AccountRaw, "SELECT * FROM accounts WHERE email = $1", email)
.fetch_one(&db.pool)
.await;
match record {
Ok(r) => Some(r.complete(db).await),
Err(_) => None,
}
}
pub async fn get_all_profiles(&self, db: &Database) -> Option<Vec<Profile>> {
let record = sqlx::query_as!(ProfileRaw, "SELECT * FROM profiles WHERE owner = $1", self.id).fetch_all(&db.pool).await;
match record {
Ok(r) => {
let mut collection = vec![];
for re in r {
collection.push(re.complete(db).await)
}
Some(collection)
} // oh boy
Err(_) => None
}
}
pub fn to_user(&self) -> Value {
json!({
"id": self.id,
"username": self.email,
"properties": [
{
"name": "preferredLanguage",
"value": self.language
},
{
"name": "registrationCountry",
"value": self.country
}
]
})
}
}
#[derive(Deserialize, Serialize, Debug)]
pub struct AccountRaw {
pub id: i64,
pub email: String,
pub password_hash: String,
pub language: String,
pub country: String,
pub selected_profile: Option<i64>
}
impl AccountRaw {
pub async fn complete(self, db: &Database) -> Account {
Account {
id: self.id,
email: self.email,
password_hash: self.password_hash,
language: self.language,
country: self.country,
selected_profile: match self.selected_profile {
None => None,
Some(id) => Profile::from_id(db, id).await
},
}
}
}