safe_nd/identity/
mod.rs

1// Copyright 2019 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under the MIT license <LICENSE-MIT
4// https://opensource.org/licenses/MIT> or the Modified BSD license <LICENSE-BSD
5// https://opensource.org/licenses/BSD-3-Clause>, at your option. This file may not be copied,
6// modified, or distributed except according to those terms. Please review the Licences for the
7// specific language governing permissions and limitations relating to use of the SAFE Network
8// Software.
9
10pub mod client;
11pub mod node;
12
13use crate::{utils, PublicKey, Result, XorName};
14use serde::{Deserialize, Serialize};
15use std::fmt::{self, Debug, Display, Formatter};
16
17/// An enum representing the identity of a network Node or Client.
18///
19/// It includes public signing key(s), and provides the entity's network address, i.e. its `name()`.
20#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, PartialOrd, Ord, Hash)]
21pub enum PublicId {
22    /// The public identity of a network Node.
23    Node(node::PublicId),
24    /// The public identity of a network Client.
25    Client(client::PublicId),
26}
27
28impl PublicId {
29    /// Returns the entity's network address.
30    pub fn name(&self) -> &XorName {
31        match self {
32            Self::Node(pub_id) => pub_id.name(),
33            Self::Client(pub_id) => pub_id.name(),
34        }
35    }
36
37    /// Returns the node public id, if applicable.
38    pub fn node_public_id(&self) -> Option<&node::PublicId> {
39        if let Self::Node(id) = self {
40            Some(id)
41        } else {
42            None
43        }
44    }
45
46    /// Returns the client public id, if applicable.
47    pub fn client_public_id(&self) -> Option<&client::PublicId> {
48        if let Self::Client(id) = self {
49            Some(id)
50        } else {
51            None
52        }
53    }
54
55    /// Returns the entity's public key, if applicable.
56    pub fn public_key(&self) -> PublicKey {
57        match self {
58            Self::Node(pub_id) => (*pub_id.ed25519_public_key()).into(),
59            Self::Client(pub_id) => *pub_id.public_key(),
60        }
61    }
62
63    /// Returns the PublicId serialised and encoded in z-base-32.
64    pub fn encode_to_zbase32(&self) -> String {
65        utils::encode(&self)
66    }
67
68    /// Creates from z-base-32 encoded string.
69    pub fn decode_from_zbase32<T: AsRef<str>>(encoded: T) -> Result<Self> {
70        utils::decode(encoded)
71    }
72}
73
74impl Debug for PublicId {
75    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
76        match self {
77            Self::Node(pub_id) => write!(formatter, "{:?}", pub_id),
78            Self::Client(pub_id) => write!(formatter, "{:?}", pub_id),
79        }
80    }
81}
82
83impl Display for PublicId {
84    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
85        Debug::fmt(self, formatter)
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92    use crate::Error;
93    use unwrap::unwrap;
94
95    #[test]
96    fn zbase32_encode_decode_client_public_id() {
97        let mut rng = rand::thread_rng();
98        let id = client::FullId::new_ed25519(&mut rng);
99        assert_eq!(
100            unwrap!(client::PublicId::decode_from_zbase32(
101                &id.public_id().encode_to_zbase32()
102            )),
103            *id.public_id()
104        );
105
106        let node_id = node::FullId::new(&mut rng);
107        assert!(match client::PublicId::decode_from_zbase32(
108            &node_id.public_id().encode_to_zbase32()
109        ) {
110            Err(Error::FailedToParse(_)) => true,
111            _ => false,
112        });
113        assert!(client::PublicId::decode_from_zbase32("sdkjf832939fjs").is_err());
114    }
115
116    #[test]
117    fn zbase32_encode_decode_node_public_id() {
118        let mut rng = rand::thread_rng();
119        let mut id = node::FullId::new(&mut rng);
120        let bls_secret_key = threshold_crypto::SecretKeySet::random(1, &mut rng);
121        id.set_bls_keys(
122            bls_secret_key.secret_key_share(0),
123            bls_secret_key.public_keys(),
124        );
125        assert_eq!(
126            unwrap!(node::PublicId::decode_from_zbase32(
127                &id.public_id().encode_to_zbase32()
128            )),
129            *id.public_id()
130        );
131        assert!(node::PublicId::decode_from_zbase32("7djsk38").is_err());
132    }
133
134    #[test]
135    fn zbase32_encode_decode_enum_public_id() {
136        let mut rng = rand::thread_rng();
137        let id = PublicId::Client(client::FullId::new_ed25519(&mut rng).public_id().clone());
138        assert_eq!(
139            id,
140            unwrap!(PublicId::decode_from_zbase32(&id.encode_to_zbase32()))
141        );
142        assert!(PublicId::decode_from_zbase32("c419cxim9").is_err());
143    }
144}