rmqtt_codec/v5/packet/
auth.rs

1use bytes::{Buf, BufMut, Bytes, BytesMut};
2use bytestring::ByteString;
3
4use crate::error::{DecodeError, EncodeError};
5use crate::utils::{self, Decode, Property};
6use crate::v5::{encode::*, property_type as pt, UserProperties, UserProperty};
7
8/// AUTH message
9#[derive(Debug, PartialEq, Eq, Clone)]
10pub struct Auth {
11    pub reason_code: AuthReasonCode,
12    pub auth_method: Option<ByteString>,
13    pub auth_data: Option<Bytes>,
14    pub reason_string: Option<ByteString>,
15    pub user_properties: UserProperties,
16}
17
18prim_enum! {
19    /// AUTH reason codes
20    pub enum AuthReasonCode {
21        Success = 0,
22        ContinueAuth = 24,
23        ReAuth = 25
24    }
25}
26
27impl From<AuthReasonCode> for u8 {
28    fn from(v: AuthReasonCode) -> Self {
29        match v {
30            AuthReasonCode::Success => 0,
31            AuthReasonCode::ContinueAuth => 24,
32            AuthReasonCode::ReAuth => 25,
33        }
34    }
35}
36
37impl Auth {
38    pub(crate) fn decode(src: &mut Bytes) -> Result<Self, DecodeError> {
39        let auth = if src.has_remaining() {
40            let reason_code = src.get_u8().try_into()?;
41
42            if src.has_remaining() {
43                let mut auth_method = None;
44                let mut auth_data = None;
45                let mut reason_string = None;
46                let mut user_properties = Vec::new();
47
48                if reason_code != AuthReasonCode::Success || src.has_remaining() {
49                    let prop_src = &mut utils::take_properties(src)?;
50                    while prop_src.has_remaining() {
51                        match prop_src.get_u8() {
52                            pt::AUTH_METHOD => auth_method.read_value(prop_src)?,
53                            pt::AUTH_DATA => auth_data.read_value(prop_src)?,
54                            pt::REASON_STRING => reason_string.read_value(prop_src)?,
55                            pt::USER => user_properties.push(UserProperty::decode(prop_src)?),
56                            _ => return Err(DecodeError::MalformedPacket),
57                        }
58                    }
59                    ensure!(!src.has_remaining(), DecodeError::InvalidLength);
60                }
61
62                Self { reason_code, auth_method, auth_data, reason_string, user_properties }
63            } else {
64                Self { reason_code, ..Default::default() }
65            }
66        } else {
67            Self::default()
68        };
69        Ok(auth)
70    }
71}
72
73impl Default for Auth {
74    fn default() -> Self {
75        Self {
76            reason_code: AuthReasonCode::Success,
77            auth_method: None,
78            auth_data: None,
79            reason_string: None,
80            user_properties: Vec::new(),
81        }
82    }
83}
84
85impl EncodeLtd for Auth {
86    fn encoded_size(&self, limit: u32) -> usize {
87        const HEADER_LEN: usize = 1; // reason code
88
89        let mut prop_len = encoded_property_size(&self.auth_method) + encoded_property_size(&self.auth_data);
90        let diag_len = encoded_size_opt_props(
91            &self.user_properties,
92            &self.reason_string,
93            reduce_limit(limit, prop_len + HEADER_LEN + 4),
94        ); // exclude other props and max of 4 bytes for property length value
95        prop_len += diag_len;
96        HEADER_LEN + var_int_len(prop_len) as usize + prop_len
97    }
98
99    fn encode(&self, buf: &mut BytesMut, size: u32) -> Result<(), EncodeError> {
100        let start_len = buf.len();
101        buf.put_u8(self.reason_code.into());
102
103        let prop_len = var_int_len_from_size(size - 1);
104        utils::write_variable_length(prop_len, buf);
105        encode_property(&self.auth_method, pt::AUTH_METHOD, buf)?;
106        encode_property(&self.auth_data, pt::AUTH_DATA, buf)?;
107        encode_opt_props(
108            &self.user_properties,
109            &self.reason_string,
110            buf,
111            size - (buf.len() - start_len) as u32,
112        )
113    }
114}