feat: libpaket: openid: logout and revoke

This commit is contained in:
jane400 2024-09-19 21:42:11 +02:00 committed by jane400
parent 31698154e0
commit 4d0f8f57ce
2 changed files with 96 additions and 13 deletions

View file

@ -1,16 +1,22 @@
use super::utils::CodeVerfier;
use super::dhl_claims::DHLClaimsOptional;
use super::utils::CodeVerfier;
use serde::Serialize;
pub fn client_id() -> &'static str {
"42ec7de4-e357-4c5d-aa63-f6aae5ca4d8f"
}
pub fn redirect_uri() -> &'static str {
pub fn redirect_uri_login() -> &'static str {
"dhllogin://de.dhl.paket/login"
}
pub fn redirect_uri_logout() -> &'static str {
"dhllogout://de.dhl.paket/logout"
}
pub mod token {
use crate::login::DHLIdToken;
use super::*;
pub fn refresh_token_form(refresh_token: &str) -> Vec<(&str, &str)> {
@ -20,7 +26,7 @@ pub mod token {
("client_id", client_id()),
]
}
pub fn authorization_code_form(
authorization_code: String,
code_verfier: &CodeVerfier,
@ -28,21 +34,33 @@ pub mod token {
vec![
("code".to_string(), authorization_code),
("grant_type".to_string(), "authorization_code".to_string()),
("redirect_uri".to_string(), redirect_uri().to_string()),
("redirect_uri".to_string(), redirect_uri_login().to_string()),
("code_verifier".to_string(), code_verfier.code_verfier()),
("client_id".to_string(), client_id().to_string()),
]
}
pub fn revoke_form(
token: String
) -> Vec<(String, String)> {
vec![
("token".into(), token),
("client_id".into(), client_id().into()),
]
}
pub fn user_agent() -> &'static str {
"Dalvik/2.1.0 (Linux; U; Android 11; OnePlus 6T Build/RQ3A.211001.001)"
}
pub fn endpoint() -> &'static str {
"https://login.dhl.de/af5f9bb6-27ad-4af4-9445-008e7a5cddb8/login/token"
}
pub fn endpoint_revoke() -> &'static str {
"https://login.dhl.de/af5f9bb6-27ad-4af4-9445-008e7a5cddb8/login/token/revoke"
}
pub fn headers() -> reqwest::header::HeaderMap {
let aaa = vec![
("Content-Type", "application/x-www-form-urlencoded"),
@ -52,19 +70,43 @@ pub mod token {
("Connection", "Keep-Alive"),
("Accept-Encoding", "gzip"),
];
let mut map = reqwest::header::HeaderMap::new();
for bbb in aaa {
map.append(bbb.0, bbb.1.parse().unwrap());
}
map
}
}
pub mod logout {
use crate::{constants::web_user_agent, login::{
constants::{client_id, redirect_uri_logout},
DHLIdToken,
}};
pub fn form(id_token: &DHLIdToken) -> Vec<(String, String)> {
vec![
("id_token_hint".into(), id_token.to_string()),
("state".into(), "esnGubTtYjK5ImleO84prQ".into()),
("client_id".into(), client_id().into()),
("redirect_uri".into(), redirect_uri_logout().into()),
]
}
pub fn endpoint() -> &'static str {
"https://login.dhl.de/af5f9bb6-27ad-4af4-9445-008e7a5cddb8/auth-ui/logout"
}
pub fn user_agent() -> String {
web_user_agent()
}
}
pub mod webbrowser_authorize {
use crate::constants::web_user_agent;
use super::*;
use crate::constants::web_user_agent;
pub fn user_agent() -> String {
web_user_agent()
@ -112,7 +154,7 @@ pub mod webbrowser_authorize {
pub fn authorize_query(nonce: &String, code_verfier: &CodeVerfier) -> Vec<(String, String)> {
vec![
("redirect_uri".to_string(), redirect_uri().to_string()),
("redirect_uri".to_string(), redirect_uri_login().to_string()),
("client_id".to_string(), client_id().to_string()),
("response_type".to_string(), "code".to_string()),
("prompt".to_string(), "login".to_string()),

View file

@ -4,12 +4,14 @@ mod openid_response;
pub mod openid_token;
mod utils;
use constants::redirect_uri_logout;
pub use self::dhl_claims::{DHLCs, DHLIdToken};
pub use self::openid_response::{RefreshToken, TokenResponse};
pub use self::utils::{create_nonce, CodeVerfier};
use super::common::APIResult;
use crate::LibraryResult;
use crate::{LibraryError, LibraryResult};
pub struct OpenIdClient {
client: reqwest::Client,
@ -67,4 +69,43 @@ impl OpenIdClient {
Ok(parse_json_response_from_apiresult!(res, TokenResponse))
}
// TODO: Unauthorized not correct error response
pub async fn logout(&self, dhli_token: &DHLIdToken) -> LibraryResult<()> {
let req = self
.client
.get(constants::logout::endpoint())
.form(constants::logout::form(dhli_token).as_slice())
.header("Host", "login.dhl.de")
.header("User-Agent", constants::logout::user_agent())
.build()
.unwrap();
let res = self.client.execute(req).await;
let res = parse_response_internal!(res);
if let Some(value) = res.headers().get("Location") {
if value.to_str().unwrap().starts_with(redirect_uri_logout()) {
Ok(())
} else {
Err(crate::LibraryError::Unauthorized)
}
} else {
Err(crate::LibraryError::Unauthorized)
}
}
// TODO: Unauthorized not correct error response
pub async fn revoke(&self, refresh_token: &RefreshToken) -> LibraryResult<()> {
let res = request_post!(self.client,
(constants::token::endpoint()),
.form(constants::token::revoke_form(refresh_token.to_string()).as_slice())
);
if res.status() == 200 {
Ok(())
} else {
Err(LibraryError::Unauthorized)
}
}
}