use crate::api::endpoint::{Endpoint, HttpMethod};
use crate::response::{DeleteResponse, MutationResponse, SiteResponse};
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum AclAction {
Allow,
Block,
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct AclRule {
pub id: String,
pub name: String,
pub action: AclAction,
#[serde(default)]
pub enabled: bool,
#[serde(default)]
pub order: Option<i32>,
#[serde(default)]
pub description: Option<String>,
#[serde(default)]
pub source_type: Option<String>,
#[serde(default)]
pub source_value: Option<String>,
#[serde(default)]
pub destination_type: Option<String>,
#[serde(default)]
pub destination_value: Option<String>,
}
#[derive(Debug, Clone)]
pub struct GetAclRules {
pub site_id: String,
}
impl GetAclRules {
pub fn new(site_id: impl Into<String>) -> Self {
Self {
site_id: site_id.into(),
}
}
}
impl Endpoint for GetAclRules {
const PATH: &'static str = "sites/{site_id}/acl-rules";
const METHOD: HttpMethod = HttpMethod::Get;
type Response = SiteResponse<AclRule>;
fn build_path(&self) -> String {
format!("sites/{}/acl-rules", self.site_id)
}
}
#[derive(Debug, Clone)]
pub struct GetAclRule {
pub site_id: String,
pub id: String,
}
impl GetAclRule {
pub fn new(site_id: impl Into<String>, id: impl Into<String>) -> Self {
Self {
site_id: site_id.into(),
id: id.into(),
}
}
}
impl Endpoint for GetAclRule {
const PATH: &'static str = "sites/{site_id}/acl-rules/{id}";
const METHOD: HttpMethod = HttpMethod::Get;
type Response = SiteResponse<AclRule>;
fn build_path(&self) -> String {
format!("sites/{}/acl-rules/{}", self.site_id, self.id)
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AclRuleRequest {
pub name: String,
pub action: AclAction,
#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub order: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub destination_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub destination_value: Option<String>,
}
impl AclRuleRequest {
pub fn new(name: impl Into<String>, action: AclAction) -> Self {
Self {
name: name.into(),
action,
enabled: None,
order: None,
description: None,
source_type: None,
source_value: None,
destination_type: None,
destination_value: None,
}
}
pub fn enabled(mut self, enabled: bool) -> Self {
self.enabled = Some(enabled);
self
}
pub fn order(mut self, order: i32) -> Self {
self.order = Some(order);
self
}
pub fn description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
pub fn source(
mut self,
source_type: impl Into<String>,
source_value: impl Into<String>,
) -> Self {
self.source_type = Some(source_type.into());
self.source_value = Some(source_value.into());
self
}
pub fn destination(
mut self,
dest_type: impl Into<String>,
dest_value: impl Into<String>,
) -> Self {
self.destination_type = Some(dest_type.into());
self.destination_value = Some(dest_value.into());
self
}
}
#[derive(Debug, Clone)]
pub struct CreateAclRule {
pub site_id: String,
pub request: AclRuleRequest,
}
impl CreateAclRule {
pub fn new(site_id: impl Into<String>, request: AclRuleRequest) -> Self {
Self {
site_id: site_id.into(),
request,
}
}
}
impl Endpoint for CreateAclRule {
const PATH: &'static str = "sites/{site_id}/acl-rules";
const METHOD: HttpMethod = HttpMethod::Post;
type Response = MutationResponse<AclRule>;
fn build_path(&self) -> String {
format!("sites/{}/acl-rules", self.site_id)
}
fn request_body(&self) -> Result<Option<Value>, serde_json::Error> {
Ok(Some(serde_json::to_value(&self.request)?))
}
}
#[derive(Debug, Clone)]
pub struct UpdateAclRule {
pub site_id: String,
pub id: String,
pub request: AclRuleRequest,
}
impl UpdateAclRule {
pub fn new(site_id: impl Into<String>, id: impl Into<String>, request: AclRuleRequest) -> Self {
Self {
site_id: site_id.into(),
id: id.into(),
request,
}
}
}
impl Endpoint for UpdateAclRule {
const PATH: &'static str = "sites/{site_id}/acl-rules/{id}";
const METHOD: HttpMethod = HttpMethod::Put;
type Response = MutationResponse<AclRule>;
fn build_path(&self) -> String {
format!("sites/{}/acl-rules/{}", self.site_id, self.id)
}
fn request_body(&self) -> Result<Option<Value>, serde_json::Error> {
Ok(Some(serde_json::to_value(&self.request)?))
}
}
#[derive(Debug, Clone)]
pub struct DeleteAclRule {
pub site_id: String,
pub id: String,
}
impl DeleteAclRule {
pub fn new(site_id: impl Into<String>, id: impl Into<String>) -> Self {
Self {
site_id: site_id.into(),
id: id.into(),
}
}
}
impl Endpoint for DeleteAclRule {
const PATH: &'static str = "sites/{site_id}/acl-rules/{id}";
const METHOD: HttpMethod = HttpMethod::Delete;
type Response = DeleteResponse;
fn build_path(&self) -> String {
format!("sites/{}/acl-rules/{}", self.site_id, self.id)
}
}
#[derive(Debug, Clone)]
pub struct ReorderAclRules {
pub site_id: String,
pub rule_ids: Vec<String>,
}
impl ReorderAclRules {
pub fn new(site_id: impl Into<String>, rule_ids: Vec<String>) -> Self {
Self {
site_id: site_id.into(),
rule_ids,
}
}
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct ReorderRequest {
rule_ids: Vec<String>,
}
impl Endpoint for ReorderAclRules {
const PATH: &'static str = "sites/{site_id}/acl-rules/order";
const METHOD: HttpMethod = HttpMethod::Put;
type Response = SiteResponse<AclRule>;
fn build_path(&self) -> String {
format!("sites/{}/acl-rules/order", self.site_id)
}
fn request_body(&self) -> Result<Option<Value>, serde_json::Error> {
Ok(Some(serde_json::to_value(ReorderRequest {
rule_ids: self.rule_ids.clone(),
})?))
}
}