Skip to content

Commit

Permalink
mv Encrypted Type to utils, use in Output
Browse files Browse the repository at this point in the history
  • Loading branch information
DougAnderson444 committed Jun 27, 2024
1 parent 7c2eba0 commit 56d014f
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 80 deletions.
41 changes: 1 addition & 40 deletions crates/seed-keeper-wit-ui/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,46 +35,7 @@ impl From<wurbo_types::Input> for Input {

impl From<&wurbo_types::Content> for Input {
fn from(content: &wurbo_types::Content) -> Self {
// if context.load.encrypted is Some, use it,
// the rest of Input is taken from context.input
println!("context.load: {:?}", content.load);
let encrypted = match &content.load {
Some(loaded_str) => {
println!("loaded_str: {:?}", loaded_str);
// try to parse the JSON
let v: serde_json::Value =
serde_json::from_str(&loaded_str).unwrap_or(serde_json::Value::Null);

println!("v: {:?}", v);
println!("v[\"encrypted\"]: {:?}", v["encrypted"]);

match &v["encrypted"] {
serde_json::Value::Array(encrypted) => {
println!("encrypted array: {:?}", encrypted);
Some(
// encrypted into Vec<u8>
encrypted
.iter()
.map(|v| v.as_u64().unwrap_or_default() as u8)
.collect::<Vec<u8>>(),
)
}
// or it could be astring of numbers, likw 1,2,3,4,5...
serde_json::Value::String(encrypted) => {
println!("encrypted string: {:?}", encrypted);
let encrypted = encrypted
.split(',')
.map(|v| v.parse::<u8>().unwrap_or_default())
.collect::<Vec<u8>>();
Some(encrypted)
}
_ => None,
}
}
None => None,
};

let encrypted: Encrypted = encrypted.into();
let encrypted = Encrypted::from(content);

Input(Some(wurbo_types::Input {
placeholder: content
Expand Down
5 changes: 3 additions & 2 deletions crates/seed-keeper-wit-ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod bindings;
mod input;
mod output;
mod page;
mod utils;

use input::Input;
use output::Output;
Expand All @@ -22,7 +23,7 @@ use bindings::seed_keeper::wit_ui::wurbo_types::{self, Context};
use wurbo::jinja::{Entry, Index, Rest, Templates};
use wurbo::prelude_bindgen;

use crate::output::Encrypted;
use crate::utils::Encrypted;

const INDEX_HTML: &str = "index.html";
const INPUT_HTML: &str = "input.html";
Expand Down Expand Up @@ -110,7 +111,7 @@ impl From<wurbo_types::Content> for StructContext {
input: Input::from(&content),
// We can use default for Output because the minijinja Object impl will
// calculate the values from the above inouts for us
output: Output::default(),
output: Output::from(&content),
target: None,
}
}
Expand Down
71 changes: 33 additions & 38 deletions crates/seed-keeper-wit-ui/src/output.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use super::*;

use base64ct::{Base64UrlUnpadded, Encoding};
/// Event types which can can emitted from this UI and listened by others
use seed_keeper_events::{Context, Message};

Expand Down Expand Up @@ -36,7 +35,7 @@ impl Output {
Ok(encrypted) => {
// if self.encrypted_seed is None, set it to the encrypted seed
if self.encrypted_seed.is_none() {
self.encrypted_seed = Encrypted(Some(encrypted.clone()));
self.encrypted_seed = Encrypted::from(Some(encrypted.clone()));
}

// if serde feature, emit the serialized encrypted seed as an event
Expand Down Expand Up @@ -80,6 +79,37 @@ impl From<Output> for Credentials {
}
}

// impl From<&Content> for Output {
impl From<&wurbo_types::Content> for Output {
fn from(content: &wurbo_types::Content) -> Self {
let encrypted = Encrypted::from(content);

let username: String = content.load.as_ref().map_or_else(
|| "".to_string(),
|loaded_str| {
let v: serde_json::Value =
serde_json::from_str(&loaded_str).unwrap_or(serde_json::Value::Null);

match &v["username"] {
serde_json::Value::String(username) => username.clone(),
_ => "".to_string(),
}
},
);

Output {
username,
password: content
.input
.as_ref()
.map(|c| c.placeholder.clone())
.unwrap_or_default(),
encrypted_seed: encrypted,
error_message: None,
}
}
}

/// Implement [Object] for Output so we can use minijina to automagically calculate the length
/// of the username and password concatenated
impl Object for Output {
Expand All @@ -91,7 +121,7 @@ impl Object for Output {
"password" => Some(Value::from(self.password.clone())),
// Show encrypted Vec as base64 string
"encrypted_seed" => match get_encrypted() {
Ok(encrypted) => Some(Value::from(Encrypted(Some(encrypted)).to_string())),
Ok(encrypted) => Some(Value::from(Encrypted::from(Some(encrypted)).to_string())),
_ => None,
},
"error_message" => match &self.error_message {
Expand All @@ -102,38 +132,3 @@ impl Object for Output {
}
}
}

/// [Encrypted] [Output] is the encrypted seed passed from the User, if any.
#[derive(Debug, Clone, Default)]
pub(super) struct Encrypted(Option<Vec<u8>>);

/// impl From Option<Vec<u8>> for Encrypted
impl From<Option<Vec<u8>>> for Encrypted {
fn from(context: Option<Vec<u8>>) -> Self {
Encrypted(context)
}
}

impl ToString for Encrypted {
fn to_string(&self) -> String {
// encode to base64
Base64UrlUnpadded::encode_string(&self.as_ref().unwrap_or(&vec![]))
}
}

/// Decode from base64 into bytes
impl From<&String> for Encrypted {
fn from(context: &String) -> Self {
Encrypted(Some(
Base64UrlUnpadded::decode_vec(context).unwrap_or_default(),
))
}
}

impl Deref for Encrypted {
type Target = Option<Vec<u8>>;

fn deref(&self) -> &Self::Target {
&self.0
}
}
75 changes: 75 additions & 0 deletions crates/seed-keeper-wit-ui/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//! This module contains the utility types and functions used in the seed-keeper-wit-ui crate.
use super::*;
use base64ct::{Base64UrlUnpadded, Encoding};

/// [Encrypted] [Output] is the encrypted seed passed from the User, if any.
#[derive(Debug, Clone, Default)]
pub(super) struct Encrypted(Option<Vec<u8>>);

/// impl From Option<Vec<u8>> for Encrypted
impl From<Option<Vec<u8>>> for Encrypted {
fn from(context: Option<Vec<u8>>) -> Self {
Encrypted(context)
}
}

impl ToString for Encrypted {
fn to_string(&self) -> String {
// encode to base64
Base64UrlUnpadded::encode_string(&self.as_ref().unwrap_or(&vec![]))
}
}

/// Decode from base64 into bytes
impl From<&String> for Encrypted {
fn from(context: &String) -> Self {
Encrypted(Some(
Base64UrlUnpadded::decode_vec(context).unwrap_or_default(),
))
}
}
impl From<&wurbo_types::Content> for Encrypted {
fn from(content: &wurbo_types::Content) -> Self {
// if context.load.encrypted is Some, use it,
// the rest of Input is taken from context.input
let encrypted = match &content.load {
Some(loaded_str) => {
// try to parse the JSON
let v: serde_json::Value =
serde_json::from_str(&loaded_str).unwrap_or(serde_json::Value::Null);

match &v["encrypted"] {
serde_json::Value::Array(encrypted) => {
Some(
// encrypted into Vec<u8>
encrypted
.iter()
.map(|v| v.as_u64().unwrap_or_default() as u8)
.collect::<Vec<u8>>(),
)
}
// or it could be astring of numbers, likw 1,2,3,4,5...
serde_json::Value::String(encrypted) => {
let encrypted = encrypted
.split(',')
.map(|v| v.parse::<u8>().unwrap_or_default())
.collect::<Vec<u8>>();
Some(encrypted)
}
_ => None,
}
}
None => None,
};

encrypted.into()
}
}

impl Deref for Encrypted {
type Target = Option<Vec<u8>>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

0 comments on commit 56d014f

Please sign in to comment.