Did server_token_validation

This commit is contained in:
2024-07-01 09:25:14 -04:00
Unverified
parent 0894a10021
commit fbdcc4eb82
4 changed files with 98 additions and 11 deletions

View File

@@ -12,4 +12,6 @@ tracing = "0.1.40"
serde = { version = "1.0.203", features = ["derive"] } serde = { version = "1.0.203", features = ["derive"] }
chrono = { version = "0.4.24", features = ["serde"] } chrono = { version = "0.4.24", features = ["serde"] }
dotenvy = "0.15" dotenvy = "0.15"
sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-rustls", "mysql", "chrono" ] } sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-rustls", "mysql", "chrono" ] }
sha3 = "0.10.8"
hex = "0.4.3"

View File

@@ -31,6 +31,7 @@ async fn main() -> anyhow::Result<()> {
id SERIAL, id SERIAL,
username VARCHAR(255) NOT NULL, username VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL,
avatar TEXT NOT NULL
login_code INT(6), login_code INT(6),
tokens TEXT, tokens TEXT,
google_oauth VARCHAR(255), google_oauth VARCHAR(255),
@@ -56,7 +57,7 @@ async fn main() -> anyhow::Result<()> {
// serve is generated by the service attribute. It takes as input any type implementing // serve is generated by the service attribute. It takes as input any type implementing
// the generated World trait. // the generated World trait.
.map(|channel| { .map(|channel| {
let server = RealmAuthServer::new(channel.transport().peer_addr().unwrap()); let server = RealmAuthServer::new(channel.transport().peer_addr().unwrap(), db_pool);
channel.execute(server.serve()).for_each(spawn) channel.execute(server.serve()).for_each(spawn)
}) })
// Max 10 channels. // Max 10 channels.

View File

@@ -1,22 +1,86 @@
use std::net::SocketAddr; use std::net::SocketAddr;
use sha3::{Digest, Sha3_256};
use sha3::digest::Update;
use sqlx::{MySql, Pool, Row};
use tarpc::context::Context; use tarpc::context::Context;
use crate::types::RealmAuth;
use crate::types::{AuthUser, ErrorCode, RealmAuth};
#[derive(Clone)] #[derive(Clone)]
pub struct RealmAuthServer { pub struct RealmAuthServer {
pub socket: SocketAddr, pub socket: SocketAddr,
pub db_pool: Pool<MySql>,
} }
impl RealmAuthServer { impl RealmAuthServer {
pub fn new(socket: SocketAddr) -> RealmAuthServer { pub fn new(socket: SocketAddr, db_pool: Pool<MySql>) -> RealmAuthServer {
RealmAuthServer { RealmAuthServer {
socket, socket,
db_pool,
} }
} }
} }
impl RealmAuth for RealmAuthServer { impl RealmAuth for RealmAuthServer {
async fn test(self, context: Context, name: String) -> String { async fn test(self, _: Context, name: String) -> String {
format!("Hello {}", name) format!("Hello {} auth!", name)
}
async fn server_token_validation(self, _: Context, server_token: String, username: String, server_id: String, domain: String, tarpc_port: u16) -> bool {
let result = sqlx::query("SELECT tokens FROM user WHERE username = ?").bind(username).fetch_one(&self.db_pool).await;
match result {
Ok(row) => {
let token_long: &str = row.try_get("tokens").unwrap();
let tokens = token_long.split(',').collect::<Vec<&str>>();
for token in tokens {
let hash = Sha3_256::new().chain(format!("{}{}{}{}", token, server_id, domain, tarpc_port)).finalize();
if hex::encode(hash) == server_token {
return true
}
}
false
},
Err(_) => false,
}
}
async fn create_account(self, _: Context, username: String, email: String, avatar: String) -> Result<String, ErrorCode> {
todo!()
}
async fn create_login_flow(self, _: Context, username: String) -> ErrorCode {
todo!()
}
async fn create_token_from_login(self, _: Context, username: String, login_code: u16) -> Result<String, ErrorCode> {
todo!()
}
async fn change_email_flow(self, _: Context, username: String, token: String) -> ErrorCode {
todo!()
}
async fn resolve_email_flow(self, _: Context, username: String, token: String, login_code: u16, new_email: String) -> ErrorCode {
todo!()
}
async fn change_username(self, _: Context, username: String, token: String, new_username: String) -> ErrorCode {
todo!()
}
async fn change_avatar(self, _: Context, username: String, token: String, avatar: String) -> ErrorCode {
todo!()
}
async fn get_all_data(self, _: Context, username: String, token: String) -> Result<AuthUser, ErrorCode> {
todo!()
}
async fn get_avatar_for_user(self, _: Context, username: String) -> Result<String, ErrorCode> {
todo!()
} }
} }

View File

@@ -3,16 +3,20 @@ use serde::{Deserialize, Serialize};
#[tarpc::service] #[tarpc::service]
pub trait RealmAuth { pub trait RealmAuth {
async fn test(name: String) -> String; async fn test(name: String) -> String;
async fn server_token_validation(username: String, server_id: String, domain: String, tarpc_port: u16) -> bool; async fn server_token_validation(server_token: String, username: String, server_id: String, domain: String, tarpc_port: u16) -> bool;
async fn create_account(username: String, email: String, avatar: String) -> Result<String, ErrorCode>; async fn create_account(username: String, email: String, avatar: String) -> Result<String, ErrorCode>;
async fn create_login_flow(username: String) -> ErrorCode; async fn create_login_flow(username: String) -> ErrorCode;
async fn create_token_from_login(username: String, login_code: u16) -> Result<String, ErrorCode>; async fn create_token_from_login(username: String, login_code: u16) -> Result<String, ErrorCode>;
//NOTE: Need to be the user //NOTE: Need to be the user
async fn change_email_flow(token: String) -> ErrorCode; async fn change_email_flow(username: String, token: String) -> ErrorCode;
async fn resolve_email_flow(token: String, login_code: u16, new_email: String) -> ErrorCode; async fn resolve_email_flow(username: String, token: String, login_code: u16, new_email: String) -> ErrorCode;
async fn change_username(token: String, new_username: String) -> ErrorCode; async fn change_username(username: String, token: String, new_username: String) -> ErrorCode;
async fn change_avatar(token: String, avatar: String) -> ErrorCode; async fn change_avatar(username: String, token: String, avatar: String) -> ErrorCode;
async fn get_all_data(username: String, token: String) -> Result<AuthUser, ErrorCode>;
//NOTE: Anyone can call
async fn get_avatar_for_user(username: String) -> Result<String, ErrorCode>;
//TODO: //TODO:
// Create account // Create account
// Change email // Change email
@@ -32,4 +36,20 @@ pub enum ErrorCode {
EmailTaken, EmailTaken,
UsernameTaken, UsernameTaken,
InvalidLoginCode, InvalidLoginCode,
InvalidImage,
InvalidUsername,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthUser {
pub id: u32,
pub username: String,
pub email: String,
pub avatar: String,
pub login_code: Option<u16>,
pub tokens: Option<Vec<String>>,
pub google_oauth: Option<String>,
pub apple_oauth: Option<String>,
pub github_oauth: Option<String>,
pub discord_oauth: Option<String>,
} }