Some decentralize
This commit is contained in:
parent
54c82537b7
commit
a6ab0d0945
11
TODO
11
TODO
@ -1,4 +1,13 @@
|
||||
Auth using tokens
|
||||
Auth using uniq id on device
|
||||
Auth using QR code
|
||||
Auth using SMS or popup
|
||||
Auth using msg or popup
|
||||
Auth using email
|
||||
|
||||
|
||||
|
||||
##### API v0
|
||||
# Auth link (device check url with this session and get data)
|
||||
/auth?session=<UNIQUE>
|
||||
# Get auth data
|
||||
/auth_finish?session=<UNIQUE>
|
||||
|
36
src/api.rs
Normal file
36
src/api.rs
Normal file
@ -0,0 +1,36 @@
|
||||
mod v0;
|
||||
|
||||
use {
|
||||
hyper::{
|
||||
StatusCode,
|
||||
Request,
|
||||
header::HeaderValue,
|
||||
body::{
|
||||
Incoming,
|
||||
},
|
||||
},
|
||||
serde_json::{
|
||||
Value as Json,
|
||||
json,
|
||||
},
|
||||
skytable::pool::ConnectionMgrTcp,
|
||||
bb8::Pool,
|
||||
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>>;
|
||||
|
||||
|
||||
pub async fn endpoint(req: Request<Incoming>, pool: DBPool) -> (String, StatusCode, HeaderValue) {
|
||||
let uri: &str = req.uri().path().as_ref();
|
||||
let res: Json = match &uri[4..uri.len()] {
|
||||
"/test" => json!({"error": false, "msg": "test"}),
|
||||
x if x.starts_with("/v0/") => v0::api(req, pool.clone()).await,
|
||||
_ => json!({"error": true, "msg": "No endpoint"})
|
||||
};
|
||||
|
||||
let restype: HeaderValue = "application/json".parse().unwrap();
|
||||
(res.to_string(), StatusCode::IM_A_TEAPOT, restype)
|
||||
}
|
42
src/api/v0.rs
Normal file
42
src/api/v0.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use {
|
||||
hyper::{
|
||||
Request,
|
||||
body::{
|
||||
Incoming,
|
||||
},
|
||||
},
|
||||
serde_json::{
|
||||
Value as Json,
|
||||
json,
|
||||
},
|
||||
skytable::pool::ConnectionMgrTcp,
|
||||
bb8::Pool,
|
||||
std::sync::Arc,
|
||||
crate::double_split,
|
||||
};
|
||||
|
||||
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>>;
|
||||
|
||||
|
||||
pub async fn api(req: Request<Incoming>, pool: DBPool) -> Json {
|
||||
let uri: &str = req.uri().path().as_ref();
|
||||
match &uri[7..uri.len()] {
|
||||
"/test" => json!({"error": false, "msg": "test endpoint v0"}),
|
||||
"/auth" => auth(req, pool.clone()).await,
|
||||
"/auth_get" => auth_get(req, pool.clone()).await,
|
||||
_ => json!({"error": true, "msg": "No endpoint"})
|
||||
}
|
||||
}
|
||||
|
||||
async fn auth(req: Request<Incoming>, pool: DBPool) -> Json {
|
||||
json!({"error": false, "msg": "test auth endpoint v0"})
|
||||
}
|
||||
|
||||
async fn auth_get(req: Request<Incoming>, pool: DBPool) -> Json {
|
||||
let query = req.uri().query().or(Some("")).unwrap();
|
||||
let query = double_split(query.to_string(), "&", "=");
|
||||
println!("{:?}", query);
|
||||
json!({"error": false, "msg": "test auth_get endpoint v0"})
|
||||
}
|
64
src/html.rs
Normal file
64
src/html.rs
Normal file
@ -0,0 +1,64 @@
|
||||
pub const HEADER_HTML: &str = r#"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">index</a>
|
||||
<a href="/login">login</a>
|
||||
<a href="/register">register</a>
|
||||
<hr>
|
||||
</header>
|
||||
<main>
|
||||
"#;
|
||||
|
||||
pub const FOOTER_HTML: &str = r#"
|
||||
</main>
|
||||
<footer>
|
||||
<hr>
|
||||
Render time: RENDER_TIMEns. Made by BitHeaven.
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
"#;
|
||||
|
||||
pub const INDEX_HTML: &str = "<h1>main</h1>";
|
||||
|
||||
pub const LOGIN_HTML: &str = r#"
|
||||
<h1>login</h1>
|
||||
<form method="POST">
|
||||
<input name="login" type="text" placeholder="login / email" required>
|
||||
<br>
|
||||
<input name="password" type="password" placeholder="password" required>
|
||||
<br>
|
||||
<br>
|
||||
<button type="submit">login</button>
|
||||
</form>
|
||||
"#;
|
||||
|
||||
pub const REG_HTML: &str = r#"
|
||||
<h1>register</h1>
|
||||
<form method="POST">
|
||||
<input name="login" type="text" placeholder="login" required>
|
||||
<br>
|
||||
<input name="email" type="email" placeholder="email (opt)">
|
||||
<br>
|
||||
<input name="password" type="password" placeholder="password" required>
|
||||
<br>
|
||||
<input name="password2" type="password" placeholder="password again" required>
|
||||
<br>
|
||||
|
||||
<br>
|
||||
<button type="submit">register</button>
|
||||
</form>
|
||||
"#;
|
||||
|
||||
pub const RECOVER_HTML: &str = "<h1>recover</h1>";
|
||||
|
||||
pub const NF_HTML: &str = "<h1>404</h1>think about it.";
|
||||
|
||||
pub const CSS3: &str = r#"<style>
|
||||
:root { color-scheme: dark; }
|
||||
body { margin: auto; max-width: 768px; }
|
||||
footer { text-align: right; }
|
||||
</style>"#;
|
125
src/main.rs
125
src/main.rs
@ -1,10 +1,13 @@
|
||||
mod types;
|
||||
mod html;
|
||||
mod api;
|
||||
|
||||
use {
|
||||
std::{
|
||||
sync::Arc,
|
||||
net::SocketAddr,
|
||||
collections::HashMap,
|
||||
process::exit,
|
||||
time::{
|
||||
SystemTime,
|
||||
UNIX_EPOCH,
|
||||
@ -79,8 +82,11 @@ use {
|
||||
Pool,
|
||||
},
|
||||
crate::{
|
||||
types::users::Users,
|
||||
types::sites::Sites,
|
||||
types::{
|
||||
users::Users,
|
||||
sites::Sites,
|
||||
},
|
||||
html::*,
|
||||
},
|
||||
};
|
||||
|
||||
@ -101,75 +107,31 @@ const DB_PASS: &str = "rootpass12345678";
|
||||
const TOKEN_LIFETIME: u32 = 300;
|
||||
const REFRESH_LIFETIME: u32 = 2_678_400;
|
||||
|
||||
const HEADER_HTML: &str = r#"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">index</a>
|
||||
<a href="/login">login</a>
|
||||
<a href="/register">register</a>
|
||||
<hr>
|
||||
</header>
|
||||
<main>
|
||||
"#;
|
||||
const FOOTER_HTML: &str = r#"
|
||||
</main>
|
||||
<footer>
|
||||
<hr>
|
||||
Made by BitHeaven.
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
"#;
|
||||
const INDEX_HTML: &str = "<h1>main</h1>";
|
||||
const LOGIN_HTML: &str = r#"
|
||||
<h1>login</h1>
|
||||
<form method="POST">
|
||||
<input name="login" type="text" placeholder="login / email" required>
|
||||
<br>
|
||||
<input name="password" type="password" placeholder="password" required>
|
||||
<br>
|
||||
<br>
|
||||
<button type="submit">login</button>
|
||||
</form>
|
||||
"#;
|
||||
const REG_HTML: &str = r#"
|
||||
<h1>register</h1>
|
||||
<form method="POST">
|
||||
<input name="login" type="text" placeholder="login" required>
|
||||
<br>
|
||||
<input name="email" type="email" placeholder="email (opt)">
|
||||
<br>
|
||||
<input name="password" type="password" placeholder="password" required>
|
||||
<br>
|
||||
<input name="password2" type="password" placeholder="password again" required>
|
||||
<br>
|
||||
<br>
|
||||
<button type="submit">register</button>
|
||||
</form>
|
||||
"#;
|
||||
const RECOVER_HTML: &str = "<h1>recover</h1>";
|
||||
const NF_HTML: &str = "<h1>404</h1>think about it.";
|
||||
const CSS3: &str = r#"<style>
|
||||
:root { color-scheme: dark; }
|
||||
body { margin: auto; max-width: 768px; }
|
||||
footer { text-align: right; }
|
||||
</style>"#;
|
||||
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
println!("Starting.");
|
||||
|
||||
print!("Binding port...");
|
||||
let addr = SocketAddr::from(([0, 0, 0, 0], PORT));
|
||||
let listener = TcpListener::bind(addr).await?;
|
||||
let listener = TcpListener::bind(addr).await;
|
||||
if listener.is_err() {
|
||||
println!(" Error.");
|
||||
exit(1);
|
||||
}
|
||||
let listener = listener?;
|
||||
println!(" OK.");
|
||||
|
||||
print!("Connecting to DB...");
|
||||
let pool = pool::get_async(DB_POOL, Config::new(DB_ADDR, DB_PORT, DB_USER, DB_PASS)).await;
|
||||
let pool = Arc::new(pool.unwrap());
|
||||
|
||||
if pool.get().await.is_err() {
|
||||
println!(" Error.");
|
||||
exit(1);
|
||||
}
|
||||
println!(" OK.");
|
||||
|
||||
let pool = Arc::new(
|
||||
pool::get_async(
|
||||
DB_POOL,
|
||||
Config::new(DB_ADDR, DB_PORT, DB_USER, DB_PASS)
|
||||
).await.unwrap()
|
||||
);
|
||||
init_tables(pool.clone()).await?;
|
||||
|
||||
println!("Server started on port: {}", PORT);
|
||||
@ -197,6 +159,8 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) -> FullBytes {
|
||||
let t = time_ns();
|
||||
|
||||
if ip == "1.1.1.1" {
|
||||
}
|
||||
|
||||
@ -217,7 +181,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/") => {}
|
||||
_ => {
|
||||
println!("{}", token);
|
||||
// println!("{}", token);
|
||||
|
||||
if token != "" && jwt_verify(pool.clone(), token)
|
||||
.await?.claims.as_object().unwrap().len() == 0
|
||||
@ -239,13 +203,14 @@ async fn handle_connection(req: Request<Incoming>, pool: DBPool, ip: String) ->
|
||||
"/register" => uri_register(req, pool.clone(), &mut headers).await?,
|
||||
"/recover" => uri_recover(),
|
||||
x if x.starts_with("/@") => uri_user(req, pool.clone()).await?,
|
||||
x if x.starts_with("/api/") => uri_api(req),
|
||||
x if x.starts_with("/api/") => api::endpoint(req, pool.clone()).await,
|
||||
_ => uri_404()
|
||||
};
|
||||
|
||||
headers.insert(hyper::header::CONTENT_TYPE, restype);
|
||||
parts.headers = headers;
|
||||
|
||||
let body = body.replace("RENDER_TIME", &format!("{}", time_ns() - t));
|
||||
Ok(Response::from_parts(parts, Full::new(Bytes::from(body))))
|
||||
}
|
||||
|
||||
@ -338,26 +303,6 @@ fn uri_recover() -> (String, StatusCode, HeaderValue) {
|
||||
(build_html(RECOVER_HTML), StatusCode::OK, restype)
|
||||
}
|
||||
|
||||
fn uri_api(req: Request<Incoming>) -> (String, StatusCode, HeaderValue) {
|
||||
let uri: &str = req.uri().path().as_ref();
|
||||
let res: Json = match &uri[4..uri.len()] {
|
||||
"/test" => json!({"error": false, "msg": "test"}),
|
||||
x if x.starts_with("/v0/") => uri_api_v0(req),
|
||||
_ => json!({"error": true, "msg": "No endpoint"})
|
||||
};
|
||||
|
||||
let restype: HeaderValue = "application/json".parse().unwrap();
|
||||
(res.to_string(), StatusCode::IM_A_TEAPOT, restype)
|
||||
}
|
||||
|
||||
fn uri_api_v0(req: Request<Incoming>) -> Json {
|
||||
let uri: &str = req.uri().path().as_ref();
|
||||
match &uri[7..uri.len()] {
|
||||
"/test" => json!({"error": false, "msg": "test endpoint v0"}),
|
||||
_ => json!({"error": true, "msg": "No endpoint"})
|
||||
}
|
||||
}
|
||||
|
||||
async fn uri_user(req: Request<Incoming>, pool: DBPool) -> Res<(String, StatusCode, HeaderValue), SkyError> {
|
||||
let uri: &str = req.uri().path().as_ref();
|
||||
let login = &uri[2..uri.len()];
|
||||
@ -610,9 +555,9 @@ fn time() -> u32 {
|
||||
.as_secs() as u32
|
||||
}
|
||||
|
||||
/*fn time_ns() -> u128 {
|
||||
fn time_ns() -> u128 {
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as u128
|
||||
}*/
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user