apisix_admin_client/models/plugins/
consumer_restriction.rs1use serde::{Deserialize, Serialize};
2use strum_macros::{Display, EnumString};
3use validator::Validate;
4use crate::{Result};
5use crate::models::Plugin;
6
7#[serde_with::skip_serializing_none]
9#[derive(Validate, Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
10pub struct ConsumerRestrictionBuilder {
11 pub type_field: Option<ConsumerRestrictionType>,
12 pub whitelist: Option<Vec<String>>,
13 pub blacklist: Option<Vec<String>>,
14 pub rejected_code: Option<i32>,
15 pub rejected_msg: Option<String>,
16 pub allowed_by_methods: Option<Vec<AllowedByMethods>>,
17}
18
19impl ConsumerRestrictionBuilder {
20 pub fn new() -> Self {
21 ConsumerRestriction::default().into()
22 }
23
24 pub fn with_type(mut self, type_field: ConsumerRestrictionType) -> Self {
26 self.type_field = Some(type_field);
27 self
28 }
29
30 pub fn with_whitelist(mut self, whitelist: Vec<String>) -> Self {
32 self.whitelist = Some(whitelist);
33 self
34 }
35
36 pub fn with_blacklist(mut self, blacklist: Vec<String>) -> Self {
38 self.blacklist = Some(blacklist);
39 self
40 }
41
42 pub fn with_rejected_code(mut self, rejected_code: i32) -> Self {
44 self.rejected_code = Some(rejected_code);
45 self
46 }
47
48 pub fn with_rejected_msg(mut self, rejected_msg: impl Into<String>) -> Self {
50 self.rejected_msg = Some(rejected_msg.into());
51 self
52 }
53
54 pub fn with_allowed_by_methods(mut self, allowed_by_methods: Vec<AllowedByMethods>) -> Self {
56 self.allowed_by_methods = Some(allowed_by_methods);
57 self
58 }
59
60 pub fn build(self) -> Result<ConsumerRestriction> {
61 Ok(ConsumerRestriction {
62 type_field: self.type_field,
63 whitelist: self.whitelist,
64 blacklist: self.blacklist,
65 rejected_code: self.rejected_code,
66 rejected_msg: self.rejected_msg,
67 allowed_by_methods: self.allowed_by_methods,
68 })
69 }
70}
71
72
73
74#[serde_with::skip_serializing_none]
77#[derive(Validate, Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
78pub struct ConsumerRestriction {
79 #[serde(rename = "type")]
80 pub type_field: Option<ConsumerRestrictionType>,
81 pub whitelist: Option<Vec<String>>,
82 pub blacklist: Option<Vec<String>>,
83 #[validate(range(min = 200, max = 999))]
84 pub rejected_code: Option<i32>,
85 pub rejected_msg: Option<String>,
86 pub allowed_by_methods: Option<Vec<AllowedByMethods>>,
87}
88
89impl Plugin for ConsumerRestriction {}
90
91impl From<ConsumerRestriction> for ConsumerRestrictionBuilder {
92 fn from(consumer_restriction: ConsumerRestriction) -> Self {
93 ConsumerRestrictionBuilder {
94 type_field: consumer_restriction.type_field,
95 whitelist: consumer_restriction.whitelist,
96 blacklist: consumer_restriction.blacklist,
97 rejected_code: consumer_restriction.rejected_code,
98 rejected_msg: consumer_restriction.rejected_msg,
99 allowed_by_methods: consumer_restriction.allowed_by_methods,
100 }
101 }
102}
103
104#[serde_with::skip_serializing_none]
108#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
109pub struct AllowedByMethods {
110 pub user: Option<String>,
111 pub methods: Option<Vec<AllowedMethodsType>>,
112}
113
114#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Display, EnumString)]
120#[allow(non_camel_case_types)]
121#[strum(ascii_case_insensitive)]
122#[non_exhaustive]
123pub enum ConsumerRestrictionType {
124 consumer_name,
125 consumer_group_id,
126 service_id,
127 route_id,
128}
129
130#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Display, EnumString)]
132#[allow(non_camel_case_types)]
133#[strum(ascii_case_insensitive)]
134#[non_exhaustive]
135pub enum AllowedMethodsType {
136 GET,
137 POST,
138 PUT,
139 HEAD,
140 DELETE,
141 PATH,
142 OPTIONS,
143 CONNECT,
144 PURGE,
145 TRACE,
146}
147
148#[cfg(test)]
150mod tests {
151 use serde_json::{to_string, to_string_pretty};
152 use super::*;
153 use tracing::{error, info};
154 use tracing_test::traced_test;
155 use crate::models::admin_upstream_requests::UpstreamType;
156 use crate::models::common::TypedItem;
157
158 #[traced_test]
159 #[tokio::test]
160 async fn test_parse_consumer_restriction_empty_response() {
161 let nodes = r#"{}"#;
162 let nodes: ConsumerRestriction = serde_json::from_str(nodes).unwrap();
163 assert_eq!(nodes.type_field, None);
164 assert_eq!(nodes.whitelist, None);
165 assert_eq!(nodes.blacklist, None);
166 assert_eq!(nodes.rejected_code, None);
167 assert_eq!(nodes.rejected_msg, None);
168 assert_eq!(nodes.allowed_by_methods, None);
169 }
170
171 #[traced_test]
172 #[tokio::test]
173 async fn test_parse_consumer_restriction_response() {
174 let nodes = r#"
175 {
176 "whitelist": [
177 "jack1"
178 ]
179 }"#;
180 let nodes: ConsumerRestriction = serde_json::from_str(nodes).unwrap();
181 assert_eq!(nodes.whitelist.unwrap(), vec!["jack1"]);
182 }
183}
184