Compare commits
	
		
			2 Commits
		
	
	
		
			0ad0a8cf0b
			...
			aeceb98ad5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| aeceb98ad5 | |||
| 6a64f87bc5 | 
| @ -18,8 +18,6 @@ use { | |||||||
| 	std::sync::Arc, | 	std::sync::Arc, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| type Res<T, E> = std::result::Result<T, E>; |  | ||||||
| type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>; |  | ||||||
| type DBPool = Arc<Pool<ConnectionMgrTcp>>; | type DBPool = Arc<Pool<ConnectionMgrTcp>>; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -12,29 +12,41 @@ use { | |||||||
| 	skytable::pool::ConnectionMgrTcp, | 	skytable::pool::ConnectionMgrTcp, | ||||||
| 	bb8::Pool, | 	bb8::Pool, | ||||||
| 	std::sync::Arc, | 	std::sync::Arc, | ||||||
| 	crate::double_split, | 	crate::{ | ||||||
|  | 		double_split, | ||||||
|  | 	}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| type Res<T, E> = std::result::Result<T, E>; | type Res<T, E> = std::result::Result<T, E>; | ||||||
| type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>; |  | ||||||
| type DBPool = Arc<Pool<ConnectionMgrTcp>>; | type DBPool = Arc<Pool<ConnectionMgrTcp>>; | ||||||
|  |  | ||||||
|  |  | ||||||
| pub async fn api(req: Request<Incoming>, pool: DBPool) -> Json { | pub async fn api(req: Request<Incoming>, pool: DBPool) -> Json { | ||||||
| 	let uri: &str = req.uri().path().as_ref(); | 	let uri: &str = req.uri().path().as_ref(); | ||||||
| 	match &uri[7..uri.len()] { | 	match &uri[7..uri.len()] { | ||||||
| 		"/test" => json!({"error": false, "msg": "test"}), |  | ||||||
| 		"/auth" => auth(req, pool.clone()).await, | 		"/auth" => auth(req, pool.clone()).await, | ||||||
| 		"/auth_get" => auth_get(req, pool.clone()).await, | 		"/auth_get" => auth_get(req, pool.clone()).await, | ||||||
| 		_ => json!({"error": true, "msg": "No endpoint"}) | 		_ => json!({"error": true, "msg": "No endpoint"}) | ||||||
| 	}	 | 	}	 | ||||||
| } | } | ||||||
|  |  | ||||||
| async fn auth(req: Request<Incoming>, pool: DBPool) -> Json { | async fn auth(req: Request<Incoming>, _pool: DBPool) -> Json { | ||||||
| 	json!({"error": false, "msg": "test auth endpoint v0"}) | 	let query = req.uri().query().or(Some("")).unwrap(); | ||||||
|  | 	let query = double_split(query.to_string(), "&", "="); | ||||||
|  | 	let sess = std::string::String::from(query | ||||||
|  | 		.get("session") | ||||||
|  | 		.or(Some(&"".to_string())) | ||||||
|  | 		.unwrap()); | ||||||
|  | 	match sess.as_str() { | ||||||
|  | 		"" => json!({"error": true, "msg": "No session in url"}), | ||||||
|  | 		_ => json!({ | ||||||
|  | 			"error": false, | ||||||
|  | 			"link": format!("https://auth.bitheaven.ru/authorize?session={}", sess) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| async fn auth_get(req: Request<Incoming>, pool: DBPool) -> Json { | async fn auth_get(req: Request<Incoming>, _pool: DBPool) -> Json { | ||||||
| 	let query = req.uri().query().or(Some("")).unwrap(); | 	let query = req.uri().query().or(Some("")).unwrap(); | ||||||
| 	let query = double_split(query.to_string(), "&", "="); | 	let query = double_split(query.to_string(), "&", "="); | ||||||
| 	println!("{:?}", query); | 	println!("{:?}", query); | ||||||
|  | |||||||
							
								
								
									
										55
									
								
								src/funcs.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/funcs.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | use { | ||||||
|  | 	std::{ | ||||||
|  | 		collections::HashMap, | ||||||
|  | 		any::type_name, | ||||||
|  | 		time::{ | ||||||
|  | 			SystemTime, | ||||||
|  | 			UNIX_EPOCH, | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
|  | 	urlencoding::decode as url_decode, | ||||||
|  | 	uuid::Uuid, | ||||||
|  | 	crate::{ | ||||||
|  | 		html::*, | ||||||
|  | 	}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #[allow(dead_code)] | ||||||
|  | pub fn type_of<T>(_: T) -> &'static str { | ||||||
|  | 	type_name::<T>() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn uuid_v4() -> Uuid { | ||||||
|  | 	Uuid::new_v4() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn build_html(body: &str) -> String { | ||||||
|  | 	format!("{}{}{}{}", HEADER_HTML, CSS3, body, FOOTER_HTML) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn double_split(body: String, first: &str, second: &str) -> HashMap<String, String> { | ||||||
|  | 	body.split(first) | ||||||
|  | 		.filter_map(|c| { | ||||||
|  | 			c.split_once(second) | ||||||
|  | 				.map(|(l, r)| ( | ||||||
|  | 					l.trim().to_owned(), | ||||||
|  | 					format!("{}", url_decode(r).expect("UTF-8")).trim().to_owned() | ||||||
|  | 				)) | ||||||
|  | 		}) | ||||||
|  | 		.collect::<HashMap<String, String>>() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn time() -> u32 { | ||||||
|  | 	SystemTime::now() | ||||||
|  | 		.duration_since(UNIX_EPOCH) | ||||||
|  | 		.unwrap() | ||||||
|  | 		.as_secs() as u32 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn time_ns() -> u128 { | ||||||
|  | 	SystemTime::now() | ||||||
|  | 		.duration_since(UNIX_EPOCH) | ||||||
|  | 		.unwrap() | ||||||
|  | 		.as_micros() | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								src/html.rs
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/html.rs
									
									
									
									
									
								
							| @ -16,7 +16,8 @@ pub const FOOTER_HTML: &str = r#" | |||||||
| 		</main> | 		</main> | ||||||
| 		<footer> | 		<footer> | ||||||
| 			<hr> | 			<hr> | ||||||
| 			Render time: RENDER_TIMEµs. Made by BitHeaven. | 			Render time: RENDER_TIMEµs. | ||||||
|  | 			Made by <a href="//bitheaven.ru/">BitHeaven</a>. | ||||||
| 		</footer> | 		</footer> | ||||||
| 	</body> | 	</body> | ||||||
| 	</html> | 	</html> | ||||||
| @ -36,6 +37,15 @@ pub const LOGIN_HTML: &str = r#" | |||||||
| 	</form> | 	</form> | ||||||
| "#; | "#; | ||||||
|  |  | ||||||
|  | pub const AUTHORIZE_HTML: &str = r#" | ||||||
|  | 	<h1>authorize</h1> | ||||||
|  | 	<h2>you authorizing in unknown service</h2> | ||||||
|  | 	<h3>yes?</h3> | ||||||
|  | 	<form method="POST"> | ||||||
|  | 		<button type="submit">yes</button> | ||||||
|  | 	</form> | ||||||
|  | "#; | ||||||
|  |  | ||||||
| pub const REG_HTML: &str = r#" | pub const REG_HTML: &str = r#" | ||||||
| 	<h1>register</h1> | 	<h1>register</h1> | ||||||
| 	<form method="POST"> | 	<form method="POST"> | ||||||
| @ -58,7 +68,7 @@ pub const RECOVER_HTML: &str = "<h1>recover</h1>"; | |||||||
| pub const NF_HTML: &str = "<h1>404</h1>think about it."; | pub const NF_HTML: &str = "<h1>404</h1>think about it."; | ||||||
|  |  | ||||||
| pub const CSS3: &str = r#"<style> | pub const CSS3: &str = r#"<style> | ||||||
| 	:root { color-scheme: dark; } | 	:root { color-scheme: dark; font-family: monospace; font-size: 16px; } | ||||||
| 	body { margin: auto; max-width: 768px; } | 	body { margin: auto; max-width: 768px; } | ||||||
| 	footer { text-align: right; } | 	footer { text-align: right; } | ||||||
| </style>"#; | </style>"#; | ||||||
|  | |||||||
							
								
								
									
										57
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -1,3 +1,4 @@ | |||||||
|  | mod funcs; | ||||||
| mod types; | mod types; | ||||||
| mod html; | mod html; | ||||||
| mod api; | mod api; | ||||||
| @ -8,10 +9,6 @@ use { | |||||||
| 		net::SocketAddr, | 		net::SocketAddr, | ||||||
| 		collections::HashMap, | 		collections::HashMap, | ||||||
| 		process::exit, | 		process::exit, | ||||||
| 		time::{ |  | ||||||
| 			SystemTime, |  | ||||||
| 			UNIX_EPOCH, |  | ||||||
| 		}, |  | ||||||
| 	}, | 	}, | ||||||
| 	chrono::{ | 	chrono::{ | ||||||
| 		DateTime, | 		DateTime, | ||||||
| @ -48,9 +45,6 @@ use { | |||||||
| 		RsaPrivateKey, | 		RsaPrivateKey, | ||||||
| 		RsaPublicKey, | 		RsaPublicKey, | ||||||
| 	}, | 	}, | ||||||
| 	urlencoding::{ |  | ||||||
| 		decode as url_decode, |  | ||||||
| 	}, |  | ||||||
| 	jsonwebtoken as jwt, | 	jsonwebtoken as jwt, | ||||||
| 	jwt::{ | 	jwt::{ | ||||||
| 		Header, | 		Header, | ||||||
| @ -66,9 +60,6 @@ use { | |||||||
| 		Value as Json, | 		Value as Json, | ||||||
| 		json, | 		json, | ||||||
| 	}, | 	}, | ||||||
| 	uuid::{ |  | ||||||
| 		Uuid, |  | ||||||
| 	}, |  | ||||||
| 	skytable::{ | 	skytable::{ | ||||||
| 		query, | 		query, | ||||||
| 		Config, | 		Config, | ||||||
| @ -87,6 +78,7 @@ use { | |||||||
| 			sites::Sites, | 			sites::Sites, | ||||||
| 		}, | 		}, | ||||||
| 		html::*, | 		html::*, | ||||||
|  | 		funcs::*, | ||||||
| 	}, | 	}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -200,6 +192,7 @@ async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) -> | |||||||
| 		"/" => uri_index(), | 		"/" => uri_index(), | ||||||
| 		"/cabinet" => uri_login(req, pool.clone(), &mut headers).await?, | 		"/cabinet" => uri_login(req, pool.clone(), &mut headers).await?, | ||||||
| 		"/login" => uri_login(req, pool.clone(), &mut headers).await?, | 		"/login" => uri_login(req, pool.clone(), &mut headers).await?, | ||||||
|  | 		"/authorize" => uri_authorize(req, pool.clone()).await?, | ||||||
| 		"/register" => uri_register(req, pool.clone(), &mut headers).await?, | 		"/register" => uri_register(req, pool.clone(), &mut headers).await?, | ||||||
| 		"/recover" => uri_recover(), | 		"/recover" => uri_recover(), | ||||||
| 		x if x.starts_with("/@") => uri_user(req, pool.clone()).await?, | 		x if x.starts_with("/@") => uri_user(req, pool.clone()).await?, | ||||||
| @ -214,10 +207,6 @@ async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) -> | |||||||
| 	Ok(Response::from_parts(parts, Full::new(Bytes::from(body)))) | 	Ok(Response::from_parts(parts, Full::new(Bytes::from(body)))) | ||||||
| } | } | ||||||
|  |  | ||||||
| fn build_html(body: &str) -> String { |  | ||||||
| 	format!("{}{}{}{}", HEADER_HTML, CSS3, body, FOOTER_HTML) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn set_cookie(headers: &mut HeaderMap, key: &str, value: &str) { | fn set_cookie(headers: &mut HeaderMap, key: &str, value: &str) { | ||||||
| 	let time = DateTime::from_timestamp((time() + REFRESH_LIFETIME) as i64, 0) | 	let time = DateTime::from_timestamp((time() + REFRESH_LIFETIME) as i64, 0) | ||||||
| 		.expect("REASON") | 		.expect("REASON") | ||||||
| @ -263,6 +252,17 @@ async fn uri_login(req: Request<Incoming>, pool: DBPool, headers: &mut HeaderMap | |||||||
| 	Ok((build_html(LOGIN_HTML), StatusCode::OK, restype)) | 	Ok((build_html(LOGIN_HTML), StatusCode::OK, restype)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | async fn uri_authorize(req: Request<Incoming>, _pool: DBPool) -> Result<(String, StatusCode, HeaderValue)> { | ||||||
|  | 	if *req.method() == Method::POST { | ||||||
|  | 		let body = get_body_from_request(req).await?; | ||||||
|  | 		let body = String::from_utf8(body).unwrap(); | ||||||
|  | 		let _body = double_split(body, "&", "="); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	let restype: HeaderValue = "text/html".parse().unwrap(); | ||||||
|  | 	Ok((build_html(AUTHORIZE_HTML), StatusCode::OK, restype)) | ||||||
|  | } | ||||||
|  |  | ||||||
| fn uri_index() -> (String, StatusCode, HeaderValue) { | fn uri_index() -> (String, StatusCode, HeaderValue) { | ||||||
| 	let restype: HeaderValue = "text/html".parse().unwrap(); | 	let restype: HeaderValue = "text/html".parse().unwrap(); | ||||||
| 	(build_html(INDEX_HTML), StatusCode::OK, restype) | 	(build_html(INDEX_HTML), StatusCode::OK, restype) | ||||||
| @ -483,18 +483,6 @@ async fn get_body_from_request(mut req: Request<Incoming>) -> Result<Vec<u8>> { | |||||||
| 	Ok(body) | 	Ok(body) | ||||||
| } | } | ||||||
|  |  | ||||||
| fn double_split(body: String, first: &str, second: &str) -> HashMap<String, String> { |  | ||||||
| 	body.split(first) |  | ||||||
| 		.filter_map(|c| { |  | ||||||
| 			c.split_once(second) |  | ||||||
| 				.map(|(l, r)| ( |  | ||||||
| 					l.trim().to_owned(), |  | ||||||
| 					format!("{}", url_decode(r).expect("UTF-8")).trim().to_owned() |  | ||||||
| 				)) |  | ||||||
| 		}) |  | ||||||
| 		.collect::<HashMap<String, String>>() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn rsa_gen() -> (Vec<u8>, Vec<u8>) { | fn rsa_gen() -> (Vec<u8>, Vec<u8>) { | ||||||
| 	let mut rng = rand::thread_rng(); | 	let mut rng = rand::thread_rng(); | ||||||
| 	let bits = 2048; | 	let bits = 2048; | ||||||
| @ -544,20 +532,3 @@ async fn jwt_verify(pool: DBPool, token: &str) -> Result<TokenData<Json>> { | |||||||
| 	Ok(ret) | 	Ok(ret) | ||||||
| } | } | ||||||
|  |  | ||||||
| fn uuid_v4() -> Uuid { |  | ||||||
| 	Uuid::new_v4() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn time() -> u32 { |  | ||||||
| 	SystemTime::now() |  | ||||||
| 		.duration_since(UNIX_EPOCH) |  | ||||||
| 		.unwrap() |  | ||||||
| 		.as_secs() as u32 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn time_ns() -> u128 { |  | ||||||
| 	SystemTime::now() |  | ||||||
| 		.duration_since(UNIX_EPOCH) |  | ||||||
| 		.unwrap() |  | ||||||
| 		.as_micros() |  | ||||||
| } |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user