finish admin panel

This commit is contained in:
SadlyNotSappho 2024-02-13 14:55:21 -08:00
parent 2fb3edeb40
commit 17f46ce71d
3 changed files with 129 additions and 51 deletions

View File

@ -77,7 +77,13 @@ async fn account(mut db: Connection<Db>, cookies: &CookieJar<'_>) -> String {
match token {
Some(t) => {
match User::get_by_token(&mut db, t).await {
Some(user) => format!("Username: {}\nAdmin: {}\nMake Posts: {}\nComment: {}", user.username, user.admin, user.make_posts, user.comment),
Some(user) => format!(
"Username: {}\nAdmin: {}\nMake Posts: {}\nComment: {}",
user.username,
user.admin,
user.make_posts,
user.comment
),
None => "User doesn't exist.".to_string()
}
},
@ -140,7 +146,7 @@ async fn adminpanel(mut db: Connection<Db>, cookies: &CookieJar<'_>) -> RawHtml<
Some(user) => match user.admin {
true => {
RawHtml(
fs::read_to_string("/srv/web/adminpanel.html").unwrap()
fs::read_to_string("/srv/web/adminpanel.html").unwrap().replace("{{username}}", &user.username[..])
)
},
false => RawHtml(fs::read_to_string("/srv/web/invalidperms.html").unwrap())
@ -157,7 +163,7 @@ async fn adminpanel(mut db: Connection<Db>, cookies: &CookieJar<'_>) -> RawHtml<
#[derive(Deserialize, Serialize)]
#[serde(crate = "rocket::serde")]
struct ApiPermsResult {
perms: Result<Perms, bool>
perms: Result<Perms, String>
}
#[derive(Deserialize, Serialize)]
#[serde(crate = "rocket::serde")]
@ -167,7 +173,13 @@ struct Perms{
comment: bool
}
#[get("/perms/<username>")]
async fn api_perms(mut db: Connection<Db>, username: String) -> Json<ApiPermsResult> {
async fn api_perms(mut db: Connection<Db>, username: String, cookies: &CookieJar<'_>) -> Json<ApiPermsResult> {
match cookies.get_private("token") {
Some(t) => {
match User::get_by_token(&mut db, t).await {
Some(user) => {
match user.admin {
true => {
match User::get_by_username(&mut db, &username).await {
Some(user) => {
Json(ApiPermsResult {
@ -175,28 +187,38 @@ async fn api_perms(mut db: Connection<Db>, username: String) -> Json<ApiPermsRes
admin: user.admin,
make_posts: user.make_posts,
comment: user.comment
})})
})
})
},
None => {
Json(ApiPermsResult { perms: Err(false) })
Json(ApiPermsResult { perms: Err("User doesn't exist".to_string()) })
}
}
},
false => {Json(ApiPermsResult { perms: Err("You don't have the permission to do this".to_string())})}
}
},
None => {Json(ApiPermsResult { perms: Err("Invalid token".to_string())})},
}},
None => {Json(ApiPermsResult { perms: Err("Not logged in".to_string())})}
}
}
#[derive(Deserialize)]
#[serde(crate = "rocket::serde")]
struct ToggleRole {
struct TogglePerms {
perm: String,
value: bool,
username: String
}
#[post("/togglerole", data = "<info>")]
async fn togglerole(
#[post("/toggleperms", data = "<info>")]
async fn toggleperms(
mut db: Connection<Db>,
info: Json<ToggleRole>,
info: Json<TogglePerms>,
cookies: &CookieJar<'_>,
) -> &'static str {
) -> String {
match cookies.get_private("token") {
Some(t) => {
match User::get_by_token(&mut db, t).await {
@ -206,38 +228,39 @@ async fn togglerole(
match User::get_by_username(&mut db, &info.username).await {
Some(toggled_user) => {
if toggled_user.username == user.username && info.perm == "admin".to_string() {
"You can't toggle your own admin status"
"You can't change your own admin status".to_string()
} else {
let admin_username = std::env::var("ADMIN_USERNAME").expect("set ADMIN_USERNAME env var");
if toggled_user.username == admin_username {
"You can't change the system admin's perms."
"You can't change the system admin's perms.".to_string()
} else {
if info.perm == "admin" && user.username != admin_username {
"You can't toggle other people's admin status."
"You can't change other people's admin status.".to_string()
} else {
// how deep is this shit
// i counted. 12.
// NOW we can actually do the thing :D
match toggled_user.set_role(db, &info.perm, &info.value).await {
Ok(_) => "Done",
Err(_) => "Couldn't update the user's role."
}
let res = match toggled_user.set_role(&mut db, &info.perm, &info.value).await {
Ok(_) => "Done".to_string(),
Err(why) => format!("Couldn't update the user's role: {why}")
};
res
}
}
}
},
None => "The user you're trying to toggle perms for doesn't exist."
None => "The user you're trying to toggle perms for doesn't exist.".to_string()
}
},
false => {
"You aren't an admin."
"You aren't an admin.".to_string()
}
}
},
None => "Invalid user"
None => "Invalid user".to_string()
}
},
None => "Not logged in"
None => "Not logged in".to_string()
}
}
@ -316,7 +339,7 @@ async fn main() {
.attach(AdHoc::on_ignite("DB Migrations", migrate))
.mount(
"/",
routes![login_page, login, logout, createuser, createuser_page, account, adminpanel, togglerole],
routes![login_page, login, logout, createuser, createuser_page, account, adminpanel, toggleperms],
)
.mount("/api", routes![api_perms])
.mount("/css", FileServer::from("/srv/web/css"))

View File

@ -55,7 +55,7 @@ impl Post {
}
}
}
#[derive(FromRow)]
#[derive(FromRow, Debug)]
pub struct User {
pub id: i32,
pub username: String,
@ -170,21 +170,28 @@ impl User {
pub async fn set_role(
&self,
mut db: Connection<Db>,
db: &mut Connection<Db>,
role: &String,
value: &bool,
) -> Result<String, String> {
let mut sql = String::from("UPDATE users SET {{perm}} = $1 WHERE id = $2");
if role == "admin" {
sql = sql.replace("{{perm}}", "admin");
} else if role == "make_posts" {
sql = sql.replace("{{perm}}", "make_posts");
} else if role == &"comment".to_string() {
sql = sql.replace("{{perm}}", "comment");
}
if sql.contains("{{perm}}") {
Err("Invalid role.".to_string())
} else {
match db
.fetch_one(
sqlx::query("UPDATE users SET $1 = $2 WHERE id = $3")
.bind(role)
.bind(value)
.bind(self.id),
)
.execute(sqlx::query(&sql[..]).bind(value).bind(self.id))
.await
{
Ok(_) => Ok("Succesfully updated role.".to_string()),
Err(why) => Err(why.to_string()),
}
}
}
}

View File

@ -17,7 +17,7 @@ struct ToggleRole {
<body>
<div id="data">
perms toggle
Welcome, {{username}}. Please select a user to modify.
</div>
<form action="/toggleperms" method="post" class="permtoggle-form" id="permtoggle-form">
<div id="username-form">
@ -48,28 +48,76 @@ struct ToggleRole {
const user = JSON.parse(await (await fetch(`/api/perms/${username}`)).text()).perms
if (user.Ok) {
// set checked
document.getElementById("admin-toggle").checked = user.Ok.admin
document.getElementById("make-post-toggle").checked = user.Ok.make_posts
document.getElementById("comment-toggle").checked = user.Ok.comment
// toggle views
document.querySelector(".toggle-form").style.display = "block"
document.getElementById("username-form").style.display = "none"
document.getElementById("load-button").style.display = "none"
document.getElementById("data").innerHTML = `Username: ${username}`
document.getElementById("admin-toggle").checked = user.Ok.admin
// update text at top
document.getElementById("data").innerHTML = `You're logged in as {{username}}. You're modifying ${username}.`
} else {
alert("User doesn't exist.")
}
break
}
// TODO: imlpement these, server handles perm checks
case "admin-toggle": {
// admin toggle
let username = document.getElementById("username").value;
const update = await (await fetch("/toggleperms", {
method: "POST",
header: {"Content-Type": "application/json"},
body: JSON.stringify(
{
username: username,
perm: "admin",
value: document.getElementById("admin-toggle").checked
}
)
})).text()
if (update == "Done") {document.getElementById("admin-toggle").checked = !document.getElementById("admin-toggle").checked}
alert(update)
break
}
case "make-post-toggle": {
// make post toggle
let username = document.getElementById("username").value;
const update = await (await fetch("/toggleperms", {
method: "POST",
header: {"Content-Type": "application/json"},
body: JSON.stringify(
{
username: username,
perm: "make_posts",
value: document.getElementById("make-post-toggle").checked
}
)
})).text()
if (update == "Done") {document.getElementById("make-post-toggle").checked = !document.getElementById("make-post-toggle").checked}
alert(update)
break
}
case "comment-toggle": {
// comment toggle
let username = document.getElementById("username").value;
const update = await (await fetch("/toggleperms", {
method: "POST",
header: {"Content-Type": "application/json"},
body: JSON.stringify(
{
username: username,
perm: "comment",
value: document.getElementById("comment-toggle").checked
}
)
})).text()
if (update == "Done") {document.getElementById("comment-toggle").checked = !document.getElementById("comment-toggle").checked}
alert(update)
break
}
}