diff --git a/Cargo.lock b/Cargo.lock
index e29d1e5..eeb7dc5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1041,6 +1041,20 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
+[[package]]
+name = "light-openid"
+version = "0.1.0-alpha"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1745cac605f9565d6fffdcf9b18ee6e51d95b16a8304533fc88e06e30537dc6f"
+dependencies = [
+ "base64",
+ "log",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "urlencoding",
+]
+
[[package]]
name = "linux-raw-sys"
version = "0.3.4"
@@ -1193,12 +1207,12 @@ dependencies = [
"env_logger",
"futures-util",
"lazy_static",
+ "light-openid",
"log",
"rand",
"reqwest",
"serde",
"serde_json",
- "urlencoding",
]
[[package]]
@@ -1413,9 +1427,9 @@ checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
[[package]]
name = "reqwest"
-version = "0.11.16"
+version = "0.11.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254"
+checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91"
dependencies = [
"base64",
"bytes",
diff --git a/Cargo.toml b/Cargo.toml
index 56f1f42..27d4563 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+light-openid = "0.1.0-alpha"
log = "0.4.17"
env_logger = "0.10.0"
clap = { version = "4.2.4", features = ["derive", "env"] }
@@ -15,7 +16,6 @@ askama = "0.12.0"
serde = { version = "1.0.160", features = ["derive"] }
serde_json = "1.0.96"
reqwest = { version = "0.11.16", features = ["json"] }
-urlencoding = "2.1.2"
futures-util = "0.3.28"
aes-gcm = "0.10.1"
base64 = "0.21.0"
diff --git a/src/lib.rs b/src/lib.rs
index 1def6df..664e496 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,7 +4,6 @@ pub type Res = Result>;
pub mod app_config;
pub mod crypto_wrapper;
-pub mod openid_primitives;
pub mod remote_ip;
pub mod state_manager;
pub mod time_utils;
diff --git a/src/main.rs b/src/main.rs
index 7faee55..150b4f6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,9 +1,9 @@
use actix_web::middleware::Logger;
use actix_web::{get, web, App, HttpResponse, HttpServer};
use askama::Template;
+use light_openid::primitives::OpenIDConfig;
use oidc_test_client::app_config::AppConfig;
-use oidc_test_client::openid_primitives::OpenIDConfig;
use oidc_test_client::remote_ip::RemoteIP;
use oidc_test_client::state_manager::StateManager;
@@ -61,7 +61,7 @@ async fn home() -> HttpResponse {
#[get("/start")]
async fn start(remote_ip: RemoteIP) -> HttpResponse {
- let config = match OpenIDConfig::load_from(&AppConfig::get().configuration_url).await {
+ let config = match OpenIDConfig::load_from_url(&AppConfig::get().configuration_url).await {
Ok(c) => c,
Err(e) => {
log::error!("Failed to load OpenID configuration! {e}");
@@ -77,7 +77,7 @@ async fn start(remote_ip: RemoteIP) -> HttpResponse {
}
};
- let authorization_url = config.authorization_url(
+ let authorization_url = config.gen_authorization_url(
&AppConfig::get().client_id,
&state,
&AppConfig::get().redirect_url(),
@@ -103,7 +103,7 @@ async fn redirect(remote_ip: RemoteIP, query: web::Query) -> Http
}
// Then, load OpenID configuration
- let config = match OpenIDConfig::load_from(&AppConfig::get().configuration_url).await {
+ let config = match OpenIDConfig::load_from_url(&AppConfig::get().configuration_url).await {
Ok(c) => c,
Err(e) => {
log::error!("Failed to load OpenID configuration! {e}");
diff --git a/src/openid_primitives.rs b/src/openid_primitives.rs
deleted file mode 100644
index 7518012..0000000
--- a/src/openid_primitives.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
-use base64::Engine;
-use std::collections::HashMap;
-
-use crate::Res;
-
-#[derive(Debug, Clone, serde::Deserialize)]
-pub struct OpenIDConfig {
- pub authorization_endpoint: String,
- pub token_endpoint: String,
- pub userinfo_endpoint: String,
-}
-
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
-pub struct TokenResponse {
- pub access_token: String,
- pub token_type: String,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub refresh_token: Option,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub expires_in: Option,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub id_token: Option,
-}
-
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
-pub struct UserInfo {
- pub sub: String,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub name: Option,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub given_name: Option,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub family_name: Option,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub preferred_username: Option,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub email: Option,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub email_verified: Option,
-}
-
-impl OpenIDConfig {
- /// Load OpenID configuration from a given URL
- pub async fn load_from(url: &str) -> Res {
- Ok(reqwest::get(url).await?.json().await?)
- }
-
- /// Get the authorization URL where a user should be redirect
- pub fn authorization_url(&self, client_id: &str, state: &str, redirect_uri: &str) -> String {
- let client_id = urlencoding::encode(client_id);
- let state = urlencoding::encode(state);
- let redirect_uri = urlencoding::encode(redirect_uri);
-
- format!("{}?response_type=code&scope=openid%20profile%20email&client_id={client_id}&state={state}&redirect_uri={redirect_uri}", self.authorization_endpoint)
- }
-
- /// Query the token endpoint
- pub async fn request_token(
- &self,
- client_id: &str,
- client_secret: &str,
- code: &str,
- redirect_uri: &str,
- ) -> Res<(TokenResponse, String)> {
- let authorization = BASE64_STANDARD.encode(format!("{}:{}", client_id, client_secret));
-
- let mut params = HashMap::new();
- params.insert("grant_type", "authorization_code");
- params.insert("code", code);
- params.insert("redirect_uri", redirect_uri);
-
- let response = reqwest::Client::new()
- .post(&self.token_endpoint)
- .header("Authorization", format!("Basic {authorization}"))
- .form(¶ms)
- .send()
- .await?
- .text()
- .await?;
-
- Ok((serde_json::from_str(&response)?, response))
- }
-
- /// Query the UserInfo endpoint
- pub async fn request_user_info(&self, token: &TokenResponse) -> Res<(UserInfo, String)> {
- let response = reqwest::Client::new()
- .get(&self.userinfo_endpoint)
- .header("Authorization", format!("Bearer {}", token.access_token))
- .send()
- .await?
- .text()
- .await?;
-
- Ok((serde_json::from_str(&response)?, response))
- }
-}