Skip to content

Commit

Permalink
chore: remove redundant payload struct
Browse files Browse the repository at this point in the history
  • Loading branch information
dariusc93 committed Dec 8, 2024
1 parent 5888108 commit e6d61ff
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 140 deletions.
76 changes: 0 additions & 76 deletions extensions/warp-ipfs/src/shuttle/identity.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
use crate::store::DidExt;
use chrono::{DateTime, Utc};
use ipld_core::cid::Cid;
use rust_ipfs::Keypair;
use serde::{Deserialize, Serialize};
use warp::crypto::DID;

use crate::store::document::identity::IdentityDocument;

Expand All @@ -17,75 +13,3 @@ pub struct IdentityDag {
#[serde(skip_serializing_if = "Option::is_none")]
pub mailbox: Option<Cid>,
}

#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Hash, Eq)]
#[serde(rename_all = "lowercase")]
pub enum RequestEvent {
/// Event indicating a friend request
Request,
/// Event accepting the request
Accept,
/// Remove identity as a friend
Remove,
/// Reject friend request, if any
Reject,
/// Retract a sent friend request
Retract,
/// Block user
Block,
/// Unblock user
Unblock,
}

#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
pub struct RequestPayload {
pub sender: DID,
pub event: RequestEvent,
pub created: DateTime<Utc>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub original_signature: Vec<u8>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub signature: Vec<u8>,
}

impl std::hash::Hash for RequestPayload {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.sender.hash(state);
}
}

impl PartialOrd for RequestPayload {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}

impl Ord for RequestPayload {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.created.cmp(&other.created)
}
}

impl RequestPayload {
pub fn sign(mut self, keypair: &Keypair) -> Result<Self, Box<dyn std::error::Error>> {
if !self.signature.is_empty() {
return Err(Box::new(warp::error::Error::InvalidSignature));
}

let bytes = serde_json::to_vec(&self)?;
let signature = keypair.sign(&bytes)?;
self.signature = signature;
Ok(self)
}

pub fn verify(&self) -> Result<(), Box<dyn std::error::Error>> {
let pk = self.sender.to_public_key()?;
let mut doc = self.clone();
let signature = std::mem::take(&mut doc.signature);
let bytes = serde_json::to_vec(&doc)?;
if !pk.verify(&bytes, &signature) {
return Err(Box::new(warp::error::Error::InvalidSignature));
}
Ok(())
}
}
14 changes: 9 additions & 5 deletions extensions/warp-ipfs/src/shuttle/identity/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ use rust_ipfs::Keypair;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use warp::{crypto::DID, multipass::identity::ShortId};

use crate::store::identity::RequestResponsePayload;
use crate::store::{
document::identity::IdentityDocument,
payload::{PayloadBuilder, PayloadMessage},
};

use super::RequestPayload;

pub fn payload_message_construct<T: Serialize + DeserializeOwned + Clone>(
keypair: &Keypair,
cosigner: Option<&Keypair>,
Expand Down Expand Up @@ -98,15 +97,20 @@ impl From<LookupResponse> for Response {
#[serde(rename_all = "snake_case")]
pub enum Mailbox {
FetchAll,
FetchFrom { did: DID },
Send { did: DID, request: RequestPayload },
FetchFrom {
did: DID,
},
Send {
did: DID,
request: RequestResponsePayload,
},
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum MailboxResponse {
Receive {
list: Vec<RequestPayload>,
list: Vec<RequestResponsePayload>,
remaining: usize,
},
Removed,
Expand Down
32 changes: 23 additions & 9 deletions extensions/warp-ipfs/src/shuttle/store/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ use rust_ipfs::{Ipfs, IpfsPath};
use tokio::sync::RwLock;
use warp::{crypto::DID, error::Error};

use super::root::RootStorage;
use crate::store::identity::RequestResponsePayload;
use crate::{
shuttle::identity::{protocol::Lookup, RequestPayload},
shuttle::identity::protocol::Lookup,
store::{
document::{identity::IdentityDocument, RootDocument},
DidExt,
},
};

use super::root::RootStorage;

#[derive(Debug, Clone)]
pub struct IdentityStorage {
inner: Arc<RwLock<IdentityStorageInner>>,
Expand Down Expand Up @@ -56,12 +56,19 @@ impl IdentityStorage {
inner.contains(did).await
}

pub async fn fetch_mailbox(&self, did: DID) -> Result<(Vec<RequestPayload>, usize), Error> {
pub async fn fetch_mailbox(
&self,
did: DID,
) -> Result<(Vec<RequestResponsePayload>, usize), Error> {
let inner = &mut *self.inner.write().await;
inner.fetch_requests(did).await
}

pub async fn deliver_request(&self, to: &DID, request: &RequestPayload) -> Result<(), Error> {
pub async fn deliver_request(
&self,
to: &DID,
request: &RequestResponsePayload,
) -> Result<(), Error> {
let inner = &mut *self.inner.write().await;
inner.deliver_request(to, request).await
}
Expand Down Expand Up @@ -374,7 +381,10 @@ impl IdentityStorageInner {
Ok(list)
}

async fn fetch_requests(&mut self, did: DID) -> Result<(Vec<RequestPayload>, usize), Error> {
async fn fetch_requests(
&mut self,
did: DID,
) -> Result<(Vec<RequestResponsePayload>, usize), Error> {
let key_str = did.to_string();
let mut list: BTreeMap<String, Cid> = match self.mailbox {
Some(cid) => self
Expand All @@ -392,7 +402,7 @@ impl IdentityStorageInner {
.ipfs
.get_dag(*cid)
.local()
.deserialized::<Vec<RequestPayload>>()
.deserialized::<Vec<RequestResponsePayload>>()
.await
.unwrap_or_default(),
None => return Ok((Vec::new(), 0)),
Expand Down Expand Up @@ -432,7 +442,11 @@ impl IdentityStorageInner {
Ok((requests, remaining))
}

async fn deliver_request(&mut self, to: &DID, request: &RequestPayload) -> Result<(), Error> {
async fn deliver_request(
&mut self,
to: &DID,
request: &RequestResponsePayload,
) -> Result<(), Error> {
if !self.contains(to).await {
return Err(Error::IdentityDoesntExist);
}
Expand All @@ -455,7 +469,7 @@ impl IdentityStorageInner {
.ipfs
.get_dag(*cid)
.local()
.deserialized::<Vec<RequestPayload>>()
.deserialized::<Vec<RequestResponsePayload>>()
.await
.unwrap_or_default(),
None => Vec::new(),
Expand Down
56 changes: 6 additions & 50 deletions extensions/warp-ipfs/src/store/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use tokio::sync::RwLock;
use tracing::Span;
use web_time::Instant;

use crate::shuttle::identity::{RequestEvent, RequestPayload};
use warp::multipass::identity::{FriendRequest, Identifier, ShortId};
use warp::multipass::GetIdentity;
use warp::{
Expand Down Expand Up @@ -188,56 +187,15 @@ pub struct RequestResponsePayload {
pub signature: Option<Vec<u8>>,
}

impl TryFrom<RequestResponsePayload> for RequestPayload {
type Error = Error;
fn try_from(req: RequestResponsePayload) -> Result<Self, Self::Error> {
req.verify()?;
let event = match req.event {
Event::Request => RequestEvent::Request,
Event::Accept => RequestEvent::Accept,
Event::Remove => RequestEvent::Remove,
Event::Reject => RequestEvent::Reject,
Event::Retract => RequestEvent::Retract,
Event::Block => RequestEvent::Block,
Event::Unblock => RequestEvent::Unblock,
Event::Response => return Err(Error::OtherWithContext("Invalid event type".into())),
};

let payload = RequestPayload {
sender: req.sender,
event,
created: req.created.ok_or(Error::InvalidConversion)?,
original_signature: req.signature.ok_or(Error::InvalidSignature)?,
signature: vec![],
};

Ok(payload)
impl PartialOrd for RequestResponsePayload {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}

impl TryFrom<RequestPayload> for RequestResponsePayload {
type Error = Box<dyn std::error::Error>;
fn try_from(req: RequestPayload) -> Result<Self, Self::Error> {
req.verify()?;
let event = match req.event {
RequestEvent::Request => Event::Request,
RequestEvent::Accept => Event::Accept,
RequestEvent::Remove => Event::Remove,
RequestEvent::Reject => Event::Reject,
RequestEvent::Retract => Event::Retract,
RequestEvent::Block => Event::Block,
RequestEvent::Unblock => Event::Unblock,
};

let payload = RequestResponsePayload {
version: RequestResponsePayloadVersion::V1,
sender: req.sender,
event,
created: Some(req.created),
signature: Some(req.original_signature),
};

Ok(payload)
impl Ord for RequestResponsePayload {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.created.cmp(&other.created)
}
}

Expand Down Expand Up @@ -2083,8 +2041,6 @@ impl IdentityStore {
request: RequestResponsePayload,
) -> Result<(), Error> {
if let DiscoveryConfig::Shuttle { addresses } = self.discovery.discovery_config() {
let request: RequestPayload = request.try_into()?;

let request = request
.sign(self.root_document().keypair())
.map_err(|e| anyhow::anyhow!("{e}"))?;
Expand Down

0 comments on commit e6d61ff

Please sign in to comment.