Compare commits

..
2 Commits
Author SHA1 Message Date
Lucas Vas 6c3371e472 Merge pull request #83 from R15-Software-Dev/fix/centralize-cognito-pool-ids
Removes duplicated magic strings across multiple files for Cognito pools and the like. These strings are alright to be public-facing.
2026-09-24 12:20:32 -04:00
alphafetus 988f5c83b7 fix: remove duplicated magic strings across multiple files 2026-09-24 12:04:12 -04:00
14 changed files with 52 additions and 32 deletions

No files matched your search

+6 -2
View File
@@ -13,5 +13,9 @@ from the AWS resources, you will need to be approved by me or someone else with
usable auth key from AWS IAM.
## Current Tasks
The application is deployed! However, it doesn't have some core features that need to be present in order for this
to be considered complete. Check the Issues tab for more information.
There are several tasks left to complete. These are a few of the larger ones:
- Build the application's custom elements
- Build out the database requests
- Create proper authentication
- PDF generation using data (server-side)
+3
View File
@@ -0,0 +1,3 @@
pub const STUDENT_PROVIDER_POOL_ID: &str = "us-east-1_Lfjuy5zaM";
pub const PROVIDER_GROUP: &str = "ScholarshipProviders";
pub const STUDENT_GROUP: &str = "ScholarshipStudents";
+4 -3
View File
@@ -4,6 +4,7 @@ use aws_config::BehaviorVersion;
use serde::{Serialize, Deserialize};
use std::collections::HashMap;
use aws_sdk_cognitoidentityprovider::error::ProvideErrorMetadata;
use crate::constants::{PROVIDER_GROUP, STUDENT_GROUP, STUDENT_PROVIDER_POOL_ID};
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
@@ -43,7 +44,7 @@ async fn add_user_to_group(provider: Client, user_id: String, group_name: impl I
println!("Adding user {} to group {}", user_id, group_name);
match provider
.admin_add_user_to_group()
.user_pool_id("us-east-1_Lfjuy5zaM")
.user_pool_id(STUDENT_PROVIDER_POOL_ID)
.username(user_id)
.group_name(group_name)
.send()
@@ -63,8 +64,8 @@ pub(crate) async fn handler(event: LambdaEvent<PostConfirmationEvent>) -> Result
// Check the client ID of the request to assign the user to the correct location.
let res = match event.payload.caller_context.client_id.as_str() {
"10jr2h3vtpu9n7gj46pvg5qo2q" => add_user_to_group(client, user_id, "ScholarshipStudents").await,
"56c2bqvl021rv8d5mq36blt7jv" => add_user_to_group(client, user_id, "ScholarshipProviders").await,
"10jr2h3vtpu9n7gj46pvg5qo2q" => add_user_to_group(client, user_id, STUDENT_GROUP).await,
"56c2bqvl021rv8d5mq36blt7jv" => add_user_to_group(client, user_id, PROVIDER_GROUP).await,
_ => Err("Invalid client ID, denying all user access.".to_string()),
};
+1
View File
@@ -1,4 +1,5 @@
use lambda_runtime::{run, service_fn, tracing, Error};
mod constants;
mod handler;
use handler::handler as function_handler;
+5
View File
@@ -0,0 +1,5 @@
pub const STUDENT_PROVIDER_POOL_ID: &str = "us-east-1_Lfjuy5zaM";
pub const ADMIN_POOL_ID: &str = "us-east-1_rvCU4Xy4j";
pub const COGNITO_REGION: &str = "us-east-1";
pub const PROVIDER_GROUP: &str = "ScholarshipProviders";
pub const STUDENT_GROUP: &str = "ScholarshipStudents";
+2 -1
View File
@@ -9,8 +9,9 @@ mod value_type;
pub mod animations;
mod tab_info;
mod schema_node;
mod constants;
pub use self::{
comparison::*, date_info::*, expandable_info::*, form_params::*, form_schema::*,
submit_status::*, user::*, value_type::*, tab_info::*, schema_node::*,
submit_status::*, user::*, value_type::*, tab_info::*, schema_node::*, constants::*,
};
+3 -2
View File
@@ -1,11 +1,12 @@
use crate::components::login::setup::provide_auth_context;
use crate::common::{ADMIN_POOL_ID, COGNITO_REGION};
use crate::components::login::setup::provide_auth_context;
use leptos::prelude::*;
#[component]
pub fn AdminLoginContext(children: Children) -> impl IntoView {
provide_auth_context(
crate::utils::use_origin(),
"https://cognito-idp.us-east-1.amazonaws.com/us-east-1_rvCU4Xy4j",
format!("https://cognito-idp.{COGNITO_REGION}.amazonaws.com/{ADMIN_POOL_ID}"),
"1vh1q994rid6cgi6tjf58r9jp4",
"/admin/callback",
);
+2 -1
View File
@@ -1,6 +1,7 @@
use leptos::prelude::*;
use leptos_router::components::Outlet;
use super::setup::provide_auth_context;
use crate::common::{COGNITO_REGION, STUDENT_PROVIDER_POOL_ID};
///# Provider Login Context Component
///
@@ -19,7 +20,7 @@ use super::setup::provide_auth_context;
pub fn ProviderLoginContext() -> impl IntoView {
provide_auth_context(
crate::utils::use_origin(),
"https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Lfjuy5zaM",
format!("https://cognito-idp.{COGNITO_REGION}.amazonaws.com/{STUDENT_PROVIDER_POOL_ID}"),
"56c2bqvl021rv8d5mq36blt7jv",
"/providers/callback"
);
+2 -1
View File
@@ -1,5 +1,6 @@
use leptos::prelude::*;
use super::setup::provide_auth_context;
use crate::common::{COGNITO_REGION, STUDENT_PROVIDER_POOL_ID};
///# Student Login Context Component
///
@@ -20,7 +21,7 @@ pub fn StudentLoginContext(
) -> impl IntoView {
provide_auth_context(
crate::utils::use_origin(),
"https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Lfjuy5zaM",
format!("https://cognito-idp.{COGNITO_REGION}.amazonaws.com/{STUDENT_PROVIDER_POOL_ID}"),
"10jr2h3vtpu9n7gj46pvg5qo2q",
"/students/callback"
);
+2 -1
View File
@@ -63,10 +63,11 @@ fn AdminApplicantsScholarshipList() -> impl IntoView {
async fn admin_get_provider_scholarships(
access_token: String,
) -> Result<Vec<ExpandableInfo>, ServerFnError> {
use crate::common::{ADMIN_POOL_ID, COGNITO_REGION};
use crate::pages::api::SCHOLARSHIPS_TABLE;
use crate::pages::api::tokens::validate_and_get_token_info;
let claims = validate_and_get_token_info(access_token, "us-east-1_rvCU4Xy4j", "us-east-1").await?;
let claims = validate_and_get_token_info(access_token, ADMIN_POOL_ID, COGNITO_REGION).await?;
// Get the information from the database.
let client = crate::utils::server::create_dynamo_client().await;
+4 -3
View File
@@ -6,6 +6,7 @@ use server_fn::codec::{MultipartData, MultipartFormData};
#[cfg(feature = "ssr")]
mod imports {
pub use super::super::{MAIN_TABLE_NAME, S3_BUCKET_NAME};
pub use crate::common::{COGNITO_REGION, STUDENT_PROVIDER_POOL_ID};
pub use crate::pages::api::tokens::validate_and_get_token_info;
pub use crate::utils::server::create_aws_config;
pub use aws_sdk_dynamodb::{
@@ -66,7 +67,7 @@ pub async fn upload_file(data: MultipartData) -> Result<String, ServerFnError> {
return Err(ServerFnError::new("Missing file contents"));
}
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, STUDENT_PROVIDER_POOL_ID, COGNITO_REGION).await?;
let subject = user_claims.subject;
let key = format!("{form_id}/{subject}/{input_name}/{file_name}");
@@ -157,7 +158,7 @@ pub async fn delete_file(
) -> Result<String, ServerFnError> {
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, STUDENT_PROVIDER_POOL_ID, COGNITO_REGION).await?;
let subject = user_claims.subject;
let entry_hk = format!("STUDENT#{subject}");
@@ -226,7 +227,7 @@ pub async fn list_files(
) -> Result<Vec<String>, ServerFnError> {
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, STUDENT_PROVIDER_POOL_ID, COGNITO_REGION).await?;
let subject = user_claims.subject;
let entry_hk = format!("STUDENT#{subject}");
+15 -15
View File
@@ -7,7 +7,7 @@ use std::process::Stdio;
#[cfg(feature = "ssr")]
mod imports {
pub use super::super::MAIN_TABLE_NAME;
pub use crate::common::ValueType;
pub use crate::common::{ADMIN_POOL_ID, COGNITO_REGION, PROVIDER_GROUP, STUDENT_PROVIDER_POOL_ID, ValueType};
pub use crate::pages::api::tokens::validate_and_get_token_info;
pub use crate::utils::server::*;
pub use aws_sdk_dynamodb::error::ProvideErrorMetadata;
@@ -148,11 +148,11 @@ pub async fn provider_get_completed_students(
use imports::*;
let claims =
validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM", "us-east-1").await?;
if !claims.groups.contains(&"ScholarshipProviders".to_string()) {
return Err(ServerFnError::new(
"User is not in the ScholarshipProviders group",
));
validate_and_get_token_info(access_token, STUDENT_PROVIDER_POOL_ID, COGNITO_REGION).await?;
if !claims.groups.contains(&PROVIDER_GROUP.to_string()) {
return Err(ServerFnError::new(format!(
"User is not in the {PROVIDER_GROUP} group",
)));
}
get_completed_students().await
@@ -164,7 +164,7 @@ pub async fn admin_get_completed_students(
) -> Result<HashMap<String, HashMap<String, crate::common::ValueType>>, ServerFnError> {
use imports::*;
let _ = validate_and_get_token_info(access_token, "us-east-1_rvCU4Xy4j", "us-east-1").await?;
let _ = validate_and_get_token_info(access_token, ADMIN_POOL_ID, COGNITO_REGION).await?;
get_completed_students().await
}
@@ -254,7 +254,7 @@ pub async fn get_file_by_key(
use imports::*;
let user_claims =
validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM", "us-east-1").await?;
validate_and_get_token_info(access_token, STUDENT_PROVIDER_POOL_ID, COGNITO_REGION).await?;
// Check if the user's subject is contained in the file_key (since all files are keyed by the
// user's subject)
@@ -262,7 +262,7 @@ pub async fn get_file_by_key(
// Check that the user is a provider.
if !user_claims
.groups
.contains(&"ScholarshipProviders".to_string())
.contains(&PROVIDER_GROUP.to_string())
{
return Err(ServerFnError::new(
"Access denied: user is not the student or a provider",
@@ -304,16 +304,16 @@ pub async fn get_student_files(
) -> Result<(String, Vec<u8>), ServerFnError> {
use imports::*;
match validate_and_get_token_info(access_token.clone(), "us-east-1_Lfjuy5zaM", "us-east-1")
match validate_and_get_token_info(access_token.clone(), STUDENT_PROVIDER_POOL_ID, COGNITO_REGION)
.await
{
Ok(claims) => {
if !claims.groups.contains(&"ScholarshipProviders".to_string()) {
if !claims.groups.contains(&PROVIDER_GROUP.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")
let _ = validate_and_get_token_info(access_token, ADMIN_POOL_ID, COGNITO_REGION)
.await?;
}
};
@@ -507,7 +507,7 @@ pub async fn admin_get_all_input_files(
) -> Result<HashMap<String, Vec<String>>, ServerFnError> {
use imports::*;
let _ = validate_and_get_token_info(access_token, "us-east-1_rvCU4Xy4j", "us-east-1").await?;
let _ = validate_and_get_token_info(access_token, ADMIN_POOL_ID, COGNITO_REGION).await?;
get_all_input_files(form_name, input_name).await
}
@@ -521,8 +521,8 @@ pub async fn provider_get_all_input_files(
use imports::*;
let claims =
validate_and_get_token_info(access_token, "us-east-1_Lfjuy5zaM", "us-east-1").await?;
if !claims.groups.contains(&"ScholarshipProviders".to_string()) {
validate_and_get_token_info(access_token, STUDENT_PROVIDER_POOL_ID, COGNITO_REGION).await?;
if !claims.groups.contains(&PROVIDER_GROUP.to_string()) {
return Err(ServerFnError::new("Access denied: user is not a provider"));
}
-1
View File
@@ -28,7 +28,6 @@ pub async fn validate_and_get_token_info(
leptos::logging::debug_log!("Validating token using group {}", pool_id);
// let jwks = fetch_jwks("us-east-1_Lfjuy5zaM".into(), "us-east-1".into()).await?;
let jwks = fetch_jwks(pool_id, pool_region.into()).await?;
let validation = Validation::new(Algorithm::RS256);
+3 -2
View File
@@ -75,13 +75,14 @@ fn ApplicantsScholarshipList() -> impl IntoView {
async fn get_provider_scholarships(
access_token: String,
) -> Result<Vec<ExpandableInfo>, ServerFnError> {
use crate::common::{COGNITO_REGION, STUDENT_PROVIDER_POOL_ID};
use crate::pages::api::SCHOLARSHIPS_TABLE;
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(),
STUDENT_PROVIDER_POOL_ID.to_string(),
COGNITO_REGION.to_string(),
)
.await?;