Support multiple types of requests.
This commit is contained in:
parent
eb0c993e03
commit
2c0a7958a7
142
src/hook_push.rs
Normal file
142
src/hook_push.rs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub(crate) struct HookPush {
|
||||||
|
#[serde(rename = "ref")]
|
||||||
|
ref_field: String,
|
||||||
|
before: String,
|
||||||
|
compare_url: String,
|
||||||
|
commits: Vec<HookCommit>,
|
||||||
|
total_commits: u64,
|
||||||
|
head_commit: HookCommit,
|
||||||
|
repository: HookRepository,
|
||||||
|
pusher: HookUser,
|
||||||
|
sender: HookUser,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub(crate) struct HookUser {
|
||||||
|
id: u64,
|
||||||
|
login: String,
|
||||||
|
login_name: String,
|
||||||
|
full_name: String,
|
||||||
|
email: String,
|
||||||
|
avatar_url: String,
|
||||||
|
language: String,
|
||||||
|
is_admin: bool,
|
||||||
|
last_login: String, // TODO: parse to datetime
|
||||||
|
created: String, // TODO: parse to datetime
|
||||||
|
restricted: bool,
|
||||||
|
active: bool,
|
||||||
|
prohibit_login: bool,
|
||||||
|
location: String,
|
||||||
|
website: String,
|
||||||
|
description: String,
|
||||||
|
visibility: String,
|
||||||
|
followers_count: u64,
|
||||||
|
following_count: u64,
|
||||||
|
starred_repos_count: u64,
|
||||||
|
username: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub(crate) struct HookRepository {
|
||||||
|
id: u64,
|
||||||
|
owner: HookUser,
|
||||||
|
name: String,
|
||||||
|
full_name: String,
|
||||||
|
description: String,
|
||||||
|
empty: bool,
|
||||||
|
private: bool,
|
||||||
|
fork: bool,
|
||||||
|
template: bool,
|
||||||
|
parent: Value, // Was null in test hook
|
||||||
|
mirror: bool,
|
||||||
|
size: u64,
|
||||||
|
language: String,
|
||||||
|
languages_url: String,
|
||||||
|
html_url: String,
|
||||||
|
url: String,
|
||||||
|
link: String,
|
||||||
|
ssh_url: String,
|
||||||
|
clone_url: String,
|
||||||
|
original_url: String,
|
||||||
|
website: String,
|
||||||
|
stars_count: u64,
|
||||||
|
forks_count: u64,
|
||||||
|
watchers_count: u64,
|
||||||
|
open_issues_count: u64,
|
||||||
|
open_pr_counter: u64,
|
||||||
|
release_counter: u64,
|
||||||
|
default_branch: String,
|
||||||
|
archived: bool,
|
||||||
|
created_at: String, // TODO: parse to datetime
|
||||||
|
updated_at: String, // TODO: parse to datetime
|
||||||
|
archived_at: String, // TODO: parse to datetime
|
||||||
|
permissions: HookRepositoryPermissions,
|
||||||
|
has_issues: bool,
|
||||||
|
internal_tracker: HookRepositoryInternalTracker,
|
||||||
|
has_wiki: bool,
|
||||||
|
has_pull_requests: bool,
|
||||||
|
has_projects: bool,
|
||||||
|
has_releases: bool,
|
||||||
|
has_packages: bool,
|
||||||
|
has_actions: bool,
|
||||||
|
ignore_whitespace_conflicts: bool,
|
||||||
|
allow_merge_commits: bool,
|
||||||
|
allow_rebase: bool,
|
||||||
|
allow_rebase_explicit: bool,
|
||||||
|
allow_squash_merge: bool,
|
||||||
|
allow_rebase_update: bool,
|
||||||
|
default_delete_branch_after_merge: bool,
|
||||||
|
default_merge_style: String,
|
||||||
|
default_allow_maintainer_edit: bool,
|
||||||
|
avatar_url: String,
|
||||||
|
internal: bool,
|
||||||
|
mirror_interval: String,
|
||||||
|
mirror_updated: String, // TODO: parse to datetime
|
||||||
|
repo_transfer: Value, // Was null in test hook
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub(crate) struct HookRepositoryPermissions {
|
||||||
|
admin: bool,
|
||||||
|
push: bool,
|
||||||
|
pull: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub(crate) struct HookRepositoryInternalTracker {
|
||||||
|
enable_time_tracker: bool,
|
||||||
|
allow_only_contributors_to_track_time: bool,
|
||||||
|
enable_issue_dependencies: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub(crate) struct HookCommit {
|
||||||
|
id: String,
|
||||||
|
message: String,
|
||||||
|
url: String,
|
||||||
|
author: HookGitUser,
|
||||||
|
committer: HookGitUser,
|
||||||
|
verification: Value, // Was null in test hook
|
||||||
|
timestamp: String, // TODO: parse to datetime
|
||||||
|
added: Vec<String>,
|
||||||
|
removed: Vec<String>,
|
||||||
|
modified: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub(crate) struct HookGitUser {
|
||||||
|
name: String,
|
||||||
|
email: String,
|
||||||
|
username: String,
|
||||||
|
}
|
@ -11,6 +11,7 @@ use tracing_subscriber::util::SubscriberInitExt;
|
|||||||
|
|
||||||
use self::webhook::hook;
|
use self::webhook::hook;
|
||||||
|
|
||||||
|
mod hook_push;
|
||||||
mod webhook;
|
mod webhook;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
200
src/webhook.rs
200
src/webhook.rs
@ -1,158 +1,74 @@
|
|||||||
|
use axum::async_trait;
|
||||||
|
use axum::extract::FromRequest;
|
||||||
|
use axum::extract::Request;
|
||||||
use axum::http::HeaderMap;
|
use axum::http::HeaderMap;
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
|
use axum::response::IntoResponse;
|
||||||
|
use axum::response::Response;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
use serde::Deserialize;
|
use axum::RequestExt;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::Value;
|
use tracing::debug;
|
||||||
|
|
||||||
|
use crate::hook_push::HookPush;
|
||||||
|
|
||||||
pub(crate) async fn hook(
|
pub(crate) async fn hook(
|
||||||
headers: HeaderMap,
|
_headers: HeaderMap,
|
||||||
Json(payload): Json<HookRequest>,
|
payload: HookRequest,
|
||||||
) -> (StatusCode, Json<HookResponse>) {
|
) -> (StatusCode, Json<HookResponse>) {
|
||||||
(StatusCode::OK, Json(HookResponse { ok: true }))
|
debug!("REQ: {:?}", payload);
|
||||||
|
match payload {
|
||||||
|
HookRequest::Push(_payload) => (
|
||||||
|
StatusCode::OK,
|
||||||
|
Json(HookResponse {
|
||||||
|
ok: true,
|
||||||
|
message: None,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
HookRequest::Unrecognized(payload) => (
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
Json(HookResponse {
|
||||||
|
ok: false,
|
||||||
|
message: Some(format!("unrecognized event type: {payload}")),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[derive(Debug)]
|
||||||
#[derive(Deserialize)]
|
pub(crate) enum HookRequest {
|
||||||
pub(crate) struct HookRequest {
|
Push(HookPush),
|
||||||
#[serde(rename = "ref")]
|
Unrecognized(String),
|
||||||
ref_field: String,
|
|
||||||
before: String,
|
|
||||||
compare_url: String,
|
|
||||||
commits: Vec<HookCommit>,
|
|
||||||
total_commits: u64,
|
|
||||||
head_commit: HookCommit,
|
|
||||||
repository: HookRepository,
|
|
||||||
pusher: HookUser,
|
|
||||||
sender: HookUser,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[async_trait]
|
||||||
#[derive(Deserialize)]
|
impl<S> FromRequest<S> for HookRequest
|
||||||
pub(crate) struct HookUser {
|
where
|
||||||
id: u64,
|
S: Send + Sync,
|
||||||
login: String,
|
{
|
||||||
login_name: String,
|
type Rejection = Response;
|
||||||
full_name: String,
|
|
||||||
email: String,
|
async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {
|
||||||
avatar_url: String,
|
let event_type = req
|
||||||
language: String,
|
.headers()
|
||||||
is_admin: bool,
|
.get("X-Gitea-Event-Type")
|
||||||
last_login: String, // TODO: parse to datetime
|
.ok_or(StatusCode::UNSUPPORTED_MEDIA_TYPE.into_response())?;
|
||||||
created: String, // TODO: parse to datetime
|
let event_type = event_type
|
||||||
restricted: bool,
|
.to_str()
|
||||||
active: bool,
|
.map_err(|_| StatusCode::UNSUPPORTED_MEDIA_TYPE.into_response())?;
|
||||||
prohibit_login: bool,
|
match event_type {
|
||||||
location: String,
|
"push" => {
|
||||||
website: String,
|
let Json(payload): Json<HookPush> =
|
||||||
description: String,
|
req.extract().await.map_err(IntoResponse::into_response)?;
|
||||||
visibility: String,
|
Ok(HookRequest::Push(payload))
|
||||||
followers_count: u64,
|
}
|
||||||
following_count: u64,
|
_ => Ok(HookRequest::Unrecognized(event_type.to_owned())),
|
||||||
starred_repos_count: u64,
|
}
|
||||||
username: String,
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[derive(Debug, Serialize)]
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub(crate) struct HookRepository {
|
|
||||||
id: u64,
|
|
||||||
owner: HookUser,
|
|
||||||
name: String,
|
|
||||||
full_name: String,
|
|
||||||
description: String,
|
|
||||||
empty: bool,
|
|
||||||
private: bool,
|
|
||||||
fork: bool,
|
|
||||||
template: bool,
|
|
||||||
parent: Value, // Was null in test hook
|
|
||||||
mirror: bool,
|
|
||||||
size: u64,
|
|
||||||
language: String,
|
|
||||||
languages_url: String,
|
|
||||||
html_url: String,
|
|
||||||
url: String,
|
|
||||||
link: String,
|
|
||||||
ssh_url: String,
|
|
||||||
clone_url: String,
|
|
||||||
original_url: String,
|
|
||||||
website: String,
|
|
||||||
stars_count: u64,
|
|
||||||
forks_count: u64,
|
|
||||||
watchers_count: u64,
|
|
||||||
open_issues_count: u64,
|
|
||||||
open_pr_counter: u64,
|
|
||||||
release_counter: u64,
|
|
||||||
default_branch: String,
|
|
||||||
archived: bool,
|
|
||||||
created_at: String, // TODO: parse to datetime
|
|
||||||
updated_at: String, // TODO: parse to datetime
|
|
||||||
archived_at: String, // TODO: parse to datetime
|
|
||||||
permissions: HookRepositoryPermissions,
|
|
||||||
has_issues: bool,
|
|
||||||
internal_tracker: HookRepositoryInternalTracker,
|
|
||||||
has_wiki: bool,
|
|
||||||
has_pull_requests: bool,
|
|
||||||
has_projects: bool,
|
|
||||||
has_releases: bool,
|
|
||||||
has_packages: bool,
|
|
||||||
has_actions: bool,
|
|
||||||
ignore_whitespace_conflicts: bool,
|
|
||||||
allow_merge_commits: bool,
|
|
||||||
allow_rebase: bool,
|
|
||||||
allow_rebase_explicit: bool,
|
|
||||||
allow_squash_merge: bool,
|
|
||||||
allow_rebase_update: bool,
|
|
||||||
default_delete_branch_after_merge: bool,
|
|
||||||
default_merge_style: String,
|
|
||||||
default_allow_maintainer_edit: bool,
|
|
||||||
avatar_url: String,
|
|
||||||
internal: bool,
|
|
||||||
mirror_interval: String,
|
|
||||||
mirror_updated: String, // TODO: parse to datetime
|
|
||||||
repo_transfer: Value, // Was null in test hook
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub(crate) struct HookRepositoryPermissions {
|
|
||||||
admin: bool,
|
|
||||||
push: bool,
|
|
||||||
pull: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub(crate) struct HookRepositoryInternalTracker {
|
|
||||||
enable_time_tracker: bool,
|
|
||||||
allow_only_contributors_to_track_time: bool,
|
|
||||||
enable_issue_dependencies: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub(crate) struct HookCommit {
|
|
||||||
id: String,
|
|
||||||
message: String,
|
|
||||||
url: String,
|
|
||||||
author: HookGitUser,
|
|
||||||
committer: HookGitUser,
|
|
||||||
verification: Value, // Was null in test hook
|
|
||||||
timestamp: String, // TODO: parse to datetime
|
|
||||||
added: Vec<String>,
|
|
||||||
removed: Vec<String>,
|
|
||||||
modified: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub(crate) struct HookGitUser {
|
|
||||||
name: String,
|
|
||||||
email: String,
|
|
||||||
username: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub(crate) struct HookResponse {
|
pub(crate) struct HookResponse {
|
||||||
ok: bool,
|
ok: bool,
|
||||||
|
message: Option<String>,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user