atagen

macltok

public
Star0
Watch0
d9b96952ec6003585d618d852b489c48fc386d5d
3
ssh://brewery@pls.lobotomise.me:33/atagen/macltok.git
src/uiaa.rsRust233 lines7.1 KB
1
use std::fmt;
2
3
use ruma::{UserId, api::client::uiaa, serde::JsonObject};
4
#[cfg(feature = "serde")]
5
use serde::{Deserialize, Serialize};
6
7
#[derive(Eq, PartialEq)]
8
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9
#[non_exhaustive]
10
pub enum InteractiveAuth {
11
    Password {
12
        password: String,
13
        session: Option<String>,
14
    },
15
    ReCaptcha {
16
        response: String,
17
        session: Option<String>,
18
    },
19
    Dummy {
20
        session: Option<String>,
21
    },
22
    FallbackAcknowledgement {
23
        session: String,
24
    },
25
    OAuth {
26
        session: Option<String>,
27
    },
28
    Stage {
29
        auth_type: String,
30
        session: Option<String>,
31
        data: JsonObject,
32
    },
33
}
34
35
impl InteractiveAuth {
36
    #[must_use]
37
    pub fn password(password: impl Into<String>, session: Option<String>) -> Self {
38
        Self::Password {
39
            password: password.into(),
40
            session,
41
        }
42
    }
43
44
    #[must_use]
45
    pub fn recaptcha(response: impl Into<String>, session: Option<String>) -> Self {
46
        Self::ReCaptcha {
47
            response: response.into(),
48
            session,
49
        }
50
    }
51
52
    #[must_use]
53
    pub fn dummy(session: Option<String>) -> Self {
54
        Self::Dummy { session }
55
    }
56
57
    #[must_use]
58
    pub fn fallback_acknowledgement(session: impl Into<String>) -> Self {
59
        Self::FallbackAcknowledgement {
60
            session: session.into(),
61
        }
62
    }
63
64
    #[must_use]
65
    pub fn oauth(session: Option<String>) -> Self {
66
        Self::OAuth { session }
67
    }
68
69
    #[must_use]
70
    pub fn stage(auth_type: impl Into<String>, session: Option<String>, data: JsonObject) -> Self {
71
        Self::Stage {
72
            auth_type: auth_type.into(),
73
            session,
74
            data,
75
        }
76
    }
77
78
    pub(crate) fn into_sdk(self, user_id: &UserId) -> Result<uiaa::AuthData, String> {
79
        match self {
80
            Self::Password { password, session } => {
81
                let mut password = uiaa::Password::new(user_id.to_owned().into(), password);
82
                password.session = session;
83
                Ok(uiaa::AuthData::Password(password))
84
            }
85
            Self::ReCaptcha { response, session } => {
86
                let mut recaptcha = uiaa::ReCaptcha::new(response);
87
                recaptcha.session = session;
88
                Ok(uiaa::AuthData::ReCaptcha(recaptcha))
89
            }
90
            Self::Dummy { session } => {
91
                let mut dummy = uiaa::Dummy::new();
92
                dummy.session = session;
93
                Ok(uiaa::AuthData::Dummy(dummy))
94
            }
95
            Self::FallbackAcknowledgement { session } => {
96
                Ok(uiaa::AuthData::fallback_acknowledgement(session))
97
            }
98
            Self::OAuth { session } => {
99
                let mut oauth = uiaa::OAuth::new();
100
                oauth.session = session;
101
                Ok(uiaa::AuthData::OAuth(oauth))
102
            }
103
            Self::Stage {
104
                auth_type,
105
                session,
106
                data,
107
            } => uiaa::AuthData::new(&auth_type, session, data).map_err(|error| error.to_string()),
108
        }
109
    }
110
}
111
112
impl fmt::Debug for InteractiveAuth {
113
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
114
        match self {
115
            Self::Password {
116
                password: _,
117
                session,
118
            } => formatter
119
                .debug_struct("Password")
120
                .field("session", &session.as_ref().map(|_| "..."))
121
                .finish_non_exhaustive(),
122
            Self::ReCaptcha {
123
                response: _,
124
                session,
125
            } => formatter
126
                .debug_struct("ReCaptcha")
127
                .field("session", &session.as_ref().map(|_| "..."))
128
                .finish_non_exhaustive(),
129
            Self::Dummy { session } => formatter
130
                .debug_struct("Dummy")
131
                .field("session", &session.as_ref().map(|_| "..."))
132
                .finish(),
133
            Self::FallbackAcknowledgement { session: _ } => formatter
134
                .debug_struct("FallbackAcknowledgement")
135
                .field("session", &"...")
136
                .finish(),
137
            Self::OAuth { session } => formatter
138
                .debug_struct("OAuth")
139
                .field("session", &session.as_ref().map(|_| "..."))
140
                .finish(),
141
            Self::Stage {
142
                auth_type,
143
                session,
144
                data: _,
145
            } => formatter
146
                .debug_struct("Stage")
147
                .field("auth_type", auth_type)
148
                .field("session", &session.as_ref().map(|_| "..."))
149
                .finish_non_exhaustive(),
150
        }
151
    }
152
}
153
154
#[derive(Clone, Eq, PartialEq)]
155
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
156
#[non_exhaustive]
157
pub struct InteractiveAuthChallenge {
158
    pub flows: Vec<InteractiveAuthFlow>,
159
    pub completed: Vec<String>,
160
    pub parameters_json: Option<String>,
161
    pub session: Option<String>,
162
    pub error: Option<InteractiveAuthFailure>,
163
}
164
165
impl fmt::Debug for InteractiveAuthChallenge {
166
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
167
        formatter
168
            .debug_struct("InteractiveAuthChallenge")
169
            .field("flows", &self.flows)
170
            .field("completed", &self.completed)
171
            .field(
172
                "parameters_json",
173
                &self.parameters_json.as_ref().map(|_| "..."),
174
            )
175
            .field("session", &self.session.as_ref().map(|_| "..."))
176
            .field("error", &self.error)
177
            .finish()
178
    }
179
}
180
181
impl From<&uiaa::UiaaInfo> for InteractiveAuthChallenge {
182
    fn from(info: &uiaa::UiaaInfo) -> Self {
183
        Self {
184
            flows: info
185
                .flows
186
                .iter()
187
                .map(|flow| InteractiveAuthFlow {
188
                    stages: flow
189
                        .stages
190
                        .iter()
191
                        .map(|stage| stage.as_str().to_owned())
192
                        .collect(),
193
                })
194
                .collect(),
195
            completed: info
196
                .completed
197
                .iter()
198
                .map(|stage| stage.as_str().to_owned())
199
                .collect(),
200
            parameters_json: info.params.as_ref().map(|params| params.get().to_owned()),
201
            session: info.session.clone(),
202
            error: info
203
                .auth_error
204
                .as_ref()
205
                .map(|error| InteractiveAuthFailure {
206
                    code: error.kind.errcode().as_str().to_owned(),
207
                    message: error.message.clone(),
208
                }),
209
        }
210
    }
211
}
212
213
#[derive(Clone, Debug, Eq, PartialEq)]
214
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
215
#[non_exhaustive]
216
pub struct InteractiveAuthFlow {
217
    pub stages: Vec<String>,
218
}
219
220
#[derive(Clone, Debug, Eq, PartialEq)]
221
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
222
#[non_exhaustive]
223
pub struct InteractiveAuthFailure {
224
    pub code: String,
225
    pub message: String,
226
}
227
228
#[derive(Clone, Debug, Eq, PartialEq)]
229
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
230
pub enum InteractiveAuthOutcome {
231
    Completed,
232
    Challenge(InteractiveAuthChallenge),
233
}