headless_lms_server/domain/oauth/
revoke_query.rs1use super::helpers::{oauth_invalid_client, oauth_invalid_request};
2use super::oauth_validate::OAuthValidate;
3use crate::prelude::*;
4use secrecy::{ExposeSecret, SecretString};
5use serde::Deserialize;
6use std::collections::HashMap;
7
8#[derive(Debug, Deserialize)]
12pub struct RevokeQuery {
13 pub client_id: Option<String>,
14 pub client_secret: Option<SecretString>,
15 pub token: Option<SecretString>,
17
18 pub token_type_hint: Option<String>,
21 #[serde(flatten)]
23 pub _extra: HashMap<String, String>,
24}
25
26#[derive(Debug)]
27pub struct RevokeParams {
28 pub client_id: String,
29 pub client_secret: Option<SecretString>,
30 pub token: SecretString,
31 pub token_type_hint: Option<String>,
32}
33
34impl OAuthValidate for RevokeQuery {
35 type Output = RevokeParams;
36
37 fn validate(&self) -> Result<Self::Output, ControllerError> {
38 let client_id = self.client_id.as_deref().unwrap_or_default();
39
40 if client_id.is_empty() {
41 return Err(oauth_invalid_client("client_id is required"));
42 }
43
44 let token = self
45 .token
46 .as_ref()
47 .map(|t| t.expose_secret())
48 .unwrap_or_default();
49 if token.is_empty() {
50 return Err(oauth_invalid_request("token is required", None, None));
51 }
52
53 let token_type_hint = self.token_type_hint.as_deref().and_then(|h| {
57 match h {
58 "access_token" | "refresh_token" => Some(h.to_string()),
59 _ => None, }
61 });
62
63 Ok(RevokeParams {
64 client_id: client_id.to_string(),
65 client_secret: self.client_secret.clone(),
66 token: SecretString::new(token.into()),
68 token_type_hint,
69 })
70 }
71}