use crate::{error::Error, id_token::AccessToken, refresh_token::RefreshToken};
#[derive(Debug, Clone, PartialEq)]
pub enum RevokeToken {
AccessToken(AccessToken),
RefreshToken(RefreshToken),
}
impl RevokeToken {
pub fn new_access_token(token: &str) -> Self {
Self::AccessToken(AccessToken(token.to_string()))
}
pub fn new_refresh_token(token: &str) -> Self {
Self::RefreshToken(RefreshToken(token.to_string()))
}
pub fn access_token(&self) -> Option<&AccessToken> {
if let RevokeToken::AccessToken(value) = self {
Some(value)
} else {
None
}
}
pub fn refresh_token(&self) -> Option<&RefreshToken> {
if let RevokeToken::RefreshToken(value) = self {
Some(value)
} else {
None
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct RevokeTokenRequest<'a> {
pub(crate) end_point: &'a str,
pub(crate) token: &'a RevokeToken,
}
impl<'a> RevokeTokenRequest<'a> {
pub fn new(token: &'a RevokeToken) -> Self {
Self {
end_point: "https://oauth2.googleapis.com/revoke",
token,
}
}
pub fn end_point(&self) -> &str {
self.end_point
}
pub fn token(&self) -> &RevokeToken {
self.token
}
pub fn inner_value(&self) -> &str {
match &self.token {
RevokeToken::AccessToken(v) => &v.0,
RevokeToken::RefreshToken(v) => &v.0,
}
}
}
pub async fn send_revoke_token_req(req: &RevokeTokenRequest<'_>) -> Result<(), Error> {
use reqwest::Client;
use std::collections::HashMap;
use tracing::error;
let end_point = req.end_point();
let mut param = HashMap::new();
param.insert("token", req.inner_value());
let client = Client::new();
let status_code = client
.post(end_point)
.header("Content-Type", "application/x-www-form-urlencoded")
.form(¶m)
.send()
.await
.map_err(|e| {
error!("Failed to end request: {:?}", e);
Error::Send
})?
.status();
if status_code.is_success() {
Ok(())
} else {
Err(Error::SendStatus(status_code))
}
}
#[cfg(test)]
mod tests {
use crate::id_token::AccessToken;
use super::{RevokeToken, RevokeTokenRequest};
#[test]
fn test_revoke_req_new() {
let token = RevokeToken::AccessToken(AccessToken("my_access_token".to_string()));
let req = RevokeTokenRequest::new(&token);
assert_eq!(req.token(), &token)
}
#[test]
fn test_revoke_req() {
let token = AccessToken("my_access_token".to_string());
let access_token = RevokeToken::AccessToken(token.clone());
let req = RevokeTokenRequest::new(&access_token);
assert_eq!(req.token(), &access_token);
}
}