From 8d2ea8ae872685ab5347a48fecb839b4db647f6f Mon Sep 17 00:00:00 2001 From: beckerinj Date: Sun, 6 Nov 2022 04:57:29 -0500 Subject: [PATCH] prog2 --- Cargo.lock | 1 + core/src/auth/github.rs | 23 +++++++++------ core/src/auth/jwt.rs | 7 +++-- core/src/auth/mod.rs | 9 ++++-- core/src/config.rs | 39 ++++---------------------- core/src/helpers.rs | 7 +++++ core/src/main.rs | 12 +++++--- lib/db_client/src/lib.rs | 60 ++++++++++++++++++++++++++++++---------- lib/types/Cargo.toml | 3 +- lib/types/src/lib.rs | 7 +++-- 10 files changed, 100 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c664be735..c246e61e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2310,6 +2310,7 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" name = "types" version = "0.1.0" dependencies = [ + "async_timing_util", "mungos", "serde", "serde_derive", diff --git a/core/src/auth/github.rs b/core/src/auth/github.rs index bf2557746..3fef1e54c 100644 --- a/core/src/auth/github.rs +++ b/core/src/auth/github.rs @@ -1,13 +1,20 @@ +use std::sync::Arc; + +use axum::{Extension, Router}; use oauth2::{basic::BasicClient, AuthUrl, ClientId, ClientSecret, RedirectUrl, TokenUrl}; use types::CoreConfig; -pub fn github_oauth_client( - secrets: &CoreConfig, - redirect_url: String, -) -> anyhow::Result { - let github_client_id = ClientId::new(secrets.github_oauth.id.clone()); - let github_client_secret = ClientSecret::new(secrets.github_oauth.secret.clone()); - let auth_url = AuthUrl::new("https://github.com/login/oauth/authorize".to_string())?; +pub type GithubOauthExtension = Extension>; + +pub fn router(config: &CoreConfig) -> Router { + Router::new().layer(github_oauth_extension(config, format!(""))) +} + +fn github_oauth_extension(config: &CoreConfig, redirect_url: String) -> GithubOauthExtension { + let github_client_id = ClientId::new(config.github_oauth.id.clone()); + let github_client_secret = ClientSecret::new(config.github_oauth.secret.clone()); + let auth_url = AuthUrl::new("https://github.com/login/oauth/authorize".to_string()) + .expect("invalid auth url"); let token_url = TokenUrl::new("https://github.com/login/oauth/access_token".to_string()) .expect("Invalid token endpoint URL"); @@ -19,5 +26,5 @@ pub fn github_oauth_client( Some(token_url), ) .set_redirect_uri(RedirectUrl::new(redirect_url).expect("Invalid redirect URL")); - Ok(client) + Extension(Arc::new(client)) } diff --git a/core/src/auth/jwt.rs b/core/src/auth/jwt.rs index 34eb9d4ca..f22408199 100644 --- a/core/src/auth/jwt.rs +++ b/core/src/auth/jwt.rs @@ -7,6 +7,7 @@ use hmac::{Hmac, Mac}; use jwt::{SignWithKey, VerifyWithKey}; use mungos::{Deserialize, Serialize}; use sha2::Sha256; +use types::CoreConfig; pub type JwtExtension = Extension>; @@ -23,11 +24,11 @@ pub struct JwtClient { } impl JwtClient { - pub fn new(secret: &str, valid_for: Timelength) -> JwtExtension { - let key = Hmac::new_from_slice(secret.as_bytes()).unwrap(); + pub fn extension(config: &CoreConfig) -> JwtExtension { + let key = Hmac::new_from_slice(config.jwt_secret.as_bytes()).unwrap(); let client = JwtClient { key, - valid_for_ms: get_timelength_in_ms(valid_for), + valid_for_ms: get_timelength_in_ms(config.jwt_valid_for), }; Extension(Arc::new(client)) } diff --git a/core/src/auth/mod.rs b/core/src/auth/mod.rs index ebaffec6a..cab6e6aa4 100644 --- a/core/src/auth/mod.rs +++ b/core/src/auth/mod.rs @@ -1,9 +1,14 @@ use axum::Router; +use types::CoreConfig; mod github; mod jwt; mod local; -pub fn router() -> Router { - Router::new().nest("/local", local::router()) +pub use self::jwt::{JwtClaims, JwtClient, JwtExtension}; + +pub fn router(config: &CoreConfig) -> Router { + Router::new() + .nest("/local", local::router()) + .nest("/github", github::router(config)) } diff --git a/core/src/config.rs b/core/src/config.rs index cbf991d86..5866942e7 100644 --- a/core/src/config.rs +++ b/core/src/config.rs @@ -10,42 +10,13 @@ use dotenv::dotenv; use mungos::{Deserialize, Mungos}; use types::CoreConfig; -#[derive(Deserialize, Debug)] -struct Env { - port: u16, - mongo_uri: String, - #[serde(default = "default_mongo_app_name")] - mongo_app_name: String, - #[serde(default = "default_mongo_db_name")] - mongo_db_name: String, +pub async fn load() -> CoreConfig { + let config = load_config(); + + config } -pub async fn load() -> (SocketAddr, DbExtension) { - dotenv().ok(); - - let env = envy::from_env::().unwrap(); - - let socket_addr = SocketAddr::from_str(&format!("0.0.0.0:{}", env.port)) - .expect("failed to parse socket addr"); - - let db_client = DbClient::new(&env.mongo_uri, &env.mongo_app_name, &env.mongo_db_name) - .await - .expect("failed to initialize db client"); - - let secrets = load_secrets(); - - (socket_addr, db_client) -} - -fn load_secrets() -> CoreConfig { +fn load_config() -> CoreConfig { let file = File::open("/secrets/secrets.json"); todo!() } - -fn default_mongo_app_name() -> String { - "monitor_core".to_string() -} - -fn default_mongo_db_name() -> String { - "monitor".to_string() -} diff --git a/core/src/helpers.rs b/core/src/helpers.rs index ef0feb051..146ec28f6 100644 --- a/core/src/helpers.rs +++ b/core/src/helpers.rs @@ -1,4 +1,7 @@ +use std::{net::SocketAddr, str::FromStr}; + use axum::http::StatusCode; +use types::CoreConfig; pub fn handle_anyhow_error(err: anyhow::Error) -> (StatusCode, String) { ( @@ -6,3 +9,7 @@ pub fn handle_anyhow_error(err: anyhow::Error) -> (StatusCode, String) { format!("Internal Error: {err:#?}"), ) } + +pub fn get_socket_addr(config: &CoreConfig) -> SocketAddr { + SocketAddr::from_str(&format!("0.0.0.0:{}", config.port)).expect("failed to parse socket addr") +} diff --git a/core/src/main.rs b/core/src/main.rs index 1093c9a17..846d53017 100644 --- a/core/src/main.rs +++ b/core/src/main.rs @@ -1,7 +1,10 @@ #![allow(unused)] +use auth::JwtClient; use axum::Router; +use db::DbClient; use docker::DockerClient; +use helpers::get_socket_addr; mod api; mod auth; @@ -10,14 +13,15 @@ mod helpers; #[tokio::main] async fn main() { - let (socket_addr, db_extension) = config::load().await; + let config = config::load().await; let app = Router::new() .nest("/api", api::router()) - .nest("/auth", auth::router()) - .layer(db_extension); + .nest("/auth", auth::router(&config)) + .layer(DbClient::extension((&config).into()).await) + .layer(JwtClient::extension(&config)); - axum::Server::bind(&socket_addr) + axum::Server::bind(&get_socket_addr(&config)) .serve(app.into_make_service()) .await .expect("server crashed"); diff --git a/lib/db_client/src/lib.rs b/lib/db_client/src/lib.rs index 0d516a07d..5b1be0096 100644 --- a/lib/db_client/src/lib.rs +++ b/lib/db_client/src/lib.rs @@ -6,7 +6,7 @@ use collections::{ updates_collection, users_collection, }; use mungos::{Collection, Mungos}; -use types::{Build, Deployment, Procedure, Server, Update, User}; +use types::{Build, CoreConfig, Deployment, Procedure, Server, Update, User}; mod collections; @@ -21,21 +21,53 @@ pub struct DbClient { pub updates: Collection, } +pub struct DbConfig { + mongo_uri: String, + mongo_app_name: String, + mongo_db_name: String, +} + +impl From<&CoreConfig> for DbConfig { + fn from(config: &CoreConfig) -> DbConfig { + DbConfig { + mongo_uri: config.mongo_uri.clone(), + mongo_app_name: config.mongo_app_name.clone(), + mongo_db_name: config.mongo_db_name.clone(), + } + } +} + impl DbClient { - pub async fn new( - mongo_uri: &str, - app_name: &str, - db_name: &str, - ) -> anyhow::Result { - let mungos = Mungos::new(mongo_uri, app_name, Duration::from_secs(3), None).await?; + pub async fn extension(config: DbConfig) -> DbExtension { + let db_name = &config.mongo_db_name; + let mungos = Mungos::new( + &config.mongo_uri, + &config.mongo_app_name, + Duration::from_secs(3), + None, + ) + .await + .expect("failed to initialize mungos"); let client = DbClient { - users: users_collection(&mungos, db_name).await?, - servers: servers_collection(&mungos, db_name).await?, - deployments: deployments_collection(&mungos, db_name).await?, - builds: builds_collection(&mungos, db_name).await?, - updates: updates_collection(&mungos, db_name).await?, - procedures: procedures_collection(&mungos, db_name).await?, + users: users_collection(&mungos, db_name) + .await + .expect("failed to make users collection"), + servers: servers_collection(&mungos, db_name) + .await + .expect("failed to make servers collection"), + deployments: deployments_collection(&mungos, db_name) + .await + .expect("failed to make deployments collection"), + builds: builds_collection(&mungos, db_name) + .await + .expect("failed to make builds collection"), + updates: updates_collection(&mungos, db_name) + .await + .expect("failed to make updates collection"), + procedures: procedures_collection(&mungos, db_name) + .await + .expect("failed to make procedures collection"), }; - Ok(Extension(Arc::new(client))) + Extension(Arc::new(client)) } } diff --git a/lib/types/Cargo.toml b/lib/types/Cargo.toml index d8341dd0c..2819cfd15 100644 --- a/lib/types/Cargo.toml +++ b/lib/types/Cargo.toml @@ -10,4 +10,5 @@ serde = "1.0" serde_derive = "1.0" mungos = "0.2.24" strum = "0.24" -strum_macros = "0.24" \ No newline at end of file +strum_macros = "0.24" +async_timing_util = "0.1.11" \ No newline at end of file diff --git a/lib/types/src/lib.rs b/lib/types/src/lib.rs index c803be9fb..a9ae4f37c 100644 --- a/lib/types/src/lib.rs +++ b/lib/types/src/lib.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use async_timing_util::Timelength; use mungos::ObjectId; use serde::{Deserialize, Serialize}; use strum_macros::{Display, EnumString}; @@ -212,16 +213,17 @@ pub struct Permission { pub level: PermissionLevel, } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "UPPERCASE")] pub struct OauthCredentials { pub id: String, pub secret: String, } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "UPPERCASE")] pub struct CoreConfig { + pub port: u16, pub passkey: String, pub docker_accounts: DockerAccounts, pub github_accounts: GithubAccounts, @@ -229,6 +231,7 @@ pub struct CoreConfig { pub jwt_secret: String, pub slack_token: Option, pub github_webhook_secret: String, + pub jwt_valid_for: Timelength, pub mongo_uri: String, #[serde(default = "default_core_mongo_app_name")] pub mongo_app_name: String,