feat: ✨ admin routing part 1
This commit is contained in:
parent
f4765630ee
commit
a462d3a82d
11 changed files with 520 additions and 506 deletions
|
@ -8,3 +8,12 @@ CREATE TABLE IF NOT EXISTS "user"(
|
|||
role_id BIGINT NOT NULL REFERENCES "role" DEFAULT 10,
|
||||
creation_time TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
INSERT INTO "user"(user_id, name, surname, gender, birth_date, role_id)
|
||||
VALUES (0, 'Builder', 'Builder', true, NOW(), 0)
|
||||
ON CONFLICT(user_id) DO UPDATE SET
|
||||
"name" = 'Builder',
|
||||
"surname" = 'Builder',
|
||||
"gender" = true,
|
||||
"birth_date" = NOW(),
|
||||
"role_id" = 0;
|
||||
|
|
|
@ -3,5 +3,6 @@ CREATE TABLE IF NOT EXISTS "user_contact"(
|
|||
user_id BIGSERIAL NOT NULL REFERENCES "user"(user_id),
|
||||
contact_id BIGSERIAL NOT NULL REFERENCES "contact"(id),
|
||||
contact_value VARCHAR(256) NOT NULL,
|
||||
PRIMARY KEY (user_id, contact_id)
|
||||
PRIMARY KEY (user_id, contact_id),
|
||||
UNIQUE (contact_id, contact_value)
|
||||
);
|
||||
|
|
|
@ -41,7 +41,7 @@ impl std::fmt::Display for ForumMailError {
|
|||
ForumMailError::TemplateLackOfParameter => {
|
||||
write!(f, "Template Parameters Are Not Enough")
|
||||
}
|
||||
ForumMailError::Send(error) => write!(f, "Sending | {}", error),
|
||||
ForumMailError::Send(err_val) => write!(f, "Sending | {}", err_val),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,12 +54,16 @@ impl std::error::Error for ForumMailError {
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum ForumAuthError {
|
||||
AuthenticationFailed(String),
|
||||
TokenRefreshTimeOver,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ForumAuthError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ForumAuthError::AuthenticationFailed(err_val) => {
|
||||
write!(f, "Authentication Failed | {}", err_val)
|
||||
}
|
||||
ForumAuthError::TokenRefreshTimeOver => write!(f, "Token Refresh Time is Over"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
pub mod admin;
|
||||
pub mod comment;
|
||||
pub mod comment_interaction;
|
||||
pub mod contact;
|
||||
|
@ -29,6 +30,7 @@ pub async fn route(concurrency_limit: &usize) -> Router {
|
|||
.nest("/comment_interactions", comment_interaction::route())
|
||||
.nest("/contacts", contact::route())
|
||||
.nest("/user_contacts", user_contact::route())
|
||||
.nest("/admin", admin::route())
|
||||
.layer(CorsLayer::permissive())
|
||||
.layer(ConcurrencyLimitLayer::new(*concurrency_limit))
|
||||
.layer(TraceLayer::new_for_http())
|
||||
|
|
15
src/routing/admin.rs
Normal file
15
src/routing/admin.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
pub mod role;
|
||||
pub mod user;
|
||||
|
||||
use axum::Router;
|
||||
|
||||
use super::middleware::pass_builder_or_admin_by_authorization_token;
|
||||
|
||||
pub fn route() -> Router {
|
||||
Router::new()
|
||||
.nest("/users", user::route())
|
||||
.nest("/roles", role::route())
|
||||
.route_layer(axum::middleware::from_fn(
|
||||
pass_builder_or_admin_by_authorization_token,
|
||||
))
|
||||
}
|
58
src/routing/admin/role.rs
Normal file
58
src/routing/admin/role.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use axum::{
|
||||
extract::Path,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{delete, patch, post},
|
||||
Json, Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::feature::role::Role;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CreateRole {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct UpdateRole {
|
||||
id: i64,
|
||||
name: String,
|
||||
}
|
||||
|
||||
pub fn route() -> Router {
|
||||
Router::new()
|
||||
.route("/", post(create))
|
||||
.route("/", patch(update))
|
||||
.route("/{id}", delete(delete_))
|
||||
}
|
||||
|
||||
async fn create(Json(create_role): Json<CreateRole>) -> impl IntoResponse {
|
||||
match Role::create(&create_role.name).await {
|
||||
Ok(role) => (StatusCode::CREATED, Json(serde_json::json!(role))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn update(Json(update_role): Json<UpdateRole>) -> impl IntoResponse {
|
||||
match Role::update(&update_role.id, &update_role.name).await {
|
||||
Ok(role) => (StatusCode::ACCEPTED, Json(serde_json::json!(role))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_(Path(id): Path<i64>) -> impl IntoResponse {
|
||||
match Role::delete(&id).await {
|
||||
Ok(role) => (StatusCode::NO_CONTENT, Json(serde_json::json!(role))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
299
src/routing/admin/user.rs
Normal file
299
src/routing/admin/user.rs
Normal file
|
@ -0,0 +1,299 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
extract::Path,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{delete, get, patch, post},
|
||||
Extension, Json, Router,
|
||||
};
|
||||
use chrono::NaiveDate;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{feature::user::User, routing::middleware::pass_by_uri_user_extraction};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CreateUser {
|
||||
name: String,
|
||||
surname: String,
|
||||
gender: bool,
|
||||
birth_date: NaiveDate,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct UpdateUser {
|
||||
name: String,
|
||||
surname: String,
|
||||
gender: bool,
|
||||
birth_date: NaiveDate,
|
||||
role_id: i64,
|
||||
}
|
||||
|
||||
pub fn route() -> Router {
|
||||
Router::new()
|
||||
.route("/", post(create))
|
||||
.route(
|
||||
"/{user_id}",
|
||||
patch(update).route_layer(axum::middleware::from_fn(pass_by_uri_user_extraction)),
|
||||
)
|
||||
.route(
|
||||
"/{user_id}",
|
||||
delete(delete_).route_layer(axum::middleware::from_fn(pass_by_uri_user_extraction)),
|
||||
)
|
||||
.route("/", get(read_all))
|
||||
.route("/names/{name}", get(read_all_for_name))
|
||||
.route("/surnames/{surname}", get(read_all_for_surname))
|
||||
.route("/birth_dates/{birth_date}", get(read_all_for_birth_date))
|
||||
.route("/roles/{role}", get(read_all_for_role))
|
||||
.route("/genders/{gender}", get(read_all_for_gender))
|
||||
.route("/users_ids", get(read_all_id))
|
||||
.route("/users_ids/names/{name}", get(read_all_id_for_name))
|
||||
.route(
|
||||
"/users_ids/surnames/{surname}",
|
||||
get(read_all_id_for_surname),
|
||||
)
|
||||
.route(
|
||||
"/users_ids/birth_dates/{birth_date}",
|
||||
get(read_all_id_for_birth_date),
|
||||
)
|
||||
.route("/users_ids/roles/{role}", get(read_all_id_for_role))
|
||||
.route("/users_ids/genders/{gender}", get(read_all_id_for_gender))
|
||||
.route("/count", get(count_all))
|
||||
.route("/count/names/{name}", get(count_all_for_name))
|
||||
.route("/count/surnames/{surname}", get(count_all_for_surname))
|
||||
.route(
|
||||
"/count/birth_dates/{birth_date}",
|
||||
get(count_all_for_birth_date),
|
||||
)
|
||||
.route("/count/roles/{role}", get(count_all_for_role))
|
||||
.route("/count/genders/{gender}", get(count_all_for_gender))
|
||||
}
|
||||
|
||||
async fn create(Json(create_user): Json<CreateUser>) -> impl IntoResponse {
|
||||
match User::create(
|
||||
&create_user.name,
|
||||
&create_user.surname,
|
||||
&create_user.gender,
|
||||
&create_user.birth_date,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(user) => (StatusCode::CREATED, Json(serde_json::json!(user))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn update(
|
||||
Extension(target_user): Extension<Arc<User>>,
|
||||
Json(update_user): Json<UpdateUser>,
|
||||
) -> impl IntoResponse {
|
||||
match User::update(
|
||||
&target_user.user_id,
|
||||
&update_user.name,
|
||||
&update_user.surname,
|
||||
&update_user.gender,
|
||||
&update_user.birth_date,
|
||||
&update_user.role_id,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(user) => (StatusCode::ACCEPTED, Json(serde_json::json!(user))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_(Extension(target_user): Extension<Arc<User>>) -> impl IntoResponse {
|
||||
match User::delete(&target_user.user_id).await {
|
||||
Ok(user) => (StatusCode::NO_CONTENT, Json(serde_json::json!(user))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all() -> impl IntoResponse {
|
||||
match User::read_all().await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_name(Path(name): Path<String>) -> impl IntoResponse {
|
||||
match User::read_all_for_name(&name).await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_surname(Path(surname): Path<String>) -> impl IntoResponse {
|
||||
match User::read_all_for_surname(&surname).await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_birth_date(Path(birth_date): Path<NaiveDate>) -> impl IntoResponse {
|
||||
match User::read_all_for_birth_date(&birth_date).await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_role(Path(role_id): Path<i64>) -> impl IntoResponse {
|
||||
match User::read_all_for_role(&role_id).await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_gender(Path(gender): Path<bool>) -> impl IntoResponse {
|
||||
match User::read_all_for_gender(&gender).await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id() -> impl IntoResponse {
|
||||
match User::read_all_id().await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id_for_name(Path(name): Path<String>) -> impl IntoResponse {
|
||||
match User::read_all_id_for_name(&name).await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id_for_surname(Path(surname): Path<String>) -> impl IntoResponse {
|
||||
match User::read_all_id_for_surname(&surname).await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id_for_birth_date(Path(birth_date): Path<NaiveDate>) -> impl IntoResponse {
|
||||
match User::read_all_id_for_birth_date(&birth_date).await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id_for_role(Path(role_id): Path<i64>) -> impl IntoResponse {
|
||||
match User::read_all_id_for_role(&role_id).await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id_for_gender(Path(gender): Path<bool>) -> impl IntoResponse {
|
||||
match User::read_all_id_for_gender(&gender).await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all() -> impl IntoResponse {
|
||||
match User::count_all().await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all_for_name(Path(name): Path<String>) -> impl IntoResponse {
|
||||
match User::count_all_for_name(&name).await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all_for_surname(Path(surname): Path<String>) -> impl IntoResponse {
|
||||
match User::count_all_for_surname(&surname).await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all_for_birth_date(Path(birth_date): Path<NaiveDate>) -> impl IntoResponse {
|
||||
match User::count_all_for_birth_date(&birth_date).await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all_for_role(Path(role_id): Path<i64>) -> impl IntoResponse {
|
||||
match User::count_all_for_role(&role_id).await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all_for_gender(Path(gender): Path<bool>) -> impl IntoResponse {
|
||||
match User::count_all_for_gender(&gender).await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::feature::{auth::OneTimePassword, login::Login, user::User, user_contact::UserContact};
|
||||
|
||||
use super::middleware::{self, UserAndToken};
|
||||
use super::middleware::{self, UserAndAuthorizationToken};
|
||||
|
||||
const CONTACT_EMAIL_DEFAULT_ID: i64 = 0;
|
||||
|
||||
|
@ -92,8 +92,15 @@ async fn read(Path((user_id, token)): Path<(i64, String)>) -> impl IntoResponse
|
|||
}
|
||||
}
|
||||
|
||||
async fn update(Extension(user_and_token): Extension<Arc<UserAndToken>>) -> impl IntoResponse {
|
||||
match Login::update(&user_and_token.user.user_id, &user_and_token.token).await {
|
||||
async fn update(
|
||||
Extension(user_and_authorization_token): Extension<Arc<UserAndAuthorizationToken>>,
|
||||
) -> impl IntoResponse {
|
||||
match Login::update(
|
||||
&user_and_authorization_token.user.user_id,
|
||||
&user_and_authorization_token.authorization_token,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(login) => (StatusCode::ACCEPTED, Json(serde_json::json!(login))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
|
|
|
@ -1,154 +1,142 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
body::{to_bytes, Body},
|
||||
extract::Request,
|
||||
http::{self, HeaderMap, Method, StatusCode},
|
||||
http::{self, HeaderMap, StatusCode, Uri},
|
||||
middleware::Next,
|
||||
response::IntoResponse,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::feature::{login::TokenMeta, user::User};
|
||||
use crate::{
|
||||
error::ForumAuthError,
|
||||
feature::{login::TokenMeta, user::User},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct UserAndRequest {
|
||||
user: User,
|
||||
request: Request,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TargetUserAndRequest {
|
||||
target_user: User,
|
||||
request: Request,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct UserAndTargetUserAndRequest {
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct UserAndTargetUser {
|
||||
user: User,
|
||||
target_user: User,
|
||||
request: Request,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct UserAndToken {
|
||||
pub struct UserAndAuthorizationToken {
|
||||
pub user: User,
|
||||
pub token: String,
|
||||
pub authorization_token: String,
|
||||
}
|
||||
|
||||
async fn authorization_token_extraction(request_headers: &HeaderMap) -> Option<String> {
|
||||
async fn authorization_token_extraction(
|
||||
request_headers: &HeaderMap,
|
||||
) -> Result<String, ForumAuthError> {
|
||||
if let Some(authorization_header) = request_headers.get(http::header::AUTHORIZATION) {
|
||||
if let Ok(authorization_header) = authorization_header.to_str() {
|
||||
if let Some((bearer, authorization_token)) = authorization_header.split_once(' ') {
|
||||
if bearer.to_lowercase() == "bearer" {
|
||||
return Some(authorization_token.to_owned());
|
||||
return Ok(authorization_token.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
Err(ForumAuthError::AuthenticationFailed("".to_owned()))
|
||||
}
|
||||
|
||||
async fn user_extraction(request: Request) -> Option<UserAndRequest> {
|
||||
if let Some(authorization_token) = authorization_token_extraction(&request.headers()).await {
|
||||
match TokenMeta::verify_token(&authorization_token.to_string()).await {
|
||||
Ok(claims) => {
|
||||
return Some(UserAndRequest {
|
||||
user: User::read(&claims.custom.user_id).await.ok()?,
|
||||
request,
|
||||
});
|
||||
}
|
||||
Err(err_val) => {
|
||||
eprintln!("Verify Token | {}", err_val);
|
||||
}
|
||||
}
|
||||
async fn user_extraction_from_authorization_token(
|
||||
authorization_token: &String,
|
||||
) -> Result<User, ForumAuthError> {
|
||||
match TokenMeta::verify_token(&authorization_token.to_string()).await {
|
||||
Ok(claims) => User::read(&claims.custom.user_id)
|
||||
.await
|
||||
.map_err(|err_val| ForumAuthError::AuthenticationFailed(err_val.to_string())),
|
||||
Err(err_val) => Err(ForumAuthError::AuthenticationFailed(err_val.to_string())),
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
async fn target_user_extraction_from_uri(request: Request) -> Option<TargetUserAndRequest> {
|
||||
let uri_parts = request.uri().path().split('/').collect::<Vec<&str>>();
|
||||
for (index, uri_part) in uri_parts.iter().enumerate() {
|
||||
async fn user_extraction_from_header(request_headers: &HeaderMap) -> Result<User, ForumAuthError> {
|
||||
match authorization_token_extraction(request_headers).await {
|
||||
Ok(authorization_token) => {
|
||||
user_extraction_from_authorization_token(&authorization_token).await
|
||||
}
|
||||
Err(err_val) => Err(err_val),
|
||||
}
|
||||
}
|
||||
|
||||
async fn user_extraction_from_uri(request_uri: &Uri) -> Result<User, ForumAuthError> {
|
||||
let request_uri_parts = request_uri.path().split('/').collect::<Vec<&str>>();
|
||||
for (index, uri_part) in request_uri_parts.iter().enumerate() {
|
||||
if *uri_part == "users" {
|
||||
if let Some(target_user_id) = uri_parts.get(index) {
|
||||
if let Ok(target_user_id) = (*target_user_id).parse::<i64>() {
|
||||
if let Ok(target_user) = User::read(&target_user_id).await {
|
||||
return Some(TargetUserAndRequest {
|
||||
target_user,
|
||||
request,
|
||||
});
|
||||
}
|
||||
if let Some(user_id) = request_uri_parts.get(index) {
|
||||
if let Ok(user_id) = (*user_id).parse::<i64>() {
|
||||
User::read(&user_id).await.map_err(|err_val| {
|
||||
ForumAuthError::AuthenticationFailed(err_val.to_string())
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
Err(ForumAuthError::AuthenticationFailed("".to_owned()))
|
||||
}
|
||||
|
||||
async fn target_user_extraction_from_json(request: Request) -> Option<TargetUserAndRequest> {
|
||||
let (parts, body) = request.into_parts();
|
||||
let bytes = to_bytes(body, usize::MAX).await.ok()?;
|
||||
let json: serde_json::Value = serde_json::from_slice(&bytes).ok()?;
|
||||
async fn user_from_header_and_target_user_from_uri_extraction(
|
||||
request_headers: &HeaderMap,
|
||||
request_uri: &Uri,
|
||||
) -> Result<UserAndTargetUser, ForumAuthError> {
|
||||
let user = user_extraction_from_header(request_headers).await?;
|
||||
let target_user = user_extraction_from_uri(request_uri).await?;
|
||||
|
||||
let body = Body::from(json.to_string());
|
||||
let request = Request::from_parts(parts, body);
|
||||
Ok(UserAndTargetUser { user, target_user })
|
||||
}
|
||||
|
||||
if let Some(target_user_id) = json.get("user_id") {
|
||||
if target_user_id.is_i64() {
|
||||
if let Some(target_user_id) = target_user_id.as_i64() {
|
||||
if let Ok(target_user) = User::read(&target_user_id).await {
|
||||
return Some(TargetUserAndRequest {
|
||||
target_user,
|
||||
request,
|
||||
});
|
||||
}
|
||||
}
|
||||
pub async fn user_and_token(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Ok(authorization_token) = authorization_token_extraction(&request.headers()).await {
|
||||
if let Ok(user) = user_extraction_from_authorization_token(&authorization_token).await {
|
||||
let user_and_token = Arc::new(UserAndAuthorizationToken {
|
||||
user,
|
||||
authorization_token,
|
||||
});
|
||||
|
||||
request.extensions_mut().insert(user_and_token);
|
||||
return Ok(next.run(request).await);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
async fn user_and_target_user_extraction(request: Request) -> Option<UserAndTargetUserAndRequest> {
|
||||
let user_and_request = user_extraction(request).await?;
|
||||
let user = user_and_request.user;
|
||||
let request = user_and_request.request;
|
||||
|
||||
let target_user_and_request = if request.method() == Method::GET {
|
||||
target_user_extraction_from_uri(request).await
|
||||
} else {
|
||||
target_user_extraction_from_json(request).await
|
||||
}?;
|
||||
|
||||
let target_user = target_user_and_request.target_user;
|
||||
let request = target_user_and_request.request;
|
||||
|
||||
Some(UserAndTargetUserAndRequest {
|
||||
user,
|
||||
target_user,
|
||||
request,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn pass(request: Request, next: Next) -> Result<impl IntoResponse, StatusCode> {
|
||||
match user_extraction(request).await {
|
||||
Some(user_and_request) => {
|
||||
let user = Arc::new(user_and_request.user);
|
||||
let mut request = user_and_request.request;
|
||||
|
||||
pub async fn pass_by_authorization_token(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
match user_extraction_from_header(request.headers()).await {
|
||||
Ok(user) => {
|
||||
let user = Arc::new(user);
|
||||
request.extensions_mut().insert(user);
|
||||
|
||||
Ok(next.run(request).await)
|
||||
}
|
||||
None => Err(StatusCode::FORBIDDEN),
|
||||
Err(_) => Err(StatusCode::FORBIDDEN),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn pass_builder(request: Request, next: Next) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Some(user_and_request) = user_extraction(request).await {
|
||||
let user = user_and_request.user;
|
||||
let mut request = user_and_request.request;
|
||||
pub async fn pass_by_uri_user_extraction(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Ok(target_user) = user_extraction_from_uri(request.uri()).await {
|
||||
let target_user = Arc::new(target_user);
|
||||
request.extensions_mut().insert(target_user);
|
||||
|
||||
return Ok(next.run(request).await);
|
||||
}
|
||||
Err(StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
pub async fn pass_builder_by_authorization_token(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Ok(user) = user_extraction_from_header(request.headers()).await {
|
||||
if User::is_builder(&user).await {
|
||||
let user = Arc::new(user);
|
||||
request.extensions_mut().insert(user);
|
||||
|
@ -159,14 +147,11 @@ pub async fn pass_builder(request: Request, next: Next) -> Result<impl IntoRespo
|
|||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn pass_builder_or_admin(
|
||||
request: Request,
|
||||
pub async fn pass_builder_or_admin_by_authorization_token(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Some(user_and_request) = user_extraction(request).await {
|
||||
let user = user_and_request.user;
|
||||
let mut request = user_and_request.request;
|
||||
|
||||
if let Ok(user) = user_extraction_from_header(request.headers()).await {
|
||||
if User::is_builder_or_admin(&user).await {
|
||||
let user = Arc::new(user);
|
||||
request.extensions_mut().insert(user);
|
||||
|
@ -177,50 +162,19 @@ pub async fn pass_builder_or_admin(
|
|||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn pass_self(request: Request, next: Next) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Some(user_and_target_user_and_request) = user_and_target_user_extraction(request).await {
|
||||
let user = user_and_target_user_and_request.user;
|
||||
let target_user = user_and_target_user_and_request.target_user;
|
||||
let mut request = user_and_target_user_and_request.request;
|
||||
|
||||
if User::is_self(&user, &target_user).await {
|
||||
let user = Arc::new(user);
|
||||
request.extensions_mut().insert(user);
|
||||
|
||||
return Ok(next.run(request).await);
|
||||
}
|
||||
}
|
||||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn pass_higher(request: Request, next: Next) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Some(user_and_target_user_and_request) = user_and_target_user_extraction(request).await {
|
||||
let user = user_and_target_user_and_request.user;
|
||||
let target_user = user_and_target_user_and_request.target_user;
|
||||
let mut request = user_and_target_user_and_request.request;
|
||||
|
||||
if User::is_higher(&user, &target_user).await {
|
||||
let user = Arc::new(user);
|
||||
request.extensions_mut().insert(user);
|
||||
|
||||
return Ok(next.run(request).await);
|
||||
}
|
||||
}
|
||||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn pass_higher_or_self(
|
||||
request: Request,
|
||||
pub async fn pass_builder_by_authorization_token_with_target_user_by_request_uri(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Some(user_and_target_user_and_request) = user_and_target_user_extraction(request).await {
|
||||
let user = user_and_target_user_and_request.user;
|
||||
let target_user = user_and_target_user_and_request.target_user;
|
||||
let mut request = user_and_target_user_and_request.request;
|
||||
if let Ok(user_and_target_user) =
|
||||
user_from_header_and_target_user_from_uri_extraction(request.headers(), request.uri()).await
|
||||
{
|
||||
let user = user_and_target_user.user;
|
||||
let target_user = user_and_target_user.target_user;
|
||||
|
||||
if User::is_higher_or_self(&user, &target_user).await {
|
||||
let user = Arc::new(user);
|
||||
request.extensions_mut().insert(user);
|
||||
if User::is_builder(&user).await {
|
||||
let target_user = Arc::new(target_user);
|
||||
request.extensions_mut().insert(target_user);
|
||||
|
||||
return Ok(next.run(request).await);
|
||||
}
|
||||
|
@ -228,14 +182,20 @@ pub async fn pass_higher_or_self(
|
|||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn user_and_token(request: Request, next: Next) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Some(token) = authorization_token_extraction(&request.headers()).await {
|
||||
if let Some(user_and_request) = user_extraction(request).await {
|
||||
let user = user_and_request.user;
|
||||
let mut request = user_and_request.request;
|
||||
let user_and_token = Arc::new(UserAndToken { user, token });
|
||||
pub async fn pass_builder_or_admin_by_authorization_token_with_target_user_by_request_uri(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Ok(user_and_target_user) =
|
||||
user_from_header_and_target_user_from_uri_extraction(request.headers(), request.uri()).await
|
||||
{
|
||||
let user = user_and_target_user.user;
|
||||
let target_user = user_and_target_user.target_user;
|
||||
|
||||
if User::is_builder_or_admin(&user).await {
|
||||
let target_user = Arc::new(target_user);
|
||||
request.extensions_mut().insert(target_user);
|
||||
|
||||
request.extensions_mut().insert(user_and_token);
|
||||
return Ok(next.run(request).await);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +1,13 @@
|
|||
use axum::{
|
||||
extract::Path,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{delete, get, patch, post},
|
||||
Json, Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use axum::{extract::Path, http::StatusCode, response::IntoResponse, routing::get, Json, Router};
|
||||
|
||||
use crate::feature::role::Role;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CreateRole {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct UpdateRole {
|
||||
id: i64,
|
||||
name: String,
|
||||
}
|
||||
|
||||
pub fn route() -> Router {
|
||||
Router::new()
|
||||
.route("/", post(create))
|
||||
.route("/{id}", get(read))
|
||||
.route("/", patch(update))
|
||||
.route("/{id}", delete(delete_))
|
||||
.route("/", get(read_all))
|
||||
}
|
||||
|
||||
async fn create(Json(create_role): Json<CreateRole>) -> impl IntoResponse {
|
||||
match Role::create(&create_role.name).await {
|
||||
Ok(role) => (StatusCode::CREATED, Json(serde_json::json!(role))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read(Path(id): Path<i64>) -> impl IntoResponse {
|
||||
match Role::read(&id).await {
|
||||
Ok(role) => (StatusCode::OK, Json(serde_json::json!(role))),
|
||||
|
@ -49,26 +18,6 @@ async fn read(Path(id): Path<i64>) -> impl IntoResponse {
|
|||
}
|
||||
}
|
||||
|
||||
async fn update(Json(update_role): Json<UpdateRole>) -> impl IntoResponse {
|
||||
match Role::update(&update_role.id, &update_role.name).await {
|
||||
Ok(role) => (StatusCode::ACCEPTED, Json(serde_json::json!(role))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_(Path(id): Path<i64>) -> impl IntoResponse {
|
||||
match Role::delete(&id).await {
|
||||
Ok(role) => (StatusCode::NO_CONTENT, Json(serde_json::json!(role))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all() -> impl IntoResponse {
|
||||
match Role::read_all().await {
|
||||
Ok(roles) => (StatusCode::OK, Json(serde_json::json!(roles))),
|
||||
|
|
|
@ -1,97 +1,16 @@
|
|||
use axum::{
|
||||
extract::Path,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{delete, get, patch, post},
|
||||
Json, Router,
|
||||
};
|
||||
use chrono::NaiveDate;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use axum::{extract::Path, http::StatusCode, response::IntoResponse, routing::get, Json, Router};
|
||||
|
||||
use crate::feature::user::User;
|
||||
|
||||
use super::middleware;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CreateUser {
|
||||
name: String,
|
||||
surname: String,
|
||||
gender: bool,
|
||||
birth_date: NaiveDate,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct UpdateUser {
|
||||
user_id: i64,
|
||||
name: String,
|
||||
surname: String,
|
||||
gender: bool,
|
||||
birth_date: NaiveDate,
|
||||
role_id: i64,
|
||||
}
|
||||
|
||||
pub fn route() -> Router {
|
||||
Router::new()
|
||||
.route("/", post(create))
|
||||
.route(
|
||||
"/{user_id}",
|
||||
get(read).route_layer(axum::middleware::from_fn(middleware::pass)),
|
||||
)
|
||||
.route(
|
||||
"/",
|
||||
patch(update).route_layer(axum::middleware::from_fn(middleware::pass_higher_or_self)),
|
||||
)
|
||||
.route(
|
||||
"/{user_id}",
|
||||
delete(delete_).route_layer(axum::middleware::from_fn(middleware::pass_higher_or_self)),
|
||||
)
|
||||
.route(
|
||||
"/",
|
||||
get(read_all).route_layer(axum::middleware::from_fn(middleware::pass_builder_or_admin)),
|
||||
)
|
||||
.route("/names/{name}", get(read_all_for_name))
|
||||
.route("/surnames/{surname}", get(read_all_for_surname))
|
||||
.route("/birth_dates/{birth_date}", get(read_all_for_birth_date))
|
||||
.route("/roles/{role}", get(read_all_for_role))
|
||||
.route("/genders/{gender}", get(read_all_for_gender))
|
||||
.route("/users_ids", get(read_all_id))
|
||||
.route("/users_ids/names/{name}", get(read_all_id_for_name))
|
||||
.route(
|
||||
"/users_ids/surnames/{surname}",
|
||||
get(read_all_id_for_surname),
|
||||
)
|
||||
.route(
|
||||
"/users_ids/birth_dates/{birth_date}",
|
||||
get(read_all_id_for_birth_date),
|
||||
)
|
||||
.route("/users_ids/roles/{role}", get(read_all_id_for_role))
|
||||
.route("/users_ids/genders/{gender}", get(read_all_id_for_gender))
|
||||
.route("/count", get(count_all))
|
||||
.route("/count/names/{name}", get(count_all_for_name))
|
||||
.route("/count/surnames/{surname}", get(count_all_for_surname))
|
||||
.route(
|
||||
"/count/birth_dates/{birth_date}",
|
||||
get(count_all_for_birth_date),
|
||||
)
|
||||
.route("/count/roles/{role}", get(count_all_for_role))
|
||||
.route("/count/genders/{gender}", get(count_all_for_gender))
|
||||
}
|
||||
|
||||
async fn create(Json(create_user): Json<CreateUser>) -> impl IntoResponse {
|
||||
match User::create(
|
||||
&create_user.name,
|
||||
&create_user.surname,
|
||||
&create_user.gender,
|
||||
&create_user.birth_date,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(user) => (StatusCode::CREATED, Json(serde_json::json!(user))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
.route("/{user_id}", get(read))
|
||||
// todo just for beta I think
|
||||
.route_layer(axum::middleware::from_fn(
|
||||
middleware::pass_by_authorization_token,
|
||||
))
|
||||
}
|
||||
|
||||
async fn read(Path(user_id): Path<i64>) -> impl IntoResponse {
|
||||
|
@ -103,212 +22,3 @@ async fn read(Path(user_id): Path<i64>) -> impl IntoResponse {
|
|||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn update(Json(update_user): Json<UpdateUser>) -> impl IntoResponse {
|
||||
match User::update(
|
||||
&update_user.user_id,
|
||||
&update_user.name,
|
||||
&update_user.surname,
|
||||
&update_user.gender,
|
||||
&update_user.birth_date,
|
||||
&update_user.role_id,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(user) => (StatusCode::ACCEPTED, Json(serde_json::json!(user))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_(Path(user_id): Path<i64>) -> impl IntoResponse {
|
||||
match User::delete(&user_id).await {
|
||||
Ok(user) => (StatusCode::NO_CONTENT, Json(serde_json::json!(user))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all() -> impl IntoResponse {
|
||||
match User::read_all().await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_name(Path(name): Path<String>) -> impl IntoResponse {
|
||||
match User::read_all_for_name(&name).await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_surname(Path(surname): Path<String>) -> impl IntoResponse {
|
||||
match User::read_all_for_surname(&surname).await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_birth_date(Path(birth_date): Path<NaiveDate>) -> impl IntoResponse {
|
||||
match User::read_all_for_birth_date(&birth_date).await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_role(Path(role_id): Path<i64>) -> impl IntoResponse {
|
||||
match User::read_all_for_role(&role_id).await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_gender(Path(gender): Path<bool>) -> impl IntoResponse {
|
||||
match User::read_all_for_gender(&gender).await {
|
||||
Ok(users) => (StatusCode::OK, Json(serde_json::json!(users))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id() -> impl IntoResponse {
|
||||
match User::read_all_id().await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id_for_name(Path(name): Path<String>) -> impl IntoResponse {
|
||||
match User::read_all_id_for_name(&name).await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id_for_surname(Path(surname): Path<String>) -> impl IntoResponse {
|
||||
match User::read_all_id_for_surname(&surname).await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id_for_birth_date(Path(birth_date): Path<NaiveDate>) -> impl IntoResponse {
|
||||
match User::read_all_id_for_birth_date(&birth_date).await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id_for_role(Path(role_id): Path<i64>) -> impl IntoResponse {
|
||||
match User::read_all_id_for_role(&role_id).await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all_id_for_gender(Path(gender): Path<bool>) -> impl IntoResponse {
|
||||
match User::read_all_id_for_gender(&gender).await {
|
||||
Ok(user_ids) => (StatusCode::OK, Json(serde_json::json!(user_ids))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all() -> impl IntoResponse {
|
||||
match User::count_all().await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all_for_name(Path(name): Path<String>) -> impl IntoResponse {
|
||||
match User::count_all_for_name(&name).await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all_for_surname(Path(surname): Path<String>) -> impl IntoResponse {
|
||||
match User::count_all_for_surname(&surname).await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all_for_birth_date(Path(birth_date): Path<NaiveDate>) -> impl IntoResponse {
|
||||
match User::count_all_for_birth_date(&birth_date).await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all_for_role(Path(role_id): Path<i64>) -> impl IntoResponse {
|
||||
match User::count_all_for_role(&role_id).await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn count_all_for_gender(Path(gender): Path<bool>) -> impl IntoResponse {
|
||||
match User::count_all_for_gender(&gender).await {
|
||||
Ok(count) => (StatusCode::OK, Json(serde_json::json!(count))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue