mqute_codec/protocol/v5/
auth.rs1use crate::Error;
8use crate::codec::util::{decode_byte, decode_variable_integer, encode_variable_integer};
9use crate::codec::{Decode, Encode, RawPacket};
10use crate::protocol::util::len_bytes;
11use crate::protocol::v5::property::{
12 Property, PropertyFrame, property_decode, property_encode, property_len,
13};
14use crate::protocol::v5::reason::ReasonCode;
15use crate::protocol::{FixedHeader, PacketType};
16use bytes::{Buf, BufMut, Bytes, BytesMut};
17
18fn validate_auth_reason_code(code: ReasonCode) -> bool {
23 matches!(code.into(), 0 | 24 | 25)
24}
25
26#[derive(Debug, Default, Clone, PartialEq, Eq)]
42pub struct AuthProperties {
43 pub auth_method: Option<String>,
45
46 pub auth_data: Option<Bytes>,
48
49 pub reason_string: Option<String>,
51
52 pub user_properties: Vec<(String, String)>,
54}
55
56impl PropertyFrame for AuthProperties {
57 fn encoded_len(&self) -> usize {
59 let mut len = 0usize;
60
61 len += property_len!(&self.auth_method);
62 len += property_len!(&self.auth_data);
63 len += property_len!(&self.reason_string);
64 len += property_len!(&self.user_properties);
65
66 len
67 }
68
69 fn encode(&self, buf: &mut BytesMut) {
71 property_encode!(&self.auth_method, Property::AuthenticationMethod, buf);
72 property_encode!(&self.auth_data, Property::AuthenticationData, buf);
73 property_encode!(&self.reason_string, Property::ReasonString, buf);
74 property_encode!(&self.user_properties, Property::UserProp, buf);
75 }
76
77 fn decode(buf: &mut Bytes) -> Result<Option<Self>, Error> {
79 if buf.is_empty() {
80 return Ok(None);
81 }
82
83 let mut properties = AuthProperties::default();
84
85 while buf.has_remaining() {
86 let property: Property = decode_byte(buf)?.try_into()?;
87 match property {
88 Property::AuthenticationMethod => {
89 property_decode!(&mut properties.auth_method, buf);
90 }
91 Property::AuthenticationData => {
92 property_decode!(&mut properties.auth_data, buf);
93 }
94 Property::ReasonString => {
95 property_decode!(&mut properties.reason_string, buf);
96 }
97 Property::UserProp => {
98 property_decode!(&mut properties.user_properties, buf);
99 }
100 _ => return Err(Error::PropertyMismatch),
101 }
102 }
103
104 Ok(Some(properties))
105 }
106}
107
108#[derive(Debug, Clone, PartialEq, Eq)]
112struct AuthHeader {
113 code: ReasonCode,
115
116 properties: Option<AuthProperties>,
118}
119
120impl AuthHeader {
121 pub(crate) fn new(code: ReasonCode, properties: Option<AuthProperties>) -> Self {
127 if !validate_auth_reason_code(code) {
128 panic!("Invalid reason code");
129 }
130 AuthHeader { code, properties }
131 }
132
133 pub(crate) fn encoded_len(&self) -> usize {
137 if self.code == ReasonCode::Success && self.properties.is_none() {
138 return 0;
139 }
140
141 let properties_len = self
142 .properties
143 .as_ref()
144 .map(|properties| properties.encoded_len())
145 .unwrap_or(0);
146
147 1 + len_bytes(properties_len) + properties_len
148 }
149
150 pub(crate) fn encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
152 if self.code == ReasonCode::Success && self.properties.is_none() {
154 return Ok(());
155 }
156
157 buf.put_u8(self.code.into());
158
159 let properties_len = self
160 .properties
161 .as_ref()
162 .map(|properties| properties.encoded_len())
163 .unwrap_or(0) as u32;
164
165 encode_variable_integer(buf, properties_len)?;
167
168 if let Some(properties) = self.properties.as_ref() {
170 properties.encode(buf);
171 }
172
173 Ok(())
174 }
175
176 pub(crate) fn decode(payload: &mut Bytes) -> Result<Self, Error> {
178 if payload.is_empty() {
179 return Ok(AuthHeader {
180 code: ReasonCode::Success,
181 properties: None,
182 });
183 }
184
185 let code: ReasonCode = decode_byte(payload)?.try_into()?;
186 if !validate_auth_reason_code(code) {
187 return Err(Error::InvalidReasonCode(code.into()));
188 }
189
190 let properties_len = decode_variable_integer(payload)? as usize;
191 if payload.len() < properties_len + len_bytes(properties_len) {
192 return Err(Error::MalformedPacket);
193 }
194
195 payload.advance(len_bytes(properties_len));
197
198 let mut properties_buf = payload.split_to(properties_len);
199
200 let properties = AuthProperties::decode(&mut properties_buf)?;
202 Ok(AuthHeader { code, properties })
203 }
204}
205
206#[derive(Debug, Clone, PartialEq, Eq)]
229pub struct Auth {
230 header: AuthHeader,
232}
233
234impl Auth {
235 pub fn new(code: ReasonCode, properties: Option<AuthProperties>) -> Self {
237 Auth {
238 header: AuthHeader::new(code, properties),
239 }
240 }
241
242 pub fn code(&self) -> ReasonCode {
244 self.header.code
245 }
246
247 pub fn properties(&self) -> Option<AuthProperties> {
249 self.header.properties.clone()
250 }
251}
252
253impl Encode for Auth {
254 fn encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
256 let header = FixedHeader::new(PacketType::Auth, self.payload_len());
257 header.encode(buf)?;
258
259 self.header.encode(buf)
260 }
261
262 fn payload_len(&self) -> usize {
264 self.header.encoded_len()
265 }
266}
267
268impl Decode for Auth {
269 fn decode(mut packet: RawPacket) -> Result<Self, Error> {
271 if packet.header.packet_type() != PacketType::Auth || !packet.header.flags().is_default() {
272 return Err(Error::MalformedPacket);
273 }
274
275 let header = AuthHeader::decode(&mut packet.payload)?;
276 Ok(Auth { header })
277 }
278}