Skip to content

Commit

Permalink
Partially complete update to add API tokens to tests (checkpt)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcua committed Nov 4, 2023
1 parent f48ea9c commit 62b9db9
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/http/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ async fn confirm(
}

let (api_token, token_string) = generate_api_token(&created_entity)?;
let _ = ayb_db.create_api_token(&api_token);
let _ = ayb_db.create_api_token(&api_token).await?;
let returned_token = APIAPIToken {
token: token_string,
};
Expand Down
140 changes: 107 additions & 33 deletions tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,44 +67,58 @@ fn client_server_integration(

// Register an entity.
Command::cargo_bin("ayb")?
.args(["client", "register", "e2e", "[email protected]"])
.args(["client", "register", "e2e-first", "[email protected]"])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.stdout("Check your email to finish registering e2e\n");
.stdout("Check your email to finish registering e2e-first\n");

// Register the same entity with the same email address.
Command::cargo_bin("ayb")?
.args(["client", "register", "e2e", "[email protected]"])
.args(["client", "register", "e2e-first", "[email protected]"])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.stdout("Check your email to finish registering e2e\n");
.stdout("Check your email to finish registering e2e-first\n");

// Can start to register an entity twice as long as you don't
// complete the process.
Command::cargo_bin("ayb")?
.args(["client", "register", "e2e", "[email protected]"])
.args(["client", "register", "e2e-first", "[email protected]"])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.stdout("Check your email to finish registering e2e\n");
.stdout("Check your email to finish registering e2e-first\n");

// Start the registration process for a second user (e2e-second)
Command::cargo_bin("ayb")?
.args([
"client",
"register",
"e2e-second",
"[email protected]",
])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.stdout("Check your email to finish registering e2e-second\n");

// Check that two emails were received
let entries = utils::parse_smtp_log(&format!("tests/smtp_data_{}/[email protected]", smtp_port))?;
assert_eq!(entries.len(), 2);
let token0 = utils::extract_token(&entries[0])?;
let token1 = utils::extract_token(&entries[1])?;
let first_token0 = utils::extract_token(&entries[0])?;
let first_token1 = utils::extract_token(&entries[1])?;
let entries = utils::parse_smtp_log(&format!(
"tests/smtp_data_{}/[email protected]",
smtp_port
))?;
assert_eq!(entries.len(), 1);
let token2 = utils::extract_token(&entries[0])?;
assert_eq!(entries.len(), 2);
let first_token2 = utils::extract_token(&entries[0])?;
let second_token0 = utils::extract_token(&entries[1])?;

// Using a bad token (appending a letter) doesn't work.
Command::cargo_bin("ayb")?
.args(["client", "confirm", &format!("{}a", token0)])
.args(["client", "confirm", &format!("{}a", first_token0)])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
Expand All @@ -116,74 +130,134 @@ fn client_server_integration(
// third token, which was with a different email address for the
// same account, won't work now that there's already a confirmed
// email address on the account..
Command::cargo_bin("ayb")?
.args(["client", "confirm", &token0])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.stdout("Successfully authenticated and saved token default/insecure, unimplemented\n");
let first_api_key0 = utils::extract_api_key(
Command::cargo_bin("ayb")?
.args(["client", "confirm", &first_token0])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.get_output(),
)?;

Command::cargo_bin("ayb")?
.args(["client", "confirm", &token1])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.stdout("Successfully authenticated and saved token default/insecure, unimplemented\n");
let first_api_key1 = utils::extract_api_key(
Command::cargo_bin("ayb")?
.args(["client", "confirm", &first_token1])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.get_output(),
)?;

Command::cargo_bin("ayb")?
.args(["client", "confirm", &token2])
.args(["client", "confirm", &first_token2])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.stdout("Error: e2e has already been registered\n");
.stdout("Error: e2e-first has already been registered\n");

// And for the second account, we can still confirm using the only
// authentication token we've requested so far.
let second_api_key0 = utils::extract_api_key(
Command::cargo_bin("ayb")?
.args(["client", "confirm", &second_token0])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.get_output(),
)?;

// Logging in as the user emails the first email address, which
// can confirm using the token it received.
Command::cargo_bin("ayb")?
.args(["client", "log_in", "e2e"])
.args(["client", "log_in", "e2e-first"])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.stdout("Check your email to finish logging in e2e\n");
.stdout("Check your email to finish logging in e2e-first\n");

let entries = utils::parse_smtp_log(&format!("tests/smtp_data_{}/[email protected]", smtp_port))?;
assert_eq!(entries.len(), 3);
let login_token = utils::extract_token(&entries[2])?;
let first_api_key2 = utils::extract_api_key(
Command::cargo_bin("ayb")?
.args(["client", "confirm", &login_token])
.env("AYB_SERVER_URL", server_url)
.assert()
.success()
.get_output(),
);

// To summarize where we are at this point
// * User e2e-first has three API tokens (first_api_key[0...2]). We'll use these
// interchangeably below.
// * User e2e-second has one API token (second_api_key0)

// Can't create database on e2e-first with e2e-second's token.
Command::cargo_bin("ayb")?
.args(["client", "confirm", &login_token])
.env("AYB_SERVER_URL", server_url)
.args([
"client",
"--url",
server_url,
"create_database",
"e2e-first/test.sqlite",
"sqlite",
])
.env("AYB_API_TOKEN", second_api_key0)
.assert()
.success()
.stdout("Successfully authenticated and saved token default/insecure, unimplemented\n");
.stdout("Successfully created e2e/test.sqlite\n");

// Create database.
// Can't create database on e2e-first with invalid token.
Command::cargo_bin("ayb")?
.args([
"client",
"--url",
server_url,
"create_database",
"e2e/test.sqlite",
"e2e-first/test.sqlite",
"sqlite",
])
.env("AYB_API_TOKEN", format!("{}bad", first_api_key0.clone()))
.assert()
.success()
.stdout("Successfully created e2e/test.sqlite\n");

// Create a database with the appropriate user/key pair.
Command::cargo_bin("ayb")?
.args([
"client",
"--url",
server_url,
"create_database",
"e2e-first/test.sqlite",
"sqlite",
])
.env("AYB_API_TOKEN", first_api_key0.clone())
.assert()
.success()
.stdout("Successfully created e2e-first/test.sqlite\n");

// Can't create a database twice.
Command::cargo_bin("ayb")?
.args([
"client",
"--url",
server_url,
"create_database",
"e2e/test.sqlite",
"e2e-first/test.sqlite",
"sqlite",
])
.env("AYB_API_TOKEN", first_api_key0.clone())
.assert()
.success()
.stdout("Error: Database already exists\n");

// TODO
// * Fix API token DB creation
// * Query with other account's key (error)
// * Query with invalid key (error)
// * Query with the first account's three API keys (all work)

// Populate and query database.
client_query(
server_url,
Expand Down
18 changes: 17 additions & 1 deletion tests/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use ayb::error::AybError;
use quoted_printable;
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::fs;
use std::process::Output;

#[derive(Serialize, Deserialize)]
pub struct EmailEntry {
Expand All @@ -15,6 +17,20 @@ pub struct EmailEntry {
content: Vec<String>,
}

pub fn extract_api_key(output: &Output) -> Result<String, AybError> {
let output_str = std::str::from_utf8(&output.stdout)?;
println!("Now featuring ---{}---", output_str);
let re = Regex::new(r"^Successfully authenticated and saved token (\S+)\n").unwrap();
if re.is_match(output_str) {
let captures = re.captures(output_str).unwrap();
Ok(captures.get(1).map_or("", |m| m.as_str()).to_string())
} else {
Err(AybError {
message: "No API key".to_string(),
})
}
}

pub fn extract_token(email: &EmailEntry) -> Result<String, AybError> {
let prefix = "\tayb client confirm ";
assert_eq!(email.subject, "Your login credentials");
Expand All @@ -27,7 +43,7 @@ pub fn extract_token(email: &EmailEntry) -> Result<String, AybError> {
}
}
return Err(AybError {
message: "No token found in email".to_owned(),
message: "No token found in email".to_string(),
});
}

Expand Down

0 comments on commit 62b9db9

Please sign in to comment.