diff --git a/docker-compose.yaml b/docker-compose.yaml index e1447e3..9de211d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -12,6 +12,8 @@ services: - GOOGLE_CLIENT_SECRET=L6uI7FQGoMJd-ay1HO_iGJ6M - DISCORD_CLIENT_ID=956189108559036427 - DISCORD_CLIENT_SECRET=dx2DZxjDhVMCCnGX4xpz5MxSTgZ4lHBI + - FACEBOOK_CLIENT_ID=1529124327484248 + - FACEBOOK_CLIENT_SECRET=189509b5eb907b3ce34b7e8459030f21 volumes: - ../jean-marie/templates:/templates ports: diff --git a/run.sh b/run.sh index 94ccb52..0e1650b 100755 --- a/run.sh +++ b/run.sh @@ -1 +1,7 @@ -GOOGLE_CLIENT_ID=735264084619-clsmvgdqdmum4rvrcj0kuk28k9agir1c.apps.googleusercontent.com GOOGLE_CLIENT_SECRET=L6uI7FQGoMJd-ay1HO_iGJ6M DISCORD_CLIENT_ID=956189108559036427 DISCORD_CLIENT_SECRET=dx2DZxjDhVMCCnGX4xpz5MxSTgZ4lHBI cargo run \ No newline at end of file +GOOGLE_CLIENT_ID=735264084619-clsmvgdqdmum4rvrcj0kuk28k9agir1c.apps.googleusercontent.com \ +GOOGLE_CLIENT_SECRET=L6uI7FQGoMJd-ay1HO_iGJ6M \ +DISCORD_CLIENT_ID=956189108559036427 \ +DISCORD_CLIENT_SECRET=dx2DZxjDhVMCCnGX4xpz5MxSTgZ4lHBI \ +FACEBOOK_CLIENT_ID=1529124327484248 \ +FACEBOOK_CLIENT_SECRET=189509b5eb907b3ce34b7e8459030f21 \ +cargo run \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 952d9fd..f3cfe9a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,10 +56,12 @@ async fn main() { 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(); // Get oauth clients for the hashmap //oauth_clients.insert("Google".to_string(), google_oauth_client); + oauth_clients.insert("Facebook", facebook_oauth_client); oauth_clients.insert("Discord", discord_oauth_client); // build our application with a route @@ -77,12 +79,14 @@ async fn main() { ), ) .route("/", get(index)) - .route("/google_auth", get(google_auth)) - .route("/discord_auth", get(discord_auth)) .route("/login", get(login)) .route("/logout", get(logout)) .route("/dashboard", get(dashboard)) + .route("/google_auth", get(google_auth)) + .route("/facebook_auth", get(facebook_auth)) + .route("/discord_auth", get(discord_auth)) .route("/auth/callback", get(google_authorized)) + .route("/auth/facebook", get(facebook_authorized)) .route("/auth/discord", get(discord_authorized)) .layer(Extension(store)) .layer(Extension(oauth_clients)); @@ -143,6 +147,27 @@ fn google_oauth_client() -> BasicClient { .set_redirect_uri(RedirectUrl::new(redirect_url).unwrap()) } +fn facebook_oauth_client() -> BasicClient { + let redirect_url = env::var("REDIRECT_URL") + .unwrap_or_else(|_| "http://localhost:40192/auth/callback".to_string()); + + let facebook_client_id = env::var("FACEBOOK_CLIENT_ID").expect("Missing FACEBOOK_CLIENT_ID!"); + let facebook_client_secret = env::var("FACEBOOK_CLIENT_SECRET").expect("Missing FACEBOOK_CLIENT_SECRET!"); + let facebook_auth_url = env::var("FACEBOOK_AUTH_URL").unwrap_or_else(|_| { + "https://www.facebook.com/v11.0/dialog/oauth".to_string() + }); + let facebook_token_url = env::var("FACEBOOK_TOKEN_URL") + .unwrap_or_else(|_| "https://graph.facebook.com/v11.0/oauth/access_token".to_string()); + + BasicClient::new( + ClientId::new(facebook_client_id), + Some(ClientSecret::new(facebook_client_secret)), + AuthUrl::new(facebook_auth_url).unwrap(), + Some(TokenUrl::new(facebook_token_url).unwrap()), + ) + .set_redirect_uri(RedirectUrl::new(redirect_url).unwrap()) +} + fn discord_oauth_client() -> BasicClient { let redirect_url = env::var("REDIRECT_URL") .unwrap_or_else(|_| "http://localhost:40192/auth/discord".to_string()); @@ -324,6 +349,25 @@ async fn google_auth() -> impl IntoResponse { Redirect::to(&auth_url.to_string()) } +async fn facebook_auth() -> impl IntoResponse { + let (pkce_code_challenge, pkce_code_verifier) = PkceCodeChallenge::new_random_sha256(); + + // Generate the authorization URL to which we'll redirect the user. + let (auth_url, csrf_state) = facebook_oauth_client() + .authorize_url(CsrfToken::new_random) + .add_scope(Scope::new( + "https://www.googleapis.com/auth/userinfo.profile".to_string(), + )) + .add_scope(Scope::new( + "https://www.googleapis.com/auth/userinfo.email".to_string(), + )) + .set_pkce_challenge(pkce_code_challenge) + .url(); + + // Redirect to Google's oauth service + Redirect::to(auth_url.to_string().parse().unwrap()) +} + async fn discord_auth() -> impl IntoResponse { let discord_oauth_client = discord_oauth_client(); let (auth_url, _csrf_token) = discord_oauth_client @@ -345,10 +389,12 @@ struct AuthRequest { async fn google_authorized( Query(query): Query, Extension(store): Extension, - Extension(google_oauth_client): Extension, + Extension(oauth_clients): Extension>, ) -> impl IntoResponse { - - print!("{}", query.code); + // Check for Facebook client + if oauth_clients.contains_key("Google") { + // Get Facebook client + let oauth_client = oauth_clients.get(&"Google").unwrap(); /* // Get an auth token let token = google_oauth_client @@ -386,6 +432,7 @@ async fn google_authorized( headers.insert(SET_COOKIE, cookie.parse().unwrap()); //(headers, Redirect::to("/dashboard".parse().unwrap())) + } let mut page = String::new(); page.push_str(&"Display the data returned by Google\n".to_string()); @@ -398,6 +445,58 @@ async fn google_authorized( page } +async fn facebook_authorized( + Query(query): Query, + Extension(store): Extension, + Extension(oauth_clients): Extension>, +) -> impl IntoResponse { + // Check for Facebook client + if oauth_clients.contains_key("Facebook") { + // Get Facebook client + let oauth_client = oauth_clients.get(&"Facebook").unwrap(); + + // Get an auth token + let token = oauth_client + .exchange_code(AuthorizationCode::new(query.code.clone())) + .request_async(async_http_client) + .await + .unwrap(); + + // Fetch user data from discord + let client = reqwest::Client::new(); + let user_data: User = client + // https://discord.com/developers/docs/resources/user#get-current-user + .get("https://discordapp.com/api/users/@me") //TODO - replace with Facebook info url + .bearer_auth(token.access_token().secret()) + .send() + .await + .unwrap() + .json::() + .await + .unwrap(); + + // Create a new session filled with user data + let mut session = Session::new(); + session.insert("user", &user_data).unwrap(); + + // Store session and get corresponding cookie + let cookie = store.store_session(session).await.unwrap().unwrap(); + + // Build the cookie + let cookie = format!("{}={}; SameSite=Lax; Path=/", COOKIE_NAME, cookie); + + // Set cookie + let mut headers = HeaderMap::new(); + headers.insert(SET_COOKIE, cookie.parse().unwrap()); + + (headers, Redirect::to("/dashboard".parse().unwrap())) + } else { + let mut headers = HeaderMap::new(); + + (headers, Redirect::to("/".parse().unwrap())) + } +} + async fn discord_authorized( Query(query): Query, Extension(store): Extension, diff --git a/templates/baseold.html b/templates/baseold.html deleted file mode 100644 index 4088d79..0000000 --- a/templates/baseold.html +++ /dev/null @@ -1,340 +0,0 @@ - - - - - - - - - - Jean-Marie Family Website - - - - - - - - - - - - - - -
-
-
-
-
-
-
- - - - - - -
{% block content %}{% endblock content %}
- - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/templates/dashboard.html b/templates/dashboard.html index 74810fd..a1a6484 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -10,6 +10,11 @@
  • Google fonts
  • Font Space
  • +

    Family tree

    + {% endblock content %} \ No newline at end of file diff --git a/templates/indexold.html b/templates/indexold.html deleted file mode 100644 index 00187a4..0000000 --- a/templates/indexold.html +++ /dev/null @@ -1,72 +0,0 @@ -{% extends "base.html" %} -{% block content %} - -
    -
    - -
    -
    - -
    -

    Welcome to the

    -
    Jean-Marie Family Website
    - Learn More - Get It Now -
    -
    -
    - - -
    -
    - -
    -

    Welcome to the

    -
    Jean-Marie Family Website
    - Learn More - Get It Now -
    -
    -
    - - -
    -
    - -
    -

    Welcome to the

    -
    Jean-Marie Family Website
    - Learn More - Get It Now -
    -
    -
    - -
    -
    - - - - -
    -
    -
    -
    -
    -
    -
    About Us
    -

    The home of the Jean-Marie extended family

    -
    -
    -
    -
    -
    -

    This wesite is for the extended Jean-Marie family.

    -
    -
    -
    -
    -
    - - -{% endblock content %} \ No newline at end of file diff --git a/templates/login.html b/templates/login.html index f32c8e3..ee91ea3 100644 --- a/templates/login.html +++ b/templates/login.html @@ -31,6 +31,12 @@ Sign Up

    Forgot your password?

    --> +
    or connect + with
    + Login with Facebook + Login with Discord diff --git a/templates/loginnew.html b/templates/loginnew.html deleted file mode 100644 index 0faffc1..0000000 --- a/templates/loginnew.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "base.html" %} -{% block content %} -
    -
    -
    -
    -
    -

    Login

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    Forgot password?
    -
    Login
    -
    Don't have an account? Sign up
    -
    -
    -
    - -
    -
    -
    -
    -
    -{% endblock content %} \ No newline at end of file diff --git a/templates/loginold.html b/templates/loginold.html deleted file mode 100644 index 4170211..0000000 --- a/templates/loginold.html +++ /dev/null @@ -1,47 +0,0 @@ -{% extends "base.html" %} -{% block content %} -
    -
    -
    -
    -
    -
    - -

    Sign in

    - -
    - - -
    - -
    - - -
    - - -
    - - -
    - - - -
    - - - Sign in with discord - - -
    -
    < -
    -
    -
    -
    -{% endblock content %} \ No newline at end of file