diff --git a/src/bin/trainee-tracker.rs b/src/bin/trainee-tracker.rs index c3c2bd7..98f7b37 100644 --- a/src/bin/trainee-tracker.rs +++ b/src/bin/trainee-tracker.rs @@ -110,6 +110,10 @@ async fn main() { "/api/expected-attendance", get(trainee_tracker::endpoints::expected_attendance), ) + .route( + "/api/started-itp", + get(trainee_tracker::endpoints::started_itp), + ) .route( "/codility/verify-webhook", post(trainee_tracker::codility::verify_webhook), diff --git a/src/endpoints.rs b/src/endpoints.rs index fef2505..0a17f62 100644 --- a/src/endpoints.rs +++ b/src/endpoints.rs @@ -1,4 +1,7 @@ -use std::{collections::BTreeMap, ops::AddAssign}; +use std::{ + collections::{BTreeMap, BTreeSet}, + ops::AddAssign, +}; use ::octocrab::models::{Author, teams::RequestedTeam}; use anyhow::Context; @@ -18,7 +21,7 @@ use crate::{ Error, ServerState, github_accounts::get_trainees, newtypes::GithubLogin, - octocrab::{all_pages, octocrab}, + octocrab::{all_pages, octocrab, octocrab_for_maybe_token}, prs::{PrWithReviews, fill_in_reviewers, get_prs}, register::{Attendance, get_register}, sheets::sheets_client, @@ -331,3 +334,30 @@ pub async fn expected_attendance( } Json(expected_attendance) } + +pub async fn started_itp( + session: Session, + State(server_state): State, + OriginalUri(original_uri): OriginalUri, +) -> Result>, Error> { + let octocrab = octocrab(&session, &server_state, original_uri).await; + // Allow un-authenticated requests to this endpoint. + let octocrab = if let Ok(octocrab) = octocrab { + octocrab + } else { + octocrab_for_maybe_token(None)? + }; + let prs = all_pages("pull requests", &octocrab, async || { + octocrab + .pulls(server_state.config.github_org, "Module-Onboarding") + .list() + .send() + .await + }) + .await?; + let usernames: BTreeSet<_> = prs + .into_iter() + .filter_map(|pr| Some(GithubLogin::from(pr.user?.login))) + .collect(); + Ok(Json(usernames)) +} diff --git a/src/octocrab.rs b/src/octocrab.rs index b05dc52..f694ea6 100644 --- a/src/octocrab.rs +++ b/src/octocrab.rs @@ -39,6 +39,19 @@ pub(crate) async fn octocrab( } pub fn octocrab_for_token(token: String) -> Result { + octocrab_for_maybe_token(Some(token)) +} + +pub fn octocrab_for_maybe_token(token: Option) -> Result { + let header_value = if let Some(token) = token { + Some( + HeaderValue::from_str(&format!("Bearer {token}")) + .context("Token couldn't used as a header")?, + ) + } else { + None + }; + let connector = HttpsConnectorBuilder::new() .with_webpki_roots() .https_only() @@ -67,10 +80,7 @@ pub fn octocrab_for_token(token: String) -> Result { HeaderValue::from_static("octocrab"), )]))) .with_layer(&AuthHeaderLayer::new( - Some( - HeaderValue::from_str(&format!("Bearer {token}")) - .context("Token couldn't used as a header")?, - ), + header_value, Uri::from_static(GITHUB_BASE_URI), Uri::from_static(GITHUB_BASE_UPLOAD_URI), ))