Moved to client.rs and added docs.

Signed-off-by: Zachary Edgell <zacharyedgell@gmail.com>
This commit is contained in:
Zachary Edgell 2024-03-23 00:06:08 -04:00
parent 8371c9070e
commit 4dfb399e25
4 changed files with 130 additions and 89 deletions

View File

@ -32,6 +32,9 @@ timeout_seconds: 90
-->
```bash
mkdir -p keys
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out keys/rsa-private-key.pem
openssl rand -out keys/symmetric-key-256 32
dapr run -f .
```

View File

@ -1,12 +1,18 @@
use std::collections::HashMap;
use async_trait::async_trait;
use futures::StreamExt;
use prost_types::Any;
use serde::{Deserialize, Serialize};
use tonic::Streaming;
use tonic::{transport::Channel as TonicChannel, Request};
use tonic::{Request, transport::Channel as TonicChannel};
use tonic::{Status, Streaming};
use tonic::codegen::tokio_stream;
use crate::dapr::dapr::proto::{common::v1 as common_v1, runtime::v1 as dapr_v1};
use crate::dapr::dapr::proto::common::v1::StreamPayload;
use crate::dapr::dapr::proto::runtime::v1::{
DecryptRequest, DecryptRequestOptions, EncryptRequest, EncryptRequestOptions,
};
use crate::error::Error;
#[derive(Clone)]
@ -627,3 +633,115 @@ where
}
}
}
impl Client<TonicClient> {
/// Encrypt binary data using Dapr. returns Vec<StreamPayload> to be used in decrypt method
///
/// # Arguments
///
/// * `payload` - A Reference to the data to encrypt, should impl Into<Vec<u8>>
/// * `request_option` - Encryption request options.
///
/// # Example
/// ```
/// let encrypted = client
/// .encrypt(
/// &"Test".to_string(),
/// EncryptRequestOptions {
/// component_name: "localstorage".to_string(),
/// key_name: "rsa-private-key.pem".to_string(),
/// key_wrap_algorithm: "RSA".to_string(),
/// data_encryption_cipher: "aes-gcm".to_string(),
/// omit_decryption_key_name: false,
/// decryption_key_name: "rsa-private-key.pem".to_string(),
/// },
/// )
/// .await
/// .unwrap();
/// ```
pub async fn encrypt<T>(
&mut self,
payload: &T,
request_options: EncryptRequestOptions,
) -> Result<Vec<StreamPayload>, Status>
where
T: Into<Vec<u8>> + Clone,
{
let stream_payload = StreamPayload {
data: payload.clone().into(),
seq: 0,
};
let request = EncryptRequest {
options: Some(request_options),
payload: Some(stream_payload),
};
let request = Request::new(tokio_stream::iter([request]));
let stream = self.0.encrypt_alpha1(request).await?;
let mut stream = stream.into_inner();
let mut return_data = vec![];
while let Some(resp) = stream.next().await {
if let Ok(resp) = resp {
if let Some(data) = resp.payload {
return_data.push(data)
}
}
}
Ok(return_data)
}
/// Decrypt binary data using Dapr. returns Vec<u8>.
///
/// # Arguments
///
/// * `encrypted` - Encrypted data usually returned from encrypted, Vec<StreamPayload>
/// * `options` - Decryption request options.
///
/// # Example
/// ```
/// let decrypted = client
/// .decrypt(
/// encrypted,
/// DecryptRequestOptions {
/// component_name: "localstorage".to_string(),
/// key_name: "rsa-private-key.pem".to_string(),
/// },
/// )
/// .await
/// .unwrap();
/// ```
pub async fn decrypt(
&mut self,
encrypted: Vec<StreamPayload>,
options: DecryptRequestOptions,
) -> Result<Vec<u8>, Status> {
let requested_items: Vec<DecryptRequest> = encrypted
.iter()
.enumerate()
.map(|(i, item)| {
if i == 0 {
DecryptRequest {
options: Some(options.clone()),
payload: Some(item.clone()),
}
} else {
DecryptRequest {
options: None,
payload: Some(item.clone()),
}
}
})
.collect();
let request = Request::new(tokio_stream::iter(requested_items));
let stream = self.0.decrypt_alpha1(request).await?;
let mut stream = stream.into_inner();
let mut data = vec![];
while let Some(resp) = stream.next().await {
if let Ok(resp) = resp {
if let Some(mut payload) = resp.payload {
data.append(payload.data.as_mut())
}
}
}
Ok(data)
}
}

View File

@ -1,78 +0,0 @@
use futures::StreamExt;
use tonic::codegen::tokio_stream;
use tonic::{Request, Status};
use crate::client::TonicClient;
use crate::dapr::dapr::proto::common::v1::StreamPayload;
use crate::dapr::dapr::proto::runtime::v1::{
DecryptRequest, DecryptRequestOptions, EncryptRequest, EncryptRequestOptions,
};
use crate::Client;
impl Client<TonicClient> {
pub async fn encrypt<T>(
&mut self,
payload: &T,
request_options: EncryptRequestOptions,
) -> Result<Vec<StreamPayload>, Status>
where
T: Into<Vec<u8>> + Clone,
{
let stream_payload = StreamPayload {
data: payload.clone().into(),
seq: 0,
};
let request = EncryptRequest {
options: Some(request_options),
payload: Some(stream_payload),
};
let request = Request::new(tokio_stream::iter([request]));
let stream = self.0.encrypt_alpha1(request).await?;
let mut stream = stream.into_inner();
let mut return_data = vec![];
while let Some(resp) = stream.next().await {
if let Ok(resp) = resp {
if let Some(data) = resp.payload {
return_data.push(data)
}
}
}
Ok(return_data)
}
pub async fn decrypt(
&mut self,
encrypted: Vec<StreamPayload>,
options: DecryptRequestOptions,
) -> Result<Vec<u8>, Status> {
let requested_items: Vec<DecryptRequest> = encrypted
.iter()
.enumerate()
.map(|(i, item)| {
if i == 0 {
DecryptRequest {
options: Some(options.clone()),
payload: Some(item.clone()),
}
} else {
DecryptRequest {
options: None,
payload: Some(item.clone()),
}
}
})
.collect();
let request = Request::new(tokio_stream::iter(requested_items));
let stream = self.0.decrypt_alpha1(request).await?;
let mut stream = stream.into_inner();
let mut data = vec![];
while let Some(resp) = stream.next().await {
if let Ok(resp) = resp {
if let Some(mut payload) = resp.payload {
data.append(payload.data.as_mut())
}
}
}
Ok(data)
}
}

View File

@ -1,15 +1,13 @@
pub mod appcallback;
pub mod client;
pub mod crypto;
pub mod dapr;
pub mod error;
pub mod server;
extern crate dapr_macros;
pub use dapr_macros::actor;
pub use serde;
pub use serde_json;
pub use client::Client;
extern crate dapr_macros;
pub use dapr_macros::actor;
pub mod appcallback;
pub mod client;
pub mod dapr;
pub mod error;
pub mod server;