use std::cmp::Ordering;
use std::fmt;
use crate::hex::to_hex;
use crate::network::auth::ConnectionAuthorizationType;
use crate::public_key::PublicKey;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum PeerAuthorizationToken {
Trust { peer_id: String },
Challenge { public_key: PublicKey },
}
impl PeerAuthorizationToken {
pub fn from_peer_id(peer_id: &str) -> Self {
PeerAuthorizationToken::Trust {
peer_id: peer_id.to_string(),
}
}
pub fn from_public_key(public_key: &[u8]) -> Self {
PeerAuthorizationToken::Challenge {
public_key: PublicKey::from_bytes(public_key.to_vec()),
}
}
pub fn has_peer_id(&self, peer_id: &str) -> bool {
match self {
PeerAuthorizationToken::Trust { peer_id: id } => peer_id == id,
PeerAuthorizationToken::Challenge { .. } => false,
}
}
pub fn peer_id(&self) -> Option<&str> {
match self {
PeerAuthorizationToken::Trust { peer_id } => Some(peer_id),
PeerAuthorizationToken::Challenge { .. } => None,
}
}
pub fn public_key(&self) -> Option<&PublicKey> {
match self {
PeerAuthorizationToken::Trust { .. } => None,
PeerAuthorizationToken::Challenge { public_key } => Some(public_key),
}
}
pub fn id_as_string(&self) -> String {
match self {
PeerAuthorizationToken::Trust { peer_id } => peer_id.to_string(),
PeerAuthorizationToken::Challenge { public_key } => {
format!("public_key::{}", to_hex(public_key.as_slice()))
}
}
}
}
impl fmt::Display for PeerAuthorizationToken {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PeerAuthorizationToken::Trust { peer_id } => {
write!(f, "Trust ( peer_id: {} )", peer_id)
}
PeerAuthorizationToken::Challenge { public_key } => {
write!(
f,
"Challenge ( public_key: {} )",
to_hex(public_key.as_slice())
)
}
}
}
}
impl From<ConnectionAuthorizationType> for PeerAuthorizationToken {
fn from(connection_type: ConnectionAuthorizationType) -> Self {
match connection_type {
ConnectionAuthorizationType::Trust { identity } => {
PeerAuthorizationToken::Trust { peer_id: identity }
}
ConnectionAuthorizationType::Challenge { public_key } => {
PeerAuthorizationToken::Challenge { public_key }
}
}
}
}
impl From<PeerAuthorizationToken> for ConnectionAuthorizationType {
fn from(peer_token: PeerAuthorizationToken) -> Self {
match peer_token {
PeerAuthorizationToken::Trust { peer_id } => {
ConnectionAuthorizationType::Trust { identity: peer_id }
}
PeerAuthorizationToken::Challenge { public_key } => {
ConnectionAuthorizationType::Challenge { public_key }
}
}
}
}
impl Ord for PeerAuthorizationToken {
fn cmp(&self, other: &Self) -> Ordering {
self.id_as_string().cmp(&other.id_as_string())
}
}
impl PartialOrd for PeerAuthorizationToken {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct PeerTokenPair {
peer_id: PeerAuthorizationToken,
local_id: PeerAuthorizationToken,
}
impl PeerTokenPair {
pub fn new(peer_id: PeerAuthorizationToken, local_id: PeerAuthorizationToken) -> Self {
Self { peer_id, local_id }
}
pub fn peer_id(&self) -> &PeerAuthorizationToken {
&self.peer_id
}
pub fn local_id(&self) -> &PeerAuthorizationToken {
&self.local_id
}
pub fn id_as_string(&self) -> String {
match self.peer_id {
PeerAuthorizationToken::Trust { .. } => self.peer_id.id_as_string(),
PeerAuthorizationToken::Challenge { .. } => {
format!(
"{}::{}",
self.peer_id.id_as_string(),
self.local_id.id_as_string()
)
}
}
}
}
impl fmt::Display for PeerTokenPair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Peer: {}, Local: {}", self.peer_id, self.local_id)
}
}