added attending endpoints, added some events endpoints

This commit is contained in:
Mitchell Marino 2023-04-14 22:17:16 -05:00
parent 9da2d2db91
commit 6a3e8508a7
5 changed files with 179 additions and 12 deletions

150
src/attending.rs Normal file
View File

@ -0,0 +1,150 @@
use axum::{extract::State, http::StatusCode, response::IntoResponse, Json};
use axum_auth::AuthBearer;
use serde_json::json;
use sqlx::query;
use crate::{
jwt::handle_token,
models::{ConfirmAttending, MarkAttending, Role},
AppState,
};
pub async fn confirm_attending(
AuthBearer(token): AuthBearer,
State(app_state): State<AppState>,
Json(body): Json<ConfirmAttending>,
) -> impl IntoResponse {
let token_data = match handle_token(token, &app_state, Role::Teacher) {
Ok(token_data) => token_data,
Err(err) => return err,
};
let result = query!(
r#"
UPDATE event_attendees
SET
confirmed = $1
WHERE event_id = $2
AND user_id = $3
AND event_id IN (SELECT id FROM events WHERE created_by = $4);
"#,
body.new_confirmed,
body.event_id,
body.user_id,
token_data.id,
)
.execute(&app_state.db_pool)
.await;
match result {
Ok(success) => {
if success.rows_affected() > 0 {
(StatusCode::OK, Json(json!({})))
} else {
(
StatusCode::NOT_FOUND,
Json(json!({"error": "no record matched the parameters."})),
)
}
}
Err(err) => (
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({
"error": format!("Unknown error confirming attendence: {:?}", err)
})),
),
}
.into_response()
}
pub async fn mark_attending(
AuthBearer(token): AuthBearer,
State(app_state): State<AppState>,
Json(body): Json<MarkAttending>,
) -> impl IntoResponse {
let token_data = match handle_token(token, &app_state, Role::Student) {
Ok(token_data) => token_data,
Err(err) => return err,
};
let result = query!(
r#"
INSERT INTO event_attendees
(event_id, user_id)
VALUES
($1, $2)
"#,
body.event_id,
token_data.id,
)
.execute(&app_state.db_pool)
.await;
match result {
Ok(_) => (StatusCode::OK, Json(json!({}))),
Err(err) => {
// See if we get an error for marking an already marked.
if let sqlx::Error::Database(database_err) = &err {
if let Some(err_code) = database_err.code() {
if err_code == "23505" {
return (StatusCode::OK, Json(json!({}))).into_response();
}
}
}
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({
"error": format!("Unknown error marking attendance: {:?}", err)
})),
)
}
}
.into_response()
}
pub async fn unmark_attending(
AuthBearer(token): AuthBearer,
State(app_state): State<AppState>,
Json(body): Json<MarkAttending>,
) -> impl IntoResponse {
let token_data = match handle_token(token, &app_state, Role::Student) {
Ok(token_data) => token_data,
Err(err) => return err,
};
let result = query!(
r#"
DELETE FROM event_attendees
WHERE
event_id = $1 AND
user_id = $2
"#,
body.event_id,
token_data.id,
)
.execute(&app_state.db_pool)
.await;
match result {
Ok(_) => (StatusCode::OK, Json(json!({}))),
Err(err) => {
// See if we get an error for marking an already marked.
if let sqlx::Error::Database(database_err) = &err {
if let Some(err_code) = database_err.code() {
if err_code == "23505" {
return (StatusCode::OK, Json(json!({}))).into_response();
}
}
}
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({
"error": format!("Unknown error unmarking attendance: {:?}", err)
})),
)
}
}
.into_response()
}

View File

@ -55,7 +55,7 @@ LIMIT
Err(err) => (
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({
"error": format!("Unknown error getting events: {}", err)
"error": format!("Unknown error getting events: {:?}", err)
})),
),
}
@ -103,7 +103,7 @@ LIMIT
Err(err) => (
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({
"error": format!("Unknown error getting events: {}", err)
"error": format!("Unknown error getting events: {:?}", err)
})),
),
}
@ -158,7 +158,7 @@ pub async fn get_event(
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({
"error": format!("Unknown error getting event: {}", err)
"error": format!("Unknown error getting event: {:?}", err)
})),
)
}
@ -199,7 +199,7 @@ pub async fn create_event(
Err(err) => (
StatusCode::BAD_REQUEST,
Json(json!({
"error": format!("Unknown error creating event: {}", err)
"error": format!("Unknown error creating event: {:?}", err)
})),
)
.into_response(),

View File

@ -1,3 +1,4 @@
mod attending;
mod events;
mod jwt;
mod models;
@ -5,7 +6,7 @@ mod report;
mod user;
use axum::{
routing::{get, post},
routing::{delete, get, post, put},
Router,
};
use jsonwebtoken::{DecodingKey, EncodingKey};
@ -38,15 +39,17 @@ async fn main() {
.await
.expect("could not connect to database_url");
// build our application with a route
let app = Router::new()
.route("/", get(root))
.route("/user/signup", post(signup))
.route("/user/signin", post(signin))
.route("/event", post(events::create_event).get(events::get_event))
.route("/event", get(events::get_event).post(events::create_event))
.route("/event/preview", get(events::get_events_preview))
.route("/event/all", get(events::get_all_events))
.route("/event/future", get(events::get_all_events))
.route("/report", get(report::get_report))
.route("/attending/confirm", put(attending::confirm_attending))
.route("/attending/mark", post(attending::mark_attending))
.route("/attending/unmark", delete(attending::unmark_attending))
.with_state(AppState {
db_pool,
jwt_encode,

View File

@ -69,7 +69,7 @@ pub struct Signup {
#[derive(
sqlx::Type, Copy, Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize,
)]
// #[sqlx(type_name = "role", rename_all = "snake_case")]
#[sqlx(type_name = "role", rename_all = "snake_case")]
pub enum Role {
Student,
Teacher,
@ -89,6 +89,20 @@ pub struct ReportQuery {
pub grade: Option<i32>,
}
/// The model for the confirm attending request.
#[derive(Copy, Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct ConfirmAttending {
pub new_confirmed: bool,
pub event_id: i32,
pub user_id: i32,
}
/// The model for the mark attending request.
#[derive(Copy, Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct MarkAttending {
pub event_id: i32,
}
/// The claims for the JWT.
#[derive(Clone, Serialize, Deserialize, Debug, Hash)]
pub struct Claims {

View File

@ -49,7 +49,7 @@ pub async fn signup(
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({
"error": format!("Unknown error signing up: {}", err)
"error": format!("Unknown error signing up: {:?}", err)
})),
)
}
@ -93,7 +93,7 @@ pub async fn signin(
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({
"error":
format!("Unknown error signing in when creating JWT: {}", err)
format!("Unknown error signing in when creating JWT: {:?}", err)
})),
)
}
@ -113,7 +113,7 @@ pub async fn signin(
return (
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({
"error": format!("Unknown error signing in: {}", err)
"error": format!("Unknown error signing in: {:?}", err)
})),
)
}