Protect routes from forbidden edits and deletes

This commit is contained in:
Elias Projahn 2020-11-23 21:38:37 +01:00
parent c61db562f4
commit 319b1505da
2 changed files with 23 additions and 33 deletions

View file

@ -167,30 +167,19 @@ pub fn authenticate(conn: &DbConn, token: &str) -> Result<User> {
database::get_user(conn, &username)?.ok_or(anyhow!("User doesn't exist: {}", &username)) database::get_user(conn, &username)?.ok_or(anyhow!("User doesn't exist: {}", &username))
} }
/// Check whether a token allows the user to create a new item. /// Check whether the user is allowed to create a new item.
pub fn may_create(conn: &DbConn, token: &str) -> Result<bool> { pub fn may_create(user: &User) -> bool {
let user = authenticate(conn, token)?; !user.is_banned
let result = if user.is_banned { false } else { false };
Ok(result)
} }
/// Check whether a token allows the user to edit an item created by him or somebody else. /// Check whether the user is allowed to edit an item created by him or somebody else.
pub fn may_edit(conn: &DbConn, token: &str, created_by: &str) -> Result<bool> { pub fn may_edit(user: &User, created_by: &str) -> bool {
let user = authenticate(conn, token)?; !user.is_banned && (user.username == created_by || user.is_editor)
}
let result = if user.is_banned { /// Check whether the user is allowed to delete an item.
false pub fn may_delete(user: &User) -> bool {
} else if user.username == created_by { !user.is_banned && user.is_editor
true
} else if user.is_editor {
true
} else {
false
};
Ok(result)
} }
/// Return a hash for a password that can be stored in the database. /// Return a hash for a password that can be stored in the database.

View file

@ -1,4 +1,4 @@
use super::{authenticate, ServerError}; use super::{authenticate, may_create, may_delete, may_edit, ServerError};
use crate::database; use crate::database;
use crate::database::{DbPool, PersonInsertion}; use crate::database::{DbPool, PersonInsertion};
use actix_web::{delete, get, post, put, web, HttpResponse}; use actix_web::{delete, get, post, put, web, HttpResponse};
@ -31,10 +31,12 @@ pub async fn post_person(
web::block(move || { web::block(move || {
let conn = db.into_inner().get()?; let conn = db.into_inner().get()?;
let user = authenticate(&conn, auth.token()).or(Err(ServerError::Unauthorized))?; let user = authenticate(&conn, auth.token()).or(Err(ServerError::Unauthorized))?;
if may_create(&user) {
database::insert_person(&conn, id, &data.into_inner(), &user.username)?; database::insert_person(&conn, id, &data.into_inner(), &user.username)?;
Ok(())
Ok(()) } else {
Err(ServerError::Forbidden)
}
}) })
.await?; .await?;
@ -56,13 +58,12 @@ pub async fn put_person(
let id = id.into_inner(); let id = id.into_inner();
let old_person = database::get_person(&conn, id)?.ok_or(ServerError::NotFound)?; let old_person = database::get_person(&conn, id)?.ok_or(ServerError::NotFound)?;
if user.username != old_person.created_by { if may_edit(&user, &old_person.created_by) {
Err(ServerError::Forbidden)?; database::update_person(&conn, id, &data.into_inner())?;
Ok(())
} else {
Err(ServerError::Forbidden)
} }
database::update_person(&conn, id, &data.into_inner())?;
Ok(())
}) })
.await?; .await?;
@ -90,7 +91,7 @@ pub async fn delete_person(
let conn = db.into_inner().get()?; let conn = db.into_inner().get()?;
let user = authenticate(&conn, auth.token()).or(Err(ServerError::Unauthorized))?; let user = authenticate(&conn, auth.token()).or(Err(ServerError::Unauthorized))?;
if user.is_editor { if may_delete(&user) {
database::delete_person(&conn, id.into_inner())?; database::delete_person(&conn, id.into_inner())?;
Ok(()) Ok(())
} else { } else {