Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error cleanup #384

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions backend/src/handlers_prelude/github_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,25 @@

use axum::routing::post;
use axum::{extract::State, http::HeaderMap, Router};
use tracing::{debug, error, info};
use tracing::{debug, info};

use crate::handlers_prelude::ApiError;
use crate::AppState;

pub async fn github_hook_handler(State(state): State<AppState>, headers: HeaderMap) {
pub async fn github_hook_handler(
State(state): State<AppState>,
headers: HeaderMap,
) -> Result<(), ApiError> {
let event_type = headers.get("x-github-event").unwrap().to_str().unwrap();
debug!("Received Github webhook event of type {event_type:?}");

debug!("Received Github webhook event of type {:?}", event_type);

if event_type == "push" {
info!("New changes pushed to Github, pulling changes...");
match state.git.pull() {
Ok(_) => {}
Err(e) => {
error!("Failed to auto-pull changes with error: {e:?}");
}
}
state.git.pull()?;
}

Ok(())
}

pub async fn create_github_route() -> Router<AppState> {
Expand Down
109 changes: 30 additions & 79 deletions backend/src/handlers_prelude/groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ use axum::{
};
use reqwest::StatusCode;
use serde::{Deserialize, Serialize};
use tracing::error;

use crate::{
db::{Database, Group},
eyre_to_axum_err,
handlers_prelude::ApiError,
perms::Permission,
require_perms, AppState,
};
Expand All @@ -33,16 +32,9 @@ pub struct GroupResponse {
pub async fn create_group_response(
db: &Database,
group: Group,
) -> Result<GroupResponse, (StatusCode, String)> {
let permissions = db
.get_group_permissions(group.id)
.await
.map_err(eyre_to_axum_err)?;

let members = db
.get_group_members(group.id)
.await
.map_err(eyre_to_axum_err)?;
) -> Result<GroupResponse, ApiError> {
let permissions = db.get_group_permissions(group.id).await?;
let members = db.get_group_members(group.id).await?;

Ok(GroupResponse {
id: group.id,
Expand All @@ -62,29 +54,17 @@ pub async fn create_group_response(
pub async fn get_groups_handler(
State(state): State<AppState>,
headers: HeaderMap,
) -> Result<Json<Vec<GroupResponse>>, (StatusCode, String)> {
) -> Result<Json<Vec<GroupResponse>>, ApiError> {
require_perms(State(&state), headers, &[Permission::ManageUsers]).await?;

match state.db.get_all_groups().await {
Ok(groups) => {
let mut get_groups_response = Vec::new();

for group in groups {
get_groups_response.push(create_group_response(&state.db, group).await?);
}

Ok(Json(get_groups_response))
}
Err(e) => {
error!("An error was encountered fetching all groups: {e:?}");
Err((
StatusCode::INTERNAL_SERVER_ERROR,
"An internal error was encountered fetching all groups, \
check server logs for more info"
.to_owned(),
))
}
let groups = state.db.get_all_groups().await?;
let mut get_groups_response = Vec::with_capacity(groups.len());

for group in groups {
get_groups_response.push(create_group_response(&state.db, group).await?);
}

Ok(Json(get_groups_response))
}

#[derive(Serialize, Deserialize)]
Expand All @@ -96,20 +76,13 @@ pub async fn post_group_handler(
State(state): State<AppState>,
headers: HeaderMap,
Json(body): Json<CreateGroupRequestBody>,
) -> Result<Json<GroupResponse>, (StatusCode, String)> {
) -> Result<Json<GroupResponse>, ApiError> {
require_perms(State(&state), headers, &[Permission::ManageUsers]).await?;

Ok(Json(
create_group_response(
&state.db,
state
.db
.create_group(body.group_name)
.await
.map_err(eyre_to_axum_err)?,
)
.await?,
))
let group = state.db.create_group(body.group_name).await?;
let response = create_group_response(&state.db, group).await?;

Ok(Json(response))
}

#[derive(Serialize, Deserialize)]
Expand All @@ -122,15 +95,10 @@ pub async fn put_group_permissions_handler(
headers: HeaderMap,
Path(group_id): Path<i64>,
Json(body): Json<UpdateGroupPermissionsRequestBody>,
) -> Result<Json<GroupResponse>, (StatusCode, String)> {
) -> Result<Json<GroupResponse>, ApiError> {
require_perms(State(&state), headers, &[Permission::ManageUsers]).await?;

let current_permissions = state
.db
.get_group_permissions(group_id)
.await
.map_err(eyre_to_axum_err)?;

let current_permissions = state.db.get_group_permissions(group_id).await?;
let new_permissions = body.permissions;

let permissions_to_remove = current_permissions
Expand All @@ -144,47 +112,30 @@ pub async fn put_group_permissions_handler(
.collect::<Vec<_>>();

for perm in permissions_to_remove {
state
.db
.remove_group_permission(group_id, *perm)
.await
.map_err(eyre_to_axum_err)?;
state.db.remove_group_permission(group_id, *perm).await?;
}

for perm in permissions_to_add {
state
.db
.add_group_permission(group_id, *perm)
.await
.map_err(eyre_to_axum_err)?;
state.db.add_group_permission(group_id, *perm).await?;
}

Ok(Json(
create_group_response(
&state.db,
state
.db
.get_group(group_id)
.await
.map_err(eyre_to_axum_err)?
.unwrap(),
)
.await?,
))
let updated_group = state.db.get_group(group_id).await?.ok_or_else(|| {
ApiError::from((StatusCode::NOT_FOUND, "Group not found in the database".to_string()))
})?;

Ok(Json(create_group_response(&state.db, updated_group).await?))
}

pub async fn delete_group_handler(
State(state): State<AppState>,
headers: HeaderMap,
Path(group_id): Path<i64>,
) -> Result<(), (StatusCode, String)> {
) -> Result<(), ApiError> {
require_perms(State(&state), headers, &[Permission::ManageUsers]).await?;

state
.db
.delete_group(group_id)
.await
.map_err(eyre_to_axum_err)
state.db.delete_group(group_id).await?;

Ok(())
}

pub async fn create_group_route() -> Router<AppState> {
Expand Down
6 changes: 6 additions & 0 deletions backend/src/handlers_prelude/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ impl From<String> for ApiError {
}
}

impl From<(StatusCode, String)> for ApiError {
fn from(err: (StatusCode, String)) -> Self {
Self(eyre::eyre!("{}: {}", err.0, err.1))
}
}

/// Quick and dirty way to convert an eyre error to a (StatusCode, message) response, meant for use with `map_err`, so that errors can be propagated out of
/// axum handlers with `?`.
pub fn eyre_to_axum_err(e: Report) -> (StatusCode, String) {
Expand Down
1 change: 0 additions & 1 deletion frontend/static/css/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
--font-family:
system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
'Open Sans', 'Helvetica Neue', sans-serif;

--green: #329932;
--red: #993232;
--toast-success: #36a331;
Expand Down