Skip to content

Commit

Permalink
add webhooks
Browse files Browse the repository at this point in the history
  • Loading branch information
danielspofford committed Oct 17, 2023
1 parent 0f5f9a2 commit 1410f56
Show file tree
Hide file tree
Showing 4 changed files with 334 additions and 1 deletion.
1 change: 0 additions & 1 deletion src/api/cohorts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use super::Error;
use snafu::ResultExt;

#[derive(Debug, Deserialize, Serialize)]

pub struct Cohort {
pub description: Option<String>,
pub name: String,
Expand Down
120 changes: 120 additions & 0 deletions src/api/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)]
pub struct Event {
#[serde(flatten)]
pub data: EventType,
pub inserted_at: String,
pub prn: String,
pub version: u16,
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type")]
pub enum EventType {
AuditLog(AuditLogEvent),
Device(DeviceEvent),
Webhook(WebhookEvent),
}

// sub-event structs

#[derive(Debug, Deserialize, Serialize)]
pub struct AuditLogEvent {
pub data: AuditLogEventType,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct DeviceEvent {
pub data: DeviceEventType,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct WebhookEvent {
pub data: WebhookEventType,
}

// sub-event types

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type", content = "data")]
pub enum AuditLogEventType {}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type", content = "data")]
pub enum DeviceEventType {
CheckedForRelease(CheckedForReleaseEvent),
ClaimedRelease(ClaimedReleaseEvent),
ReleaseChanged(ReleaseChangedEvent),
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type", content = "data")]
pub enum WebhookEventType {
TestFire(TestFireEvent),
RequestFailed(RequestFailedEvent),
}

// audit_log

// audit_log.api_request

#[derive(Debug, Deserialize, Serialize)]
pub struct APIRequestEvent {}

// device

// device.checked_for_release

#[derive(Debug, Deserialize, Serialize)]
pub struct CheckedForReleaseEvent {}

// device.claimed_release

#[derive(Debug, Deserialize, Serialize)]
pub struct ClaimedReleaseEvent {}

// device.release_changed

#[derive(Debug, Deserialize, Serialize)]
pub struct ReleaseChangedEvent {}

// webhook

// webhook.test_fire

#[derive(Debug, Deserialize, Serialize)]
pub struct TestFireEvent {
pub webhook_prn: String,
}

// webhook.request_failed

#[derive(Debug, Deserialize, Serialize)]
pub struct RequestFailedEvent {
pub data: RequestFailedType,
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type", content = "data")]
pub enum RequestFailedType {
HostResolutionFailed(HostResolutionFailedEvent),
ResponseStatus(ResponseStatusEvent),
ResponseTimeout(ResponseTimeoutEvent),
}

#[derive(Debug, Deserialize, Serialize)]
pub struct HostResolutionFailedEvent {}

#[derive(Debug, Deserialize, Serialize)]
pub struct ResponseStatusEvent {
pub status: u16,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct ResponseTimeoutEvent {}
7 changes: 7 additions & 0 deletions src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ pub mod deployments;
pub mod device_certificates;
pub mod devices;
pub mod error;
pub mod events;
pub mod firmwares;
pub mod organization_users;
pub mod product_users;
pub mod products;
pub mod products_v2;
pub mod releases;
pub mod signing_keys;
pub mod webhooks;

use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
use reqwest::{header, Client, ClientBuilder, Method};
Expand Down Expand Up @@ -50,6 +52,7 @@ pub use releases::ReleasesApi;
pub use reqwest::Body;
pub use signing_keys::SigningKeysApi;
pub use users::UsersApi;
pub use webhooks::WebhooksApi;

use self::artifact_versions::ArtifactVersionsApi;
use self::bundles::BundlesApi;
Expand Down Expand Up @@ -409,4 +412,8 @@ impl Api {
pub fn users(&self) -> UsersApi {
UsersApi(self)
}

pub fn webhooks(&self) -> WebhooksApi {
WebhooksApi(self)
}
}
207 changes: 207 additions & 0 deletions src/api/webhooks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
use reqwest::Method;
use serde::{Deserialize, Serialize};

use crate::api::events::Event;
use crate::json_body;
use crate::Api;

use super::Error;
use snafu::ResultExt;

#[derive(Debug, Deserialize, Serialize)]
pub struct Webhook {
pub description: Option<String>,
pub enabled_events: Vec<String>,
pub inserted_at: String,
pub prn: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub secret: Option<String>,
pub state: Option<String>,
pub updated_at: String,
pub url: Option<String>,
}

#[derive(Debug, Serialize)]
pub struct CreateWebhookParams {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub enabled_events: Option<Vec<String>>,
pub organization_prn: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub state: Option<String>,
pub url: String,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct CreateWebhookResponse {
pub webhook: Webhook,
}

#[derive(Debug, Serialize)]
pub struct GetWebhookParams {
pub prn: String,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct GetWebhookResponse {
pub webhook: Webhook,
}

#[derive(Debug, Serialize)]
pub struct ListWebhooksParams {
pub limit: Option<u8>,
pub order: Option<String>,
pub search: String,
pub page: Option<String>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct ListWebhooksResponse {
pub webhooks: Vec<Webhook>,
pub next_page: Option<String>,
}

#[derive(Debug, Serialize)]
pub struct UpdateWebhookParams {
pub prn: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub state: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub enabled_events: Option<Vec<String>>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct UpdateWebhookResponse {
pub webhook: Webhook,
}

#[derive(Debug, Serialize)]
pub struct DeleteWebhookParams {
pub webhook_prn: String,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct DeleteWebhookResponse {}

#[derive(Debug, Serialize)]
pub struct RollSecretWebhookParams {
pub prn: String,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct RollSecretWebhookResponse {
pub webhook: Webhook,
}

#[derive(Debug, Serialize)]
pub struct TestFireWebhookParams {
pub prn: String,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct TestFireWebhookResponse {
pub event: Event,
}

pub struct WebhooksApi<'a>(pub &'a Api);

impl<'a> WebhooksApi<'a> {
pub async fn create(
&'a self,
params: CreateWebhookParams,
) -> Result<Option<CreateWebhookResponse>, Error> {
self.0
.execute(Method::POST, "/webhooks", Some(json_body!(&params)))
.await
}

pub async fn get(
&'a self,
params: GetWebhookParams,
) -> Result<Option<GetWebhookResponse>, Error> {
let webhook_prn: String = params.prn;
self.0
.execute(Method::GET, format!("/webhooks/{webhook_prn}"), None)
.await
}

pub async fn list(
&'a self,
params: ListWebhooksParams,
) -> Result<Option<ListWebhooksResponse>, Error> {
let search_string = params.search;
self.0
.execute(
Method::GET,
format!("/webhooks?search={search_string}"),
None,
)
.await
}

pub async fn update(
&'a self,
params: UpdateWebhookParams,
) -> Result<Option<UpdateWebhookResponse>, Error> {
let webhook_prn: &String = &params.prn;

self.0
.execute(
Method::PATCH,
format!("/webhooks/{webhook_prn}"),
Some(json_body!(&params)),
)
.await
}

pub async fn delete(
&'a self,
params: DeleteWebhookParams,
) -> Result<Option<DeleteWebhookResponse>, Error> {
let webhook_prn: String = params.webhook_prn;
self.0
.execute(Method::DELETE, format!("/webhooks/{webhook_prn}"), None)
.await
}

pub async fn roll_secret(
&'a self,
params: RollSecretWebhookParams,
) -> Result<Option<RollSecretWebhookResponse>, Error> {
let webhook_prn: String = params.prn;
self.0
.execute(
Method::POST,
format!("/webhooks/{webhook_prn}/roll_secret"),
None,
)
.await
}

pub async fn test_fire(
&'a self,
params: TestFireWebhookParams,
) -> Result<Option<TestFireWebhookResponse>, Error> {
let webhook_prn: String = params.prn;
self.0
.execute(
Method::POST,
format!("/webhooks/{webhook_prn}/test_fire"),
None,
)
.await
}
}

0 comments on commit 1410f56

Please sign in to comment.