Skip to content

Commit

Permalink
feat(webhooks): add support for "subdomain"-based webhook URLs
Browse files Browse the repository at this point in the history
  • Loading branch information
azasypkin committed Oct 9, 2023
1 parent efb87c3 commit eada924
Show file tree
Hide file tree
Showing 23 changed files with 1,384 additions and 594 deletions.
3 changes: 3 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod scheduler_jobs_config;
mod smtp_catch_all_config;
mod smtp_config;

use crate::server::WebhookUrlType;
use url::Url;

pub use self::{
Expand All @@ -19,6 +20,8 @@ pub struct Config {
pub http_port: u16,
/// External/public URL through which service is being accessed.
pub public_url: Url,
/// Describes the preferred way to construct webhook URLs.
pub webhook_url_type: WebhookUrlType,
/// Configuration for the SMTP functionality.
pub smtp: Option<SmtpConfig>,
/// Configuration for the components that are deployed separately.
Expand Down
24 changes: 21 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ mod templates;
mod users;
mod utils;

use crate::config::{
ComponentsConfig, Config, SchedulerJobsConfig, SmtpCatchAllConfig, SmtpConfig,
use crate::{
config::{ComponentsConfig, Config, SchedulerJobsConfig, SmtpCatchAllConfig, SmtpConfig},
server::WebhookUrlType,
};
use anyhow::{anyhow, Context};
use bytes::Buf;
Expand Down Expand Up @@ -81,6 +82,13 @@ fn process_command(version: &str, matches: ArgMatches) -> Result<(), anyhow::Err
Url::parse(public_url)
.with_context(|| "Cannot parse public URL parameter.".to_string())
})?,
webhook_url_type: matches
.get_one::<String>("WEBHOOK_URL_TYPE")
.ok_or_else(|| anyhow!("<WEBHOOK_URL_TYPE> argument is not provided."))
.and_then(|webhook_url_type| {
WebhookUrlType::from_str(webhook_url_type)
.with_context(|| "Cannot parse webhook URL type parameter.".to_string())
})?,
components: ComponentsConfig {
web_scraper_url: matches
.get_one::<String>("COMPONENT_WEB_SCRAPER_URL")
Expand Down Expand Up @@ -228,6 +236,15 @@ fn main() -> Result<(), anyhow::Error> {
.default_value("http://localhost:7070")
.help("External/public URL through which service is being accessed."),
)
.arg(
Arg::new("WEBHOOK_URL_TYPE")
.long("webhook-url-type")
.global(true)
.env("SECUTILS_WEBHOOK_URL_TYPE")
.default_value("path")
.value_names(["path", "subdomain"])
.help("Describes how Secutils.dev WebUI should construct webhook URLs. The server supports all types of URL simultaneously."),
)
.arg(
Arg::new("COMPONENT_WEB_SCRAPER_URL")
.long("component-web-scraper-url")
Expand Down Expand Up @@ -290,7 +307,7 @@ mod tests {
use url::Url;

pub use crate::{network::tests::*, server::tests::*, utils::tests::*};
use crate::{search::SearchIndex, templates::create_templates};
use crate::{search::SearchIndex, server::WebhookUrlType, templates::create_templates};

pub struct MockUserBuilder {
user: User,
Expand Down Expand Up @@ -451,6 +468,7 @@ mod tests {
version: "1.0.0".to_string(),
http_port: 1234,
public_url: Url::parse("http://localhost:1234")?,
webhook_url_type: WebhookUrlType::Subdomain,
smtp: Some(SmtpConfig {
username: "[email protected]".to_string(),
password: "password".to_string(),
Expand Down
8 changes: 5 additions & 3 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod app_state;
mod extractors;
mod handlers;
mod http_errors;
mod status;
mod ui_state;

use crate::{
api::Api,
Expand All @@ -27,6 +27,7 @@ use std::sync::Arc;
pub use self::app_state::tests;

pub use app_state::AppState;
pub use ui_state::{License, Status, StatusLevel, UiState, WebhookUrlType};

#[actix_rt::main]
pub async fn run(
Expand Down Expand Up @@ -160,9 +161,10 @@ pub async fn run(
.route("/user/data", web::post().to(handlers::user_data_set))
.route("/user/data", web::get().to(handlers::user_data_get))
.route(
"/webhooks/ar/{user_handle}/{name}",
web::route().to(handlers::webhooks_auto_responders),
"/webhooks/{user_handle}/{responder_path:.*}",
web::route().to(handlers::webhooks_responders),
)
.route("/webhooks", web::route().to(handlers::webhooks_responders))
.service(
web::scope("/users")
.route("/remove", web::post().to(handlers::security_users_remove)),
Expand Down
2 changes: 1 addition & 1 deletion src/server/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
config::Config,
network::{DnsResolver, EmailTransport, TokioDnsResolver},
security::Security,
server::status::{Status, StatusLevel},
server::{Status, StatusLevel},
users::{User, UserRole},
};
use actix_web::{error::ErrorForbidden, Error};
Expand Down
4 changes: 2 additions & 2 deletions src/server/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mod user_data_get;
mod user_data_set;
mod user_get;
mod utils_handle_action;
mod webhooks_auto_responders;
mod webhooks_responders;

pub use self::{
search::search,
Expand All @@ -46,5 +46,5 @@ pub use self::{
user_data_set::user_data_set,
user_get::user_get,
utils_handle_action::utils_handle_action,
webhooks_auto_responders::webhooks_auto_responders,
webhooks_responders::webhooks_responders,
};
2 changes: 1 addition & 1 deletion src/server/handlers/status_set.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
server::{app_state::AppState, status::StatusLevel},
server::{app_state::AppState, StatusLevel},
users::User,
};
use actix_web::{error::ErrorInternalServerError, web, HttpResponse, Responder};
Expand Down
25 changes: 3 additions & 22 deletions src/server/handlers/ui_state_get.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,12 @@
use crate::{
error::SecutilsError,
server::{status::Status, AppState},
users::{ClientUserShare, PublicUserDataNamespace, User, UserSettings, UserShare},
utils::Util,
server::{AppState, License, UiState},
users::{ClientUserShare, PublicUserDataNamespace, User, UserShare},
};
use actix_web::{web, HttpResponse};
use anyhow::anyhow;
use serde::Serialize;
use std::ops::Deref;

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct License;

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct UiState<'a> {
status: &'a Status,
license: License,
#[serde(skip_serializing_if = "Option::is_none")]
user: Option<User>,
#[serde(skip_serializing_if = "Option::is_none")]
user_share: Option<ClientUserShare>,
#[serde(skip_serializing_if = "Option::is_none")]
settings: Option<UserSettings>,
utils: Vec<Util>,
}

pub async fn ui_state_get(
state: web::Data<AppState>,
user: Option<User>,
Expand Down Expand Up @@ -62,5 +42,6 @@ pub async fn ui_state_get(
user_share: user_share.map(ClientUserShare::from),
settings,
utils,
webhook_url_type: state.config.webhook_url_type,
}))
}
174 changes: 0 additions & 174 deletions src/server/handlers/webhooks_auto_responders.rs

This file was deleted.

Loading

0 comments on commit eada924

Please sign in to comment.