feat: ✨ admin routing part 2
This commit is contained in:
parent
a462d3a82d
commit
bf2b0a439c
13 changed files with 370 additions and 171 deletions
|
@ -124,49 +124,25 @@ impl User {
|
|||
user::count_all_for_gender(gender).await
|
||||
}
|
||||
|
||||
pub async fn is_builder(user: &User) -> bool {
|
||||
if user.role_id == 0 {
|
||||
async fn is_normal(&self) -> bool {
|
||||
if self.role_id == 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_admin(user: &User) -> bool {
|
||||
if user.role_id == 1 {
|
||||
async fn is_same_level(&self, target_user: &User) -> bool {
|
||||
if self.role_id == target_user.role_id {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_banned(user: &User) -> bool {
|
||||
if user.role_id == -1 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_builder_or_admin(user: &User) -> bool {
|
||||
if user.role_id == 0 || user.role_id == 1 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_self(user: &User, target_user: &User) -> bool {
|
||||
if user.user_id == target_user.user_id {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_higher(user: &User, target_user: &User) -> bool {
|
||||
if user.user_id >= 0 {
|
||||
if user.user_id < target_user.user_id {
|
||||
async fn is_higher(&self, target_user: &User) -> bool {
|
||||
if self.user_id >= 0 {
|
||||
if self.user_id < target_user.user_id {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -174,11 +150,55 @@ impl User {
|
|||
false
|
||||
}
|
||||
|
||||
pub async fn is_higher_or_self(user: &User, target_user: &User) -> bool {
|
||||
if User::is_self(user, target_user).await {
|
||||
pub async fn is_builder(&self) -> bool {
|
||||
if self.role_id == 0 {
|
||||
true
|
||||
} else {
|
||||
User::is_higher(user, target_user).await
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_admin(&self) -> bool {
|
||||
if self.role_id == 1 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_banned(&self) -> bool {
|
||||
if self.role_id == -1 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_builder_or_admin(&self) -> bool {
|
||||
if self.role_id == 0 || self.role_id == 1 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_default(&self, target_user: &User) -> bool {
|
||||
if self.is_banned().await {
|
||||
false
|
||||
} else {
|
||||
if self.is_normal().await {
|
||||
false
|
||||
} else {
|
||||
if self.is_same_level(target_user).await {
|
||||
true
|
||||
} else {
|
||||
if self.is_higher(target_user).await {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::database::user_contact;
|
||||
|
||||
use super::user::User;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct UserContact {
|
||||
pub user_id: i64,
|
||||
|
@ -11,34 +13,34 @@ pub struct UserContact {
|
|||
|
||||
impl UserContact {
|
||||
pub async fn create(
|
||||
user_id: &i64,
|
||||
user: &User,
|
||||
contact_id: &i64,
|
||||
contact_value: &String,
|
||||
) -> Result<UserContact, sqlx::Error> {
|
||||
user_contact::create(user_id, contact_id, contact_value).await
|
||||
user_contact::create(&user.user_id, contact_id, contact_value).await
|
||||
}
|
||||
|
||||
pub async fn read(user_id: &i64, contact_id: &i64) -> Result<UserContact, sqlx::Error> {
|
||||
user_contact::read(user_id, contact_id).await
|
||||
pub async fn read(user: &User, contact_id: &i64) -> Result<UserContact, sqlx::Error> {
|
||||
user_contact::read(&user.user_id, contact_id).await
|
||||
}
|
||||
|
||||
pub async fn update(
|
||||
user_id: &i64,
|
||||
user: &User,
|
||||
contact_id: &i64,
|
||||
contact_value: &String,
|
||||
) -> Result<UserContact, sqlx::Error> {
|
||||
user_contact::update(user_id, contact_id, contact_value).await
|
||||
user_contact::update(&user.user_id, contact_id, contact_value).await
|
||||
}
|
||||
|
||||
pub async fn delete(user_id: &i64, contact_id: &i64) -> Result<UserContact, sqlx::Error> {
|
||||
user_contact::delete(user_id, contact_id).await
|
||||
pub async fn delete(user: &User, contact_id: &i64) -> Result<UserContact, sqlx::Error> {
|
||||
user_contact::delete(&user.user_id, contact_id).await
|
||||
}
|
||||
|
||||
pub async fn read_all_for_user(user_id: &i64) -> Result<Vec<UserContact>, sqlx::Error> {
|
||||
user_contact::read_all_for_user(user_id).await
|
||||
pub async fn read_all_for_user(user: &User) -> Result<Vec<UserContact>, sqlx::Error> {
|
||||
user_contact::read_all_for_user(&user.user_id).await
|
||||
}
|
||||
|
||||
pub async fn delete_all_for_user(user_id: &i64) -> Result<Vec<UserContact>, sqlx::Error> {
|
||||
user_contact::delete_all_for_user(user_id).await
|
||||
pub async fn delete_all_for_user(user: &User) -> Result<Vec<UserContact>, sqlx::Error> {
|
||||
user_contact::delete_all_for_user(&user.user_id).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ pub mod user;
|
|||
pub mod user_contact;
|
||||
|
||||
use axum::{http::StatusCode, response::IntoResponse, routing::get, Router};
|
||||
use middleware::by_authorization_token;
|
||||
use tower::limit::ConcurrencyLimitLayer;
|
||||
use tower_http::{cors::CorsLayer, trace::TraceLayer};
|
||||
|
||||
|
@ -31,6 +32,8 @@ pub async fn route(concurrency_limit: &usize) -> Router {
|
|||
.nest("/contacts", contact::route())
|
||||
.nest("/user_contacts", user_contact::route())
|
||||
.nest("/admin", admin::route())
|
||||
// todo just for beta I think
|
||||
.route_layer(axum::middleware::from_fn(by_authorization_token))
|
||||
.layer(CorsLayer::permissive())
|
||||
.layer(ConcurrencyLimitLayer::new(*concurrency_limit))
|
||||
.layer(TraceLayer::new_for_http())
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
pub mod contact;
|
||||
pub mod role;
|
||||
pub mod user;
|
||||
pub mod user_contact;
|
||||
|
||||
use axum::Router;
|
||||
|
||||
use super::middleware::pass_builder_or_admin_by_authorization_token;
|
||||
use super::middleware::builder_or_admin_by_authorization_token;
|
||||
|
||||
pub fn route() -> Router {
|
||||
Router::new()
|
||||
.nest("/users", user::route())
|
||||
.nest("/roles", role::route())
|
||||
.nest("/contacts", contact::route())
|
||||
.nest("/user_contacts", user_contact::route())
|
||||
.route_layer(axum::middleware::from_fn(
|
||||
pass_builder_or_admin_by_authorization_token,
|
||||
builder_or_admin_by_authorization_token,
|
||||
))
|
||||
}
|
||||
|
|
58
src/routing/admin/contact.rs
Normal file
58
src/routing/admin/contact.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::contact::Contact;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CreateContact {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct UpdateContact {
|
||||
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_contact): Json<CreateContact>) -> impl IntoResponse {
|
||||
match Contact::create(&create_contact.name).await {
|
||||
Ok(contact) => (StatusCode::CREATED, Json(serde_json::json!(contact))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn update(Json(update_contact): Json<UpdateContact>) -> impl IntoResponse {
|
||||
match Contact::update(&update_contact.id, &update_contact.name).await {
|
||||
Ok(contact) => (StatusCode::ACCEPTED, Json(serde_json::json!(contact))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_(Path(id): Path<i64>) -> impl IntoResponse {
|
||||
match Contact::delete(&id).await {
|
||||
Ok(contact) => (StatusCode::NO_CONTENT, Json(serde_json::json!(contact))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
|
@ -2,18 +2,13 @@ use axum::{
|
|||
extract::Path,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{delete, patch, post},
|
||||
routing::{delete, patch},
|
||||
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,
|
||||
|
@ -22,21 +17,10 @@ struct UpdateRole {
|
|||
|
||||
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))),
|
||||
|
|
|
@ -10,7 +10,7 @@ use axum::{
|
|||
use chrono::NaiveDate;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{feature::user::User, routing::middleware::pass_by_uri_user_extraction};
|
||||
use crate::{feature::user::User, routing::middleware::by_uri_then_insert};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CreateUser {
|
||||
|
@ -34,11 +34,11 @@ pub fn route() -> Router {
|
|||
.route("/", post(create))
|
||||
.route(
|
||||
"/{user_id}",
|
||||
patch(update).route_layer(axum::middleware::from_fn(pass_by_uri_user_extraction)),
|
||||
patch(update).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
|
||||
)
|
||||
.route(
|
||||
"/{user_id}",
|
||||
delete(delete_).route_layer(axum::middleware::from_fn(pass_by_uri_user_extraction)),
|
||||
delete(delete_).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
|
||||
)
|
||||
.route("/", get(read_all))
|
||||
.route("/names/{name}", get(read_all_for_name))
|
||||
|
|
128
src/routing/admin/user_contact.rs
Normal file
128
src/routing/admin/user_contact.rs
Normal file
|
@ -0,0 +1,128 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
extract::Path,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{delete, get, patch, post},
|
||||
Extension, Json, Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
feature::{user::User, user_contact::UserContact},
|
||||
routing::middleware::by_uri_then_insert,
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CreateUserContact {
|
||||
pub contact_id: i64,
|
||||
pub contact_value: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct UpdateUserContact {
|
||||
pub contact_id: i64,
|
||||
pub contact_value: String,
|
||||
}
|
||||
|
||||
pub fn route() -> Router {
|
||||
Router::new()
|
||||
.route(
|
||||
"/users/{user_id}",
|
||||
post(create).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
|
||||
)
|
||||
.route(
|
||||
"/users/{user_id}/contacts/{contact_id}",
|
||||
get(read).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
|
||||
)
|
||||
.route(
|
||||
"/users/{user_id}",
|
||||
patch(update).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
|
||||
)
|
||||
.route(
|
||||
"/users/{user_id}/contacts/{contact_id}",
|
||||
delete(delete_).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
|
||||
)
|
||||
.route(
|
||||
"/users/{user_id}",
|
||||
delete(delete_all_for_user).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
|
||||
)
|
||||
}
|
||||
|
||||
async fn create(
|
||||
Extension(user): Extension<Arc<User>>,
|
||||
Json(create_user_contact): Json<CreateUserContact>,
|
||||
) -> impl IntoResponse {
|
||||
match UserContact::create(
|
||||
&user,
|
||||
&create_user_contact.contact_id,
|
||||
&create_user_contact.contact_value,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(user_contact) => (StatusCode::CREATED, Json(serde_json::json!(user_contact))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read(
|
||||
Extension(user): Extension<Arc<User>>,
|
||||
Path(contact_id): Path<i64>,
|
||||
) -> impl IntoResponse {
|
||||
match UserContact::read(&user, &contact_id).await {
|
||||
Ok(user_contact) => (StatusCode::OK, Json(serde_json::json!(user_contact))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn update(
|
||||
Extension(user): Extension<Arc<User>>,
|
||||
Json(update_user_contact): Json<UpdateUserContact>,
|
||||
) -> impl IntoResponse {
|
||||
match UserContact::update(
|
||||
&user,
|
||||
&update_user_contact.contact_id,
|
||||
&update_user_contact.contact_value,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(user_contact) => (StatusCode::ACCEPTED, Json(serde_json::json!(user_contact))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_(
|
||||
Extension(user): Extension<Arc<User>>,
|
||||
Path(contact_id): Path<i64>,
|
||||
) -> impl IntoResponse {
|
||||
match UserContact::delete(&user, &contact_id).await {
|
||||
Ok(user_contact) => (
|
||||
StatusCode::NO_CONTENT,
|
||||
Json(serde_json::json!(user_contact)),
|
||||
),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_all_for_user(Extension(user): Extension<Arc<User>>) -> impl IntoResponse {
|
||||
match UserContact::delete_all_for_user(&user).await {
|
||||
Ok(user_contacts) => (StatusCode::OK, Json(serde_json::json!(user_contacts))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
|
@ -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::contact::Contact;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CreateContact {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct UpdateContact {
|
||||
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_contact): Json<CreateContact>) -> impl IntoResponse {
|
||||
match Contact::create(&create_contact.name).await {
|
||||
Ok(contact) => (StatusCode::CREATED, Json(serde_json::json!(contact))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read(Path(id): Path<i64>) -> impl IntoResponse {
|
||||
match Contact::read(&id).await {
|
||||
Ok(contact) => (StatusCode::OK, Json(serde_json::json!(contact))),
|
||||
|
@ -49,26 +18,6 @@ async fn read(Path(id): Path<i64>) -> impl IntoResponse {
|
|||
}
|
||||
}
|
||||
|
||||
async fn update(Json(update_contact): Json<UpdateContact>) -> impl IntoResponse {
|
||||
match Contact::update(&update_contact.id, &update_contact.name).await {
|
||||
Ok(contact) => (StatusCode::ACCEPTED, Json(serde_json::json!(contact))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_(Path(id): Path<i64>) -> impl IntoResponse {
|
||||
match Contact::delete(&id).await {
|
||||
Ok(contact) => (StatusCode::NO_CONTENT, Json(serde_json::json!(contact))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_all() -> impl IntoResponse {
|
||||
match Contact::read_all().await {
|
||||
Ok(contacts) => (StatusCode::OK, Json(serde_json::json!(contacts))),
|
||||
|
|
|
@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::feature::{auth::OneTimePassword, login::Login, user::User, user_contact::UserContact};
|
||||
|
||||
use super::middleware::{self, UserAndAuthorizationToken};
|
||||
use super::middleware::{user_and_token_then_insert, UserAndAuthorizationToken};
|
||||
|
||||
const CONTACT_EMAIL_DEFAULT_ID: i64 = 0;
|
||||
|
||||
|
@ -33,7 +33,7 @@ pub fn route() -> Router {
|
|||
.route("/users/{user_id}/tokens/{token}", get(read))
|
||||
.route(
|
||||
"/",
|
||||
patch(update).route_layer(axum::middleware::from_fn(middleware::user_and_token)),
|
||||
patch(update).route_layer(axum::middleware::from_fn(user_and_token_then_insert)),
|
||||
)
|
||||
.route("/users/{user_id}/tokens/{token}", delete(delete_))
|
||||
.route("/users/{user_id}", get(read_all_for_user))
|
||||
|
@ -45,7 +45,7 @@ async fn create_one_time_password(
|
|||
) -> impl IntoResponse {
|
||||
//todo get user from middleware or something
|
||||
let user = User::read(&create_one_time_password.user_id).await.unwrap();
|
||||
match UserContact::read(&user.user_id, &CONTACT_EMAIL_DEFAULT_ID).await {
|
||||
match UserContact::read(&user, &CONTACT_EMAIL_DEFAULT_ID).await {
|
||||
Ok(user_email) => match OneTimePassword::new(&user, &user_email.contact_value).await {
|
||||
Ok(_) => (StatusCode::CREATED, Json(serde_json::json!(""))),
|
||||
Err(err_val) => (
|
||||
|
|
|
@ -86,7 +86,7 @@ async fn user_from_header_and_target_user_from_uri_extraction(
|
|||
Ok(UserAndTargetUser { user, target_user })
|
||||
}
|
||||
|
||||
pub async fn user_and_token(
|
||||
pub async fn user_and_token_then_insert(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
|
@ -104,7 +104,17 @@ pub async fn user_and_token(
|
|||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn pass_by_authorization_token(
|
||||
pub async fn by_authorization_token(
|
||||
request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
match user_extraction_from_header(request.headers()).await {
|
||||
Ok(_) => Ok(next.run(request).await),
|
||||
Err(_) => Err(StatusCode::FORBIDDEN),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn by_authorization_token_then_insert(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
|
@ -119,7 +129,7 @@ pub async fn pass_by_authorization_token(
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn pass_by_uri_user_extraction(
|
||||
pub async fn by_uri_then_insert(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
|
@ -132,7 +142,19 @@ pub async fn pass_by_uri_user_extraction(
|
|||
Err(StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
pub async fn pass_builder_by_authorization_token(
|
||||
pub async fn builder_by_authorization_token(
|
||||
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 {
|
||||
return Ok(next.run(request).await);
|
||||
}
|
||||
}
|
||||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn builder_by_authorization_token_then_insert(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
|
@ -147,7 +169,19 @@ pub async fn pass_builder_by_authorization_token(
|
|||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn pass_builder_or_admin_by_authorization_token(
|
||||
pub async fn builder_or_admin_by_authorization_token(
|
||||
request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
if let Ok(user) = user_extraction_from_header(request.headers()).await {
|
||||
if User::is_builder_or_admin(&user).await {
|
||||
return Ok(next.run(request).await);
|
||||
}
|
||||
}
|
||||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn builder_or_admin_by_authorization_token_then_insert(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
|
@ -162,7 +196,7 @@ pub async fn pass_builder_or_admin_by_authorization_token(
|
|||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn pass_builder_by_authorization_token_with_target_user_by_request_uri(
|
||||
pub async fn builder_by_authorization_token_and_target_user_by_uri_then_insert_target(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
|
@ -172,7 +206,7 @@ pub async fn pass_builder_by_authorization_token_with_target_user_by_request_uri
|
|||
let user = user_and_target_user.user;
|
||||
let target_user = user_and_target_user.target_user;
|
||||
|
||||
if User::is_builder(&user).await {
|
||||
if user.is_builder().await && user.is_default(&target_user).await {
|
||||
let target_user = Arc::new(target_user);
|
||||
request.extensions_mut().insert(target_user);
|
||||
|
||||
|
@ -182,7 +216,7 @@ pub async fn pass_builder_by_authorization_token_with_target_user_by_request_uri
|
|||
Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
pub async fn pass_builder_or_admin_by_authorization_token_with_target_user_by_request_uri(
|
||||
pub async fn builder_or_admin_by_authorization_token_and_target_user_by_uri_then_insert_target(
|
||||
mut request: Request,
|
||||
next: Next,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
|
@ -192,7 +226,7 @@ pub async fn pass_builder_or_admin_by_authorization_token_with_target_user_by_re
|
|||
let user = user_and_target_user.user;
|
||||
let target_user = user_and_target_user.target_user;
|
||||
|
||||
if User::is_builder_or_admin(&user).await {
|
||||
if user.is_default(&target_user).await {
|
||||
let target_user = Arc::new(target_user);
|
||||
request.extensions_mut().insert(target_user);
|
||||
|
||||
|
|
|
@ -2,15 +2,8 @@ use axum::{extract::Path, http::StatusCode, response::IntoResponse, routing::get
|
|||
|
||||
use crate::feature::user::User;
|
||||
|
||||
use super::middleware;
|
||||
|
||||
pub fn route() -> Router {
|
||||
Router::new()
|
||||
.route("/{user_id}", get(read))
|
||||
// todo just for beta I think
|
||||
.route_layer(axum::middleware::from_fn(
|
||||
middleware::pass_by_authorization_token,
|
||||
))
|
||||
Router::new().route("/{user_id}", get(read))
|
||||
}
|
||||
|
||||
async fn read(Path(user_id): Path<i64>) -> impl IntoResponse {
|
||||
|
|
|
@ -1,41 +1,66 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
extract::Path,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{delete, get, patch, post},
|
||||
Json, Router,
|
||||
Extension, Json, Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::feature::user_contact::UserContact;
|
||||
use crate::feature::{user::User, user_contact::UserContact};
|
||||
|
||||
use super::middleware::{by_authorization_token_then_insert, by_uri_then_insert};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CreateUserContact {
|
||||
pub user_id: i64,
|
||||
pub contact_id: i64,
|
||||
pub contact_value: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct UpdateUserContact {
|
||||
pub user_id: i64,
|
||||
pub contact_id: i64,
|
||||
pub contact_value: String,
|
||||
}
|
||||
|
||||
pub fn route() -> Router {
|
||||
Router::new()
|
||||
.route("/", post(create))
|
||||
.route("/roles/{user_id}/contacts/{contact_id}", get(read))
|
||||
.route("/", patch(update))
|
||||
.route("/roles/{user_id}/contacts/{contact_id}", delete(delete_))
|
||||
.route("/users/{user_id}", get(read_all_for_user))
|
||||
.route("/users/{user_id}", delete(delete_all_for_user))
|
||||
.route(
|
||||
"/",
|
||||
post(create).route_layer(axum::middleware::from_fn(
|
||||
by_authorization_token_then_insert,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/users/{user_id}/contacts/{contact_id}",
|
||||
get(read).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
|
||||
)
|
||||
.route(
|
||||
"/",
|
||||
patch(update).route_layer(axum::middleware::from_fn(
|
||||
by_authorization_token_then_insert,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/users/contacts/{contact_id}",
|
||||
delete(delete_).route_layer(axum::middleware::from_fn(
|
||||
by_authorization_token_then_insert,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/users/{user_id}",
|
||||
get(read_all_for_user).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
|
||||
)
|
||||
}
|
||||
|
||||
async fn create(Json(create_user_contact): Json<CreateUserContact>) -> impl IntoResponse {
|
||||
async fn create(
|
||||
Extension(user): Extension<Arc<User>>,
|
||||
Json(create_user_contact): Json<CreateUserContact>,
|
||||
) -> impl IntoResponse {
|
||||
match UserContact::create(
|
||||
&create_user_contact.user_id,
|
||||
&user,
|
||||
&create_user_contact.contact_id,
|
||||
&create_user_contact.contact_value,
|
||||
)
|
||||
|
@ -49,8 +74,11 @@ async fn create(Json(create_user_contact): Json<CreateUserContact>) -> impl Into
|
|||
}
|
||||
}
|
||||
|
||||
async fn read(Path((user_id, contact_id)): Path<(i64, i64)>) -> impl IntoResponse {
|
||||
match UserContact::read(&user_id, &contact_id).await {
|
||||
async fn read(
|
||||
Extension(user): Extension<Arc<User>>,
|
||||
Path(contact_id): Path<i64>,
|
||||
) -> impl IntoResponse {
|
||||
match UserContact::read(&user, &contact_id).await {
|
||||
Ok(user_contact) => (StatusCode::OK, Json(serde_json::json!(user_contact))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
|
@ -59,9 +87,12 @@ async fn read(Path((user_id, contact_id)): Path<(i64, i64)>) -> impl IntoRespons
|
|||
}
|
||||
}
|
||||
|
||||
async fn update(Json(update_user_contact): Json<UpdateUserContact>) -> impl IntoResponse {
|
||||
async fn update(
|
||||
Extension(user): Extension<Arc<User>>,
|
||||
Json(update_user_contact): Json<UpdateUserContact>,
|
||||
) -> impl IntoResponse {
|
||||
match UserContact::update(
|
||||
&update_user_contact.user_id,
|
||||
&user,
|
||||
&update_user_contact.contact_id,
|
||||
&update_user_contact.contact_value,
|
||||
)
|
||||
|
@ -75,8 +106,11 @@ async fn update(Json(update_user_contact): Json<UpdateUserContact>) -> impl Into
|
|||
}
|
||||
}
|
||||
|
||||
async fn delete_(Path((user_id, contact_id)): Path<(i64, i64)>) -> impl IntoResponse {
|
||||
match UserContact::delete(&user_id, &contact_id).await {
|
||||
async fn delete_(
|
||||
Extension(user): Extension<Arc<User>>,
|
||||
Path(contact_id): Path<i64>,
|
||||
) -> impl IntoResponse {
|
||||
match UserContact::delete(&user, &contact_id).await {
|
||||
Ok(user_contact) => (
|
||||
StatusCode::NO_CONTENT,
|
||||
Json(serde_json::json!(user_contact)),
|
||||
|
@ -88,19 +122,9 @@ async fn delete_(Path((user_id, contact_id)): Path<(i64, i64)>) -> impl IntoResp
|
|||
}
|
||||
}
|
||||
|
||||
async fn read_all_for_user(Path(user_id): Path<i64>) -> impl IntoResponse {
|
||||
match UserContact::read_all_for_user(&user_id).await {
|
||||
Ok(role_contacts) => (StatusCode::OK, Json(serde_json::json!(role_contacts))),
|
||||
Err(err_val) => (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!(err_val.to_string())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_all_for_user(Path(user_id): Path<i64>) -> impl IntoResponse {
|
||||
match UserContact::delete_all_for_user(&user_id).await {
|
||||
Ok(role_contacts) => (StatusCode::OK, Json(serde_json::json!(role_contacts))),
|
||||
async fn read_all_for_user(Extension(user): Extension<Arc<User>>) -> impl IntoResponse {
|
||||
match UserContact::read_all_for_user(&user).await {
|
||||
Ok(user_contacts) => (StatusCode::OK, Json(serde_json::json!(user_contacts))),
|
||||
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