Skip to content

Commit

Permalink
wip: webhooks
Browse files Browse the repository at this point in the history
  • Loading branch information
pnmadelaine committed Sep 22, 2023
1 parent 82dd102 commit 4b70853
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 1 deletion.
38 changes: 38 additions & 0 deletions typhon-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,41 @@ pub enum Event {
BuildNew(handles::Build),
BuildFinished(handles::Build),
}

pub mod actions {
pub mod webhooks {
use crate::handles;
use crate::requests;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Clone, Serialize)]
pub struct Input {
pub headers: HashMap<String, String>,
pub body: String,
}

#[derive(Clone, Deserialize)]
#[serde(tag = "type")]
pub enum Command {
UpdateJobsets,
EvaluateJobset(String),
}

impl Command {
pub fn lift(self, project: handles::Project) -> requests::Request {
match self {
Command::UpdateJobsets => {
requests::Request::Project(project, requests::Project::UpdateJobsets)
}
Command::EvaluateJobset(jobset) => requests::Request::Jobset(
handles::Jobset { project, jobset },
requests::Jobset::Evaluate(true),
),
}
}
}

pub type Output = Vec<Command>;
}
}
7 changes: 7 additions & 0 deletions typhon/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh
set -eu

password="hello"
hashed_password=$(echo -n $password | sha256sum | head -c 64)

cargo run -- -p $hashed_password -j 'null' -w ""
39 changes: 38 additions & 1 deletion typhon/src/api.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use typhon_types::actions::webhooks;

use crate::listeners::Session;
use crate::requests::*;
use crate::{handle_request, handles, Response, ResponseError, User};
use crate::{BUILD_LOGS, SETTINGS};
use actix_cors::Cors;
use actix_files::NamedFile;
use actix_web::{
body::EitherBody, guard, http::StatusCode, web, Error, HttpRequest, HttpResponse, Responder,
body::EitherBody, guard, http::StatusCode, web, web::Bytes, Error, HttpRequest, HttpResponse,
Responder,
};
use actix_web_actors::ws;

Expand Down Expand Up @@ -233,6 +236,39 @@ async fn events(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse,
ws::start(Session::new(), &req, stream)
}

async fn webhook(
path: web::Json<String>,
req: HttpRequest,
body: Bytes,
) -> Result<HttpResponse, Error> {
let project_handle = handles::project(path.into_inner().to_string());
let project = crate::models::Project::get(&project_handle)
.await
.map_err(|_| ResponseErrorWrapper(ResponseError::BadRequest("TODO".to_string())))?;
let input = webhooks::Input {
headers: req
.headers()
.into_iter()
.map(|(name, value)| {
(
name.as_str().to_string(),
std::str::from_utf8(value.as_bytes()).unwrap().to_string(),
)
})
.collect(),
body: std::str::from_utf8(&body).unwrap().to_string(),
};
let requests = project
.webhook(input)
.await
.map_err(|_| ResponseErrorWrapper(ResponseError::BadRequest("TODO".to_string())))?
.into_iter();
for req in requests {
let _ = handle_request(User::Admin, req).await;
}
Ok(HttpResponse::Ok().finish())
}

pub fn config(cfg: &mut web::ServiceConfig) {
let cors = Cors::permissive(); // TODO: configure
cfg.service(
Expand All @@ -250,6 +286,7 @@ pub fn config(cfg: &mut web::ServiceConfig) {
.route("/update_jobsets", web::post().to(project_update_jobsets))
.route("/set_decl", web::post().to(project_set_decl))
.route("/set_private_key", web::post().to(project_set_private_key))
.route("/webhook", web::post().to(webhook))
.service(
web::scope("/jobsets/{jobset}")
.route("", web::get().to(jobset_info))
Expand Down
29 changes: 29 additions & 0 deletions typhon/src/projects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,33 @@ impl Project {

Ok(decls.into_keys().collect())
}

pub async fn webhook(
&self,
input: typhon_types::actions::webhooks::Input,
) -> Result<Vec<typhon_types::requests::Request>, Error> {
match &self.project_actions_path {
Some(path) => {
if Path::new(&format!("{}/webhooks", path)).exists() {
let action_input = serde_json::to_value(input).unwrap();
let (action_output, _) = actions::run(
&self.project_key,
&format!("{}/webhooks", path),
&format!("{}/secrets", path),
&action_input,
)
.await?;
let commands: typhon_types::actions::webhooks::Output =
serde_json::from_str(&action_output).map_err(|_| Error::Todo)?;
Ok(commands
.into_iter()
.map(|cmd| cmd.lift(self.handle()))
.collect())
} else {
Ok(Vec::new())
}
}
None => Ok(Vec::new()),
}
}
}
46 changes: 46 additions & 0 deletions typhon/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/sh

token="hello"
url="http://localhost:8000/api"
curl_opts=( -s -H "token: $token" )

list_projects () {
curl "${curl_opts[@]}" "$url/projects" | jq
}
project_create () {
curl "${curl_opts[@]}" --json "\"$2\"" "$url/projects/$1/create"
}
project_delete () {
curl "${curl_opts[@]}" -X POST "$url/projects/$1/delete"
}
project_info () {
curl "${curl_opts[@]}" "$url/projects/$1"
}
project_refresh () {
curl "${curl_opts[@]}" -X POST "$url/projects/$1/refresh"
}
project_update_jobsets () {
curl "${curl_opts[@]}" -X POST "$url/projects/$1/update_jobsets"
}
jobset_info() {

curl "${curl_opts[@]}" "$url/projects/$1/jobsets/$2"
}
jobset_evaluate () {
curl "${curl_opts[@]}" -X POST "$url/projects/$1/jobsets/$2/evaluate"
}
evaluation_info () {
curl "${curl_opts[@]}" "$url/projects/$1/jobsets/$2/evaluations/$3"
}

project_delete "test"
echo ""
project_create "test" "github:typhon-ci/test"
echo ""
project_refresh "test"
echo ""
project_update_jobsets "test"
echo ""
jobset_evaluate "test" "main"
echo ""
evaluation_info "test" "main" "1"

0 comments on commit 4b70853

Please sign in to comment.