Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add webhooks #11

Merged
merged 1 commit into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
}
}
204 changes: 204 additions & 0 deletions src/api/webhooks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
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,
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
}
}
14 changes: 14 additions & 0 deletions tests/fixtures/webhooks-create-201.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"webhook": {
"description": "description",
"inserted_at": "date1",
"organization_prn": "string",
"prn": "string",
"state": "disabled",
"url": "https://peridio.com",
"enabled_events": [
"device.release_changed"
],
"updated_at": "date2"
}
}
14 changes: 14 additions & 0 deletions tests/fixtures/webhooks-get-200.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"webhook": {
"description": "description",
"inserted_at": "date1",
"state": "enabled",
"url": "https://peridio.com",
"organization_prn": "string",
"prn": "string",
"enabled_events": [
"device.release_changed"
],
"updated_at": "date2"
}
}
Loading
Loading