fix: allow essays and fafsa to be requested by administrators
This commit is contained in:
1 parent
61b0c8b83b
commit
6d6862a680
2 files changed
+56
-41
No files matched your search
+38
-27
@@ -13,10 +13,10 @@ mod imports {
|
|||||||
pub use aws_sdk_dynamodb::error::ProvideErrorMetadata;
|
pub use aws_sdk_dynamodb::error::ProvideErrorMetadata;
|
||||||
pub use aws_sdk_dynamodb::types::AttributeValue;
|
pub use aws_sdk_dynamodb::types::AttributeValue;
|
||||||
pub use leptos::logging::{debug_log, error};
|
pub use leptos::logging::{debug_log, error};
|
||||||
pub use std::collections::HashMap;
|
|
||||||
pub use zip::write::SimpleFileOptions;
|
|
||||||
pub use leptos::serde_json;
|
pub use leptos::serde_json;
|
||||||
|
pub use std::collections::HashMap;
|
||||||
pub use std::process::Command;
|
pub use std::process::Command;
|
||||||
|
pub use zip::write::SimpleFileOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PDF_TEMPLATE: &str = include_str!("../../../pdf_template.typ");
|
static PDF_TEMPLATE: &str = include_str!("../../../pdf_template.typ");
|
||||||
@@ -147,7 +147,8 @@ pub async fn provider_get_completed_students(
|
|||||||
) -> Result<HashMap<String, HashMap<String, crate::common::ValueType>>, ServerFnError> {
|
) -> Result<HashMap<String, HashMap<String, crate::common::ValueType>>, ServerFnError> {
|
||||||
use imports::*;
|
use imports::*;
|
||||||
|
|
||||||
let claims = validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM", "us-east-1").await?;
|
let claims =
|
||||||
|
validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM", "us-east-1").await?;
|
||||||
if !claims.groups.contains(&"ScholarshipProviders".to_string()) {
|
if !claims.groups.contains(&"ScholarshipProviders".to_string()) {
|
||||||
return Err(ServerFnError::new(
|
return Err(ServerFnError::new(
|
||||||
"User is not in the ScholarshipProviders group",
|
"User is not in the ScholarshipProviders group",
|
||||||
@@ -169,7 +170,8 @@ pub async fn admin_get_completed_students(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[server]
|
#[server]
|
||||||
async fn get_completed_students() -> Result<HashMap<String, HashMap<String, crate::common::ValueType>>, ServerFnError> {
|
async fn get_completed_students()
|
||||||
|
-> Result<HashMap<String, HashMap<String, crate::common::ValueType>>, ServerFnError> {
|
||||||
use imports::*;
|
use imports::*;
|
||||||
|
|
||||||
// We want to get all student information. The requirements are that the students have completed
|
// We want to get all student information. The requirements are that the students have completed
|
||||||
@@ -251,7 +253,8 @@ pub async fn get_file_by_key(
|
|||||||
) -> Result<Vec<u8>, ServerFnError> {
|
) -> Result<Vec<u8>, ServerFnError> {
|
||||||
use imports::*;
|
use imports::*;
|
||||||
|
|
||||||
let user_claims = validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM", "us-east-1").await?;
|
let user_claims =
|
||||||
|
validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM", "us-east-1").await?;
|
||||||
|
|
||||||
// Check if the user's subject is contained in the file_key (since all files are keyed by the
|
// Check if the user's subject is contained in the file_key (since all files are keyed by the
|
||||||
// user's subject)
|
// user's subject)
|
||||||
@@ -301,12 +304,19 @@ pub async fn get_student_files(
|
|||||||
) -> Result<(String, Vec<u8>), ServerFnError> {
|
) -> Result<(String, Vec<u8>), ServerFnError> {
|
||||||
use imports::*;
|
use imports::*;
|
||||||
|
|
||||||
let claims = validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM", "us-east-1").await?;
|
match validate_and_get_token_info(access_token.clone(), "us-east-1_Lfjuy5zaM", "us-east-1")
|
||||||
|
.await
|
||||||
// Check if the user has permission to get these files.
|
{
|
||||||
if !claims.groups.contains(&"ScholarshipProviders".to_string()) {
|
Ok(claims) => {
|
||||||
return Err(ServerFnError::new("Access denied: user is not a provider"));
|
if !claims.groups.contains(&"ScholarshipProviders".to_string()) {
|
||||||
}
|
return Err(ServerFnError::new("Access denied: user is not a provider"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
let _ = validate_and_get_token_info(access_token, "us-east-1_rvCU4Xy4j", "us-east-1")
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let client = create_dynamo_client().await;
|
let client = create_dynamo_client().await;
|
||||||
|
|
||||||
@@ -510,7 +520,8 @@ pub async fn provider_get_all_input_files(
|
|||||||
) -> Result<HashMap<String, Vec<String>>, ServerFnError> {
|
) -> Result<HashMap<String, Vec<String>>, ServerFnError> {
|
||||||
use imports::*;
|
use imports::*;
|
||||||
|
|
||||||
let claims = validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM", "us-east-1").await?;
|
let claims =
|
||||||
|
validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM", "us-east-1").await?;
|
||||||
if !claims.groups.contains(&"ScholarshipProviders".to_string()) {
|
if !claims.groups.contains(&"ScholarshipProviders".to_string()) {
|
||||||
return Err(ServerFnError::new("Access denied: user is not a provider"));
|
return Err(ServerFnError::new("Access denied: user is not a provider"));
|
||||||
}
|
}
|
||||||
@@ -519,9 +530,7 @@ pub async fn provider_get_all_input_files(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[server]
|
#[server]
|
||||||
pub async fn get_student_pdf(
|
pub async fn get_student_pdf(student_id: String) -> Result<(String, Vec<u8>), ServerFnError> {
|
||||||
student_id: String,
|
|
||||||
) -> Result<(String, Vec<u8>), ServerFnError> {
|
|
||||||
use imports::*;
|
use imports::*;
|
||||||
|
|
||||||
// NOTE: this API requires that the server has the typst-cli available ON PATH.
|
// NOTE: this API requires that the server has the typst-cli available ON PATH.
|
||||||
@@ -529,11 +538,13 @@ pub async fn get_student_pdf(
|
|||||||
let student_info_str = get_student_info_json(student_id.clone()).await?;
|
let student_info_str = get_student_info_json(student_id.clone()).await?;
|
||||||
let student_info = get_student_data(student_id, "DEMOGRAPHICS".to_string()).await?;
|
let student_info = get_student_data(student_id, "DEMOGRAPHICS".to_string()).await?;
|
||||||
|
|
||||||
let first_name = student_info.get("first_name")
|
let first_name = student_info
|
||||||
|
.get("first_name")
|
||||||
.map(|v| v.to_string())
|
.map(|v| v.to_string())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let last_name = student_info.get("last_name")
|
let last_name = student_info
|
||||||
|
.get("last_name")
|
||||||
.map(|v| v.to_string())
|
.map(|v| v.to_string())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
@@ -577,9 +588,7 @@ pub async fn get_student_pdf(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[server]
|
#[server]
|
||||||
pub async fn get_student_info_json(
|
pub async fn get_student_info_json(student_id: String) -> Result<String, ServerFnError> {
|
||||||
student_id: String,
|
|
||||||
) -> Result<String, ServerFnError> {
|
|
||||||
use imports::*;
|
use imports::*;
|
||||||
|
|
||||||
let client = create_dynamo_client().await;
|
let client = create_dynamo_client().await;
|
||||||
@@ -613,7 +622,8 @@ pub async fn get_student_info_json(
|
|||||||
.map(|output| {
|
.map(|output| {
|
||||||
let items = output.items.unwrap_or_default();
|
let items = output.items.unwrap_or_default();
|
||||||
debug_log!("Number of items: {}", items.len());
|
debug_log!("Number of items: {}", items.len());
|
||||||
items.into_iter()
|
items
|
||||||
|
.into_iter()
|
||||||
.next()
|
.next()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.get("extracurricular")
|
.get("extracurricular")
|
||||||
@@ -637,7 +647,8 @@ pub async fn get_student_info_json(
|
|||||||
.map(|output| {
|
.map(|output| {
|
||||||
let items = output.items.unwrap_or_default();
|
let items = output.items.unwrap_or_default();
|
||||||
debug_log!("Number of items: {}", items.len());
|
debug_log!("Number of items: {}", items.len());
|
||||||
items.into_iter()
|
items
|
||||||
|
.into_iter()
|
||||||
.next()
|
.next()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.get("extracurricular")
|
.get("extracurricular")
|
||||||
@@ -650,12 +661,12 @@ pub async fn get_student_info_json(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Join items together into a single object.
|
// Join items together into a single object.
|
||||||
let mut data = items.into_iter()
|
let mut data = items.into_iter().fold(HashMap::new(), |mut map, item| {
|
||||||
.fold(HashMap::new(), |mut map, item| {
|
item.into_iter().for_each(|(k, v)| {
|
||||||
item.into_iter()
|
map.insert(k, v);
|
||||||
.for_each(|(k, v)| { map.insert(k, v); });
|
|
||||||
map
|
|
||||||
});
|
});
|
||||||
|
map
|
||||||
|
});
|
||||||
|
|
||||||
data.insert("work_experience".to_string(), work_exp);
|
data.insert("work_experience".to_string(), work_exp);
|
||||||
data.insert("extracurricular".to_string(), extracurricular);
|
data.insert("extracurricular".to_string(), extracurricular);
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
use crate::common::{ComparisonData, ExpandableInfo, SchemaContainerStyle, SchemaHeaderStyle, SchemaNode, SchemaType, ValueType};
|
use crate::common::{
|
||||||
|
ComparisonData, ExpandableInfo, SchemaContainerStyle, SchemaHeaderStyle, SchemaNode,
|
||||||
|
SchemaType, ValueType,
|
||||||
|
};
|
||||||
use crate::components::{ActionButton, Banner, DataDisplay, Loading};
|
use crate::components::{ActionButton, Banner, DataDisplay, Loading};
|
||||||
use crate::pages::UnauthenticatedPage;
|
use crate::pages::UnauthenticatedPage;
|
||||||
use crate::pages::api::get_comparison_info;
|
use crate::pages::api::get_comparison_info;
|
||||||
use crate::pages::api::students::{GetStudentFiles, provider_get_all_input_files, get_student_data, GetStudentPdf};
|
use crate::pages::api::students::{
|
||||||
|
GetStudentFiles, GetStudentPdf, get_student_data, provider_get_all_input_files,
|
||||||
|
};
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use leptos::ev::{Event, MouseEvent};
|
use leptos::ev::{Event, MouseEvent};
|
||||||
use leptos::html::Dialog;
|
use leptos::html::Dialog;
|
||||||
@@ -68,12 +73,17 @@ fn ApplicantsScholarshipList() -> impl IntoView {
|
|||||||
|
|
||||||
#[server]
|
#[server]
|
||||||
async fn get_provider_scholarships(
|
async fn get_provider_scholarships(
|
||||||
access_token: String
|
access_token: String,
|
||||||
) -> Result<Vec<ExpandableInfo>, ServerFnError> {
|
) -> Result<Vec<ExpandableInfo>, ServerFnError> {
|
||||||
use crate::pages::api::SCHOLARSHIPS_TABLE;
|
use crate::pages::api::SCHOLARSHIPS_TABLE;
|
||||||
use crate::pages::api::tokens::validate_and_get_token_info;
|
use crate::pages::api::tokens::validate_and_get_token_info;
|
||||||
|
|
||||||
let claims = validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM".to_string(), "us-east-1".to_string()).await?;
|
let claims = validate_and_get_token_info(
|
||||||
|
access_token,
|
||||||
|
"us-east-1_Lfjuy5zaM".to_string(),
|
||||||
|
"us-east-1".to_string(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Get the information from the database.
|
// Get the information from the database.
|
||||||
let client = crate::utils::server::create_dynamo_client().await;
|
let client = crate::utils::server::create_dynamo_client().await;
|
||||||
@@ -108,9 +118,7 @@ fn ApplicantsScholarshipList() -> impl IntoView {
|
|||||||
let scholarships_res = Resource::new(
|
let scholarships_res = Resource::new(
|
||||||
move || (trigger.track(), access_token.get()),
|
move || (trigger.track(), access_token.get()),
|
||||||
move |(_, access_token)| async move {
|
move |(_, access_token)| async move {
|
||||||
get_provider_scholarships(
|
get_provider_scholarships(access_token.unwrap_or_default()).await
|
||||||
access_token.unwrap_or_default()
|
|
||||||
).await
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1121,9 +1129,8 @@ pub fn StudentInformationDialog(
|
|||||||
|
|
||||||
let get_student_files = ServerAction::<GetStudentFiles>::new();
|
let get_student_files = ServerAction::<GetStudentFiles>::new();
|
||||||
let get_student_pdf = ServerAction::<GetStudentPdf>::new();
|
let get_student_pdf = ServerAction::<GetStudentPdf>::new();
|
||||||
let get_buttons_disabled = Memo::new(move |_| {
|
let get_buttons_disabled =
|
||||||
get_student_files.pending().get() && get_student_pdf.pending().get()
|
Memo::new(move |_| get_student_files.pending().get() && get_student_pdf.pending().get());
|
||||||
});
|
|
||||||
let on_click_fafsa = move |_| {
|
let on_click_fafsa = move |_| {
|
||||||
get_student_files.dispatch(GetStudentFiles {
|
get_student_files.dispatch(GetStudentFiles {
|
||||||
access_token: access_token.get().unwrap_or_default(),
|
access_token: access_token.get().unwrap_or_default(),
|
||||||
@@ -1310,10 +1317,7 @@ pub fn StudentInformationDialog(
|
|||||||
})
|
})
|
||||||
})}
|
})}
|
||||||
{move || Suspend::new(async move {
|
{move || Suspend::new(async move {
|
||||||
get_student_data(
|
get_student_data(student_id.get().unwrap_or_default(), "family".to_string())
|
||||||
student_id.get().unwrap_or_default(),
|
|
||||||
"family".to_string()
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.map(|student_info| {
|
.map(|student_info| {
|
||||||
view! {
|
view! {
|
||||||
|
|||||||
Reference in new issue
Block a user