-
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: GitHub upstream userinfo custom impl for private E-Mails (#665)
* add custom impl for Github private emails * update Github UI template
- Loading branch information
Showing
4 changed files
with
108 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
use crate::entity::auth_providers::AuthProviderIdClaims; | ||
use rauthy_common::constants::APPLICATION_JSON; | ||
use rauthy_error::{ErrorResponse, ErrorResponseType}; | ||
use reqwest::header::{ACCEPT, AUTHORIZATION}; | ||
use serde::Deserialize; | ||
use tracing::debug; | ||
|
||
#[derive(Debug, Deserialize)] | ||
struct GithubEmailPrivateResponse { | ||
email: String, | ||
primary: bool, | ||
verified: bool, | ||
// The visibility exists as well, but we don't care about it at all - no need to deserialize | ||
// visibility: Option<String>, | ||
} | ||
|
||
/// Github is very special and does its own thing, which is super annoying. | ||
/// If a user has no public E-Mail and changed the visibility settings, the | ||
/// user info endpoint will not return any address, even if a valid access token | ||
/// has been provided. In this case, there is another special endpoint only for | ||
/// E-Mail addresses which needs to be used to actually retrieve the address. | ||
/// This means we need a 3rd request to Github. | ||
/// | ||
/// Note: The user endpoint is hardcoded because it is very unlikely to ever | ||
/// change in the future. If we would allow this to be customizable, everything | ||
/// would get super messy. If the Github API ever updates, we just need to update | ||
/// the URL here as well. | ||
pub async fn get_update_github_private_email( | ||
client: &reqwest::Client, | ||
access_token: &str, | ||
claims: &mut AuthProviderIdClaims<'_>, | ||
) -> Result<(), ErrorResponse> { | ||
debug!("Trying to get User E-Mail via Github /user/emails endpoint"); | ||
|
||
let res = client | ||
.get("https://api.github.com/user/emails") | ||
.header(AUTHORIZATION, format!("Bearer {}", access_token)) | ||
// .header(ACCEPT, "application/vnd.github+json") | ||
.header(ACCEPT, APPLICATION_JSON) | ||
.header("X-GitHub-Api-Version", "2022-11-28") | ||
.send() | ||
.await?; | ||
|
||
let status = res.status().as_u16(); | ||
debug!("GET /user/emails status: {}\n{:?}", status, res); | ||
|
||
if status < 300 { | ||
let mut emails = res.json::<Vec<GithubEmailPrivateResponse>>().await?; | ||
debug!("GET /user/emails status: {}", status); | ||
|
||
if emails.len() == 1 { | ||
let email = emails.swap_remove(0); | ||
claims.email = Some(email.email.into()); | ||
claims.email_verified = Some(email.verified); | ||
return Ok(()); | ||
} | ||
|
||
for email in emails { | ||
if email.primary { | ||
claims.email = Some(email.email.into()); | ||
claims.email_verified = Some(email.verified); | ||
return Ok(()); | ||
} | ||
} | ||
|
||
// TODO is it possible that Github returns multiple E-Mails for a user without | ||
// any of them being flagged as primary? | ||
Err(ErrorResponse::new( | ||
ErrorResponseType::Internal, | ||
"Could not find a the primary user E-Mail in Github response", | ||
)) | ||
} else { | ||
let text = res.text().await?; | ||
Err(ErrorResponse::new( | ||
ErrorResponseType::Connection, | ||
format!("Error during User E-Mails lookup: {}", text), | ||
)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters