+++ /dev/null
-[source]
-[source.debian-packages]
-directory = "/usr/share/cargo/registry"
-[source.crates-io]
-replace-with = "debian-packages"
+++ /dev/null
-[package]
-name = "proxmox-openid"
-version = "0.9.9"
-authors = ["Dietmar Maurer <dietmar@proxmox.com>"]
-edition = "2018"
-license = "AGPL-3"
-exclude = [
- "build",
- "debian",
-]
-
-[lib]
-name = "proxmox_openid"
-path = "src/lib.rs"
-
-[dependencies]
-anyhow = "1.0"
-http = "0.2"
-nix = "0.26"
-openidconnect = { version = "2.4", default-features = false, features = ["accept-rfc3339-timestamps"] }
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-thiserror="1.0"
-ureq = { version = "2.4", default-features = false, features = ["native-tls", "gzip"] }
-native-tls = "0.2"
-url = "2.1"
-
-proxmox-time = "1"
-proxmox-sys = { version = "0.4", features = ["timer"] }
+++ /dev/null
-.PHONY: all
-all: check
-
-.PHONY: check
-check:
- cargo test --all-features
-
-.PHONY: dinstall
-dinstall: deb
- sudo -k dpkg -i build/librust-*.deb
-
-.PHONY: build
-build:
- rm -rf build
- rm -f debian/control
- mkdir build
- debcargo package \
- --config "$(PWD)/debian/debcargo.toml" \
- --changelog-ready \
- --no-overlay-write-back \
- --directory "$(PWD)/build/proxmox-openid" \
- "proxmox-openid" \
- "$$(dpkg-parsechangelog -l "debian/changelog" -SVersion | sed -e 's/-.*//')"
- echo system >build/rust-toolchain
- rm -f build/proxmox-openid/Cargo.lock
- find build/proxmox-openid/debian -name '*.hint' -delete
- cp build/proxmox-openid/debian/control debian/control
-
-.PHONY: deb
-deb: build
- (cd build/proxmox-openid && CARGO=/usr/bin/cargo RUSTC=/usr/bin/rustc dpkg-buildpackage -b -uc -us)
- lintian build/*.deb
-
-.PHONY: clean
-clean:
- rm -rf build *.deb *.buildinfo *.changes *.orig.tar.gz
- cargo clean
-
-upload: deb
- cd build; \
- dcmd --deb rust-proxmox-openid_*.changes \
- | grep -v '.changes$$' \
- | tar -cf "rust-proxmox-openid-debs.tar" -T-; \
- cat "rust-proxmox-openid-debs.tar" | ssh -X repoman@repo.proxmox.com upload --product devel --dist bullseye; \
- rm -f rust-proxmox-openid-debs.tar
--- /dev/null
+This repository was moved into the `proxmox.git` repository.
+++ /dev/null
-rust-proxmox-openid (0.9.9-1) stable; urgency=medium
-
- * update openidconnect to 2.4
-
- -- Proxmox Support Team <support@proxmox.com> Wed, 11 Jan 2023 18:41:25 +0100
-
-rust-proxmox-openid (0.9.8-1) stable; urgency=medium
-
- * update nix to 0.26
-
- -- Proxmox Support Team <support@proxmox.com> Thu, 05 Jan 2023 12:25:10 +0100
-
-rust-proxmox-openid (0.9.7-1) stable; urgency=medium
-
- * bump proxmox-sys to 0.4
-
- -- Proxmox Support Team <support@proxmox.com> Thu, 28 Jul 2022 13:40:44 +0200
-
-rust-proxmox-openid (0.9.6-1) stable; urgency=medium
-
- * rebuild with nix 0.24 and proxmox-sys 0.3
-
- -- Proxmox Support Team <support@proxmox.com> Thu, 2 Jun 2022 12:38:28 +0200
-
-rust-proxmox-openid (0.9.5-1) stable; urgency=medium
-
- * avoid chunked transfer-encoding when submitting to the provider's token
- endpoint, as some providers like Microsoft's Azure are quite inflexible
- and cannot cope with such basic HTTP requests.
-
- -- Proxmox Support Team <support@proxmox.com> Fri, 01 Apr 2022 15:56:07 +0200
-
-rust-proxmox-openid (0.9.4-1) stable; urgency=medium
-
- * re-add HTTP proxy support via the ALL_PROXY environment variable. This got
- lost with switching the HTTP client from curl to ureq.
-
- -- Proxmox Support Team <support@proxmox.com> Tue, 22 Mar 2022 11:31:08 +0100
-
-rust-proxmox-openid (0.9.3-1) stable; urgency=medium
-
- * use much simpler ureq (with native-tls) HTTP client instead of curl
-
- * enable "accept-rfc3339-timestamps" feature to fix support for some OIDC
- providers like `auth0`
-
- -- Proxmox Support Team <support@proxmox.com> Tue, 01 Feb 2022 09:08:31 +0100
-
-rust-proxmox-openid (0.9.2-1) stable; urgency=medium
-
- * depend on proxmox-sys 0.2
-
- -- Proxmox Support Team <support@proxmox.com> Tue, 23 Nov 2021 12:35:41 +0100
-
-rust-proxmox-openid (0.9.1-1) unstable; urgency=medium
-
- * rebuild with openidconnect 0.2.1
-
- -- Proxmox Support Team <support@proxmox.com> Thu, 18 Nov 2021 12:54:24 +0100
-
-rust-proxmox-openid (0.9.0-1) unstable; urgency=medium
-
- * allow to configure used scopes
-
- * allow to configure prompt behaviour
-
- * allow to configure acr values
-
- * new helper verify_authorization_code_simple()
-
- * also return data from UserInfo endpoint
-
- -- Proxmox Support Team <support@proxmox.com> Thu, 18 Nov 2021 09:36:29 +0100
-
-rust-proxmox-openid (0.8.1-1) unstable; urgency=medium
-
- * add fsync parameter to replace_file
-
- * Depend on proxmox 0.15.0
-
- -- Proxmox Support Team <support@proxmox.com> Thu, 21 Oct 2021 07:14:52 +0200
-
-rust-proxmox-openid (0.8.0-1) unstable; urgency=medium
-
- * update to proxmox crate split
-
- -- Proxmox Support Team <support@proxmox.com> Fri, 08 Oct 2021 12:19:55 +0200
-
-rust-proxmox-openid (0.7.0-1) unstable; urgency=medium
-
- * bump proxmox to 0.13.0
-
- -- Proxmox Support Team <support@proxmox.com> Tue, 24 Aug 2021 16:06:55 +0200
-
-rust-proxmox-openid (0.6.1-1) unstable; urgency=medium
-
- * depend on proxmox 0.12.0
-
- -- Proxmox Support Team <support@proxmox.com> Tue, 20 Jul 2021 13:19:23 +0200
-
-rust-proxmox-openid (0.6.0-2) unstable; urgency=medium
-
- * remove debug output
-
- -- Proxmox Support Team <support@proxmox.com> Wed, 30 Jun 2021 08:43:06 +0200
-
-rust-proxmox-openid (0.6.0-1) unstable; urgency=medium
-
- * use one lock file per realm
-
- -- Proxmox Support Team <support@proxmox.com> Fri, 25 Jun 2021 11:09:08 +0200
-
-rust-proxmox-openid (0.5.0-1) unstable; urgency=medium
-
- * avoid unused features "sortable-macro" and "api-macro"
-
- -- Proxmox Support Team <support@proxmox.com> Wed, 23 Jun 2021 11:29:05 +0200
-
-rust-proxmox-openid (0.4.0-1) unstable; urgency=medium
-
- * set "default-features = false" for proxmox crate
-
- -- Proxmox Support Team <support@proxmox.com> Wed, 23 Jun 2021 11:17:22 +0200
-
-rust-proxmox-openid (0.3.0-1) unstable; urgency=medium
-
- * return authorize_url() as string
-
- -- Proxmox Support Team <support@proxmox.com> Tue, 22 Jun 2021 09:23:33 +0200
-
-rust-proxmox-openid (0.2.0-1) devel; urgency=medium
-
- * implement Deserialize/Serialize for OpenIdConfig
-
- -- Proxmox Support Team <support@proxmox.com> Mon, 21 Jun 2021 13:37:24 +0200
-
-rust-proxmox-openid (0.1.0-1) devel; urgency=medium
-
- * initial release
-
- -- Proxmox Support Team <support@proxmox.com> Fri, 18 Jun 2021 16:05:49 +0200
+++ /dev/null
-Source: rust-proxmox-openid
-Section: rust
-Priority: optional
-Build-Depends: debhelper (>= 12),
- dh-cargo (>= 25),
- cargo:native <!nocheck>,
- rustc:native <!nocheck>,
- libstd-rust-dev <!nocheck>,
- librust-anyhow-1+default-dev <!nocheck>,
- librust-http-0.2+default-dev <!nocheck>,
- librust-native-tls-0.2+default-dev <!nocheck>,
- librust-nix-0.26+default-dev <!nocheck>,
- librust-openidconnect-2+accept-rfc3339-timestamps-dev (>= 2.4-~~) <!nocheck>,
- librust-proxmox-sys-0.4+default-dev <!nocheck>,
- librust-proxmox-sys-0.4+timer-dev <!nocheck>,
- librust-proxmox-time-1+default-dev <!nocheck>,
- librust-serde-1+default-dev <!nocheck>,
- librust-serde-1+derive-dev <!nocheck>,
- librust-serde-json-1+default-dev <!nocheck>,
- librust-thiserror-1+default-dev <!nocheck>,
- librust-ureq-2+gzip-dev (>= 2.4-~~) <!nocheck>,
- librust-ureq-2+native-tls-dev (>= 2.4-~~) <!nocheck>,
- librust-url-2+default-dev (>= 2.1-~~) <!nocheck>
-Maintainer: Proxmox Support Team <support@proxmox.com>
-Standards-Version: 4.6.1
-Vcs-Git:
-Vcs-Browser:
-X-Cargo-Crate: proxmox-openid
-Rules-Requires-Root: no
-
-Package: librust-proxmox-openid-dev
-Architecture: any
-Multi-Arch: same
-Depends:
- ${misc:Depends},
- librust-anyhow-1+default-dev,
- librust-http-0.2+default-dev,
- librust-native-tls-0.2+default-dev,
- librust-nix-0.26+default-dev,
- librust-openidconnect-2+accept-rfc3339-timestamps-dev (>= 2.4-~~),
- librust-proxmox-sys-0.4+default-dev,
- librust-proxmox-sys-0.4+timer-dev,
- librust-proxmox-time-1+default-dev,
- librust-serde-1+default-dev,
- librust-serde-1+derive-dev,
- librust-serde-json-1+default-dev,
- librust-thiserror-1+default-dev,
- librust-ureq-2+gzip-dev (>= 2.4-~~),
- librust-ureq-2+native-tls-dev (>= 2.4-~~),
- librust-url-2+default-dev (>= 2.1-~~)
-Provides:
- librust-proxmox-openid+default-dev (= ${binary:Version}),
- librust-proxmox-openid-0-dev (= ${binary:Version}),
- librust-proxmox-openid-0+default-dev (= ${binary:Version}),
- librust-proxmox-openid-0.9-dev (= ${binary:Version}),
- librust-proxmox-openid-0.9+default-dev (= ${binary:Version}),
- librust-proxmox-openid-0.9.9-dev (= ${binary:Version}),
- librust-proxmox-openid-0.9.9+default-dev (= ${binary:Version})
-Description: Rust crate "proxmox-openid" - Rust source code
- This package contains the source for the Rust proxmox-openid crate, packaged by
- debcargo for use with cargo and dh-cargo.
+++ /dev/null
-Copyright (C) 2020-2021 Proxmox Server Solutions GmbH
-
-This software is written by Proxmox Server Solutions GmbH <support@proxmox.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
+++ /dev/null
-overlay = "."
-crate_src_path = ".."
-maintainer = "Proxmox Support Team <support@proxmox.com>"
-
-[source]
-# TODO: update once public
-vcs_git = ""
-vcs_browser = ""
+++ /dev/null
-use std::path::{Path, PathBuf};
-
-use anyhow::{bail, Error};
-use serde_json::{json, Value};
-
-use proxmox_sys::fs::{
- replace_file,
- open_file_locked,
- file_get_json,
- CreateOptions,
-};
-use proxmox_time::epoch_i64;
-
-use super::{PublicAuthState, PrivateAuthState};
-
-fn load_auth_state_locked(
- state_dir: &Path,
- realm: &str,
- default: Option<Value>,
-) -> Result<(PathBuf, std::fs::File, Vec<Value>), Error> {
-
- let mut lock_path = state_dir.to_owned();
- lock_path.push(format!("proxmox-openid-auth-state-{}.lck", realm));
-
- let lock = open_file_locked(
- lock_path,
- std::time::Duration::new(10, 0),
- true,
- CreateOptions::new()
- )?;
-
- let mut path = state_dir.to_owned();
- path.push(format!("proxmox-openid-auth-state-{}", realm));
-
- let now = epoch_i64();
-
- let old_data = file_get_json(&path, default)?;
-
- let mut data: Vec<Value> = Vec::new();
-
- let timeout = 10*60; // 10 minutes
-
- for v in old_data.as_array().unwrap() {
- let ctime = v["ctime"].as_i64().unwrap_or(0);
- if (ctime + timeout) < now {
- continue;
- }
- data.push(v.clone());
- }
-
- Ok((path, lock, data))
-}
-
-fn replace_auth_state(
- path: &Path,
- data: &Vec<Value>,
-) -> Result<(), Error> {
-
- let mode = nix::sys::stat::Mode::from_bits_truncate(0o0600);
- let options = CreateOptions::new().perm(mode);
- let raw = serde_json::to_string_pretty(data)?;
-
- replace_file(path, raw.as_bytes(), options, false)?;
-
- Ok(())
-}
-
-pub fn verify_public_auth_state(
- state_dir: &Path,
- state: &str,
-) -> Result<(String, PrivateAuthState), Error> {
-
- let public_auth_state: PublicAuthState = serde_json::from_str(state)?;
-
- let (path, _lock, old_data) = load_auth_state_locked(state_dir, &public_auth_state.realm, None)?;
-
- let mut data: Vec<Value> = Vec::new();
-
- let mut entry: Option<PrivateAuthState> = None;
- let find_csrf_token = public_auth_state.csrf_token.secret();
- for v in old_data {
- if v["csrf_token"].as_str() == Some(find_csrf_token) {
- entry = Some(serde_json::from_value(v)?);
- } else {
- data.push(v);
- }
- }
-
- let entry = match entry {
- None => bail!("no openid auth state found (possible timeout)"),
- Some(entry) => entry,
- };
-
- replace_auth_state(&path, &data)?;
-
- Ok((public_auth_state.realm, entry))
-}
-
-pub fn store_auth_state(
- state_dir: &Path,
- realm: &str,
- auth_state: &PrivateAuthState,
-) -> Result<(), Error> {
-
- let (path, _lock, mut data) = load_auth_state_locked(state_dir, realm, Some(json!([])))?;
-
- if data.len() > 100 {
- bail!("too many pending openid auth request for realm {}", realm);
- }
-
- data.push(serde_json::to_value(&auth_state)?);
-
- replace_auth_state(&path, &data)?;
-
- Ok(())
-}
+++ /dev/null
-use std::env;
-use std::sync::Arc;
-
-use http::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
-use http::method::Method;
-use http::status::StatusCode;
-
-use openidconnect::{HttpRequest, HttpResponse};
-
-// Copied from OAuth2 create, because we want to use ureq with
-// native-tls. But current OAuth2 crate pulls in rustls, so we cannot
-// use their 'ureq' feature.
-
-///
-/// Error type returned by failed ureq HTTP requests.
-///
-#[derive(Debug, thiserror::Error)]
-pub enum Error {
- /// Non-ureq HTTP error.
- #[error("HTTP error - {0}")]
- Http(#[from] http::Error),
-
- /// IO error
- #[error("IO error - {0}")]
- IO(#[from] std::io::Error),
-
- /// Error returned by ureq crate.
- // boxed due to https://github.com/algesten/ureq/issues/296
- #[error("ureq request failed - {0}")]
- Ureq(#[from] Box<ureq::Error>),
-
- #[error("TLS error - {0}")]
- Tls(#[from] native_tls::Error),
-
- /// Other error.
- #[error("Other error: {0}")]
- Other(String),
-}
-
-fn ureq_agent() -> Result<ureq::Agent, Error> {
- let mut agent =
- ureq::AgentBuilder::new().tls_connector(Arc::new(native_tls::TlsConnector::new()?));
- if let Ok(val) = env::var("all_proxy").or_else(|_| env::var("ALL_PROXY")) {
- let proxy = ureq::Proxy::new(val).map_err(Box::new)?;
- agent = agent.proxy(proxy);
- }
-
- Ok(agent.build())
-}
-
-///
-/// Synchronous HTTP client for ureq.
-///
-pub fn http_client(request: HttpRequest) -> Result<HttpResponse, Error> {
- let agent = ureq_agent()?;
- let mut req = if let Method::POST = request.method {
- agent.post(&request.url.to_string())
- } else {
- agent.get(&request.url.to_string())
- };
-
- for (name, value) in request.headers {
- if let Some(name) = name {
- req = req.set(
- &name.to_string(),
- value.to_str().map_err(|_| {
- Error::Other(format!(
- "invalid {} header value {:?}",
- name,
- value.as_bytes()
- ))
- })?,
- );
- }
- }
-
- let response = if let Method::POST = request.method {
- // send_bytes makes sure that Content-Length is set. This is important, because some
- // endpoints don't accept `Transfer-Encoding: chunked`, which would otherwise be set.
- // see https://docs.rs/ureq/2.4.0/ureq/index.html#content-length-and-transfer-encoding
- req.send_bytes(request.body.as_slice())
- } else {
- req.call()
- }
- .map_err(Box::new)?;
-
- let status_code =
- StatusCode::from_u16(response.status()).map_err(|err| Error::Http(err.into()))?;
-
- let content_type =
- HeaderValue::from_str(response.content_type()).map_err(|err| Error::Http(err.into()))?;
-
- Ok(HttpResponse {
- status_code,
- headers: vec![(CONTENT_TYPE, content_type)]
- .into_iter()
- .collect::<HeaderMap>(),
- body: response.into_string()?.as_bytes().into(),
- })
-}
+++ /dev/null
-use std::path::Path;
-
-use anyhow::{format_err, Error};
-use serde::{Deserialize, Serialize};
-use serde_json::Value;
-
-mod http_client;
-pub use http_client::http_client;
-
-mod auth_state;
-pub use auth_state::*;
-
-
-use openidconnect::{
- //curl::http_client,
- core::{
- CoreProviderMetadata,
- CoreClient,
- CoreIdTokenClaims,
- CoreIdTokenVerifier,
- CoreAuthenticationFlow,
- CoreAuthDisplay,
- CoreAuthPrompt,
- CoreGenderClaim,
- },
- PkceCodeChallenge,
- PkceCodeVerifier,
- AuthorizationCode,
- ClientId,
- ClientSecret,
- CsrfToken,
- IssuerUrl,
- Nonce,
- OAuth2TokenResponse,
- RedirectUrl,
- Scope,
- UserInfoClaims,
- AdditionalClaims,
- AuthenticationContextClass,
-};
-
-/// Stores Additional Claims into a serde_json::Value;
-#[derive(Debug, Deserialize, Serialize)]
-pub struct GenericClaims(Value);
-impl AdditionalClaims for GenericClaims {}
-
-pub type GenericUserInfoClaims = UserInfoClaims<GenericClaims, CoreGenderClaim>;
-
-#[derive(Debug, Deserialize, Serialize, Clone)]
-pub struct OpenIdConfig {
- pub issuer_url: String,
- pub client_id: String,
- #[serde(skip_serializing_if="Option::is_none")]
- pub client_key: Option<String>,
- #[serde(skip_serializing_if="Option::is_none")]
- pub scopes: Option<Vec<String>>,
- #[serde(skip_serializing_if="Option::is_none")]
- pub prompt: Option<String>,
- #[serde(skip_serializing_if="Option::is_none")]
- pub acr_values: Option<Vec<String>>,
-}
-
-pub struct OpenIdAuthenticator {
- client: CoreClient,
- config: OpenIdConfig,
-}
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct PublicAuthState {
- pub csrf_token: CsrfToken,
- pub realm: String,
-}
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct PrivateAuthState {
- pub csrf_token: CsrfToken,
- pub nonce: Nonce,
- pub pkce_verifier: PkceCodeVerifier,
- pub ctime: i64,
-}
-
-impl PrivateAuthState {
-
- pub fn new() -> Self {
- let nonce = Nonce::new_random();
- let csrf_token = CsrfToken::new_random();
- let (_pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256();
-
- PrivateAuthState {
- csrf_token,
- nonce,
- pkce_verifier,
- ctime: proxmox_time::epoch_i64(),
- }
- }
-
- pub fn pkce_verifier(&self) -> PkceCodeVerifier {
- // Note: PkceCodeVerifier does not impl. clone()
- PkceCodeVerifier::new(self.pkce_verifier.secret().to_string())
- }
-
- pub fn pkce_challenge(&self) -> PkceCodeChallenge {
- PkceCodeChallenge::from_code_verifier_sha256(&self.pkce_verifier)
- }
-
- pub fn public_state_string(&self, realm: String) -> Result<String, Error> {
- let pub_state = PublicAuthState {
- csrf_token: self.csrf_token.clone(),
- realm,
- };
- Ok(serde_json::to_string(&pub_state)?)
- }
-}
-
-impl OpenIdAuthenticator {
-
- pub fn discover(config: &OpenIdConfig, redirect_url: &str) -> Result<Self, Error> {
-
- let client_id = ClientId::new(config.client_id.clone());
- let client_key = config.client_key.clone().map(|key| ClientSecret::new(key));
- let issuer_url = IssuerUrl::new(config.issuer_url.clone())?;
-
- let provider_metadata = CoreProviderMetadata::discover(&issuer_url, http_client)?;
-
- let client = CoreClient::from_provider_metadata(
- provider_metadata,
- client_id,
- client_key,
- ).set_redirect_uri(RedirectUrl::new(String::from(redirect_url))?);
-
- Ok(Self {
- client,
- config: config.clone(),
- })
- }
-
- pub fn authorize_url(&self, state_dir: &str, realm: &str) -> Result<String, Error> {
-
- let private_auth_state = PrivateAuthState::new();
- let public_auth_state = private_auth_state.public_state_string(realm.to_string())?;
- let nonce = private_auth_state.nonce.clone();
-
- store_auth_state(Path::new(state_dir), realm, &private_auth_state)?;
-
- // Generate the authorization URL to which we'll redirect the user.
- let mut request = self.client
- .authorize_url(
- CoreAuthenticationFlow::AuthorizationCode,
- || CsrfToken::new(public_auth_state),
- || nonce,
- )
- .set_pkce_challenge(private_auth_state.pkce_challenge());
-
- request = request.set_display(CoreAuthDisplay::Page);
-
- match self.config.prompt.as_deref() {
- None => { /* nothing */ },
- Some("none") => {
- request = request.add_prompt(CoreAuthPrompt::None);
- }
- Some("login") => {
- request = request.add_prompt(CoreAuthPrompt::Login);
- }
- Some("consent") => {
- request = request.add_prompt(CoreAuthPrompt::Consent);
- }
- Some("select_account") => {
- request = request.add_prompt(CoreAuthPrompt::SelectAccount);
- }
- Some(extension) => {
- request = request.add_prompt(CoreAuthPrompt::Extension(extension.into()));
- }
- }
-
- if let Some(ref scopes) = self.config.scopes {
- for scope in scopes.clone() {
- request = request.add_scope(Scope::new(scope));
- }
- }
-
- if let Some(ref acr_values) = self.config.acr_values {
- for acr in acr_values.clone() {
- request = request.add_auth_context_value(AuthenticationContextClass::new(acr));
- }
- }
-
- let (authorize_url, _csrf_state, _nonce) = request.url();
-
- Ok(authorize_url.to_string())
- }
-
- pub fn verify_public_auth_state(
- state_dir: &str,
- state: &str,
- ) -> Result<(String, PrivateAuthState), Error> {
- verify_public_auth_state(Path::new(state_dir), state)
- }
-
- pub fn verify_authorization_code(
- &self,
- code: &str,
- private_auth_state: &PrivateAuthState,
- ) -> Result<(CoreIdTokenClaims, GenericUserInfoClaims), Error> {
-
- let code = AuthorizationCode::new(code.to_string());
- // Exchange the code with a token.
- let token_response = self.client
- .exchange_code(code)
- .set_pkce_verifier(private_auth_state.pkce_verifier())
- .request(http_client)
- .map_err(|err| format_err!("Failed to contact token endpoint: {}", err))?;
-
- let id_token_verifier: CoreIdTokenVerifier = self.client.id_token_verifier();
- let id_token_claims: &CoreIdTokenClaims = token_response
- .extra_fields()
- .id_token()
- .expect("Server did not return an ID token")
- .claims(&id_token_verifier, &private_auth_state.nonce)
- .map_err(|err| format_err!("Failed to verify ID token: {}", err))?;
-
- let userinfo_claims: GenericUserInfoClaims = self.client
- .user_info(token_response.access_token().to_owned(), None)?
- .request(http_client)
- .map_err(|err| format_err!("Failed to contact userinfo endpoint: {}", err))?;
-
- Ok((id_token_claims.clone(), userinfo_claims))
- }
-
- /// Like verify_authorization_code(), but returns claims as serde_json::Value
- pub fn verify_authorization_code_simple(
- &self,
- code: &str,
- private_auth_state: &PrivateAuthState,
- ) -> Result<Value, Error> {
-
- let (id_token_claims, userinfo_claims) = self.verify_authorization_code(&code, &private_auth_state)?;
-
- let mut data = serde_json::to_value(id_token_claims)?;
-
- let data2 = serde_json::to_value(userinfo_claims)?;
-
- if let Some(map) = data2.as_object() {
- for (key, value) in map {
- if data[key] != Value::Null {
- continue; // already set
- }
- data[key] = value.clone();
- }
- }
-
- Ok(data)
- }
-}