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}