From 419aafc5c1bfbbb5e5f30c6537128a7c473c6bf4 Mon Sep 17 00:00:00 2001
From: Chris Jean-Marie
Date: Wed, 30 Mar 2022 09:49:19 -0400
Subject: [PATCH] Convert to Bootstrap 5 Add facebook login
---
docker-compose.yaml | 2 +
run.sh | 8 +-
src/main.rs | 109 ++++++++++++-
templates/baseold.html | 340 ---------------------------------------
templates/dashboard.html | 5 +
templates/indexold.html | 72 ---------
templates/login.html | 6 +
templates/loginnew.html | 30 ----
templates/loginold.html | 47 ------
9 files changed, 124 insertions(+), 495 deletions(-)
delete mode 100644 templates/baseold.html
delete mode 100644 templates/indexold.html
delete mode 100644 templates/loginnew.html
delete mode 100644 templates/loginold.html
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 d7c92d3..aec1afd 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().parse().unwrap())
}
+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 %}
-
-
-
-
-
-
-
-
-
-
-
-
-
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
+
+
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 %}
-
-{% 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