added attending endpoints, added some events endpoints
This commit is contained in:
parent
9da2d2db91
commit
6a3e8508a7
150
src/attending.rs
Normal file
150
src/attending.rs
Normal 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()
|
||||||
|
}
|
||||||
@ -55,7 +55,7 @@ LIMIT
|
|||||||
Err(err) => (
|
Err(err) => (
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
Json(json!({
|
Json(json!({
|
||||||
"error": format!("Unknown error getting events: {}", err)
|
"error": format!("Unknown error getting events: {:?}", err)
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -103,7 +103,7 @@ LIMIT
|
|||||||
Err(err) => (
|
Err(err) => (
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
Json(json!({
|
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,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
Json(json!({
|
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) => (
|
Err(err) => (
|
||||||
StatusCode::BAD_REQUEST,
|
StatusCode::BAD_REQUEST,
|
||||||
Json(json!({
|
Json(json!({
|
||||||
"error": format!("Unknown error creating event: {}", err)
|
"error": format!("Unknown error creating event: {:?}", err)
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
.into_response(),
|
.into_response(),
|
||||||
|
|||||||
11
src/main.rs
11
src/main.rs
@ -1,3 +1,4 @@
|
|||||||
|
mod attending;
|
||||||
mod events;
|
mod events;
|
||||||
mod jwt;
|
mod jwt;
|
||||||
mod models;
|
mod models;
|
||||||
@ -5,7 +6,7 @@ mod report;
|
|||||||
mod user;
|
mod user;
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
routing::{get, post},
|
routing::{delete, get, post, put},
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use jsonwebtoken::{DecodingKey, EncodingKey};
|
use jsonwebtoken::{DecodingKey, EncodingKey};
|
||||||
@ -38,15 +39,17 @@ async fn main() {
|
|||||||
.await
|
.await
|
||||||
.expect("could not connect to database_url");
|
.expect("could not connect to database_url");
|
||||||
|
|
||||||
// build our application with a route
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(root))
|
.route("/", get(root))
|
||||||
.route("/user/signup", post(signup))
|
.route("/user/signup", post(signup))
|
||||||
.route("/user/signin", post(signin))
|
.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/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("/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 {
|
.with_state(AppState {
|
||||||
db_pool,
|
db_pool,
|
||||||
jwt_encode,
|
jwt_encode,
|
||||||
|
|||||||
@ -69,7 +69,7 @@ pub struct Signup {
|
|||||||
#[derive(
|
#[derive(
|
||||||
sqlx::Type, Copy, Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize,
|
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 {
|
pub enum Role {
|
||||||
Student,
|
Student,
|
||||||
Teacher,
|
Teacher,
|
||||||
@ -89,6 +89,20 @@ pub struct ReportQuery {
|
|||||||
pub grade: Option<i32>,
|
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.
|
/// The claims for the JWT.
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug, Hash)]
|
#[derive(Clone, Serialize, Deserialize, Debug, Hash)]
|
||||||
pub struct Claims {
|
pub struct Claims {
|
||||||
|
|||||||
@ -49,7 +49,7 @@ pub async fn signup(
|
|||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
Json(json!({
|
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,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
Json(json!({
|
Json(json!({
|
||||||
"error":
|
"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 (
|
return (
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
Json(json!({
|
Json(json!({
|
||||||
"error": format!("Unknown error signing in: {}", err)
|
"error": format!("Unknown error signing in: {:?}", err)
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user