diff --git a/rsc/css/league/about.css b/rsc/css/league/about.css new file mode 100644 index 0000000..e020c15 --- /dev/null +++ b/rsc/css/league/about.css @@ -0,0 +1,22 @@ + + +table#AboutPermissionsTable { + text-align: center; + margin: 0 auto; +} + +table#AboutPermissionsTable th { + background: transparent; +} + +table#AboutPermissionsTable td { + background: transparent; +} + +table#AboutPermissionsTable td.PermDenied { + background-color: var(--color-red); +} + +table#AboutPermissionsTable td.PermGranted { + background-color: var(--color-green); +} \ No newline at end of file diff --git a/sslo_league/src/http.rs b/sslo_league/src/http.rs index 7db298a..42b6d3d 100644 --- a/sslo_league/src/http.rs +++ b/sslo_league/src/http.rs @@ -83,6 +83,7 @@ pub fn create_router(app_state: AppState) -> Router { .route("/html/presets", routing::get(routes_html::presets::handler)) .route("/html/about/third_party", routing::get(routes_html::about::handler_third_party)) + .route("/html/about/permissions", routing::get(routes_html::about::handler_permissions)) .merge(SwaggerUi::new("/api/v0/").url("/apidoc/openapi.json", api)) @@ -325,7 +326,7 @@ impl HtmlTemplate { html += "
"; html += " General"; html += " Third Party Integrations"; - html += " Data Protection"; + html += " Permission System"; html += " REST API v0"; html += "
"; html += " "; diff --git a/sslo_league/src/http/routes_html/about.rs b/sslo_league/src/http/routes_html/about.rs index f519c74..22e1090 100644 --- a/sslo_league/src/http/routes_html/about.rs +++ b/sslo_league/src/http/routes_html/about.rs @@ -1,9 +1,12 @@ use axum::extract::State; use axum::http::StatusCode; use axum::response::Response; +use strum::IntoEnumIterator; use crate::app_state::AppState; use crate::http::HtmlTemplate; use crate::http::http_user::HttpUserExtractor; +use crate::user_grade::Promotion; +use crate::user_permissions::PermissionContainer; pub async fn handler_third_party(State(app_state): State, HttpUserExtractor(http_user): HttpUserExtractor, @@ -19,3 +22,80 @@ pub async fn handler_third_party(State(app_state): State, Ok(html.into_response().await) } + + +pub async fn handler_permissions(State(app_state): State, + HttpUserExtractor(http_user): HttpUserExtractor, +) -> Result { + let mut html = HtmlTemplate::new(http_user, app_state.clone()); + html.include_css("/rsc/css/league/about.css"); + + // gather table data per column (not per row as usual) + let mut tbl_row_data: Vec> = Vec::new(); + struct ColumnCache { + content: &'static str, + css_class: Option<&'static str>, + is_header: bool, + } + impl ColumnCache { + fn to_html(&self) -> String { + let tag = match self.is_header {true=>"th", false=>"td"}; + match self.css_class { + None => format!("<{0}>{1}", tag, self.content), + Some(css) => format!("<{0} class=\"{1}\">{2}", tag, css, self.content) + } + + } + } + + // first column + let mut col_data : Vec = Vec::new(); + col_data.push(ColumnCache {content: "", css_class: None, is_header:true}); + tbl_row_data.push(col_data); + for perm_grp in PermissionContainer::new(Promotion::None).list_groups() { + + let mut col_data : Vec = Vec::new(); + col_data.push(ColumnCache {content: perm_grp.label(), css_class: None, is_header:true}); + tbl_row_data.push(col_data); + + for perm in perm_grp.list_permissions() { + let mut col_data : Vec = Vec::new(); + col_data.push(ColumnCache {content: perm.label(), css_class: None, is_header:false}); + tbl_row_data.push(col_data); + } + } + + // promotion columns + for promo in Promotion::iter() { + let mut row_index = 0; + + tbl_row_data[row_index].push(ColumnCache {content: promo.title_str(), css_class: None, is_header:true}); + row_index += 1; + + for perm_grp in PermissionContainer::new(promo).list_groups() { + tbl_row_data[row_index].push(ColumnCache {content: "", css_class: None, is_header:false}); + row_index += 1; + + for perm in perm_grp.list_permissions() { + let mut col_data : Vec = Vec::new(); + let css_class: Option<&'static str> = Some(match perm.granted() {true=>"PermGranted", false=>"PermDenied"}); + tbl_row_data[row_index].push(ColumnCache {content: " ", css_class, is_header:false}); + row_index += 1; + } + } + } + + // build table + html.push_body(""); + for row in tbl_row_data { + html.push_body(""); + for col in row { + html.push_body(&col.to_html()); + } + html.push_body(""); + } + html.push_body("
"); + + + Ok(html.into_response().await) +} \ No newline at end of file diff --git a/sslo_league/src/user_permissions.rs b/sslo_league/src/user_permissions.rs index f8df92f..a164b72 100644 --- a/sslo_league/src/user_permissions.rs +++ b/sslo_league/src/user_permissions.rs @@ -1,13 +1,13 @@ use crate::user_grade::Promotion; -struct Permission { +pub struct Permission { promotion_actual: Promotion, promotion_min: Promotion, label: &'static str, } impl Permission { - fn label(&self) -> &'static str { self.label } + pub fn label(&self) -> &'static str { self.label } pub fn granted(&self) -> bool { self.promotion_actual >= self.promotion_min