Skip to content

Commit 32d9b56

Browse files
committed
feat: finalized verifier auth through gh handle. moved middleware file to separate folder
1 parent 6339dc3 commit 32d9b56

File tree

3 files changed

+139
-118
lines changed

3 files changed

+139
-118
lines changed

fplus-http-server/src/main.rs

Lines changed: 4 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,18 @@
11
use env_logger;
22
use log::info;
3-
use fplus_database::database;
3+
mod middleware;
4+
use middleware::gh_auth;
45
pub(crate) mod router;
5-
use reqwest::Client;
6-
use serde::Deserialize;
7-
8-
use std::{env, future::{ready, Ready}};
6+
use std::env;
97

108
use actix_web::{
119
App,
1210
HttpServer,
1311
web,
1412
middleware::Logger,
15-
dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
16-
Error,
17-
HttpResponse,
18-
http::StatusCode,
1913
};
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-
let RepoQuery { owner, repo } = match query {
67-
Ok(q) => q.into_inner(),
68-
Err(_) => {
69-
return Box::pin(async {
70-
return Err(actix_web::error::ErrorBadRequest("Wrong query string format"));
71-
});
72-
}
73-
};
74-
75-
let auth_header_value = req.headers().get("Authorization")
76-
.and_then(|hv| hv.to_str().ok())
77-
.filter(|hv| hv.starts_with("Bearer "))
78-
.map(|hv| hv["Bearer ".len()..].to_string());
79-
let fut = self.service.call(req);
80-
81-
Box::pin(async move {
82-
if let Some(token) = auth_header_value {
83-
// Make the asynchronous HTTP request here
84-
let client = Client::new();
85-
let user_info_result = client.get("https://api.github.com/user")
86-
.header("Authorization", format!("Bearer {}", token))
87-
.header("User-Agent", "Actix-web")
88-
.send()
89-
.await;
90-
91-
match user_info_result {
92-
Ok(response) => {
93-
//Raise an actix test error
94-
if response.status().is_success() {
95-
let user_info = response
96-
.json::<serde_json::Value>()
97-
.await
98-
.expect("Failed to parse JSON");
99-
100-
if let Some(login) = user_info.get("login").and_then(|v| v.as_str()) {
101-
println!("Login: {}", login);
102-
} else {
103-
println!("Login information not found.");
104-
}
105-
} else {
106-
println!("Failed to get GitHub user info");
107-
}
108-
},
109-
Err(e) => println!("Request error: {:?}", e),
110-
}
111-
}
112-
113-
match database::get_allocator(&owner, &repo).await {
114-
Ok(allocator) => {
115-
println!("Allocator: {:?}", allocator);
116-
},
117-
Err(e) => {
118-
println!("Failed to get allocator: {:?}", e);
119-
}
120-
}
121-
122-
let res = fut.await?;
123-
println!("Hi from response");
124-
Ok(res)
125-
})
126-
}
127-
}
12814

15+
use gh_auth::GHAuth;
12916

13017
#[tokio::main]
13118
async fn main() -> std::io::Result<()> {
@@ -150,7 +37,6 @@ async fn main() -> std::io::Result<()> {
15037
.service(
15138
web::scope("/api")
15239
.wrap(GHAuth) // Apply GitHubAuth to all routes under "/api"
153-
.service(router::application::testz)
15440
.service(router::application::trigger)
15541
.service(router::application::propose)
15642
.service(router::application::approve)
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
use actix_web::{
2+
dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
3+
Error, web,
4+
};
5+
use futures_util::future::{LocalBoxFuture, ready, Ready};
6+
use reqwest::Client;
7+
use serde::Deserialize;
8+
9+
// Import any other modules that you reference in this file
10+
use fplus_database::database;
11+
#[derive(Deserialize, Debug)]
12+
struct RepoQuery {
13+
owner: String,
14+
repo: String,
15+
}
16+
17+
pub struct GHAuth;
18+
19+
impl<S, B> Transform<S, ServiceRequest> for GHAuth
20+
where
21+
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
22+
S::Future: 'static,
23+
B: 'static,
24+
{
25+
type Response = ServiceResponse<B>;
26+
type Error = Error;
27+
type InitError = ();
28+
type Transform = GHAuthMiddleware<S>;
29+
type Future = Ready<Result<Self::Transform, Self::InitError>>;
30+
31+
fn new_transform(&self, service: S) -> Self::Future {
32+
ready(Ok(GHAuthMiddleware { service }))
33+
}
34+
}
35+
36+
pub struct GHAuthMiddleware<S> {
37+
service: S,
38+
}
39+
40+
impl<S, B> Service<ServiceRequest> for GHAuthMiddleware<S>
41+
where
42+
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
43+
S::Future: 'static,
44+
B: 'static,
45+
{
46+
type Response = ServiceResponse<B>;
47+
type Error = Error;
48+
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
49+
50+
forward_ready!(service);
51+
52+
fn call(&self, req: ServiceRequest) -> Self::Future {
53+
let query_string = req.query_string();
54+
let query: Result<web::Query<RepoQuery>, _> = web::Query::from_query(query_string);
55+
let RepoQuery { owner, repo } = match query {
56+
Ok(q) => q.into_inner(),
57+
Err(_) => {
58+
return Box::pin(async {
59+
return Err(actix_web::error::ErrorBadRequest("Wrong query string format"));
60+
});
61+
}
62+
};
63+
64+
let auth_header_value = req.headers().get("Authorization")
65+
.and_then(|hv| hv.to_str().ok())
66+
.filter(|hv| hv.starts_with("Bearer "))
67+
.map(|hv| hv["Bearer ".len()..].to_string());
68+
let fut = self.service.call(req);
69+
70+
Box::pin(async move {
71+
let mut user_handle = String::new();
72+
73+
if let Some(token) = auth_header_value {
74+
// Make the asynchronous HTTP request here
75+
let client = Client::new();
76+
let user_info_result = client.get("https://api.github.com/user")
77+
.header("Authorization", format!("Bearer {}", token))
78+
.header("User-Agent", "Actix-web")
79+
.send()
80+
.await;
81+
82+
match user_info_result {
83+
Ok(response) => {
84+
//Raise an actix test error
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+
user_handle = login.to_string();
93+
} else {
94+
println!("GitHub handle information not found.");
95+
return Err(actix_web::error::ErrorInternalServerError("GitHub handle information not found."))
96+
}
97+
} else {
98+
println!("Failed to get GitHub user info");
99+
return Err(actix_web::error::ErrorUnauthorized("Failed to get GitHub user info."))
100+
}
101+
},
102+
Err(e) => {
103+
println!("Request error: {:?}", e);
104+
return Err(actix_web::error::ErrorBadRequest(e))
105+
}
106+
}
107+
}
108+
109+
match database::get_allocator(&owner, &repo).await {
110+
Ok(allocator) => {
111+
if let Some(allocator) = &allocator {
112+
if let Some(verifiers) = &allocator.verifiers_gh_handles {
113+
let verifier_handles: Vec<String> = verifiers.split(',')
114+
.map(|s| s.trim().to_lowercase())
115+
.collect();
116+
if verifier_handles.contains(&user_handle.to_lowercase()) {
117+
println!("{} is a verifier.", user_handle);
118+
} else {
119+
println!("The user is not a verifier.");
120+
return Err(actix_web::error::ErrorUnauthorized("The user is not a verifier."))
121+
}
122+
}
123+
}
124+
},
125+
Err(e) => {
126+
println!("Failed to get allocator: {:?}", e);
127+
}
128+
}
129+
130+
let res = fut.await?;
131+
return Ok(res)
132+
})
133+
}
134+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod gh_auth;

0 commit comments

Comments
 (0)