feat: HTTP authentication for events endpoint
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
6145695980
commit
f9d23cb3ef
4 changed files with 53 additions and 1 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -193,6 +193,21 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "actix-web-httpauth"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6dda62cf04bc3a9ad2ea8f314f721951cfdb4cdacec4e984d20e77c7bb170991"
|
||||||
|
dependencies = [
|
||||||
|
"actix-utils",
|
||||||
|
"actix-web",
|
||||||
|
"base64",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler"
|
name = "adler"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -405,6 +420,7 @@ dependencies = [
|
||||||
"actix-rt",
|
"actix-rt",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"actix-web-codegen-const-routes",
|
"actix-web-codegen-const-routes",
|
||||||
|
"actix-web-httpauth",
|
||||||
"base64",
|
"base64",
|
||||||
"clap",
|
"clap",
|
||||||
"config",
|
"config",
|
||||||
|
|
|
@ -24,6 +24,7 @@ derive_more = "0.99.17"
|
||||||
url = { version = "2.2.2", features = ["serde"]}
|
url = { version = "2.2.2", features = ["serde"]}
|
||||||
serde_json = { version ="1", features = ["raw_value"]}
|
serde_json = { version ="1", features = ["raw_value"]}
|
||||||
clap = { vesrion = "3.2.20", features = ["derive"]}
|
clap = { vesrion = "3.2.20", features = ["derive"]}
|
||||||
|
actix-web-httpauth = "0.8.0"
|
||||||
|
|
||||||
[dependencies.libconductor]
|
[dependencies.libconductor]
|
||||||
path = "./env/libconductor"
|
path = "./env/libconductor"
|
||||||
|
|
|
@ -14,11 +14,33 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
use actix_web::dev::ServiceRequest;
|
||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
|
use actix_web::Error;
|
||||||
|
use actix_web_httpauth::extractors::basic::BasicAuth;
|
||||||
|
|
||||||
|
use crate::errors::*;
|
||||||
|
use crate::AppCtx;
|
||||||
|
use crate::SETTINGS;
|
||||||
|
|
||||||
pub mod meta;
|
pub mod meta;
|
||||||
pub mod webhook;
|
pub mod webhook;
|
||||||
|
|
||||||
|
pub async fn httpauth(
|
||||||
|
req: ServiceRequest,
|
||||||
|
credentials: BasicAuth,
|
||||||
|
) -> Result<ServiceRequest, (Error, ServiceRequest)> {
|
||||||
|
let _ctx: &AppCtx = req.app_data().unwrap();
|
||||||
|
let username = credentials.user_id();
|
||||||
|
let password = credentials.password().unwrap();
|
||||||
|
if SETTINGS.authenticate(username, password) {
|
||||||
|
Ok(req)
|
||||||
|
} else {
|
||||||
|
let e = Error::from(ServiceError::Unauthorized);
|
||||||
|
Err((e, req))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const API_V1_ROUTES: routes::Routes = routes::Routes::new();
|
pub const API_V1_ROUTES: routes::Routes = routes::Routes::new();
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
use actix_web::{web, HttpResponse, Responder};
|
use actix_web::{web, HttpResponse, Responder};
|
||||||
|
use actix_web_httpauth::middleware::HttpAuthentication;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use libconductor::EventType;
|
use libconductor::EventType;
|
||||||
|
@ -23,6 +24,8 @@ use crate::errors::*;
|
||||||
use crate::AppCtx;
|
use crate::AppCtx;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
use super::httpauth;
|
||||||
|
|
||||||
pub mod routes {
|
pub mod routes {
|
||||||
use super::*;
|
use super::*;
|
||||||
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
|
||||||
|
@ -42,7 +45,10 @@ pub fn services(cfg: &mut web::ServiceConfig) {
|
||||||
cfg.service(post_event);
|
cfg.service(post_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web_codegen_const_routes::post(path = "API_V1_ROUTES.webhook.post_event")]
|
#[actix_web_codegen_const_routes::post(
|
||||||
|
path = "API_V1_ROUTES.webhook.post_event",
|
||||||
|
wrap = "HttpAuthentication::basic(httpauth)"
|
||||||
|
)]
|
||||||
async fn post_event(ctx: AppCtx, payload: web::Json<EventType>) -> ServiceResult<impl Responder> {
|
async fn post_event(ctx: AppCtx, payload: web::Json<EventType>) -> ServiceResult<impl Responder> {
|
||||||
ctx.conductor.process(payload.into_inner()).await;
|
ctx.conductor.process(payload.into_inner()).await;
|
||||||
Ok(HttpResponse::Created())
|
Ok(HttpResponse::Created())
|
||||||
|
@ -65,12 +71,19 @@ pub mod tests {
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
let creds = settings.api_keys.get(0).unwrap().clone();
|
||||||
|
let auth = format!(
|
||||||
|
"Basic {}",
|
||||||
|
base64::encode(format!("{}:{}", creds.username.clone(), creds.password))
|
||||||
|
);
|
||||||
|
|
||||||
let new_hostname = EventType::NewHostname("demo.librepages.org".into());
|
let new_hostname = EventType::NewHostname("demo.librepages.org".into());
|
||||||
|
|
||||||
// upload json
|
// upload json
|
||||||
let upload_json = test::call_service(
|
let upload_json = test::call_service(
|
||||||
&app,
|
&app,
|
||||||
test::TestRequest::post()
|
test::TestRequest::post()
|
||||||
|
.append_header((actix_web::http::header::AUTHORIZATION, auth.clone()))
|
||||||
.uri(API_V1_ROUTES.webhook.post_event)
|
.uri(API_V1_ROUTES.webhook.post_event)
|
||||||
.set_json(&new_hostname)
|
.set_json(&new_hostname)
|
||||||
.to_request(),
|
.to_request(),
|
||||||
|
|
Loading…
Reference in a new issue