diff --git a/.env b/.env index 21169dc..c3e9108 100644 --- a/.env +++ b/.env @@ -4,10 +4,6 @@ JWT_SECRET=my_ultra_secure_secret TOKEN_EXPIRED_IN=60m TOKEN_MAXAGE=60 -GOOGLE_OAUTH_CLIENT_ID=176116788100-cv8354tkaqlpf69qmi3d8hkv4t5osm9e.apps.googleusercontent.com -GOOGLE_OAUTH_CLIENT_SECRET=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 -GOOGLE_OAUTH_REDIRECT_URL=http://localhost:8000/api/sessions/oauth/google - -GITHUB_OAUTH_CLIENT_ID=27e779e9877f02cb75ed -GITHUB_OAUTH_CLIENT_SECRET=f41bff01b821b471ff163e938364a7586b0180c6 +GITHUB_OAUTH_CLIENT_ID= +GITHUB_OAUTH_CLIENT_SECRET= GITHUB_OAUTH_REDIRECT_URL=http://localhost:8000/api/sessions/oauth/github \ No newline at end of file diff --git a/src/google_oauth.rs b/src/google_oauth.rs deleted file mode 100644 index fc4dbd0..0000000 --- a/src/google_oauth.rs +++ /dev/null @@ -1,74 +0,0 @@ -use actix_web::web; -use reqwest::{Client, Url}; -use serde::Deserialize; -use std::error::Error; - -use crate::model::AppState; - -#[derive(Deserialize)] -pub struct OAuthResponse { - pub access_token: String, - pub id_token: String, -} - -#[derive(Deserialize)] -pub struct GoogleUserResult { - pub id: String, - pub email: String, - pub verified_email: bool, - pub name: String, - pub given_name: String, - pub family_name: String, - pub picture: String, - pub locale: String, -} - -pub async fn request_token( - authorization_code: &str, - data: &web::Data, -) -> Result> { - let redirect_url = data.env.google_oauth_redirect_url.to_owned(); - let client_secret = data.env.google_oauth_client_secret.to_owned(); - let client_id = data.env.google_oauth_client_id.to_owned(); - - let root_url = "https://oauth2.googleapis.com/token"; - let client = Client::new(); - - let params = [ - ("grant_type", "authorization_code"), - ("redirect_uri", redirect_url.as_str()), - ("client_id", client_id.as_str()), - ("code", authorization_code), - ("client_secret", client_secret.as_str()), - ]; - let response = client.post(root_url).form(¶ms).send().await?; - - if response.status().is_success() { - let oauth_response = response.json::().await?; - Ok(oauth_response) - } else { - let message = "An error occurred while trying to retrieve access token."; - Err(From::from(message)) - } -} - -pub async fn get_google_user( - access_token: &str, - id_token: &str, -) -> Result> { - let client = Client::new(); - let mut url = Url::parse("https://www.googleapis.com/oauth2/v1/userinfo").unwrap(); - url.query_pairs_mut().append_pair("alt", "json"); - url.query_pairs_mut() - .append_pair("access_token", access_token); - - let response = client.get(url).bearer_auth(id_token).send().await?; - - if response.status().is_success() { - let user_info = response.json::().await?; - Ok(user_info) - } else { - let message = "An error occurred while trying to retrieve user information."; - Err(From::from(message)) - } -} diff --git a/src/handler.rs b/src/handler.rs index e386bdb..e52c6c5 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -1,7 +1,6 @@ use crate::{ authenticate_token::AuthenticationGuard, github_oauth::{get_github_oauth_token, get_github_user}, - google_oauth::{get_google_user, request_token}, model::{AppState, LoginUserSchema, QueryCode, RegisterUserSchema, TokenClaims, User}, response::{FilteredUser, UserData, UserResponse}, }; @@ -16,7 +15,7 @@ use uuid::Uuid; #[get("/healthchecker")] async fn health_checker_handler() -> impl Responder { - const MESSAGE: &str = "Implement Google and GitHub OAuth2 in Rust"; + const MESSAGE: &str = "How to Implement GitHub OAuth in Rust"; HttpResponse::Ok().json(serde_json::json!({"status": "success", "message": MESSAGE})) } @@ -116,99 +115,6 @@ async fn login_user_handler( .json(serde_json::json!({"status": "success"})) } -#[get("/sessions/oauth/google")] -async fn google_oauth_handler( - query: web::Query, - data: web::Data, -) -> impl Responder { - let code = &query.code; - let state = &query.state; - - if code.is_empty() { - return HttpResponse::Unauthorized().json( - serde_json::json!({"status": "fail", "message": "Authorization code not provided!"}), - ); - } - - let token_response = request_token(code.as_str(), &data).await; - if token_response.is_err() { - let message = token_response.err().unwrap().to_string(); - return HttpResponse::BadGateway() - .json(serde_json::json!({"status": "fail", "message": message})); - } - - let token_response = token_response.unwrap(); - let google_user = get_google_user(&token_response.access_token, &token_response.id_token).await; - if google_user.is_err() { - let message = google_user.err().unwrap().to_string(); - return HttpResponse::BadGateway() - .json(serde_json::json!({"status": "fail", "message": message})); - } - - let google_user = google_user.unwrap(); - - let mut vec = data.db.lock().unwrap(); - let email = google_user.email.to_lowercase(); - let user = vec.iter_mut().find(|user| user.email == email); - - let user_id: String; - - if user.is_some() { - let user = user.unwrap(); - user_id = user.id.to_owned().unwrap(); - user.email = email.to_owned(); - user.photo = google_user.picture; - user.updatedAt = Some(Utc::now()); - } else { - let datetime = Utc::now(); - let id = Uuid::new_v4(); - user_id = id.to_owned().to_string(); - let user_data = User { - id: Some(id.to_string()), - name: google_user.name, - verified: google_user.verified_email, - email, - provider: "Google".to_string(), - role: "user".to_string(), - password: "".to_string(), - photo: google_user.picture, - createdAt: Some(datetime), - updatedAt: Some(datetime), - }; - - vec.push(user_data.to_owned()); - } - - let jwt_secret = data.env.jwt_secret.to_owned(); - let now = Utc::now(); - let iat = now.timestamp() as usize; - let exp = (now + Duration::minutes(data.env.jwt_max_age)).timestamp() as usize; - let claims: TokenClaims = TokenClaims { - sub: user_id, - exp, - iat, - }; - - let token = encode( - &Header::default(), - &claims, - &EncodingKey::from_secret(jwt_secret.as_ref()), - ) - .unwrap(); - - let cookie = Cookie::build("token", token) - .path("/") - .max_age(ActixWebDuration::new(60 * data.env.jwt_max_age, 0)) - .http_only(true) - .finish(); - - let frontend_origin = data.env.client_origin.to_owned(); - let mut response = HttpResponse::Found(); - response.append_header((LOCATION, format!("{}{}", frontend_origin, state))); - response.cookie(cookie); - response.finish() -} - #[get("/sessions/oauth/github")] async fn github_oauth_handler( query: web::Query, @@ -356,7 +262,6 @@ pub fn config(conf: &mut web::ServiceConfig) { .service(health_checker_handler) .service(register_user_handler) .service(login_user_handler) - .service(google_oauth_handler) .service(github_oauth_handler) .service(logout_handler) .service(get_me_handler); diff --git a/src/main.rs b/src/main.rs index 741904c..758c293 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ mod authenticate_token; mod config; mod github_oauth; -mod google_oauth; mod handler; mod model; mod response;