Ordering auth methods in the CLI (#2508)

* rewriting ordering of authallowed enum
* ordering the authstate in the CLI

---------

Co-authored-by: William Brown <william@blackhats.net.au>
This commit is contained in:
James Hodgkinson 2024-02-15 12:31:01 +10:00 committed by GitHub
parent e880a63be4
commit 6b44495704
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 24 additions and 23 deletions

View file

@ -1012,30 +1012,26 @@ impl PartialEq for AuthAllowed {
}
}
impl From<&AuthAllowed> for u8 {
fn from(a: &AuthAllowed) -> u8 {
match a {
AuthAllowed::Anonymous => 0,
AuthAllowed::Password => 1,
AuthAllowed::BackupCode => 2,
AuthAllowed::Totp => 3,
AuthAllowed::Passkey(_) => 4,
AuthAllowed::SecurityKey(_) => 5,
}
}
}
impl Eq for AuthAllowed {}
impl Ord for AuthAllowed {
fn cmp(&self, other: &Self) -> Ordering {
if self.eq(other) {
Ordering::Equal
} else {
// Relies on the fact that match is executed in order!
match (self, other) {
(AuthAllowed::Anonymous, _) => Ordering::Less,
(_, AuthAllowed::Anonymous) => Ordering::Greater,
(AuthAllowed::Password, _) => Ordering::Less,
(_, AuthAllowed::Password) => Ordering::Greater,
(AuthAllowed::BackupCode, _) => Ordering::Less,
(_, AuthAllowed::BackupCode) => Ordering::Greater,
(AuthAllowed::Totp, _) => Ordering::Less,
(_, AuthAllowed::Totp) => Ordering::Greater,
(AuthAllowed::SecurityKey(_), _) => Ordering::Less,
(_, AuthAllowed::SecurityKey(_)) => Ordering::Greater,
(AuthAllowed::Passkey(_), _) => Ordering::Less,
// Unreachable
// (_, AuthAllowed::Passkey(_)) => Ordering::Greater,
}
}
let self_ord: u8 = self.into();
let other_ord: u8 = other.into();
self_ord.cmp(&other_ord)
}
}

View file

@ -1,4 +1,5 @@
use crate::common::OpType;
use std::cmp::Reverse;
use std::collections::BTreeMap;
use std::fs::{create_dir, File};
use std::io::{self, BufReader, BufWriter, ErrorKind, IsTerminal, Write};
@ -264,16 +265,18 @@ async fn process_auth_state(
}
_ => {
let mut options = Vec::new();
// because we want them in "most secure to least secure" order.
allowed.sort_unstable_by(|a, b| Reverse(a).cmp(&Reverse(b)));
for val in allowed.iter() {
options.push(val.to_string());
}
let msg = "Please choose what credential to provide:";
let msg = "Please choose which credential to provide:";
let selection = get_index_choice_dialoguer(msg, &options);
#[allow(clippy::expect_used)]
allowed
.get(selection)
.expect("can not fail - bounds already checked.")
.expect("Failed to select an authentication option!")
}
};
@ -391,7 +394,7 @@ impl LoginOpt {
};
// What auth mechanisms exist?
let mechs: Vec<_> = client
let mut mechs: Vec<_> = client
.auth_step_init(username)
.await
.unwrap_or_else(|e| {
@ -401,6 +404,8 @@ impl LoginOpt {
.into_iter()
.collect();
mechs.sort_unstable_by(|a, b| Reverse(a).cmp(&Reverse(b)));
let mech = match mechs.len() {
0 => {
error!("Error during authentication init phase: Server offered no authentication mechanisms");