Skip to content

Commit

Permalink
feat(rust): return enrollment ticket hex-encoded
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianbenavides committed Oct 21, 2024
1 parent 5f7ec79 commit 191ff03
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 19 deletions.
49 changes: 39 additions & 10 deletions implementations/rust/ockam/ockam_api/src/cli_state/enrollments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,13 @@ impl FromStr for ExportedEnrollmentTicket {
type Err = ApiError;

fn from_str(contents: &str) -> std::result::Result<Self, Self::Err> {
// Try to hex-decode the contents
let contents = match hex::decode(contents) {
Ok(decoded) => String::from_utf8(decoded)
.map_err(|_| ApiError::core("Failed to hex decode enrollment ticket"))?,
Err(_) => contents.to_string(),
};

// Decode as comma-separated text
let values: Vec<&str> = contents.split(',').collect();
if values.len() < Self::MANDATORY_FIELDS_NUM {
Expand Down Expand Up @@ -378,19 +385,20 @@ impl FromStr for ExportedEnrollmentTicket {

impl Display for ExportedEnrollmentTicket {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
let mut output = String::new();
output.push_str(&format!(
"{},{},{},{},{},{}",
self.project_route.route,
self.project_identifier,
self.project_name,
String::from(&self.one_time_code),
self.project_change_history,
self.authority_change_history,
)?;
));
if let Some(authority_route) = &self.authority_route {
write!(f, ",{}", authority_route)?;
output.push_str(&format!(",{}", authority_route));
}
write!(f, "{}", hex::encode(output))?;
Ok(())
}
}
Expand Down Expand Up @@ -601,25 +609,46 @@ impl EnrollmentTicket {
Some(self.authority_route.to_string()),
))
}

pub fn export_legacy(self) -> Result<LegacyEnrollmentTicket> {
let project = self.project()?;
Ok(LegacyEnrollmentTicket::new(
self.one_time_code,
Some(project),
))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[tokio::test]
async fn text_export_as_legacy() {
let ticket = ExportedEnrollmentTicket::new_test();
let exported = ticket.import().await.unwrap();
let legacy = exported.clone().export_legacy().unwrap();
assert_eq!(legacy.one_time_code, exported.one_time_code);
assert_eq!(legacy.project.unwrap(), exported.project().unwrap());
}

#[test]
fn test_exported_enrollment_ticket() {
let exported = ExportedEnrollmentTicket::new_test();
let encoded = exported.to_string();
assert!(encoded.contains(&String::from(&exported.one_time_code)));
assert!(encoded.contains(&exported.project_route.id));
assert!(encoded.contains(&exported.project_route.route.to_string()));
assert!(encoded.contains(&exported.project_name));
assert!(encoded.contains(&exported.project_change_history));
assert!(encoded.contains(&exported.authority_change_history));
let hex_decoded = String::from_utf8(hex::decode(&encoded).unwrap()).unwrap();
assert!(hex_decoded.contains(&String::from(&exported.one_time_code)));
assert!(hex_decoded.contains(&exported.project_route.id));
assert!(hex_decoded.contains(&exported.project_route.route.to_string()));
assert!(hex_decoded.contains(&exported.project_name));
assert!(hex_decoded.contains(&exported.project_change_history));
assert!(hex_decoded.contains(&exported.authority_change_history));

let decoded = ExportedEnrollmentTicket::from_str(&encoded).unwrap();
assert_eq!(decoded, exported);

let decoded = ExportedEnrollmentTicket::from_str(&hex_decoded).unwrap();
assert_eq!(decoded, exported);
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@ impl Command for TicketCommand {
.as_ref()
.ok_or(miette!("missing authority's change history"))?,
project.authority_access_route.as_ref(),
);
)
.import()
.await?
.export_legacy()?
.hex_encoded()?;

opts.terminal
.write_line(fmt_ok!("Created enrollment ticket\n"))?;
Expand Down
15 changes: 7 additions & 8 deletions implementations/rust/ockam/ockam_command/src/value_parsers.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use crate::util::parsers::hostname_parser;
use crate::CommandGlobalOpts;
use colorful::Colorful;
use miette::{miette, Context, IntoDiagnostic};
use ockam_api::cli_state::{EnrollmentTicket, ExportedEnrollmentTicket, LegacyEnrollmentTicket};
use ockam_api::fmt_warn;
use std::str::FromStr;
use tracing::trace;
use url::Url;
Expand All @@ -27,19 +25,20 @@ where

/// Parse an enrollment ticket given a path, a URL or encoded string
pub async fn parse_enrollment_ticket(
opts: &CommandGlobalOpts,
_opts: &CommandGlobalOpts,
value: &str,
) -> miette::Result<EnrollmentTicket> {
trace!(%value, "parsing enrollment ticket");
let contents = parse_string_or_path_or_url(value).await?;

// Try to parse it using the old format
if let Ok(ticket) = LegacyEnrollmentTicket::from_hex(&contents) {
opts.terminal.write_line(fmt_warn!(
"The enrollment ticket was generated from an old Ockam version"
))?;
opts.terminal
.write_line(fmt_warn!("Please make sure the machine that generated the ticket is using the latest Ockam version"))?;
// TODO: disabled until release 0.138.0
// opts.terminal.write_line(fmt_warn!(
// "The enrollment ticket was generated from an old Ockam version"
// ))?;
// opts.terminal
// .write_line(fmt_warn!("Please make sure the machine that generated the ticket is using the latest Ockam version"))?;
return Ok(EnrollmentTicket::new_from_legacy(ticket).await?);
}

Expand Down

0 comments on commit 191ff03

Please sign in to comment.