-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Examples: Move shared functions into utils module
- Loading branch information
David Graeff
committed
Jan 22, 2021
1 parent
814663f
commit 42e2d17
Showing
2 changed files
with
83 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,11 @@ | ||
use firestore_db_and_auth::{ | ||
documents, dto, errors, sessions, Credentials, FirebaseAuthBearer, JWKSet, ServiceSession, | ||
documents, dto, errors, sessions, Credentials, FirebaseAuthBearer, ServiceSession, | ||
}; | ||
|
||
use firestore_db_and_auth::documents::WriteResult; | ||
use firestore_db_and_auth::jwt::download_google_jwks; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
const TEST_USER_ID: &str = include_str!("test_user_id.txt"); | ||
mod utils; | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
struct DemoDTO { | ||
|
@@ -93,43 +92,16 @@ fn service_account_session(cred: Credentials) -> errors::Result<()> { | |
Ok(()) | ||
} | ||
|
||
fn user_session_with_cached_refresh_token(cred: &Credentials) -> errors::Result<sessions::user::Session> { | ||
println!("Refresh token from file"); | ||
// Read refresh token from file if possible instead of generating a new refresh token each time | ||
let refresh_token: String = match std::fs::read_to_string("refresh-token-for-tests.txt") { | ||
Ok(v) => v, | ||
Err(e) => { | ||
if e.kind() != std::io::ErrorKind::NotFound { | ||
return Err(errors::FirebaseError::IO(e)); | ||
} | ||
String::new() | ||
} | ||
}; | ||
|
||
// Generate a new refresh token if necessary | ||
println!("Generate new user auth token"); | ||
let user_session: sessions::user::Session = if refresh_token.is_empty() { | ||
let session = sessions::user::Session::by_user_id(&cred, TEST_USER_ID, true)?; | ||
std::fs::write("refresh-token-for-tests.txt", &session.refresh_token.as_ref().unwrap())?; | ||
session | ||
} else { | ||
println!("user::Session::by_refresh_token"); | ||
sessions::user::Session::by_refresh_token(&cred, &refresh_token)? | ||
}; | ||
|
||
Ok(user_session) | ||
} | ||
|
||
fn user_account_session(cred: Credentials) -> errors::Result<()> { | ||
let user_session = user_session_with_cached_refresh_token(&cred)?; | ||
let user_session = utils::user_session_with_cached_refresh_token(&cred)?; | ||
|
||
assert_eq!(user_session.user_id, TEST_USER_ID); | ||
assert_eq!(user_session.user_id, utils::TEST_USER_ID); | ||
assert_eq!(user_session.project_id(), cred.project_id); | ||
|
||
println!("user::Session::by_access_token"); | ||
let user_session = sessions::user::Session::by_access_token(&cred, &user_session.access_token_unchecked())?; | ||
|
||
assert_eq!(user_session.user_id, TEST_USER_ID); | ||
assert_eq!(user_session.user_id, utils::TEST_USER_ID); | ||
|
||
let obj = DemoDTO { | ||
a_string: "abc".to_owned(), | ||
|
@@ -213,29 +185,6 @@ fn user_account_session(cred: Credentials) -> errors::Result<()> { | |
Ok(()) | ||
} | ||
|
||
/// Download the two public key JWKS files if necessary and cache the content at the given file path. | ||
/// Only use this option in cloud functions if the given file path is persistent. | ||
/// You can use [`Credentials::add_jwks_public_keys`] to manually add more public keys later on. | ||
pub fn from_cache_file(cache_file: &std::path::Path, c: &Credentials) -> errors::Result<JWKSet> { | ||
use std::fs::File; | ||
use std::io::BufReader; | ||
|
||
Ok(if cache_file.exists() { | ||
let f = BufReader::new(File::open(cache_file)?); | ||
let jwks_set: JWKSet = serde_json::from_reader(f)?; | ||
jwks_set | ||
} else { | ||
// If not present, download the two jwks (specific service account + google system account), | ||
// merge them into one set of keys and store them in the cache file. | ||
let mut jwks = JWKSet::new(&download_google_jwks(&c.client_email)?)?; | ||
jwks.keys | ||
.append(&mut JWKSet::new(&download_google_jwks("[email protected]")?)?.keys); | ||
let f = File::create(cache_file)?; | ||
serde_json::to_writer_pretty(f, &jwks)?; | ||
jwks | ||
}) | ||
} | ||
|
||
fn main() -> errors::Result<()> { | ||
// Search for a credentials file in the root directory | ||
use std::path::PathBuf; | ||
|
@@ -244,7 +193,7 @@ fn main() -> errors::Result<()> { | |
let mut cred = Credentials::from_file(credential_file.to_str().unwrap())?; | ||
|
||
// Only download the public keys once, and cache them. | ||
let jwkset = from_cache_file(credential_file.with_file_name("cached_jwks.jwks").as_path(), &cred)?; | ||
let jwkset = utils::from_cache_file(credential_file.with_file_name("cached_jwks.jwks").as_path(), &cred)?; | ||
cred.add_jwks_public_keys(&jwkset); | ||
cred.verify()?; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use firestore_db_and_auth::{ | ||
errors, sessions, Credentials, JWKSet, | ||
}; | ||
|
||
use firestore_db_and_auth::jwt::download_google_jwks; | ||
|
||
#[warn(dead_code)] | ||
pub const TEST_USER_ID: &str = include_str!("../test_user_id.txt"); | ||
|
||
pub fn user_session_with_cached_refresh_token(cred: &Credentials) -> errors::Result<sessions::user::Session> { | ||
println!("Refresh token from file"); | ||
// Read refresh token from file if possible instead of generating a new refresh token each time | ||
let refresh_token: String = match std::fs::read_to_string("refresh-token-for-tests.txt") { | ||
Ok(v) => v, | ||
Err(e) => { | ||
if e.kind() != std::io::ErrorKind::NotFound { | ||
return Err(errors::FirebaseError::IO(e)); | ||
} | ||
String::new() | ||
} | ||
}; | ||
|
||
// Generate a new refresh token if necessary | ||
println!("Generate new user auth token"); | ||
let user_session: sessions::user::Session = if refresh_token.is_empty() { | ||
let session = sessions::user::Session::by_user_id(&cred, TEST_USER_ID, true)?; | ||
std::fs::write("refresh-token-for-tests.txt", &session.refresh_token.as_ref().unwrap())?; | ||
session | ||
} else { | ||
println!("user::Session::by_refresh_token"); | ||
sessions::user::Session::by_refresh_token(&cred, &refresh_token)? | ||
}; | ||
|
||
Ok(user_session) | ||
} | ||
|
||
|
||
/// Download the two public key JWKS files if necessary and cache the content at the given file path. | ||
/// Only use this option in cloud functions if the given file path is persistent. | ||
/// You can use [`Credentials::add_jwks_public_keys`] to manually add more public keys later on. | ||
pub fn from_cache_file(cache_file: &std::path::Path, c: &Credentials) -> errors::Result<JWKSet> { | ||
use std::fs::File; | ||
use std::io::BufReader; | ||
|
||
Ok(if cache_file.exists() { | ||
let f = BufReader::new(File::open(cache_file)?); | ||
let jwks_set: JWKSet = serde_json::from_reader(f)?; | ||
jwks_set | ||
} else { | ||
// If not present, download the two jwks (specific service account + google system account), | ||
// merge them into one set of keys and store them in the cache file. | ||
let mut jwks = JWKSet::new(&download_google_jwks(&c.client_email)?)?; | ||
jwks.keys | ||
.append(&mut JWKSet::new(&download_google_jwks("[email protected]")?)?.keys); | ||
let f = File::create(cache_file)?; | ||
serde_json::to_writer_pretty(f, &jwks)?; | ||
jwks | ||
}) | ||
} | ||
|
||
/// For integration tests and doc code snippets: Create a Credentials instance. | ||
/// Necessary public jwk sets are downloaded or re-used if already present. | ||
#[cfg(test)] | ||
pub fn valid_test_credentials() -> errors::Result<Credentials> { | ||
use std::path::PathBuf; | ||
let mut jwks_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); | ||
jwks_path.push("firebase-service-account.jwks"); | ||
|
||
let mut cred: Credentials = Credentials::new(include_str!("../../firebase-service-account.json"))?; | ||
|
||
// Only download the public keys once, and cache them. | ||
let jwkset = from_cache_file(jwks_path.as_path(), &cred)?; | ||
cred.add_jwks_public_keys(&jwkset); | ||
cred.verify()?; | ||
|
||
Ok(cred) | ||
} |