From f5d0364244032cc522d3a603a2ef9c4fc99c3e41 Mon Sep 17 00:00:00 2001 From: Manuel Gugger Date: Thu, 18 Aug 2022 13:58:26 +0200 Subject: [PATCH] change parameter match in for case auth_is_enabled --- actix_admin_macros/src/lib.rs | 15 ++------------- src/builder.rs | 4 ++-- src/lib.rs | 4 ++-- src/routes/create_or_edit_get.rs | 13 +++++++------ src/routes/create_or_edit_post.rs | 16 +++++++++------- src/routes/delete.rs | 16 ++++++++++++---- src/routes/helpers.rs | 13 ++++++------- src/routes/list.rs | 13 ++++++------- src/view_model.rs | 25 ++++++++++++++++++++++--- 9 files changed, 68 insertions(+), 51 deletions(-) diff --git a/actix_admin_macros/src/lib.rs b/actix_admin_macros/src/lib.rs index 885c314..a09bde3 100644 --- a/actix_admin_macros/src/lib.rs +++ b/actix_admin_macros/src/lib.rs @@ -39,18 +39,6 @@ pub fn derive_actix_admin(_input: proc_macro::TokenStream) -> proc_macro::TokenS proc_macro::TokenStream::from(expanded) } -#[proc_macro_derive(DeriveActixAdminViewModelAccess, attributes(actix_admin))] -pub fn derive_actix_admin_view_model_access(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let expanded = quote! { - impl ActixAdminViewModelAccessTrait for Entity { - fn user_can_access(session: &Session) -> bool { - true - } - } - }; - proc_macro::TokenStream::from(expanded) -} - #[proc_macro_derive(DeriveActixAdminViewModel, attributes(actix_admin))] pub fn derive_actix_admin_view_model(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let fields = get_fields_for_tokenstream(input); @@ -69,7 +57,8 @@ pub fn derive_actix_admin_view_model(input: proc_macro::TokenStream) -> proc_mac primary_key: #name_primary_field_str.to_string(), entity_name: entity.table_name().to_string(), fields: Entity::get_fields(), - show_search: #has_searchable_fields + show_search: #has_searchable_fields, + user_can_access: None } } } diff --git a/src/builder.rs b/src/builder.rs index 639472e..75d8871 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -12,7 +12,7 @@ pub struct ActixAdminBuilder { pub trait ActixAdminBuilderTrait { fn new(configuration: ActixAdminConfiguration) -> Self; - fn add_entity( + fn add_entity( &mut self, view_model: &ActixAdminViewModel, ); @@ -32,7 +32,7 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder { } } - fn add_entity( + fn add_entity( &mut self, view_model: &ActixAdminViewModel, ) { diff --git a/src/lib.rs b/src/lib.rs index 7ce8aa3..afe5a37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,8 +13,8 @@ pub mod builder; pub mod prelude { pub use crate::builder::{ ActixAdminBuilder, ActixAdminBuilderTrait}; pub use crate::model::{ ActixAdminModel, ActixAdminModelTrait}; - pub use crate::view_model::{ ActixAdminViewModel, ActixAdminViewModelTrait, ActixAdminViewModelAccessTrait, ActixAdminViewModelField, ActixAdminViewModelFieldType }; - pub use actix_admin_macros::{ DeriveActixAdmin, DeriveActixAdminModel, DeriveActixAdminViewModel, DeriveActixAdminSelectList, DeriveActixAdminViewModelAccess }; + pub use crate::view_model::{ ActixAdminViewModel, ActixAdminViewModelTrait, ActixAdminViewModelField, ActixAdminViewModelSerializable, ActixAdminViewModelFieldType }; + pub use actix_admin_macros::{ DeriveActixAdmin, DeriveActixAdminModel, DeriveActixAdminViewModel, DeriveActixAdminSelectList }; pub use crate::{ ActixAdminAppDataTrait, ActixAdmin, ActixAdminConfiguration }; pub use crate::{ hashmap, ActixAdminSelectListTrait }; } diff --git a/src/routes/create_or_edit_get.rs b/src/routes/create_or_edit_get.rs index 6eab313..eac4905 100644 --- a/src/routes/create_or_edit_get.rs +++ b/src/routes/create_or_edit_get.rs @@ -6,7 +6,7 @@ use crate::prelude::*; use crate::TERA; use super::{ add_auth_context, user_can_access_page, render_unauthorized}; -pub async fn create_get( +pub async fn create_get( session: Session, _req: HttpRequest, data: web::Data, @@ -19,7 +19,7 @@ pub async fn create_get(&session, &data, db, model).await } -pub async fn edit_get( +pub async fn edit_get( session: Session, _req: HttpRequest, data: web::Data, @@ -32,7 +32,7 @@ pub async fn edit_get(&session, &data, db, model).await } -async fn create_or_edit_get(session: &Session, data: &web::Data, db: &sea_orm::DatabaseConnection, model: ActixAdminModel) -> Result{ +async fn create_or_edit_get(session: &Session, data: &web::Data, db: &sea_orm::DatabaseConnection, model: ActixAdminModel) -> Result{ let actix_admin = &data.get_actix_admin(); let mut ctx = Context::new(); add_auth_context(&session, actix_admin, &mut ctx); @@ -40,12 +40,13 @@ async fn create_or_edit_get(&session, actix_admin) { + let view_model = actix_admin.view_models.get(&entity_name).unwrap(); + + if !user_can_access_page(&session, actix_admin, view_model) { return render_unauthorized(&ctx); } - let view_model = actix_admin.view_models.get(&entity_name).unwrap(); - ctx.insert("view_model", &view_model); + ctx.insert("view_model", &ActixAdminViewModelSerializable::from(view_model.clone())); ctx.insert("select_lists", &E::get_select_lists(db).await); ctx.insert("list_link", &E::get_list_link(&entity_name)); ctx.insert("model", &model); diff --git a/src/routes/create_or_edit_post.rs b/src/routes/create_or_edit_post.rs index de6eb90..e89da91 100644 --- a/src/routes/create_or_edit_post.rs +++ b/src/routes/create_or_edit_post.rs @@ -7,7 +7,7 @@ use actix_multipart::Multipart; use super::{ user_can_access_page, render_unauthorized}; use crate::prelude::*; -pub async fn create_post( +pub async fn create_post( session: Session, data: web::Data, payload: Multipart, @@ -15,7 +15,7 @@ pub async fn create_post(&session, &data, payload, None).await } -pub async fn edit_post( +pub async fn edit_post( session: Session, data: web::Data, payload: Multipart, @@ -24,23 +24,25 @@ pub async fn edit_post(&session, &data, payload, Some(id.into_inner())).await } -async fn create_or_edit_post(session: &Session, data: &web::Data, payload: Multipart, id: Option) -> Result { +async fn create_or_edit_post(session: &Session, data: &web::Data, payload: Multipart, id: Option) -> Result { let actix_admin = data.get_actix_admin(); - if !user_can_access_page::(&session, actix_admin) { + let entity_name = E::get_entity_name(); + + let view_model = actix_admin.view_models.get(&entity_name).unwrap(); + + if !user_can_access_page(&session, actix_admin, view_model) { let mut ctx = Context::new(); ctx.insert("render_partial", &true); return render_unauthorized(&ctx); } let db = &data.get_db(); - let entity_name = E::get_entity_name(); - let view_model = actix_admin.view_models.get(&entity_name).unwrap(); let model = ActixAdminModel::create_from_payload(payload).await.unwrap(); if model.has_errors() { let mut ctx = Context::new(); ctx.insert("entity_names", &actix_admin.entity_names); - ctx.insert("view_model", &view_model); + ctx.insert("view_model", &ActixAdminViewModelSerializable::from(view_model.clone())); ctx.insert("select_lists", &E::get_select_lists(db).await); ctx.insert("list_link", &E::get_list_link(&entity_name)); ctx.insert("model", &model); diff --git a/src/routes/delete.rs b/src/routes/delete.rs index e6cc96f..5c55022 100644 --- a/src/routes/delete.rs +++ b/src/routes/delete.rs @@ -5,7 +5,7 @@ use crate::prelude::*; use tera::{Context}; use super::{ user_can_access_page, render_unauthorized}; -pub async fn delete( +pub async fn delete( session: Session, _req: HttpRequest, data: web::Data, @@ -13,7 +13,11 @@ pub async fn delete ) -> Result { let actix_admin = data.get_actix_admin(); - if !user_can_access_page::(&session, actix_admin) { + let entity_name = E::get_entity_name(); + + let view_model = actix_admin.view_models.get(&entity_name).unwrap(); + + if !user_can_access_page(&session, actix_admin, view_model) { let mut ctx = Context::new(); ctx.insert("render_partial", &true); return render_unauthorized(&ctx); @@ -26,14 +30,18 @@ pub async fn delete( +pub async fn delete_many( session: Session, _req: HttpRequest, data: web::Data, text: String, ) -> Result { let actix_admin = data.get_actix_admin(); - if !user_can_access_page::(&session, actix_admin) { + let entity_name = E::get_entity_name(); + + let view_model = actix_admin.view_models.get(&entity_name).unwrap(); + + if !user_can_access_page(&session, actix_admin, view_model) { let mut ctx = Context::new(); ctx.insert("render_partial", &true); return render_unauthorized(&ctx); diff --git a/src/routes/helpers.rs b/src/routes/helpers.rs index b7412ea..adcc80c 100644 --- a/src/routes/helpers.rs +++ b/src/routes/helpers.rs @@ -17,16 +17,15 @@ pub fn add_auth_context(session: &Session, actix_admin: &ActixAdmin, ctx: &mut C } } -pub fn user_can_access_page(session: &Session, actix_admin: &ActixAdmin) -> bool { +pub fn user_can_access_page(session: &Session, actix_admin: &ActixAdmin, view_model: &ActixAdminViewModel) -> bool { let auth_is_enabled = &actix_admin.configuration.enable_auth; let user_is_logged_in = &actix_admin.configuration.user_is_logged_in; - let user_can_access_viewmodel = E::user_can_access(session); + let user_can_access_view_model = &view_model.user_can_access; - match (auth_is_enabled, user_can_access_viewmodel, user_is_logged_in) { - (true, true, Some(auth_func)) => auth_func(session), - (true, false, _) => false, - (true, _, None) => false, - (false, _, _) => true + match (auth_is_enabled, user_is_logged_in, user_can_access_view_model) { + (true, Some(auth_func), Some(view_model_access_func)) => auth_func(session) && view_model_access_func(session), + (true, Some(auth_func), _) => auth_func(session), + (_, _, _) => !auth_is_enabled, } } diff --git a/src/routes/list.rs b/src/routes/list.rs index da80838..eda8066 100644 --- a/src/routes/list.rs +++ b/src/routes/list.rs @@ -1,7 +1,6 @@ use actix_web::{error, web, Error, HttpRequest, HttpResponse}; use serde::{Deserialize}; use tera::{Context}; - use crate::prelude::*; use crate::ActixAdminViewModelTrait; @@ -21,24 +20,24 @@ pub struct Params { search: Option } -pub async fn list( +pub async fn list( session: Session, req: HttpRequest, data: web::Data, ) -> Result { let actix_admin = data.get_actix_admin(); + let entity_name = E::get_entity_name(); + let view_model: &ActixAdminViewModel = actix_admin.view_models.get(&entity_name).unwrap(); + let mut ctx = Context::new(); add_auth_context(&session, actix_admin, &mut ctx); ctx.insert("entity_names", &actix_admin.entity_names); - if !user_can_access_page::(&session, actix_admin) { + if !user_can_access_page(&session, actix_admin, view_model) { return render_unauthorized(&ctx); } - let entity_name = E::get_entity_name(); - let view_model: &ActixAdminViewModel = actix_admin.view_models.get(&entity_name).unwrap(); - let params = web::Query::::from_query(req.query_string()).unwrap(); let page = params.page.unwrap_or(1); @@ -60,7 +59,7 @@ pub async fn list bool; +#[derive(Clone)] +pub struct ActixAdminViewModel { + pub entity_name: String, + pub primary_key: String, + pub fields: Vec, + pub show_search: bool, + pub user_can_access: Option bool> } #[derive(Clone, Debug, Serialize)] -pub struct ActixAdminViewModel { +pub struct ActixAdminViewModelSerializable { pub entity_name: String, pub primary_key: String, pub fields: Vec, pub show_search: bool } +// TODO: better alternative to serialize only specific fields for ActixAdminViewModel +impl From for ActixAdminViewModelSerializable { + fn from(entity: ActixAdminViewModel) -> Self { + ActixAdminViewModelSerializable { + entity_name: entity.entity_name, + primary_key: entity.primary_key, + fields: entity.fields, + show_search: entity.show_search + } + } +} + + #[derive(Clone, Debug, Serialize, Deserialize)] pub enum ActixAdminViewModelFieldType { Number,