Skip to content

Commit 434b39b

Browse files
committed
Merge pull-request #498
2 parents 39e8b41 + 2eb8783 commit 434b39b

File tree

3 files changed

+139
-36
lines changed

3 files changed

+139
-36
lines changed

src/integration/tests/boot.rs

+20-10
Original file line numberDiff line numberDiff line change
@@ -189,22 +189,32 @@ async fn standard_boot_e2e() {
189189

190190
assert_eq!(
191191
&stdout.next().unwrap().unwrap(),
192-
"Is this the correct namespace name: quit-coding-to-vape? (yes/no)"
192+
"Is this the correct namespace name: quit-coding-to-vape? (y/n)"
193193
);
194-
stdin.write_all("yes\n".as_bytes()).expect("Failed to write to stdin");
194+
stdin.write_all("y\n".as_bytes()).expect("Failed to write to stdin");
195195

196196
assert_eq!(
197197
&stdout.next().unwrap().unwrap(),
198-
"Is this the correct namespace nonce: 2? (yes/no)"
198+
"Is this the correct namespace nonce: 2? (y/n)"
199199
);
200-
stdin.write_all("yes\n".as_bytes()).expect("Failed to write to stdin");
200+
// On purpose, try to input a bad value, neither yes or no
201+
stdin
202+
.write_all("maybe\n".as_bytes())
203+
.expect("Failed to write to stdin");
201204

202205
assert_eq!(
203206
&stdout.next().unwrap().unwrap(),
204-
"Is this the correct pivot restart policy: RestartPolicy::Never? (yes/no)"
207+
"Please answer with either \"yes\" (y) or \"no\" (n)"
205208
);
209+
// Try the longer option ("yes" rather than "y")
206210
stdin.write_all("yes\n".as_bytes()).expect("Failed to write to stdin");
207211

212+
assert_eq!(
213+
&stdout.next().unwrap().unwrap(),
214+
"Is this the correct pivot restart policy: RestartPolicy::Never? (y/n)"
215+
);
216+
stdin.write_all("y\n".as_bytes()).expect("Failed to write to stdin");
217+
208218
assert_eq!(
209219
&stdout.next().unwrap().unwrap(),
210220
"Are these the correct pivot args:"
@@ -213,8 +223,8 @@ async fn standard_boot_e2e() {
213223
&stdout.next().unwrap().unwrap(),
214224
"[\"--msg\", \"testing420\"]?"
215225
);
216-
assert_eq!(&stdout.next().unwrap().unwrap(), "(yes/no)");
217-
stdin.write_all("yes\n".as_bytes()).expect("Failed to write to stdin");
226+
assert_eq!(&stdout.next().unwrap().unwrap(), "(y/n)");
227+
stdin.write_all("y\n".as_bytes()).expect("Failed to write to stdin");
218228

219229
// Wait for the command to write the approval and exit
220230
assert!(child.wait().unwrap().success());
@@ -390,19 +400,19 @@ async fn standard_boot_e2e() {
390400
// Answer prompts with yes
391401
assert_eq!(
392402
&stdout.next().unwrap().unwrap(),
393-
"Is this the correct namespace name: quit-coding-to-vape? (yes/no)"
403+
"Is this the correct namespace name: quit-coding-to-vape? (y/n)"
394404
);
395405
stdin.write_all("yes\n".as_bytes()).expect("Failed to write to stdin");
396406

397407
assert_eq!(
398408
&stdout.next().unwrap().unwrap(),
399-
"Is this the correct namespace nonce: 2? (yes/no)"
409+
"Is this the correct namespace nonce: 2? (y/n)"
400410
);
401411
stdin.write_all("yes\n".as_bytes()).expect("Failed to write to stdin");
402412

403413
assert_eq!(
404414
&stdout.next().unwrap().unwrap(),
405-
"Does this AWS IAM role belong to the intended organization: arn:aws:iam::123456789012:role/Webserver? (yes/no)"
415+
"Does this AWS IAM role belong to the intended organization: arn:aws:iam::123456789012:role/Webserver? (y/n)"
406416
);
407417
stdin.write_all("yes\n".as_bytes()).expect("Failed to write to stdin");
408418

src/integration/tests/preprod_sharding.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,14 @@ fn preprod_reshard_ceremony() {
8888
.unwrap();
8989

9090
// For each of the enclaves...
91-
for enclave_name in
92-
["ump", "evm-parser", "notarizer", "signer", "tls-fetcher", "deploy-test"]
93-
{
91+
for enclave_name in [
92+
"ump",
93+
"evm-parser",
94+
"notarizer",
95+
"signer",
96+
"tls-fetcher",
97+
"deploy-test",
98+
] {
9499
// Decrypt the old dev share and assert that the resulting quorum key
95100
// has the right public key. Decrypted dev shares are _basically_ master
96101
// seeds. They're just have a "01" prefix because it's the one and only

src/qos_client/src/cli/services.rs

+111-23
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,7 @@ where
921921
// Check the namespace name
922922
{
923923
let prompt = format!(
924-
"Is this the correct namespace name: {}? (yes/no)",
924+
"Is this the correct namespace name: {}? (y/n)",
925925
manifest.namespace.name
926926
);
927927
if !prompter.prompt_is_yes(&prompt) {
@@ -932,7 +932,7 @@ where
932932
// Check the namespace nonce
933933
{
934934
let prompt = format!(
935-
"Is this the correct namespace nonce: {}? (yes/no)",
935+
"Is this the correct namespace nonce: {}? (y/n)",
936936
manifest.namespace.nonce
937937
);
938938
if !prompter.prompt_is_yes(&prompt) {
@@ -943,7 +943,7 @@ where
943943
// Check pivot restart policy
944944
{
945945
let prompt = format!(
946-
"Is this the correct pivot restart policy: {:?}? (yes/no)",
946+
"Is this the correct pivot restart policy: {:?}? (y/n)",
947947
manifest.pivot.restart
948948
);
949949
if !prompter.prompt_is_yes(&prompt) {
@@ -954,7 +954,7 @@ where
954954
// Check pivot arguments
955955
{
956956
let prompt = format!(
957-
"Are these the correct pivot args:\n{:?}?\n(yes/no)",
957+
"Are these the correct pivot args:\n{:?}?\n(y/n)",
958958
manifest.pivot.args
959959
);
960960
if !prompter.prompt_is_yes(&prompt) {
@@ -1352,7 +1352,7 @@ where
13521352
// Check the namespace name
13531353
{
13541354
let prompt = format!(
1355-
"Is this the correct namespace name: {}? (yes/no)",
1355+
"Is this the correct namespace name: {}? (y/n)",
13561356
manifest_envelope.manifest.namespace.name
13571357
);
13581358
if !prompter.prompt_is_yes(&prompt) {
@@ -1363,7 +1363,7 @@ where
13631363
// Check the namespace nonce
13641364
{
13651365
let prompt = format!(
1366-
"Is this the correct namespace nonce: {}? (yes/no)",
1366+
"Is this the correct namespace nonce: {}? (y/n)",
13671367
manifest_envelope.manifest.namespace.nonce
13681368
);
13691369
if !prompter.prompt_is_yes(&prompt) {
@@ -1374,7 +1374,7 @@ where
13741374
// Check that the IAM role is correct
13751375
{
13761376
let prompt = format!(
1377-
"Does this AWS IAM role belong to the intended organization: {pcr3_preimage}? (yes/no)"
1377+
"Does this AWS IAM role belong to the intended organization: {pcr3_preimage}? (y/n)"
13781378
);
13791379
if !prompter.prompt_is_yes(&prompt) {
13801380
return false;
@@ -1393,7 +1393,7 @@ where
13931393
let approvers = approvers.join("\n");
13941394

13951395
let prompt = format!(
1396-
"The following manifest set members approved:\n{approvers}\nIs this ok? (yes/no)"
1396+
"The following manifest set members approved:\n{approvers}\nIs this ok? (y/n)"
13971397
);
13981398

13991399
if !prompter.prompt_is_yes(&prompt) {
@@ -1738,9 +1738,8 @@ pub(crate) fn shamir_reconstruct(
17381738
})
17391739
.collect::<Result<Vec<Vec<u8>>, Error>>()?;
17401740

1741-
let secret = Zeroizing::new(
1742-
qos_crypto::shamir::shares_reconstruct(shares).unwrap(),
1743-
);
1741+
let secret =
1742+
Zeroizing::new(qos_crypto::shamir::shares_reconstruct(shares).unwrap());
17441743

17451744
write_with_msg(output_path.as_ref(), &secret, "Reconstructed secret");
17461745

@@ -2129,7 +2128,26 @@ where
21292128
}
21302129

21312130
fn prompt_is_yes(&mut self, question: &str) -> bool {
2132-
self.prompt(question) == "yes"
2131+
// Fixed amount of attempts to avoid a "while true" loop
2132+
let mut attempts = 3;
2133+
// First prompt is the question. Subsequent prompts (if any) are the reminder to answer either yes or no.
2134+
let mut prompt = question;
2135+
2136+
while attempts > 0 {
2137+
let answer = self.prompt(prompt);
2138+
2139+
if ["yes", "Yes", "YES", "Y", "y"].contains(&answer.as_ref()) {
2140+
return true;
2141+
}
2142+
2143+
if ["no", "No", "NO", "N", "n"].contains(&answer.as_ref()) {
2144+
return false;
2145+
}
2146+
2147+
attempts -= 1;
2148+
prompt = "Please answer with either \"yes\" (y) or \"no\" (n)";
2149+
}
2150+
false
21332151
}
21342152
}
21352153

@@ -2557,7 +2575,7 @@ mod tests {
25572575
let Setup { manifest, .. } = setup();
25582576

25592577
let mut vec_out: Vec<u8> = vec![];
2560-
let vec_in = "ye\n".as_bytes();
2578+
let vec_in = "No\n".as_bytes();
25612579

25622580
let mut prompter =
25632581
Prompter { reader: vec_in, writer: &mut vec_out };
@@ -2568,7 +2586,10 @@ mod tests {
25682586
));
25692587

25702588
let output = String::from_utf8(vec_out).unwrap();
2571-
assert_eq!(&output, "Is this the correct namespace name: test-namespace? (yes/no)\n");
2589+
assert_eq!(
2590+
&output,
2591+
"Is this the correct namespace name: test-namespace? (y/n)\n"
2592+
);
25722593
}
25732594

25742595
#[test]
@@ -2591,7 +2612,7 @@ mod tests {
25912612

25922613
assert_eq!(
25932614
output[1],
2594-
"Is this the correct namespace nonce: 2? (yes/no)"
2615+
"Is this the correct namespace nonce: 2? (y/n)"
25952616
);
25962617
}
25972618

@@ -2615,7 +2636,7 @@ mod tests {
26152636

26162637
assert_eq!(
26172638
output[2],
2618-
"Is this the correct pivot restart policy: RestartPolicy::Never? (yes/no)"
2639+
"Is this the correct pivot restart policy: RestartPolicy::Never? (y/n)"
26192640
);
26202641
}
26212642

@@ -2639,7 +2660,7 @@ mod tests {
26392660

26402661
assert_eq!(output[3], "Are these the correct pivot args:");
26412662
assert_eq!(output[4], "[\"--option1\", \"argument\"]?");
2642-
assert_eq!(output[5], "(yes/no)");
2663+
assert_eq!(output[5], "(y/n)");
26432664
}
26442665
}
26452666

@@ -2690,7 +2711,7 @@ mod tests {
26902711
.get_mut(0)
26912712
.unwrap()
26922713
.member
2693-
.alias = "yoloswag420blazeit".to_string();
2714+
.alias = "not-a-member".to_string();
26942715

26952716
let member = share_set.members[0].clone();
26962717
assert!(!proxy_re_encrypt_share_programmatic_verifications(
@@ -2755,6 +2776,41 @@ mod tests {
27552776
));
27562777
}
27572778

2779+
#[test]
2780+
fn accepts_with_some_typos_from_operator() {
2781+
let Setup { manifest_envelope, .. } = setup();
2782+
2783+
let mut vec_out: Vec<u8> = vec![];
2784+
// Try all the accepted yes variants: y, yes, Yes, and YES!
2785+
let vec_in = "y\nyes\nyea\ntes\nYes\nYES\n".as_bytes();
2786+
2787+
let mut prompter =
2788+
Prompter { reader: vec_in, writer: &mut vec_out };
2789+
2790+
assert!(proxy_re_encrypt_share_human_verifications(
2791+
&manifest_envelope,
2792+
"pr3",
2793+
&mut prompter
2794+
));
2795+
2796+
let output = String::from_utf8(vec_out).unwrap();
2797+
let output: Vec<_> = output.lines().collect();
2798+
assert_eq!(
2799+
output,
2800+
vec![
2801+
"Is this the correct namespace name: test-namespace? (y/n)",
2802+
"Is this the correct namespace nonce: 2? (y/n)",
2803+
"Does this AWS IAM role belong to the intended organization: pr3? (y/n)",
2804+
"Please answer with either \"yes\" (y) or \"no\" (n)",
2805+
"Please answer with either \"yes\" (y) or \"no\" (n)",
2806+
"The following manifest set members approved:",
2807+
"\talias: 0",
2808+
"\talias: 1",
2809+
"Is this ok? (y/n)",
2810+
]
2811+
);
2812+
}
2813+
27582814
#[test]
27592815
fn exits_early_bad_namespace_name() {
27602816
let Setup { manifest_envelope, .. } = setup();
@@ -2772,7 +2828,10 @@ mod tests {
27722828
));
27732829

27742830
let output = String::from_utf8(vec_out).unwrap();
2775-
assert_eq!(&output, "Is this the correct namespace name: test-namespace? (yes/no)\n");
2831+
assert_eq!(
2832+
&output,
2833+
"Is this the correct namespace name: test-namespace? (y/n)\n"
2834+
);
27762835
}
27772836

27782837
#[test]
@@ -2795,7 +2854,7 @@ mod tests {
27952854
let output: Vec<_> = output.lines().collect();
27962855
assert_eq!(
27972856
output.last().unwrap(),
2798-
&"Is this the correct namespace nonce: 2? (yes/no)"
2857+
&"Is this the correct namespace nonce: 2? (y/n)"
27992858
);
28002859
}
28012860

@@ -2819,7 +2878,7 @@ mod tests {
28192878
let output: Vec<_> = output.lines().collect();
28202879
assert_eq!(
28212880
output.last().unwrap(),
2822-
&"Does this AWS IAM role belong to the intended organization: pr3? (yes/no)"
2881+
&"Does this AWS IAM role belong to the intended organization: pr3? (y/n)"
28232882
);
28242883
}
28252884

@@ -2828,7 +2887,7 @@ mod tests {
28282887
let Setup { manifest_envelope, .. } = setup();
28292888

28302889
let mut vec_out: Vec<u8> = vec![];
2831-
let vec_in = "yes\nyes\nyes\ny".as_bytes();
2890+
let vec_in = "yes\nyes\nyes\nno".as_bytes();
28322891

28332892
let mut prompter =
28342893
Prompter { reader: vec_in, writer: &mut vec_out };
@@ -2848,8 +2907,37 @@ mod tests {
28482907
);
28492908
assert_eq!(output[4], "\talias: 0");
28502909
assert_eq!(output[5], "\talias: 1");
2851-
assert_eq!(output[6], "Is this ok? (yes/no)");
2910+
assert_eq!(output[6], "Is this ok? (y/n)");
28522911
assert_eq!(output.len(), 7);
28532912
}
2913+
2914+
#[test]
2915+
fn exits_after_three_hesitations() {
2916+
let Setup { manifest_envelope, .. } = setup();
2917+
2918+
let mut vec_out: Vec<u8> = vec![];
2919+
let vec_in = "maybe\ndunno\nunsure\n".as_bytes();
2920+
2921+
let mut prompter =
2922+
Prompter { reader: vec_in, writer: &mut vec_out };
2923+
2924+
assert!(!proxy_re_encrypt_share_human_verifications(
2925+
&manifest_envelope,
2926+
"pr3",
2927+
&mut prompter
2928+
));
2929+
2930+
let output = String::from_utf8(vec_out).unwrap();
2931+
let output: Vec<_> = output.lines().collect();
2932+
2933+
assert_eq!(
2934+
output,
2935+
vec![
2936+
"Is this the correct namespace name: test-namespace? (y/n)",
2937+
"Please answer with either \"yes\" (y) or \"no\" (n)",
2938+
"Please answer with either \"yes\" (y) or \"no\" (n)",
2939+
]
2940+
);
2941+
}
28542942
}
28552943
}

0 commit comments

Comments
 (0)