use serde_json::Value;
use std::ops::Not;
use super::constants::{AUTH_RULE, AUTH_RULES, GET_AUTH_RULE};
use super::{ProtocolVersion, RequestType};
use crate::common::error::prelude::*;
use crate::ledger::constants::LedgerRole;
#[allow(non_camel_case_types)]
#[derive(Deserialize, Debug, Serialize, PartialEq)]
pub enum AuthAction {
ADD,
EDIT,
}
impl AuthAction {
pub fn to_string(&self) -> &str {
match self {
Self::ADD => "ADD",
Self::EDIT => "EDIT",
}
}
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
#[serde(tag = "constraint_id")]
pub enum Constraint {
#[serde(rename = "OR")]
OrConstraint(CombinationConstraint),
#[serde(rename = "AND")]
AndConstraint(CombinationConstraint),
#[serde(rename = "ROLE")]
RoleConstraint(RoleConstraint),
#[serde(rename = "FORBIDDEN")]
ForbiddenConstraint(ForbiddenConstraint),
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct RoleConstraint {
pub sig_count: u32,
pub role: Option<LedgerRole>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<Value>,
#[serde(default)]
pub need_to_be_owner: bool,
#[serde(default)]
#[serde(skip_serializing_if = "Not::not")]
pub off_ledger_signature: bool,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct CombinationConstraint {
pub auth_constraints: Vec<Constraint>,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct ForbiddenConstraint {}
#[derive(Serialize, PartialEq, Debug)]
#[serde(untagged)]
pub enum AuthRuleOperation {
Add(AddAuthRuleOperation),
Edit(EditAuthRuleOperation),
}
#[derive(Serialize, PartialEq, Debug)]
pub struct AddAuthRuleOperation {
#[serde(rename = "type")]
pub _type: String,
pub auth_type: String,
pub field: String,
pub auth_action: AuthAction,
pub new_value: Option<String>,
pub constraint: Constraint,
}
#[derive(Serialize, PartialEq, Debug)]
pub struct EditAuthRuleOperation {
#[serde(rename = "type")]
pub _type: String,
pub auth_type: String,
pub field: String,
pub auth_action: AuthAction,
pub old_value: Option<String>,
pub new_value: Option<String>,
pub constraint: Constraint,
}
impl AuthRuleOperation {
pub fn new(
auth_type: String,
field: String,
auth_action: AuthAction,
old_value: Option<String>,
new_value: Option<String>,
constraint: Constraint,
) -> AuthRuleOperation {
match auth_action {
AuthAction::ADD => AuthRuleOperation::Add(AddAuthRuleOperation {
_type: Self::get_txn_type().to_string(),
auth_type,
field,
auth_action,
new_value,
constraint,
}),
AuthAction::EDIT => AuthRuleOperation::Edit(EditAuthRuleOperation {
_type: Self::get_txn_type().to_string(),
auth_type,
field,
auth_action,
old_value,
new_value,
constraint,
}),
}
}
}
impl RequestType for AuthRuleOperation {
fn get_txn_type<'a>() -> &'a str {
AUTH_RULE
}
}
#[derive(Serialize, PartialEq, Debug)]
#[serde(untagged)]
pub enum GetAuthRuleOperation {
All(GetAllAuthRuleOperation),
Add(GetAddAuthRuleOperation),
Edit(GetEditAuthRuleOperation),
}
#[derive(Serialize, PartialEq, Debug)]
pub struct GetAllAuthRuleOperation {
#[serde(rename = "type")]
pub _type: String,
}
#[derive(Serialize, PartialEq, Debug)]
pub struct GetAddAuthRuleOperation {
#[serde(rename = "type")]
pub _type: String,
pub auth_type: String,
pub field: String,
pub auth_action: AuthAction,
pub new_value: Option<String>,
}
#[derive(Serialize, PartialEq, Debug)]
pub struct GetEditAuthRuleOperation {
#[serde(rename = "type")]
pub _type: String,
pub auth_type: String,
pub field: String,
pub auth_action: AuthAction,
pub old_value: Option<String>,
pub new_value: Option<String>,
}
impl GetAuthRuleOperation {
pub fn get_all() -> GetAuthRuleOperation {
GetAuthRuleOperation::All(GetAllAuthRuleOperation {
_type: Self::get_txn_type().to_string(),
})
}
pub fn get_one(
auth_type: String,
field: String,
auth_action: AuthAction,
old_value: Option<String>,
new_value: Option<String>,
) -> GetAuthRuleOperation {
match auth_action {
AuthAction::ADD => GetAuthRuleOperation::Add(GetAddAuthRuleOperation {
_type: Self::get_txn_type().to_string(),
auth_type,
field,
auth_action,
new_value,
}),
AuthAction::EDIT => GetAuthRuleOperation::Edit(GetEditAuthRuleOperation {
_type: Self::get_txn_type().to_string(),
auth_type,
field,
auth_action,
old_value,
new_value,
}),
}
}
}
impl RequestType for GetAuthRuleOperation {
fn get_txn_type<'a>() -> &'a str {
GET_AUTH_RULE
}
fn get_sp_key(&self, _protocol_version: ProtocolVersion) -> VdrResult<Option<Vec<u8>>> {
let (auth_type, auth_action, field, new_value, old_value) = match self {
GetAuthRuleOperation::Add(GetAddAuthRuleOperation {
_type,
auth_type,
auth_action,
field,
new_value,
}) => (
auth_type,
auth_action,
field,
new_value.as_ref().map(String::as_str),
Some("*"),
),
GetAuthRuleOperation::Edit(GetEditAuthRuleOperation {
_type,
auth_type,
auth_action,
field,
new_value,
old_value,
}) => (
auth_type,
auth_action,
field,
new_value.as_ref().map(String::as_str),
old_value.as_ref().map(String::as_str),
),
GetAuthRuleOperation::All(_) => return Ok(None),
};
Ok(Some(
format!(
"1:{}--{}--{}--{}--{}",
auth_type,
auth_action.to_string(),
field,
old_value.unwrap_or(""),
new_value.unwrap_or("")
)
.as_bytes()
.to_vec(),
))
}
}
pub type AuthRules = Vec<AuthRuleData>;
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
#[serde(tag = "auth_action")]
pub enum AuthRuleData {
#[serde(rename = "ADD")]
Add(AddAuthRuleData),
#[serde(rename = "EDIT")]
Edit(EditAuthRuleData),
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct AddAuthRuleData {
pub auth_type: String,
pub field: String,
pub new_value: Option<String>,
pub constraint: Constraint,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct EditAuthRuleData {
pub auth_type: String,
pub field: String,
pub old_value: Option<String>,
pub new_value: Option<String>,
pub constraint: Constraint,
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct GetAuthRuleResult {
pub data: Vec<AuthRule>,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct AuthRule {
pub auth_type: String,
pub auth_action: String,
pub field: String,
pub old_value: Option<String>,
pub new_value: Option<String>,
pub constraint: Constraint,
}
#[derive(Serialize, PartialEq, Debug)]
pub struct AuthRulesOperation {
#[serde(rename = "type")]
pub _type: String,
pub rules: AuthRules,
}
impl AuthRulesOperation {
pub fn new(rules: AuthRules) -> AuthRulesOperation {
AuthRulesOperation {
_type: Self::get_txn_type().to_string(),
rules,
}
}
}
impl RequestType for AuthRulesOperation {
fn get_txn_type<'a>() -> &'a str {
AUTH_RULES
}
}