Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

github-on-prem - auth_info retrieval from github app #14

Merged
merged 8 commits into from
Oct 21, 2023
Merged
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ ARG BITBUCKET_CLIENT_SECRET
ARG BITBUCKET_BASE_URL
ARG INSTALL_ID
ARG SERVER_URL
ARG GITHUB_CLIENT_ID
ARG GITHUB_CLIENT_SECRET
ARG GITHUB_BASE_URL
ARG GITHUB_APP_ID


ENV GCP_CREDENTIALS=$GCP_CREDENTIALS
Expand All @@ -29,9 +33,14 @@ ENV BITBUCKET_CLIENT_SECRET=$BITBUCKET_CLIENT_SECRET
ENV BITBUCKET_BASE_URL=$BITBUCKET_BASE_URL
ENV INSTALL_ID=$INSTALL_ID
ENV SERVER_URL=$SERVER_URL
ENV GITHUB_CLIENT_ID=$GITHUB_CLIENT_ID
ENV GITHUB_CLIENT_SECRET=$GITHUB_CLIENT_SECRET
ENV GITHUB_BASE_URL=$GITHUB_BASE_URL
ENV GITHUB_APP_ID=$GITHUB_APP_ID

COPY ./vibi-dpu/target/debug/vibi-dpu /app/vibi-dpu
COPY ./pubsub-sa-test.json /app/pubsub-sa.json
COPY ./repoprofiler_private.pem /app/repoprofiler_private.pem

# Start the Rust application
CMD ["/app/vibi-dpu"]
71 changes: 54 additions & 17 deletions vibi-dpu/src/github/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use serde_json::Value;
use std::env;
use chrono::{Utc, Duration};
use std::fs;
use crate::client::config::get_client;
use crate::{client::config::get_client, utils::auth::AuthInfo};

#[derive(Debug, Serialize, Deserialize)]
struct AccessTokenResponse {
Expand All @@ -19,34 +19,71 @@ struct Claims {
iss: String,
}

fn generate_jwt(github_app_id: &str) -> Result<String, Box<dyn std::error::Error>> {
let pem_file_path = "/tmp/repoprofiler_private.pem";
let pem_data = fs::read(pem_file_path)?;
fn generate_jwt(github_app_id: &str) -> Option<String> {
let pem_file_path = "/app/repoprofiler_private.pem";
let pem_data_res = fs::read(pem_file_path);

if pem_data_res.is_err() {
let pem_data_err = pem_data_res.expect_err("No error in reading pem file");
println!("Error reading pem file: {:?}", pem_data_err);
return None;
}
let pem_data = pem_data_res.expect("Error reading pem file");

let my_claims = Claims {
iat: Utc::now().timestamp(),
exp: (Utc::now() + Duration::minutes(5)).timestamp(),
iss: github_app_id.to_string(),
};

let encoding_key = EncodingKey::from_rsa_pem(&pem_data)?;
let token = encode(&Header::new(Algorithm::RS256), &my_claims, &encoding_key)?;
let encoding_key = EncodingKey::from_rsa_pem(&pem_data);
if encoding_key.is_err() {
println!("Error creating encoding key");
return None;
}

Ok(token)
let token_res = encode(&Header::new(Algorithm::RS256), &my_claims, &encoding_key.unwrap());
if token_res.is_err() {
let token_err = token_res.expect_err("No error in fetching token");
println!("Error encoding JWT: {:?}", token_err);
return None;
};
let token = token_res.expect("Error encoding JWT");
Some(token)
}

pub async fn fetch_access_token(installation_id: &str) -> Result<Value, Box<dyn std::error::Error>> {
let github_app_id = env::var("GITHUB_APP_ID")?;
let jwt_token = generate_jwt(&github_app_id)?;
pub async fn fetch_access_token(installation_id: &str) -> Option<Value> {
let github_app_id = env::var("GITHUB_APP_ID");
let github_app_id_str = github_app_id.expect("GITHUB_APP_ID must be set");
let jwt_token = generate_jwt(&github_app_id_str).expect("Error generating JWT");

let client = get_client();
let response: Value = client.post(&format!("https://api.github.com/app/installations/{}/access_tokens", installation_id))
let response = client.post(&format!("https://api.github.com/app/installations/{}/access_tokens", installation_id))
.header("Accept", "application/vnd.github+json")
.header("Authorization", format!("Bearer {}", jwt_token))
.header("User-Agent", "Vibinex code review Test App")
.send()
.await?
.json()
.await?;
println!("[fetch_access_token] response = {:?}", response);
Ok(response)
}
.await;
if response.is_err() {
let e = response.expect_err("No error in response");
eprintln!("error in calling github api : {:?}", e);
return None;
}
let response_access_token = response.expect("Uncaught error in reponse");
if !response_access_token.status().is_success() {
println!(
"Failed to exchange code for access token. Status code: {}, Response content: {:?}",
response_access_token.status(),
response_access_token.text().await
);
return None;
}
let parse_res = response_access_token.json().await ;
if parse_res.is_err() {
let e = parse_res.expect_err("No error in parse_res for AuthInfo");
eprintln!("error deserializing AuthInfo: {:?}", e);
return None;
}
let response_json: Value = parse_res.expect("Uncaught error in parse_res for AuthInfo");
return Some(response_json);
}