Skip to content

Commit f620303

Browse files
committed
feat: added middleware for security purposes on verifier api calls
1 parent c9196d5 commit f620303

File tree

3 files changed

+149
-25
lines changed

3 files changed

+149
-25
lines changed

fplus-http-server/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ edition = "2021"
99
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1010

1111
[dependencies]
12+
futures-util = "0.3"
1213
actix-web = "4.3.1"
14+
actix-utils = "3.0.1"
1315
serde = { version = "1.0.164", features = ["derive", "std",
1416
"serde_derive", "alloc", "rc"] }
1517
tokio = { version = "1.29.1", features = ["full"] }
@@ -26,4 +28,3 @@ anyhow = "1.0.75"
2628
async-trait = "0.1.73"
2729
uuidv4 = "1.0.0"
2830
log = "0.4.20"
29-

fplus-http-server/src/main.rs

Lines changed: 126 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,125 @@
1-
use std::env;
2-
3-
use actix_web::middleware::Logger;
4-
use actix_web::{App, HttpServer};
51
use env_logger;
62
use log::info;
73
use fplus_database;
84
pub(crate) mod router;
5+
use reqwest::Client;
6+
use serde::Deserialize;
7+
8+
use std::{env, future::{ready, Ready}};
9+
10+
use actix_web::{
11+
App,
12+
HttpServer,
13+
web,
14+
middleware::Logger,
15+
dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
16+
Error,
17+
HttpResponse,
18+
http::StatusCode,
19+
};
20+
use futures_util::future::LocalBoxFuture;
21+
22+
#[derive(Deserialize, Debug)]
23+
struct RepoQuery {
24+
owner: String,
25+
repo: String,
26+
}
27+
28+
pub struct GHAuth;
29+
30+
impl<S, B> Transform<S, ServiceRequest> for GHAuth
31+
where
32+
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
33+
S::Future: 'static,
34+
B: 'static,
35+
{
36+
type Response = ServiceResponse<B>;
37+
type Error = Error;
38+
type InitError = ();
39+
type Transform = GHAuthMiddleware<S>;
40+
type Future = Ready<Result<Self::Transform, Self::InitError>>;
41+
42+
fn new_transform(&self, service: S) -> Self::Future {
43+
ready(Ok(GHAuthMiddleware { service }))
44+
}
45+
}
46+
47+
pub struct GHAuthMiddleware<S> {
48+
service: S,
49+
}
50+
51+
impl<S, B> Service<ServiceRequest> for GHAuthMiddleware<S>
52+
where
53+
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
54+
S::Future: 'static,
55+
B: 'static,
56+
{
57+
type Response = ServiceResponse<B>;
58+
type Error = Error;
59+
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
60+
61+
forward_ready!(service);
62+
63+
fn call(&self, req: ServiceRequest) -> Self::Future {
64+
let query_string = req.query_string();
65+
let query: Result<web::Query<RepoQuery>, _> = web::Query::from_query(query_string);
66+
67+
let auth_header_value = req.headers().get("Authorization")
68+
.and_then(|hv| hv.to_str().ok())
69+
.filter(|hv| hv.starts_with("Bearer "))
70+
.map(|hv| hv["Bearer ".len()..].to_string());
71+
let fut = self.service.call(req);
72+
73+
Box::pin(async move {
74+
// if let Some(token) = auth_header_value {
75+
// // Make the asynchronous HTTP request here
76+
// let client = Client::new();
77+
// let user_info_result = client.get("https://api.github.com/user")
78+
// .header("Authorization", format!("Bearer {}", token))
79+
// .header("User-Agent", "Actix-web")
80+
// .send()
81+
// .await;
82+
83+
// match user_info_result {
84+
// Ok(response) => {
85+
// if response.status().is_success() {
86+
// let user_info = response
87+
// .json::<serde_json::Value>()
88+
// .await
89+
// .expect("Failed to parse JSON");
90+
91+
// if let Some(login) = user_info.get("login").and_then(|v| v.as_str()) {
92+
// println!("Login: {}", login);
93+
// } else {
94+
// println!("Login information not found.");
95+
// }
96+
// } else {
97+
// println!("Failed to get GitHub user info");
98+
// }
99+
// },
100+
// Err(e) => println!("Request error: {:?}", e),
101+
// }
102+
// }
103+
104+
// match database::get_allocator(&owner, &repo).await {
105+
// Ok(allocator) => {
106+
// match allocator {
107+
// Some(allocator) => HttpResponse::Ok().json(allocator),
108+
// None => HttpResponse::NotFound().finish(),
109+
// }
110+
// },
111+
// Err(e) => {
112+
// HttpResponse::InternalServerError().body(e.to_string())
113+
// }
114+
// }
115+
116+
let res = fut.await?;
117+
println!("Hi from response");
118+
Ok(res)
119+
})
120+
}
121+
}
122+
9123

10124
#[tokio::main]
11125
async fn main() -> std::io::Result<()> {
@@ -27,9 +141,14 @@ async fn main() -> std::io::Result<()> {
27141
.wrap(cors)
28142
.service(router::health)
29143
.service(router::application::create)
30-
.service(router::application::trigger)
31-
.service(router::application::propose)
32-
.service(router::application::approve)
144+
.service(
145+
web::scope("/api")
146+
.wrap(GHAuth) // Apply GitHubAuth to all routes under "/api"
147+
.service(router::application::testz)
148+
.service(router::application::trigger)
149+
.service(router::application::propose)
150+
.service(router::application::approve)
151+
)
33152
.service(router::application::merged)
34153
.service(router::application::active)
35154
.service(router::application::all_applications)

fplus-http-server/src/router/application.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,30 @@ pub async fn single(query: web::Query<ApplicationQueryParams>) -> impl Responder
3232
}
3333
}
3434

35-
#[post("/application/{id}/trigger")]
35+
#[post("/testz")]
36+
pub async fn testz(
37+
query: web::Query<ApplicationQueryParams>
38+
) -> impl Responder {
39+
println!("testzzzz {:?} {:?}", query.owner, query.repo);
40+
return HttpResponse::Ok()
41+
}
42+
43+
#[post("/application/trigger")]
3644
pub async fn trigger(
37-
id: web::Path<String>,
45+
query: web::Query<ApplicationQueryParams>,
3846
info: web::Json<CompleteGovernanceReviewInfo>,
3947
) -> impl Responder {
4048

41-
let CompleteGovernanceReviewInfo { actor, owner, repo } = info.into_inner();
42-
let ldn_application = match LDNApplication::load(id.into_inner(), owner.clone(), repo.clone()).await {
49+
let CompleteGovernanceReviewInfo { actor} = info.into_inner();
50+
let ldn_application = match LDNApplication::load(query.id.clone(), query.owner.clone(), query.repo.clone()).await {
4351
Ok(app) => app,
4452
Err(e) => {
4553
return HttpResponse::BadRequest().body(e.to_string());
4654
}
4755
};
4856
dbg!(&ldn_application);
4957
match ldn_application
50-
.complete_governance_review(actor, owner, repo)
58+
.complete_governance_review(actor, query.id.clone(), query.repo.clone())
5159
.await
5260
{
5361
Ok(app) => HttpResponse::Ok().body(serde_json::to_string_pretty(&app).unwrap()),
@@ -58,25 +66,23 @@ pub async fn trigger(
5866
}
5967
}
6068

61-
#[post("/application/{id}/propose")]
69+
#[post("/application/propose")]
6270
pub async fn propose(
63-
id: web::Path<String>,
6471
info: web::Json<CompleteNewApplicationProposalInfo>,
72+
query: web::Query<ApplicationQueryParams>,
6573
) -> impl Responder {
6674
let CompleteNewApplicationProposalInfo {
6775
signer,
6876
request_id,
69-
owner,
70-
repo
7177
} = info.into_inner();
72-
let ldn_application = match LDNApplication::load(id.into_inner(), owner.clone(), repo.clone()).await {
78+
let ldn_application = match LDNApplication::load(query.id.clone(), query.owner.clone(), query.repo.clone()).await {
7379
Ok(app) => app,
7480
Err(e) => {
7581
return HttpResponse::BadRequest().body(e.to_string());
7682
}
7783
};
7884
match ldn_application
79-
.complete_new_application_proposal(signer, request_id, owner, repo)
85+
.complete_new_application_proposal(signer, request_id, query.owner.clone(), query.repo.clone())
8086
.await
8187
{
8288
Ok(app) => HttpResponse::Ok().body(serde_json::to_string_pretty(&app).unwrap()),
@@ -86,26 +92,24 @@ pub async fn propose(
8692
}
8793
}
8894

89-
#[post("/application/{id}/approve")]
95+
#[post("/application/approve")]
9096
pub async fn approve(
91-
id: web::Path<String>,
97+
query: web::Query<ApplicationQueryParams>,
9298
info: web::Json<CompleteNewApplicationProposalInfo>,
9399
) -> impl Responder {
94100
let CompleteNewApplicationProposalInfo {
95101
signer,
96102
request_id,
97-
owner,
98-
repo
99103
} = info.into_inner();
100-
let ldn_application = match LDNApplication::load(id.into_inner(), owner.clone(), repo.clone()).await {
104+
let ldn_application = match LDNApplication::load(query.id.clone(), query.owner.clone(), query.repo.clone()).await {
101105
Ok(app) => app,
102106
Err(e) => {
103107
return HttpResponse::BadRequest().body(e.to_string());
104108
}
105109
};
106110
dbg!(&ldn_application);
107111
match ldn_application
108-
.complete_new_application_approval(signer, request_id, owner, repo)
112+
.complete_new_application_approval(signer, request_id, query.owner.clone(), query.repo.clone())
109113
.await
110114
{
111115
Ok(app) => HttpResponse::Ok().body(serde_json::to_string_pretty(&app).unwrap()),

0 commit comments

Comments
 (0)