From c877b02286ac76c4098baee10e16e2ac79718176 Mon Sep 17 00:00:00 2001
From: BitHeaven <bit.heaven@bk.ru>
Date: Sat, 23 Mar 2024 22:45:32 +0500
Subject: [PATCH] Finished refresh token and remove all warns

---
 src/api/v0.rs      |   1 -
 src/main.rs        | 123 +++++++++++++++++++++++++--------------------
 src/types/users.rs |  14 +++---
 3 files changed, 75 insertions(+), 63 deletions(-)

diff --git a/src/api/v0.rs b/src/api/v0.rs
index 8a9255b..67dba4e 100644
--- a/src/api/v0.rs
+++ b/src/api/v0.rs
@@ -17,7 +17,6 @@ use {
 	},
 };
 
-type Res<T, E> = std::result::Result<T, E>;
 type DBPool = Arc<Pool<ConnectionMgrTcp>>;
 
 
diff --git a/src/main.rs b/src/main.rs
index c060e05..0943356 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -165,7 +165,7 @@ async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) ->
 
 	let cookies = get_cookies(req.headers().clone());
 	let token = cookies.get("token");
-	let mut token = match token.is_none() {
+	let token = match token.is_none() {
 		false => token.unwrap(),
 		_ => ""
 	};
@@ -174,7 +174,7 @@ async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) ->
 	match <str as AsRef<str>>::as_ref(req.uri().path()) {
 		x if x.starts_with("/api/") => {},
 		_ => 'jwt_check: {
-//			if token == "" { break 'jwt_check; }
+			if token == "" { break 'jwt_check; }
 /*			if token != "" {
 				parts.status = StatusCode::FOUND;
 				set_cookie(&mut headers, "token", "");
@@ -217,7 +217,6 @@ async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) ->
 						let newtok = format!("{}", uuid_v4().as_hyphenated());
 						let newref = format!("{}", uuid_v4().as_hyphenated());
 						let time = time();
-						println!("Penis1");
 						let (uuid,) = con.query_parse::<(String,)>(&query!(
 							r#"
 								SELECT uid
@@ -226,7 +225,6 @@ async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) ->
 							"#,
 							tokenid
 						)).await?;
-						println!("Penis2");
 						let (login,) = con.query_parse::<(String,)>(&query!(
 							r#"
 								SELECT login
@@ -235,7 +233,6 @@ async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) ->
 							"#,
 							uuid.clone()
 						)).await?;					
-						println!("Penis3");
 						let _ = con.query_parse::<()>(&query!(
 							r#"
 								UPDATE bitauth.tokens
@@ -244,7 +241,6 @@ async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) ->
 							"#,
 							newtok.clone(), newref.clone(), time + REFRESH_LIFETIME, tokenid
 						)).await;
-						println!("Penis4");
 
 						set_cookie(&mut headers, "token",
 							&jwt_sign(pool.clone(), json!({
@@ -262,18 +258,8 @@ async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) ->
 								"exp": time + REFRESH_LIFETIME
 							})).await.unwrap()
 						);
-						println!("Penis5");
 
 						logged = true;
-/*
-CREATE MODEL IF NOT EXISTS bitauth.tokens(
-	uuid: string,
-	uid: string,
-	sid: string,
-	ref: string,
-	refend: uint32
-)
-*/						
 					}
 				}
 			}
@@ -287,6 +273,7 @@ CREATE MODEL IF NOT EXISTS bitauth.tokens(
 		"/" => uri_index(),
 		"/cabinet" => uri_login(req, pool.clone(), &mut headers).await?,
 		"/login" => uri_login(req, pool.clone(), &mut headers).await?,
+		x if x == "/authorize" && logged => uri_authorize(req, pool.clone()).await?,
 		"/authorize" => uri_authorize(req, pool.clone()).await?,
 		"/register" => uri_register(req, pool.clone(), &mut headers).await?,
 		"/recover" => uri_recover(),
@@ -426,13 +413,19 @@ async fn init_tables(pool: DBPool) -> Res<(), SkyError> {
 	let _ = con.query_parse::<()>(&query!("CREATE SPACE IF NOT EXISTS bitauth")).await;
 	let _ = con.query_parse::<()>(&query!(r#"
 		CREATE MODEL IF NOT EXISTS bitauth.users(
-			login: string,
 			uuid: string,
+			login: string,
 			password: string,
 			email: string,
 			tokens: list {type: string}
 		)
 	"#)).await;
+	let _ = con.query_parse::<()>(&query!(r#"
+		CREATE MODEL IF NOT EXISTS bitauth.users_uuid(
+			login: string,
+			uuid: string
+		)
+	"#)).await;
 	let _ = con.query_parse::<()>(&query!(r#"
 		CREATE MODEL IF NOT EXISTS bitauth.sites(
 			uuid: string,
@@ -451,6 +444,13 @@ async fn init_tables(pool: DBPool) -> Res<(), SkyError> {
 			refend: uint32
 		)
 	"#)).await;
+	let _ = con.query_parse::<()>(&query!(r#"
+		CREATE MODEL IF NOT EXISTS bitauth.v0(
+			session: string,
+			login: string,
+			uuid: string
+		)
+	"#)).await;
 
 	let q = con.query_parse::<Sites>(&query!("SELECT * FROM bitauth.sites WHERE uuid = 0")).await;
 	if q.is_err() {
@@ -475,7 +475,6 @@ async fn get_user(pool: DBPool, login: String) -> Res<Users, SkyError> {
 }
 
 async fn login_user(pool: DBPool, data: HashMap<String, String>) -> Res<(String, String), SkyError> {
-	let mut err = false;
 	let mut ret: (String, String) = Default::default();
 	let mut con = pool.get().await.unwrap();
 
@@ -483,43 +482,48 @@ async fn login_user(pool: DBPool, data: HashMap<String, String>) -> Res<(String,
 	let pass = data.get("password").unwrap().trim();
 
 	let q = con
-		.query_parse::<Users>(&query!("SELECT * FROM bitauth.users WHERE login = ?", login))
+		.query_parse::<(String,)>(&query!("SELECT uuid FROM bitauth.users_uuid WHERE login = ?", login))
 		.await;
-	if q.is_err() { err = true };
+	if q.is_err() { println!("{:?}", q.err()); return Ok(ret); };
+	let (uuid,) = q.unwrap();
 
-	if !err {
-		let q = q.unwrap();
-		if bcrypt::verify(pass, q.password.as_str()).unwrap() {
-			let token = format!("{}", uuid_v4().as_hyphenated());
-			let reftoken = format!("{}", uuid_v4().as_hyphenated());
-			let time = time();
-			let uuid: String = q.uuid;
-			let login: String = q.login;
+	let q = con
+		.query_parse::<Users>(&query!("SELECT * FROM bitauth.users WHERE uuid = ?", uuid.clone()))
+		.await;
+	// TODO: Send to admin notify about trouble!
+	if q.is_err() { return Ok(ret); };
 
-			let _ = con.query_parse::<()>(&query!(
-				"INSERT INTO bitauth.tokens { uuid: ?, uid: ?, sid: ?, ref: ?, refend: ? }",
-				token.clone(), uuid.clone(), "0", reftoken.clone(), time + REFRESH_LIFETIME
-			)).await;
-			let _ = con.query_parse::<()>(&query!(
-				"UPDATE bitauth.users SET tokens += ? WHERE login = ?",
-				token.clone(), login.clone()
-			)).await;
+	let q = q.unwrap();
+	if bcrypt::verify(pass, q.password.as_str()).unwrap() {
+		let token = format!("{}", uuid_v4().as_hyphenated());
+		let reftoken = format!("{}", uuid_v4().as_hyphenated());
+		let time = time();
+		let uuid: String = q.uuid;
+		let login: String = q.login;
 
-			ret = (
-				jwt_sign(pool.clone(), json!({
-					"login": login.clone(),
-					"uuid": uuid.clone(),
-					"iat": time,
-					"exp": time + TOKEN_LIFETIME
-				})).await.unwrap(),
-				jwt_sign(pool.clone(), json!({
-					"uuid": token.clone(),
-					"iat": time,
-					"ref": reftoken.clone(),
-					"exp": time + REFRESH_LIFETIME
-				})).await.unwrap()
-			);
-		}
+		let _ = con.query_parse::<()>(&query!(
+			"INSERT INTO bitauth.tokens { uuid: ?, uid: ?, sid: ?, ref: ?, refend: ? }",
+			token.clone(), uuid.clone(), "0", reftoken.clone(), time + REFRESH_LIFETIME
+		)).await;
+		let _ = con.query_parse::<()>(&query!(
+			"UPDATE bitauth.users SET tokens += ? WHERE login = ?",
+			token.clone(), login.clone()
+		)).await;
+
+		ret = (
+			jwt_sign(pool.clone(), json!({
+				"login": login.clone(),
+				"uuid": uuid.clone(),
+				"iat": time,
+				"exp": time + TOKEN_LIFETIME
+			})).await.unwrap(),
+			jwt_sign(pool.clone(), json!({
+				"uuid": token.clone(),
+				"iat": time,
+				"ref": reftoken.clone(),
+				"exp": time + REFRESH_LIFETIME
+			})).await.unwrap()
+		);
 	}
 
 	Ok(ret)
@@ -538,7 +542,7 @@ async fn create_user(pool: DBPool, data: HashMap<String, String>) -> Res<bool, S
 	if pass.len() < 8 { ret = false };
 
 	let q = con
-		.query_parse::<(String,)>(&query!("SELECT uuid FROM bitauth.users WHERE login = ?", login))
+		.query_parse::<(String,)>(&query!("SELECT uuid FROM bitauth.users_uuid WHERE login = ?", login))
 		.await;
 	if q.is_ok() { ret = false };
 
@@ -548,18 +552,27 @@ async fn create_user(pool: DBPool, data: HashMap<String, String>) -> Res<bool, S
 
 		let q = con.query_parse::<()>(&query!(
 			r#"INSERT INTO bitauth.users {
-				login: ?,
 				uuid: ?,
+				login: ?,
 				password: ?,
 				email: ?,
 				tokens: []
 			}"#,
-			login,
-			uuid,
+			uuid.clone(),
+			login.clone(),
 			pass,
 			email,
 		)).await;
+		if q.is_err() { ret = false }
 
+		let q = con.query_parse::<()>(&query!(
+			r#"INSERT INTO bitauth.users_uuid {
+				login: ?,
+				uuid: ?
+			}"#,
+			login.clone(),
+			uuid.clone()
+		)).await;
 		if q.is_err() { ret = false }
 	}
 
diff --git a/src/types/users.rs b/src/types/users.rs
index 845a8de..d16d9d2 100644
--- a/src/types/users.rs
+++ b/src/types/users.rs
@@ -10,18 +10,18 @@ use skytable::{
 
 
 pub struct Users {
-	pub login: String,
 	pub uuid: String,
+	pub login: String,
 	pub password: String,
 	pub email: String,
 	pub tokens: Vec<Value>,
 }
 
 impl Users {
-	pub fn new(login: String, uuid: String, password: String, email: String, tokens: Vec<Value>) -> Self {
+	pub fn new(uuid: String, login: String, password: String, email: String, tokens: Vec<Value>) -> Self {
 		Self {
-			login,
 			uuid,
+			login,
 			password,
 			email,
 			tokens,
@@ -31,8 +31,8 @@ impl Users {
 
 impl SQParam for Users {
 	fn append_param(&self, q: &mut Vec<u8>) -> usize {
-		self.login.append_param(q)
-			+ self.uuid.append_param(q)
+		self.uuid.append_param(q)
+			+ self.login.append_param(q)
 			+ self.password.append_param(q)
 			+ self.email.append_param(q)
 	}
@@ -40,7 +40,7 @@ impl SQParam for Users {
 
 impl FromResponse for Users {
 	fn from_response(resp: Response) -> ClientResult<Self> {
-		let (login, uuid, password, email, tokens) = FromResponse::from_response(resp)?;
-		Ok(Self::new(login, uuid, password, email, tokens))
+		let (uuid, login, password, email, tokens) = FromResponse::from_response(resp)?;
+		Ok(Self::new(uuid, login, password, email, tokens))
 	}
 }