Merge of dev-auth #1
148
src/main.rs
148
src/main.rs
@@ -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,
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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();
|
||||||
Reference in New Issue
Block a user