Merge of dev-auth #1

Merged
AINDUSTRIES merged 28 commits from dev-auth into main 2024-10-05 13:58:45 +00:00
3 changed files with 178 additions and 48 deletions
Showing only changes of commit 5a13cf9214 - Show all commits

View File

@@ -293,26 +293,37 @@ async fn get_admin(
db: Arc<Mutex<SqlitePool>>, db: Arc<Mutex<SqlitePool>>,
) -> Result<Response<Body>, Error> { ) -> Result<Response<Body>, Error> {
let authorised = is_authorised(req, db.clone(), 3).await; let authorised = is_authorised(req, db.clone(), 3).await;
if authorised { if !authorised {
return not_found().await; return get_page(&req, "/unauthorised", db).await;
} }
if path == "/admin" { match path {
return get_page(req, path, db).await; "/admin" => {
} get_page(req, path, db).await},
if path == "/admin/users" { "/admin/users" => {
let pool = db.clone().lock().unwrap().clone(); let pool = db.clone().lock().unwrap().clone();
let users = sqlx::query!(r#"SELECT username, permissions FROM users"#) let users = sqlx::query!(r#"SELECT id, username, permissions FROM users"#)
.fetch_all(&pool) .fetch_all(&pool)
.await .await
.unwrap(); .unwrap();
let users: Vec<(String, i64)> = users let users: Vec<(i64, String, i64)> = users
.iter() .iter()
.map(|x| (x.username.clone(), x.permissions)) .map(|x| (x.id, x.username.clone(), x.permissions))
.collect(); .collect();
let stringed = serde_json::to_string(&users).unwrap_or("".to_string()); let stringed = serde_json::to_string(&users).unwrap_or("".to_string());
return Ok(Response::builder().body(Body::new(stringed)).unwrap()); Ok(Response::builder().body(Body::new(stringed)).unwrap())
},
"/admin/players" => {
let pool = db.clone().lock().unwrap().clone();
let players = sqlx::query!(r#"SELECT id, name FROM players"#)
.fetch_all(&pool)
.await
.unwrap();
let players: Vec<Player> = players.iter().map(|x| Player{id: x.id, name: x.name.clone()}).collect();
let stringed = serde_json::to_string(&players).unwrap_or("".to_string());
Ok(Response::builder().body(Body::new(stringed)).unwrap())
}
_ => not_found().await,
} }
not_found().await
} }
async fn post(req: Request<Incoming>, db: Arc<Mutex<SqlitePool>>) -> Result<Response<Body>, Error> { async fn post(req: Request<Incoming>, db: Arc<Mutex<SqlitePool>>) -> Result<Response<Body>, Error> {
@@ -369,19 +380,92 @@ async fn post_admin(
db: Arc<Mutex<SqlitePool>>, db: Arc<Mutex<SqlitePool>>,
) -> Result<Response<Body>, Error> { ) -> Result<Response<Body>, Error> {
let authorised = is_authorised(&req, db.clone(), 3).await; let authorised = is_authorised(&req, db.clone(), 3).await;
if authorised { if !authorised {
return get_page(&req, "/unauthorised", db).await; return get_page(&req, "/unauthorised", db).await;
} }
let path = req.uri().path(); let path = req.uri().path();
match path { match path {
"/admin/post/user" => { "/admin/edit/user" => {
req_json::<User>(req).await; match req_json::<Value>(req).await {
Some(Value::Object(user)) => {
let username = user.get("username");
let permissions = user.get("permissions");
let id = user.get("id");
if username.is_none() || permissions.is_none() || id.is_none() {
return bad_request().await;
} }
"/admin/post/vote" => {} let pool = db.clone().lock().unwrap().clone();
"/admin/post/player" => {} let mut conn = pool.acquire().await.unwrap();
_ => {} let username = username.unwrap().as_str().unwrap();
let permissions = permissions.unwrap();
let id = id.unwrap();
let _ = sqlx::query!(r#"UPDATE users SET username = ?1, permissions = ?2 WHERE id = ?3"#, username, permissions, id).execute(&mut *conn).await;
ok().await
},
_ => {bad_request().await}
}
},
"/admin/delete/user" => {
match req_json::<Value>(req).await {
Some(Value::Object(user)) => {
let id = user.get("id");
if id.is_none() {
return bad_request().await;
}
let pool = db.clone().lock().unwrap().clone();
let mut conn = pool.acquire().await.unwrap();
let id = id.unwrap().as_i64().unwrap();
let _ = sqlx::query!(r#"DELETE FROM users WHERE id = ?1"#, id).execute(&mut *conn).await;
ok().await
}
_ => {bad_request().await}
}
},
"/admin/edit/player" => {
match req_json::<Player>(req).await {
Some(player) => {
let pool = db.clone().lock().unwrap().clone();
let mut conn = pool.acquire().await.unwrap();
let _ = sqlx::query!(r#"UPDATE players SET name = ?1 WHERE id = ?2"#, player.name, player.id).execute(&mut *conn).await;
ok().await
},
_ => bad_request().await
}
}
"/admin/new/player" => {
match req_json::<Value>(req).await {
Some(Value::Object(player)) => {
let name = player.get("name");
if name.is_none() {
return bad_request().await;
}
let pool = db.clone().lock().unwrap().clone();
let mut conn = pool.acquire().await.unwrap();
let name = name.unwrap().as_str().unwrap();
let _ = sqlx::query!(r#"INSERT INTO players (name) VALUES (?1)"#, name).execute(&mut *conn).await;
ok().await
},
_ => {bad_request().await}
}
},
"/admin/delete/player" => {
match req_json::<Value>(req).await {
Some(Value::Object(player)) => {
let id = player.get("id");
if id.is_none() {
return bad_request().await;
}
let pool = db.clone().lock().unwrap().clone();
let mut conn = pool.acquire().await.unwrap();
let id = id.unwrap().as_i64().unwrap();
let _ = sqlx::query!(r#"DELETE FROM players WHERE id = ?1"#, id).execute(&mut *conn).await;
ok().await
}
_ => {bad_request().await}
}
}
_ => {bad_request().await}
} }
not_found().await
} }
async fn login( async fn login(
@@ -391,17 +475,11 @@ async fn login(
let body = req.into_body().collect().await; let body = req.into_body().collect().await;
let data: Result<Login, serde_json::Error> = from_reader(body?.aggregate().reader()); let data: Result<Login, serde_json::Error> = from_reader(body?.aggregate().reader());
if data.is_err() { if data.is_err() {
return Ok(Response::builder() return bad_request().await;
.status(StatusCode::BAD_REQUEST)
.body(Body::Empty)
.unwrap());
} }
let data = data.unwrap(); let data = data.unwrap();
if !check_username(&data.username) { if !check_username(&data.username) {
return Ok(Response::builder() return bad_request().await;
.status(StatusCode::BAD_REQUEST)
.body(Body::Empty)
.unwrap());
} }
let pool = db.clone().lock().unwrap().clone(); let pool = db.clone().lock().unwrap().clone();
let result = sqlx::query!(r#"SELECT * FROM users WHERE username=?1"#, data.username) let result = sqlx::query!(r#"SELECT * FROM users WHERE username=?1"#, data.username)
@@ -415,7 +493,6 @@ async fn login(
Ok(()) => { Ok(()) => {
let date: DateTime<Utc> = DateTime::from(SystemTime::now()); let date: DateTime<Utc> = DateTime::from(SystemTime::now());
let date = date.checked_add_days(Days::new(7)).unwrap(); let date = date.checked_add_days(Days::new(7)).unwrap();
// With server side rendering, redirect here to "/"
Ok(Response::builder() Ok(Response::builder()
.header( .header(
SET_COOKIE, SET_COOKIE,
@@ -435,16 +512,10 @@ async fn login(
.body(Body::Empty) .body(Body::Empty)
.unwrap()) .unwrap())
} }
Err(_) => Ok(Response::builder() Err(_) => bad_request().await,
.status(StatusCode::BAD_REQUEST)
.body(Body::Empty)
.unwrap()),
} }
} }
Ok(None) => Ok(Response::builder() Ok(None) => bad_request().await,
.status(StatusCode::BAD_REQUEST)
.body(Body::Empty)
.unwrap()),
Err(_) => Ok(Response::builder() Err(_) => Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR) .status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::Empty) .body(Body::Empty)
@@ -599,6 +670,13 @@ async fn not_found() -> Result<Response<Body>, Error> {
.unwrap()) .unwrap())
} }
async fn bad_request() -> Result<Response<Body>, Error> {
Ok(Response::builder().status(StatusCode::BAD_REQUEST).body(Body::Empty).unwrap())
}
async fn ok() -> Result<Response<Body>, Error> {
Ok(Response::builder().body(Body::Empty).unwrap())
}
async fn req_json<T>(req: Request<Incoming>) -> Option<T> async fn req_json<T>(req: Request<Incoming>) -> Option<T>
where where
T: DeserializeOwned, T: DeserializeOwned,

View File

@@ -12,11 +12,13 @@
<body> <body>
<div> <div>
<h1>Users</h1> <h1>Users</h1>
<p>id, username, permission</p>
<div id="users"></div> <div id="users"></div>
</div> </div>
<div> <div>
<h1>Votes</h1> <h1>Players</h1>
<div id="votes"></div> <p>id, name</p>
<div id="players"></div>
</div> </div>
</body> </body>
</html> </html>

View File

@@ -4,19 +4,69 @@ async function run() {
let usersDiv = document.getElementById("users"); let usersDiv = document.getElementById("users");
for (let i = 0; i < users.length; i++) { for (let i = 0; i < users.length; i++) {
let item = document.createElement("div"); let item = document.createElement("div");
let id = document.createElement("p");
let username = document.createElement("input"); let username = document.createElement("input");
let permissions = document.createElement("input"); let permissions = document.createElement("input");
let edit = document.createElement("button"); let edit = document.createElement("button");
let del = document.createElement("button");
edit.textContent = "Edit"; edit.textContent = "Edit";
username.value = users[i][0]; del.textContent = "Delete";
permissions.value = users[i][1]; id.textContent = users[i][0];
username.value = users[i][1];
permissions.value = users[i][2];
item.style.display = "flex"; item.style.display = "flex";
item.append(username, permissions, edit); item.append(id, username, permissions, edit, del);
usersDiv.appendChild(item); usersDiv.appendChild(item);
edit.addEventListener("click", async () => {
await fetch("/admin/edit/user", {method: "POST", body: JSON.stringify({"id": users[i][0], "username": username.value, "permissions": parseInt(permissions.value)})});
window.location.reload();
})
del.addEventListener("click", async () => {
await fetch("/admin/delete/user", {method:"POST", body: JSON.stringify({"id": users[i][0]})});
window.location.reload();
})
} }
// let votes = await fetch("/admin/votes").then(r => r.json()); let players = await fetch("/admin/players").then(r => r.json());
let playersDiv = document.getElementById("players");
for (let i=0; i<players.length; i++) {
let item = document.createElement("div");
let id = document.createElement("p");
let name = document.createElement("input");
let edit = document.createElement("button");
let del = document.createElement("button");
edit.textContent = "Edit";
del.textContent = "Delete";
id.textContent = players[i]["id"];
name.value = players[i]["name"];
item.style.display = "flex";
item.append(id, name, edit, del);
playersDiv.appendChild(item);
edit.addEventListener("click", async () => {
await fetch("/admin/edit/player", {method: "POST", body: JSON.stringify({"id": players[i]["id"], "name": name.value})});
window.location.reload();
})
del.addEventListener("click", async () => {
await fetch("/admin/delete/player", {method:"POST", body: JSON.stringify({"id": players[i]["id"]})});
window.location.reload();
})
}
let newPlayer = document.createElement("button");
newPlayer.textContent = "Add Player";
newPlayer.addEventListener("click", () => {
let item = document.createElement("div");
let name = document.createElement("input");
let save = document.createElement("button");
save.textContent = "Save";
item.append(name, save);
playersDiv.appendChild(item);
save.addEventListener("click", async () => {
await fetch("/admin/new/player", {method:"POST", body: JSON.stringify({"name": name.value})})
window.location.reload();
})
})
playersDiv.parentNode.append(newPlayer);
} }
let _ = run(); let _ = run();