rocket_webhook/
state.rs

1use std::marker::PhantomData;
2
3use bon::bon;
4
5use crate::webhooks::Webhook;
6
7/**
8Webhook configuration stored in Rocket state.
9
10# Example
11
12```
13use rocket::{Rocket, Build};
14use rocket_webhook::{
15    RocketWebhook,
16    webhooks::built_in::{GitHubWebhook},
17};
18
19fn setup_webhooks(rocket: Rocket<Build>) -> Rocket<Build> {
20    let github_webhook = RocketWebhook::builder()
21        .webhook(GitHubWebhook::with_secret(b"my-github-secret"))
22        .max_body_size(1024 * 10)
23        .build();
24
25    rocket.manage(github_webhook)
26}
27```
28*/
29pub struct RocketWebhook<W, M = W>
30where
31    W: Webhook,
32{
33    pub(crate) webhook: W,
34    pub(crate) max_body_size: u32,
35    pub(crate) timestamp_tolerance: (u32, u32),
36    marker: PhantomData<M>,
37}
38
39#[bon]
40impl<W> RocketWebhook<W, W>
41where
42    W: Webhook,
43{
44    /// Build a webhook configuration
45    #[builder]
46    pub fn new(
47        /// The webhook to validate
48        webhook: W,
49        /// The maximum allowed body size of the webhook request in bytes (default: 64 KB)
50        #[builder(default = 64 * 1024)]
51        max_body_size: u32,
52        /// For webhooks that use a timestamp, how many seconds in the past and future is allowed to be valid
53        /// (default: 5 minutes in past, 15 seconds in future)
54        #[builder(default = (5 * 60, 15), with = |past_secs: u32, future_secs: u32| (past_secs, future_secs))]
55        timestamp_tolerance: (u32, u32),
56    ) -> RocketWebhook<W, W> {
57        RocketWebhook {
58            webhook,
59            max_body_size,
60            timestamp_tolerance,
61            marker: PhantomData::<W>,
62        }
63    }
64}
65
66#[bon]
67impl<W, M> RocketWebhook<W, M>
68where
69    W: Webhook,
70{
71    /**
72    Build a webhook configuration with a given marker type, to distingiush between multiple
73    webhooks of the same type (e.g. multiple GitHub webhooks with different secret keys).
74
75    # Example
76
77    ```
78    use rocket_webhook::{
79        RocketWebhook,
80        webhooks::built_in::{GitHubWebhook},
81    };
82
83    struct GithubPR;
84    struct GithubIssue;
85
86    let webhook_1 = RocketWebhook::builder_with_marker()
87        .webhook(GitHubWebhook::with_secret("secret-1"))
88        .marker(GithubPR) // pass in marker here
89        .build();
90    let webhook_2 = RocketWebhook::builder_with_marker()
91        .webhook(GitHubWebhook::with_secret("secret-2"))
92        .marker(GithubIssue) // pass in marker here
93        .build();
94    ```
95    */
96    #[builder(start_fn(name = builder_with_marker, vis = "pub"), finish_fn = build, builder_type(vis = "pub"))]
97    fn with_marker(
98        /// The webhook to validate
99        webhook: W,
100        /// A marker struct to distinguish this webhook from other webhooks of the same type
101        #[builder(with = |marker: M| PhantomData)]
102        marker: PhantomData<M>,
103        /// The maximum allowed body size of the webhook request in bytes (default: 64 KB)
104        #[builder(default = 64 * 1024)]
105        max_body_size: u32,
106        /// For webhooks that use a timestamp, how many seconds in the past and future is allowed to be valid
107        /// (default: 5 minutes in past, 15 seconds in future)
108        #[builder(default = (5 * 60, 15), with = |past_secs: u32, future_secs: u32| (past_secs, future_secs))]
109        timestamp_tolerance: (u32, u32),
110    ) -> RocketWebhook<W, M> {
111        RocketWebhook {
112            webhook,
113            marker,
114            max_body_size,
115            timestamp_tolerance,
116        }
117    }
118}