diff --git a/backend/.env b/backend/.env new file mode 100644 index 0000000..1f95035 --- /dev/null +++ b/backend/.env @@ -0,0 +1,3 @@ +DATABASE_URL=sqlite://db/db.sqlite3 +GOOGLE_CLIENT_ID=735264084619-clsmvgdqdmum4rvrcj0kuk28k9agir1c.apps.googleusercontent.com +GOOGLE_CLIENT_SECRET=L6uI7FQGoMJd-ay1HO_iGJ6M \ No newline at end of file diff --git a/backend/db/.gitkeep b/backend/db/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/backend/db/db.sqlite3 b/backend/db/db.sqlite3 new file mode 100644 index 0000000..c5f41e1 Binary files /dev/null and b/backend/db/db.sqlite3 differ diff --git a/backend/src/google_oauth.rs b/backend/src/google_oauth.rs index 99a43fe..72994e6 100644 --- a/backend/src/google_oauth.rs +++ b/backend/src/google_oauth.rs @@ -91,7 +91,7 @@ pub fn google_oauth_client() -> BasicClient { } let redirect_url = env::var("REDIRECT_URL") - .unwrap_or_else(|_| "http://localhost:40192/auth/google".to_string()); + .unwrap_or_else(|_| "http://localhost:40192/google_auth_return".to_string()); // .unwrap_or_else(|_| "https://www.jean-marie.ca/auth/google".to_string()); let google_client_id = env::var("GOOGLE_CLIENT_ID").expect("Missing GOOGLE_CLIENT_ID!"); diff --git a/backend/src/main.rs b/backend/src/main.rs index 17fbfde..69596c5 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,25 +1,23 @@ use std::net::SocketAddr; use askama::Template; -use axum_session::{Session, SessionAnyPool, SessionConfig, SessionStore, SessionLayer}; use axum::{ - Router, - routing::{get, get_service}, response::{Html, IntoResponse, Response}, + extract::{FromRef, State}, middleware, response::{Html, IntoResponse, Redirect, Response}, routing::{get, get_service}, Extension, Router }; -use axum_extra::extract::cookie::PrivateCookieJar; -use http::StatusCode; -use serde::{Serialize, Deserialize}; +use axum_extra::TypedHeader; +use headers::Cookie; +use http::{Request, StatusCode}; use sqlx::{sqlite::SqlitePoolOptions, SqlitePool}; use tower_http::services::ServeDir; mod error_handling; +use middlewares::{check_auth, inject_user_data}; mod google_oauth; mod middlewares; mod oauth; use error_handling::AppError; use google_oauth::*; -use middlewares::{check_auth, inject_user_data}; -use oauth::{login, logout, oauth_return}; +use oauth::{login, logout, google_auth_return}; struct HtmlTemplate(T); @@ -53,13 +51,6 @@ struct LoginTemplate { name: String, } -#[derive(Template)] -#[template(path = "dashboard.html")] -struct DashboardTemplate { - logged_in: bool, - name: String, -} - #[derive(Clone)] pub struct AppState { pub db_pool: SqlitePool, @@ -70,62 +61,41 @@ pub struct UserData { #[allow(dead_code)] pub user_id: i64, pub user_email: String, -} - -#[derive(Debug, Serialize, Deserialize)] -struct User { - id: String, - avatar: Option, - username: String, - discriminator: String, -} +/* pub user_name: String, + pub user_discriminator: String, + pub user_avatar: String, + pub user_access_token: String, + pub user_refresh_token: String, + pub user_expires_at: i64, + */} #[tokio::main] async fn main() { // initialize tracing tracing_subscriber::fmt::init(); - let session_config = SessionConfig::default() - .with_table_name("sessions"); - - //let session_store = SessionStore::::new(None, session_config).await.unwrap(); - let db_pool = SqlitePoolOptions::new() .max_connections(5) .connect("sqlite://db/db.sqlite3") - .await - .map_err(|e| format!("DB connection failed: {}", e))?; + .await; - let app_state = AppState { - db_pool: db_pool - }; + let app_state = AppState {db_pool: db_pool.expect("Failed to get db_pool") }; - // Create HashMap to store oauth configurations - // let mut oauth_clients = HashMap::<&str, BasicClient>::new(); - - // Get the client structures - // let facebook_oauth_client = facebook_oauth_client(); - // let discord_oauth_client = discord_oauth_client(); - // let google_oauth_client = google_oauth_client(); - - // Get oauth clients for the hashmap - // oauth_clients.insert("Facebook", facebook_oauth_client); - // oauth_clients.insert("Discord", discord_oauth_client); - // oauth_clients.insert("Google", google_oauth_client); + let user_data: Option = None; // build our application with some routes let app = Router::new() .nest_service("/assets", ServeDir::new("templates/assets") .fallback(get_service(ServeDir::new("templates/assets")))) + .route_layer(middleware::from_fn_with_state(app_state.clone(), check_auth)) .route("/", get(index)) - .route("/dashboard", get(dashboard)) .route("/login", get(login)) - .route("/google_auth", get(google_auth)) - .route("/auth/google", get(google_authorized)) .route("/logout", get(logout)) - //.layer(SessionLayer::new(session_store)) - .with_state(app_state) - // .layer(Extension(oauth_clients)); + .route("/google_auth", get(google_auth)) + .route("/google_auth_return", get(google_auth_return)) + .route_layer(middleware::from_fn_with_state(app_state.db_pool.clone(), inject_user_data)) + .with_state(app_state.db_pool) + .layer(Extension(user_data)) ; // run it @@ -137,36 +107,15 @@ async fn main() { .unwrap(); } -async fn index(session: Session) -> impl IntoResponse { - let logged_in = session.get("logged_in").unwrap_or(false); - let name = session.get("name").unwrap_or("You're not logged in.".to_string()); +async fn index( + Extension(user_data): Extension>, + request: Request, +) -> impl IntoResponse { + let user_email = user_data.map(|s| s.user_email); + let login_return_url = "?return_url=".to_owned() + &*request.uri().to_string(); + let logged_in = user_email.is_some(); + let name = user_email.unwrap_or_default(); let template = IndexTemplate { logged_in, name}; HtmlTemplate(template) } - -/* async fn login(session: Session) -> impl IntoResponse { - let logged_in = session.get("logged_in").unwrap_or(false); - let name = session.get("name").unwrap_or("".to_string()); - - session.set_store(true); - - session.set("logged_in", logged_in); - session.set("name", &name); - - let template = LoginTemplate { logged_in, name }; - HtmlTemplate(template) -} */ - -async fn dashboard(session: Session) -> impl IntoResponse { - let logged_in = session.get("logged_in").unwrap_or(false); - let name = session.get("name").unwrap_or("".to_string()); - - session.set_store(true); - - session.set("logged_in", logged_in); - session.set("name", &name); - - let template = DashboardTemplate { logged_in, name }; - HtmlTemplate(template) -} \ No newline at end of file diff --git a/backend/src/oauth.rs b/backend/src/oauth.rs index 155e20e..aae4871 100644 --- a/backend/src/oauth.rs +++ b/backend/src/oauth.rs @@ -38,7 +38,7 @@ fn get_client(hostname: String) -> Result { "https" }; - let redirect_url = format!("{}://{}/oauth_return", protocol, hostname); + let redirect_url = format!("{}://{}/google_auth_return", protocol, hostname); // Set up the config for the Google OAuth2 process. let client = BasicClient::new( @@ -61,6 +61,7 @@ pub async fn login( State(db_pool): State, Host(hostname): Host, ) -> Result { + if user_data.is_some() { // check if already authenticated return Ok(Redirect::to("/")); @@ -95,7 +96,7 @@ pub async fn login( Ok(Redirect::to(authorize_url.as_str())) } -pub async fn oauth_return( +pub async fn google_auth_return( Query(mut params): Query>, State(db_pool): State, Host(hostname): Host,