matrix_sdk/authentication/oauth/
account_management_url.rs1use ruma::{
20 api::client::discovery::get_authorization_server_metadata::v1::AccountManagementAction,
21 OwnedDeviceId,
22};
23use url::Url;
24
25#[derive(Debug, Clone, PartialEq, Eq)]
32#[non_exhaustive]
33pub enum AccountManagementActionFull {
34 Profile,
38
39 SessionsList,
43
44 SessionView {
48 device_id: OwnedDeviceId,
50 },
51
52 SessionEnd {
56 device_id: OwnedDeviceId,
58 },
59
60 AccountDeactivate,
64
65 CrossSigningReset,
69}
70
71impl AccountManagementActionFull {
72 pub fn action_type(&self) -> AccountManagementAction {
75 match self {
76 Self::Profile => AccountManagementAction::Profile,
77 Self::SessionsList => AccountManagementAction::SessionsList,
78 Self::SessionView { .. } => AccountManagementAction::SessionView,
79 Self::SessionEnd { .. } => AccountManagementAction::SessionEnd,
80 Self::AccountDeactivate => AccountManagementAction::AccountDeactivate,
81 Self::CrossSigningReset => AccountManagementAction::CrossSigningReset,
82 }
83 }
84
85 fn append_to_url(&self, url: &mut Url) {
87 let mut query_pairs = url.query_pairs_mut();
88 query_pairs.append_pair("action", self.action_type().as_str());
89
90 match self {
91 Self::SessionView { device_id } | Self::SessionEnd { device_id } => {
92 query_pairs.append_pair("device_id", device_id.as_str());
93 }
94 _ => {}
95 }
96 }
97}
98
99#[derive(Debug, Clone)]
135pub struct AccountManagementUrlBuilder {
136 account_management_uri: Url,
137 action: Option<AccountManagementActionFull>,
138}
139
140impl AccountManagementUrlBuilder {
141 pub(super) fn new(account_management_uri: Url) -> Self {
143 Self { account_management_uri, action: None }
144 }
145
146 pub fn action(mut self, action: AccountManagementActionFull) -> Self {
148 self.action = Some(action);
149 self
150 }
151
152 pub fn build(self) -> Url {
154 let mut account_management_uri = self.account_management_uri;
156
157 if let Some(action) = &self.action {
158 action.append_to_url(&mut account_management_uri);
159 }
160
161 account_management_uri
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use ruma::owned_device_id;
168 use url::Url;
169
170 use super::{AccountManagementActionFull, AccountManagementUrlBuilder};
171
172 #[test]
173 fn test_build_account_management_url_actions() {
174 let base_url = Url::parse("https://example.org").unwrap();
175 let device_id = owned_device_id!("ABCDEFG");
176
177 let url = AccountManagementUrlBuilder::new(base_url.clone()).build();
178 assert_eq!(url, base_url);
179
180 let url = AccountManagementUrlBuilder::new(base_url.clone())
181 .action(AccountManagementActionFull::Profile)
182 .build();
183 assert_eq!(url.as_str(), "https://example.org/?action=org.matrix.profile");
184
185 let url = AccountManagementUrlBuilder::new(base_url.clone())
186 .action(AccountManagementActionFull::SessionsList)
187 .build();
188 assert_eq!(url.as_str(), "https://example.org/?action=org.matrix.sessions_list");
189
190 let url = AccountManagementUrlBuilder::new(base_url.clone())
191 .action(AccountManagementActionFull::SessionView { device_id: device_id.clone() })
192 .build();
193 assert_eq!(
194 url.as_str(),
195 "https://example.org/?action=org.matrix.session_view&device_id=ABCDEFG"
196 );
197
198 let url = AccountManagementUrlBuilder::new(base_url.clone())
199 .action(AccountManagementActionFull::SessionEnd { device_id })
200 .build();
201 assert_eq!(
202 url.as_str(),
203 "https://example.org/?action=org.matrix.session_end&device_id=ABCDEFG"
204 );
205
206 let url = AccountManagementUrlBuilder::new(base_url.clone())
207 .action(AccountManagementActionFull::AccountDeactivate)
208 .build();
209 assert_eq!(url.as_str(), "https://example.org/?action=org.matrix.account_deactivate");
210
211 let url = AccountManagementUrlBuilder::new(base_url)
212 .action(AccountManagementActionFull::CrossSigningReset)
213 .build();
214 assert_eq!(url.as_str(), "https://example.org/?action=org.matrix.cross_signing_reset");
215 }
216
217 #[test]
218 fn test_build_account_management_url_with_query() {
219 let base_url = Url::parse("https://example.org/?sid=123456").unwrap();
220
221 let url = AccountManagementUrlBuilder::new(base_url.clone())
222 .action(AccountManagementActionFull::Profile)
223 .build();
224 assert_eq!(url.as_str(), "https://example.org/?sid=123456&action=org.matrix.profile");
225
226 let url = AccountManagementUrlBuilder::new(base_url)
227 .action(AccountManagementActionFull::SessionView {
228 device_id: owned_device_id!("ABCDEFG"),
229 })
230 .build();
231 assert_eq!(
232 url.as_str(),
233 "https://example.org/?sid=123456&action=org.matrix.session_view&device_id=ABCDEFG"
234 );
235 }
236}