]> git.proxmox.com Git - proxmox-openid-rs.git/commitdiff
This repository was moved into the `proxmox.git` repository master
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 24 May 2023 09:27:07 +0000 (11:27 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 24 May 2023 09:27:07 +0000 (11:27 +0200)
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
.cargo/config [deleted file]
Cargo.toml [deleted file]
Makefile [deleted file]
README [new file with mode: 0644]
debian/changelog [deleted file]
debian/control [deleted file]
debian/copyright [deleted file]
debian/debcargo.toml [deleted file]
src/auth_state.rs [deleted file]
src/http_client.rs [deleted file]
src/lib.rs [deleted file]

diff --git a/.cargo/config b/.cargo/config
deleted file mode 100644 (file)
index 3b5b6e4..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-[source]
-[source.debian-packages]
-directory = "/usr/share/cargo/registry"
-[source.crates-io]
-replace-with = "debian-packages"
diff --git a/Cargo.toml b/Cargo.toml
deleted file mode 100644 (file)
index 2410ac5..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-[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"] }
diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index e108fb1..0000000
--- a/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-.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
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e87b585
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+This repository was moved into the `proxmox.git` repository.
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644 (file)
index 21341ce..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-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
diff --git a/debian/control b/debian/control
deleted file mode 100644 (file)
index 4c5e7c5..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-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.
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644 (file)
index 477c305..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-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/>.
diff --git a/debian/debcargo.toml b/debian/debcargo.toml
deleted file mode 100644 (file)
index 703440f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-overlay = "."
-crate_src_path = ".."
-maintainer = "Proxmox Support Team <support@proxmox.com>"
-
-[source]
-# TODO: update once public
-vcs_git = ""
-vcs_browser = ""
diff --git a/src/auth_state.rs b/src/auth_state.rs
deleted file mode 100644 (file)
index 7692ff3..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-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(())
-}
diff --git a/src/http_client.rs b/src/http_client.rs
deleted file mode 100644 (file)
index e391421..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-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(),
-    })
-}
diff --git a/src/lib.rs b/src/lib.rs
deleted file mode 100644 (file)
index e9fbd94..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-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)
-    }
-}