1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
// Copyright 2021 MaidSafe.net limited.
//
// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.
use super::{CmdError, Error, QueryResponse, Result};
use crate::messaging::data::OperationId;
use crate::types::{
register::{Entry, Register, RegisterOp, User},
PublicKey, RegisterAddress as Address,
};
use serde::{Deserialize, Serialize};
use xor_name::XorName;
/// [`Register`] read operations.
#[derive(Hash, Eq, PartialEq, PartialOrd, Clone, Serialize, Deserialize, Debug)]
pub enum RegisterRead {
/// Retrieve the [`Register`] at the given address.
///
/// This should eventually lead to a [`GetRegister`] response.
///
/// [`GetRegister`]: QueryResponse::GetRegister
Get(Address),
/// Retrieve the current entries from the [`Register`] at the given address.
///
/// Multiple entries occur on concurrent writes. This should eventually lead to a
/// [`ReadRegister`] response.
///
/// [`ReadRegister`]: QueryResponse::ReadRegister
Read(Address),
/// Retrieve the policy of the [`Register`] at the given address.
///
/// This should eventually lead to a [`GetRegisterPolicy`] response.
///
/// [`GetRegisterPolicy`]: QueryResponse::GetRegisterPolicy
GetPolicy(Address),
/// Retrieve the permissions of a given user for the [`Register`] at the given address.
///
/// This should eventually lead to a [`GetRegisterUserPermissions`] response.
///
/// [`GetRegisterUserPermissions`]: QueryResponse::GetRegisterUserPermissions
GetUserPermissions {
/// Register address.
address: Address,
/// User to get permissions for.
user: User,
},
/// Retrieve the owner of the [`Register`] at the given address.
///
/// This should eventually lead to a [`GetRegisterOwner`] response.
///
/// [`GetRegisterOwner`]: QueryResponse::GetRegisterOwner
GetOwner(Address),
}
/// A [`Register`] write operation.
#[derive(Eq, PartialEq, Clone, Serialize, Deserialize, Debug)]
pub struct RegisterCmd {
/// The operation to perform.
pub write: RegisterWrite,
/// A signature carrying authority to perform the operation.
///
/// This will be verified against the register's owner and permissions.
pub auth: crate::messaging::ServiceAuth,
}
/// [`Register`] write operations.
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
pub enum RegisterWrite {
/// Create a new [`Register`] on the network.
New(Register),
/// Edit a [`Register`].
Edit(RegisterOp<Entry>),
/// Delete a private [`Register`].
///
/// This operation will result in an error if applied to a public register. Only private
/// registers can be deleted, and only by their current owner(s).
Delete(Address),
}
impl RegisterRead {
/// Creates a Response containing an error, with the Response variant corresponding to the
/// Request variant.
pub fn error(&self, error: Error) -> Result<QueryResponse> {
match *self {
RegisterRead::Get(_) => Ok(QueryResponse::GetRegister((
Err(error),
self.operation_id()?,
))),
RegisterRead::Read(_) => Ok(QueryResponse::ReadRegister((
Err(error),
self.operation_id()?,
))),
RegisterRead::GetPolicy(_) => Ok(QueryResponse::GetRegisterPolicy((
Err(error),
self.operation_id()?,
))),
RegisterRead::GetUserPermissions { .. } => Ok(
QueryResponse::GetRegisterUserPermissions((Err(error), self.operation_id()?)),
),
RegisterRead::GetOwner(_) => Ok(QueryResponse::GetRegisterOwner((
Err(error),
self.operation_id()?,
))),
}
}
/// Returns the address of the data for request. (Scoped to Private/Public)
pub fn dst_address(&self) -> Address {
match self {
RegisterRead::Get(ref address)
| RegisterRead::Read(ref address)
| RegisterRead::GetPolicy(ref address)
| RegisterRead::GetUserPermissions { ref address, .. }
| RegisterRead::GetOwner(ref address) => *address,
}
}
/// Returns the xorname of the data for request.
pub fn dst_name(&self) -> XorName {
match self {
RegisterRead::Get(ref address)
| RegisterRead::Read(ref address)
| RegisterRead::GetPolicy(ref address)
| RegisterRead::GetUserPermissions { ref address, .. }
| RegisterRead::GetOwner(ref address) => *address.name(),
}
}
/// Retrieves the operation identifier for this response, use in tracking node liveness
/// and responses at clients.
/// Must be the same as the query response
/// Right now returning result to fail for anything non-chunk, as that's all we're tracking from other nodes here just now.
pub fn operation_id(&self) -> Result<OperationId> {
match self {
RegisterRead::Get(ref address) => Ok(format!(
"Get-{:?}",
address
.encode_to_zbase32()
.map_err(|_| Error::NoOperationId)?
)),
RegisterRead::Read(ref address) => Ok(format!(
"Read-{:?}",
address
.encode_to_zbase32()
.map_err(|_| Error::NoOperationId)?
)),
RegisterRead::GetPolicy(ref address) => Ok(format!(
"GetPolicy-{:?}",
address
.encode_to_zbase32()
.map_err(|_| Error::NoOperationId)?
)),
RegisterRead::GetUserPermissions { ref address, .. } => Ok(format!(
"GetUserPermissions-{:?}",
address
.encode_to_zbase32()
.map_err(|_| Error::NoOperationId)?
)),
RegisterRead::GetOwner(ref address) => Ok(format!(
"GetOwner-{:?}",
address
.encode_to_zbase32()
.map_err(|_| Error::NoOperationId)?
)),
}
}
}
impl RegisterWrite {
/// Creates a Response containing an error, with the Response variant corresponding to the
/// Request variant.
pub fn error(&self, error: Error) -> CmdError {
CmdError::Data(error)
}
/// Returns the address of the destination for request.
pub fn dst_name(&self) -> XorName {
match self {
RegisterWrite::New(ref data) => *data.name(),
RegisterWrite::Delete(ref address) => *address.name(),
RegisterWrite::Edit(ref op) => *op.address.name(),
}
}
/// Returns the address of the map.
pub fn address(&self) -> &Address {
match self {
Self::New(map) => map.address(),
Self::Delete(address) => address,
Self::Edit(ref op) => &op.address,
}
}
/// Owner of the RegisterWrite
pub fn owner(&self) -> Option<PublicKey> {
match self {
Self::New(data) => Some(data.owner()),
_ => None,
}
}
}