Draft: SSO login (OAuth 2.0 + OpenID Connect) #1012
6 changed files with 137 additions and 227 deletions
89
Cargo.lock
generated
89
Cargo.lock
generated
|
@ -540,7 +540,6 @@ dependencies = [
|
|||
"jsonwebtoken",
|
||||
"lazy_static",
|
||||
"lru-cache",
|
||||
"macaroon",
|
||||
"nix",
|
||||
"num_cpus",
|
||||
"openidconnect",
|
||||
|
@ -845,19 +844,10 @@ dependencies = [
|
|||
"digest",
|
||||
"elliptic-curve",
|
||||
"rfc6979",
|
||||
"signature 2.2.0",
|
||||
"signature",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7"
|
||||
dependencies = [
|
||||
"signature 1.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519"
|
||||
version = "2.2.3"
|
||||
|
@ -865,7 +855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
|
||||
dependencies = [
|
||||
"pkcs8",
|
||||
"signature 2.2.0",
|
||||
"signature",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -875,7 +865,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"ed25519 2.2.3",
|
||||
"ed25519",
|
||||
"rand_core",
|
||||
"serde",
|
||||
"sha2",
|
||||
|
@ -1678,18 +1668,6 @@ dependencies = [
|
|||
"zstd-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsodium-sys"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b779387cd56adfbc02ea4a668e704f729be8d6a6abd2c27ca5ee537849a92fd"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.26.0"
|
||||
|
@ -1753,19 +1731,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macaroon"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b15778101dd1d3a58a95fd2af33821b38bc44a408bcf03e0e5e194f42c08050"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sodiumoxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
|
@ -2610,7 +2575,7 @@ dependencies = [
|
|||
"pkcs1",
|
||||
"pkcs8",
|
||||
"rand_core",
|
||||
"signature 2.2.0",
|
||||
"signature",
|
||||
"spki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
|
@ -2907,15 +2872,6 @@ version = "1.0.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.23"
|
||||
|
@ -3184,12 +3140,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "1.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "2.2.0"
|
||||
|
@ -3243,18 +3193,6 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sodiumoxide"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e26be3acb6c2d9a7aac28482586a7856436af4cfe7100031d219de2d2ecb0028"
|
||||
dependencies = [
|
||||
"ed25519 1.5.3",
|
||||
"libc",
|
||||
"libsodium-sys",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
|
@ -3899,16 +3837,6 @@ version = "0.9.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
|
@ -4040,15 +3968,6 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
|
|
@ -55,8 +55,6 @@ bytes = "1.4.0"
|
|||
http = "0.2.9"
|
||||
# Used to find data directory for default db path
|
||||
directories = "4.0.1"
|
||||
# Used for SSO authorization
|
||||
macaroon = "0.3.0"
|
||||
# Used for ruma wrapper
|
||||
serde_json = { version = "1.0.96", features = ["raw_value"] }
|
||||
# Used for appservice registration files
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
use crate::{
|
||||
service::sso::{templates, Provider, COOKIE_STATE_EXPIRATION_SECS},
|
||||
services, Error, Ruma, RumaResponse,
|
||||
service::sso::{macaroon::Macaroon, templates, COOKIE_STATE_EXPIRATION_SECS},
|
||||
services, Error, Ruma,
|
||||
};
|
||||
use askama::Template;
|
||||
use axum::{body::Full, response::IntoResponse};
|
||||
use axum_extra::extract::cookie::{Cookie, SameSite};
|
||||
use bytes::BytesMut;
|
||||
use http::StatusCode;
|
||||
use macaroon::ByteString;
|
||||
use openidconnect::{reqwest::{http_client, async_http_client}, AuthorizationCode, CsrfToken, TokenResponse};
|
||||
use http::{HeaderValue, StatusCode};
|
||||
use openidconnect::{
|
||||
AuthorizationCode, CsrfToken,
|
||||
};
|
||||
use ruma::api::{
|
||||
client::{error::ErrorKind, session},
|
||||
OutgoingResponse,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use time::macros::format_description;
|
||||
|
||||
/// # `GET /_matrix/client/v3/login/sso/redirect`
|
||||
///
|
||||
|
@ -50,11 +50,13 @@ pub async fn get_sso_redirect_with_provider(
|
|||
|
||||
let location = Some(body.idp_id.clone());
|
||||
|
||||
let (url, nonce, cookie) = match services().sso.find_one(&body.idp_id).map(|provider| provider.handle_redirect(body.redirect_url.as_deref().unwrap_or_default())) {
|
||||
Ok(fut)=> fut.await,
|
||||
Err(e)=> return e.into_response(),
|
||||
};
|
||||
|
||||
let (url, nonce, cookie) =
|
||||
match services().sso.find_one(&body.idp_id).map(|provider| {
|
||||
provider.handle_redirect(body.redirect_url.unwrap())
|
||||
}) {
|
||||
Ok(fut) => fut.await,
|
||||
Err(e) => return e.into_response(),
|
||||
};
|
||||
|
||||
let cookie = Cookie::build("openid-state", cookie)
|
||||
.path("/_conduit/client/sso")
|
||||
|
@ -107,8 +109,11 @@ fn get_sso_fallback_template(redirect_url: &str) -> axum::response::Response {
|
|||
pub struct Callback {
|
||||
pub code: AuthorizationCode,
|
||||
pub state: CsrfToken,
|
||||
pub verifier: String,
|
||||
}
|
||||
|
||||
pub struct Session {}
|
||||
|
||||
/// # `GET /_conduit/client/oidc/callback`
|
||||
///
|
||||
/// Verify the response received from the identity provider.
|
||||
|
@ -117,9 +122,16 @@ pub async fn get_sso_callback(
|
|||
cookie: axum::extract::TypedHeader<axum::headers::Cookie>,
|
||||
axum::extract::Query(callback): axum::extract::Query<Callback>,
|
||||
) -> axum::response::Response {
|
||||
// TODO
|
||||
let clear_cookie = Cookie::build("openid-state", "")
|
||||
.path("/_conduit/client/sso")
|
||||
.finish()
|
||||
.to_string();
|
||||
|
||||
let Callback { code, state } = callback;
|
||||
let Callback {
|
||||
code,
|
||||
state,
|
||||
verifier,
|
||||
} = callback;
|
||||
|
||||
let Some(cookie) = cookie.get("openid-state") else {
|
||||
return Error::BadRequest(
|
||||
|
@ -129,26 +141,24 @@ pub async fn get_sso_callback(
|
|||
.into_response();
|
||||
};
|
||||
|
||||
let provider = match Provider::verify_macaroon(cookie.as_bytes(), state)
|
||||
.and_then(|macaroon| services().sso.find_one(macaroon.identifier().into()))
|
||||
{
|
||||
Ok(provider) => provider,
|
||||
let macaroon = match Macaroon::verify(cookie, state.secret()) {
|
||||
Ok(macaroon) => macaroon,
|
||||
Err(error) => return error.into_response(),
|
||||
};
|
||||
|
||||
let provider = match services().sso.find_one(macaroon.idp_id.as_ref()) {
|
||||
Ok(provider) => provider,
|
||||
Err(error) => return error.into_response(),
|
||||
};
|
||||
let session = serde_json::to_string(cookie).unwrap();
|
||||
|
||||
let user_info = provider.handle_callback(code, macaroon.nonce).await;
|
||||
|
||||
|
||||
let cookie = Cookie::build("openid-state", "")
|
||||
.path("/_conduit/client/sso")
|
||||
.finish()
|
||||
.to_string();
|
||||
|
||||
let user_info = provider.handle_callback(code, nonce);
|
||||
|
||||
// if let Some(verifier) = pkce {
|
||||
// macaroon.add_first_party_caveat(format!("verifier = {}", verifier).into());
|
||||
// }
|
||||
|
||||
(TypedHeader(ContentType::text_utf8()), "Hello, World!").into_response()
|
||||
(
|
||||
axum::TypedHeader(axum::headers::Location(
|
||||
HeaderValue::from_str(clear_cookie.as_str()).unwrap(),
|
||||
)),
|
||||
"Hello, World!",
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ pub struct Service {
|
|||
pub rotate: RotationHandler,
|
||||
|
||||
pub shutdown: AtomicBool,
|
||||
pub macaroon: Option<macaroon::MacaroonKey>,
|
||||
pub macaroon_key: Option<String>,
|
||||
}
|
||||
|
||||
/// Handles "rotation" of long-polling requests. "Rotation" in this context is similar to "rotation" of log files and the like.
|
||||
|
@ -183,11 +183,6 @@ impl Service {
|
|||
// Experimental, partially supported room versions
|
||||
let unstable_room_versions = vec![RoomVersionId::V3, RoomVersionId::V4, RoomVersionId::V5];
|
||||
|
||||
let macaroon = config
|
||||
.macaroon_key
|
||||
.as_ref()
|
||||
.map(|s| macaroon::MacaroonKey::generate(s.as_bytes()));
|
||||
|
||||
let mut s = Self {
|
||||
db,
|
||||
config,
|
||||
|
@ -218,7 +213,7 @@ impl Service {
|
|||
sync_receivers: RwLock::new(HashMap::new()),
|
||||
rotate: RotationHandler::new(),
|
||||
shutdown: AtomicBool::new(false),
|
||||
macaroon,
|
||||
macaroon_key: config.macaroon_key.clone(),
|
||||
};
|
||||
|
||||
fs::create_dir_all(s.get_media_folder())?;
|
||||
|
|
44
src/service/sso/macaroon.rs
Normal file
44
src/service/sso/macaroon.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation};
|
||||
use openidconnect::{Nonce, PkceCodeVerifier, RedirectUrl, CsrfToken};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::Error;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Macaroon {
|
||||
pub idp_id: String,
|
||||
pub nonce: Nonce,
|
||||
pub csrf: CsrfToken,
|
||||
pub redirect_url: Option<RedirectUrl>,
|
||||
pub pkce_verifier: Option<PkceCodeVerifier>,
|
||||
pub time: i64,
|
||||
}
|
||||
|
||||
impl Macaroon {
|
||||
pub fn encode(&self, macaroon: &str) -> Result<String, jsonwebtoken::errors::Error> {
|
||||
jsonwebtoken::encode(
|
||||
&Header::default(),
|
||||
self,
|
||||
&EncodingKey::from_secret(macaroon.as_bytes()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn verify(token: &str, macaroon: &str) -> Result<Self, Error> {
|
||||
let decoded = jsonwebtoken::decode::<Self>(
|
||||
token,
|
||||
&DecodingKey::from_secret(macaroon.as_bytes()),
|
||||
&Validation::new(Algorithm::HS256),
|
||||
)
|
||||
.map_err(|_| {
|
||||
Error::BadRequest(
|
||||
ruma::api::client::error::ErrorKind::Unauthorized,
|
||||
"macaroon decoding",
|
||||
)
|
||||
})?;
|
||||
|
||||
Err(Error::BadRequest(
|
||||
ruma::api::client::error::ErrorKind::Unauthorized,
|
||||
"macaroon invalid",
|
||||
))
|
||||
}
|
||||
}
|
|
@ -1,24 +1,32 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
mod session;
|
||||
|
||||
use futures_util::future::{self};
|
||||
use macaroon::{Macaroon, Verifier};
|
||||
use openidconnect::{
|
||||
core::{CoreAuthenticationFlow, CoreClient, CoreGenderClaim, CoreProviderMetadata},
|
||||
core::{
|
||||
CoreAuthenticationFlow, CoreClient, CoreGenderClaim, CoreIdTokenClaims,
|
||||
CoreProviderMetadata, CoreUserInfoClaims,
|
||||
},
|
||||
reqwest::async_http_client,
|
||||
AccessTokenHash, AdditionalClaims, AuthUrl, AuthorizationCode, ClientId, ClientSecret,
|
||||
CsrfToken, IssuerUrl, Nonce, NonceVerifier, OAuth2TokenResponse, PkceCodeChallenge,
|
||||
RedirectUrl, Scope, SubjectIdentifier, TokenResponse, TokenUrl, UserInfoClaims, UserInfoUrl,
|
||||
PkceCodeVerifier, RedirectUrl, Scope, SubjectIdentifier, TokenResponse, TokenUrl,
|
||||
UserInfoClaims, UserInfoUrl,
|
||||
};
|
||||
use ruma::api::client::{error::ErrorKind, session::get_login_types::v3::IdentityProvider};
|
||||
use time::macros::format_description;
|
||||
use time::{macros::format_description, OffsetDateTime};
|
||||
|
||||
use crate::{
|
||||
config::{ClientConfig, DiscoveryConfig as Discovery, ProviderConfig},
|
||||
services, Config, Error,
|
||||
};
|
||||
|
||||
use self::macaroon::Macaroon;
|
||||
|
||||
pub const COOKIE_STATE_EXPIRATION_SECS: i64 = 60 * 60;
|
||||
|
||||
pub mod macaroon;
|
||||
pub mod templates;
|
||||
|
||||
pub struct Service {
|
||||
|
@ -128,116 +136,54 @@ impl Provider {
|
|||
Ok(Arc::new(config))
|
||||
}
|
||||
|
||||
pub async fn handle_redirect(&self, redirect_url: &str) -> (url::Url, String, String) {
|
||||
pub async fn handle_redirect(&self, redirect_url: &RedirectUrl) -> (url::Url, String, String) {
|
||||
let client = self.client.clone();
|
||||
let scopes = self.scopes.iter().map(ToOwned::to_owned).map(Scope::new);
|
||||
|
||||
let mut req = client
|
||||
.authorize_url(
|
||||
CoreAuthenticationFlow::Implicit(true),
|
||||
|| CsrfToken::new_random_len(36),
|
||||
|| Nonce::new_random_len(36),
|
||||
|| CsrfToken::new_random_len(48),
|
||||
|| Nonce::new_random_len(48),
|
||||
)
|
||||
.add_scopes(scopes);
|
||||
|
||||
let (challenge, verifier) = PkceCodeChallenge::new_random_sha256();
|
||||
if let Some(true) = self.pkce {
|
||||
req = req.set_pkce_challenge(challenge);
|
||||
}
|
||||
let pkce_verifier = match self.pkce {
|
||||
Some(true) => {
|
||||
let (challenge, verifier) = PkceCodeChallenge::new_random_sha256();
|
||||
req = req.set_pkce_challenge(challenge);
|
||||
|
||||
Some(verifier)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let (url, csrf, nonce) = req.url();
|
||||
|
||||
let cookie = self.generate_macaroon(
|
||||
self.inner.id.as_str(),
|
||||
csrf.secret(),
|
||||
nonce.secret(),
|
||||
redirect_url,
|
||||
self.pkce.map(|_| verifier.secret().as_str()),
|
||||
);
|
||||
let key = services()
|
||||
.globals
|
||||
.macaroon_key
|
||||
.as_deref()
|
||||
.expect("macaroon key")
|
||||
.to_owned();
|
||||
let cookie = Macaroon {
|
||||
idp_id: self.inner.id.clone(),
|
||||
csrf,
|
||||
nonce: nonce.clone(),
|
||||
time: OffsetDateTime::now_utc().unix_timestamp(),
|
||||
redirect_url: Some(redirect_url.clone()),
|
||||
pkce_verifier,
|
||||
};
|
||||
let cookie = cookie.encode(&key).expect("bad key");
|
||||
|
||||
(url, nonce.secret().to_owned(), cookie)
|
||||
}
|
||||
|
||||
pub fn generate_macaroon(
|
||||
&self,
|
||||
idp_id: &str,
|
||||
state: &str,
|
||||
nonce: &str,
|
||||
redirect_url: &str,
|
||||
pkce: Option<&str>,
|
||||
) -> String {
|
||||
let key = services().globals.macaroon.unwrap();
|
||||
|
||||
let mut macaroon = Macaroon::create(None, &key, idp_id.into()).unwrap();
|
||||
let expires = (time::OffsetDateTime::now_utc()
|
||||
+ time::Duration::seconds(COOKIE_STATE_EXPIRATION_SECS))
|
||||
.to_string();
|
||||
|
||||
let idp_id = self.inner.id.as_str();
|
||||
|
||||
for caveat in [
|
||||
format!("idp_id = {idp_id}"),
|
||||
format!("state = {state}"),
|
||||
format!("nonce = {nonce}"),
|
||||
format!("redirect_url = {redirect_url}"),
|
||||
format!("time < {expires}"),
|
||||
] {
|
||||
macaroon.add_first_party_caveat(caveat.into());
|
||||
}
|
||||
|
||||
if let Some(verifier) = pkce {
|
||||
macaroon.add_first_party_caveat(format!("verifier = {}", verifier).into());
|
||||
}
|
||||
|
||||
macaroon.serialize(macaroon::Format::V2).unwrap()
|
||||
}
|
||||
|
||||
pub fn verify_macaroon(cookie: &[u8], state: CsrfToken) -> Result<Macaroon, Error> {
|
||||
let mut verifier = Verifier::default();
|
||||
|
||||
let macaroon = Macaroon::deserialize(cookie).map_err(|e| {
|
||||
Error::BadRequest(ErrorKind::BadJson, "Could not deserialize SSO macaroon")
|
||||
})?;
|
||||
|
||||
verifier.satisfy_exact(format!("state = {}", state.secret()).into());
|
||||
|
||||
// let verification = |s: &ByteString, id: &str| {
|
||||
// s.0.starts_with(format!("{id} =").as_bytes()); // TODO
|
||||
// };
|
||||
|
||||
verifier.satisfy_general(|s| s.0.starts_with(b"idp_id ="));
|
||||
verifier.satisfy_general(|s| s.0.starts_with(b"nonce ="));
|
||||
verifier.satisfy_general(|s| s.0.starts_with(b"redirect_url ="));
|
||||
|
||||
verifier.satisfy_general(|s| {
|
||||
let format_desc = format_description!(
|
||||
"[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour \
|
||||
sign:mandatory]:[offset_minute]:[offset_second]"
|
||||
);
|
||||
|
||||
let now = time::OffsetDateTime::now_utc();
|
||||
|
||||
time::OffsetDateTime::parse(std::str::from_utf8(&s.0).unwrap(), format_desc)
|
||||
.map(|expires| now < expires)
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
let key = services().globals.macaroon.unwrap();
|
||||
|
||||
verifier
|
||||
.verify(&macaroon, &key, Default::default())
|
||||
.map_err(|e| {
|
||||
Error::BadRequest(ErrorKind::Unauthorized, "Macaroon verification failed")
|
||||
})?;
|
||||
|
||||
Ok(macaroon)
|
||||
}
|
||||
|
||||
pub async fn handle_callback<Claims: AdditionalClaims>(
|
||||
&self,
|
||||
code: AuthorizationCode,
|
||||
nonce: Nonce,
|
||||
) -> Result<UserInfoClaims<Claims, CoreGenderClaim>, Error> {
|
||||
) -> Result<(), Error> {
|
||||
let resp = self
|
||||
.client
|
||||
.exchange_code(code)
|
||||
|
@ -260,14 +206,12 @@ impl Provider {
|
|||
}
|
||||
}
|
||||
|
||||
let Ok(req) = self.client.user_info(
|
||||
resp.access_token().to_owned(),
|
||||
self.subject_claim.clone().map(SubjectIdentifier::new),
|
||||
) else {
|
||||
resp.extra_fields();
|
||||
panic!()
|
||||
};
|
||||
|
||||
Ok(req.request_async(async_http_client).await.unwrap())
|
||||
// match self.client.user_info(
|
||||
// resp.access_token().to_owned(),
|
||||
// self.subject_claim.clone().map(SubjectIdentifier::new),
|
||||
// ).map(|req| req.request_async(async_http_client)) {
|
||||
// Err(e) => Ok(claims),
|
||||
// Ok(req) => req.await,
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue