Skip to content

Commit

Permalink
fix: Slugify app-names passed to the API -- (Fixes #158)
Browse files Browse the repository at this point in the history
  • Loading branch information
stmh committed Jan 3, 2025
1 parent d234fc6 commit d7619c8
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 23 deletions.
17 changes: 1 addition & 16 deletions scotty-core/src/apps/create_app_request.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{app_data::AppSettings, file_list::FileList};
use crate::utils::serde::{deserialize_app_name, serialize_app_name};

#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
pub struct CustomDomainMapping {
Expand All @@ -16,19 +17,3 @@ pub struct CreateAppRequest {
pub files: FileList,
pub custom_domains: Vec<CustomDomainMapping>,
}

fn serialize_app_name<S>(app_name: &str, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let slugified_name = slug::slugify(app_name);
serializer.serialize_str(&slugified_name)
}

fn deserialize_app_name<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: serde::Deserializer<'de>,
{
let app_name: String = serde::Deserialize::deserialize(deserializer)?;
Ok(slug::slugify(app_name))
}
9 changes: 9 additions & 0 deletions scotty-core/src/notification_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use async_trait::async_trait;
use serde::{Deserialize, Serialize};

use crate::apps::app_data::AppData;
use crate::utils::serde::{deserialize_app_name, serialize_app_name};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, utoipa::ToSchema, Hash, Eq)]
pub struct GitlabContext {
Expand Down Expand Up @@ -99,12 +100,20 @@ mod tests {

#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct AddNotificationRequest {
#[serde(
serialize_with = "serialize_app_name",
deserialize_with = "deserialize_app_name"
)]
pub app_name: String,
pub service_ids: Vec<NotificationReceiver>,
}

#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct RemoveNotificationRequest {
#[serde(
serialize_with = "serialize_app_name",
deserialize_with = "deserialize_app_name"
)]
pub app_name: String,
pub service_ids: Vec<NotificationReceiver>,
}
1 change: 1 addition & 0 deletions scotty-core/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod format;
pub mod serde;
15 changes: 15 additions & 0 deletions scotty-core/src/utils/serde.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pub fn serialize_app_name<S>(app_name: &str, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let slugified_name = slug::slugify(app_name);
serializer.serialize_str(&slugified_name)
}

pub fn deserialize_app_name<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: serde::Deserializer<'de>,
{
let app_name: String = serde::Deserialize::deserialize(deserializer)?;
Ok(slug::slugify(app_name))
}
14 changes: 7 additions & 7 deletions scotty/src/api/handlers/apps/run.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use axum::{
debug_handler,
extract::{Path, State},
response::IntoResponse,
Json,
Expand Down Expand Up @@ -30,6 +29,7 @@ pub async fn run_app_handler(
Path(app_id): Path<String>,
State(state): State<SharedAppState>,
) -> Result<impl IntoResponse, AppError> {
let app_id = slug::slugify(&app_id);
let app_data = state.apps.get_app(&app_id).await;
if app_data.is_none() {
return Err(AppError::AppNotFound(app_id.clone()));
Expand All @@ -46,11 +46,11 @@ pub async fn run_app_handler(
(status = 200, response = inline(RunningAppContext))
)
)]
#[debug_handler]
pub async fn stop_app_handler(
Path(app_id): Path<String>,
State(state): State<SharedAppState>,
) -> Result<impl IntoResponse, AppError> {
let app_id = slug::slugify(&app_id);
let app_data = state.apps.get_app(&app_id).await;
if app_data.is_none() {
return Err(AppError::AppNotFound(app_id.clone()));
Expand All @@ -67,11 +67,11 @@ pub async fn stop_app_handler(
(status = 200, response = inline(RunningAppContext))
)
)]
#[debug_handler]
pub async fn purge_app_handler(
Path(app_id): Path<String>,
State(state): State<SharedAppState>,
) -> Result<impl IntoResponse, AppError> {
let app_id = slug::slugify(&app_id);
let app_data = state.apps.get_app(&app_id).await;
if app_data.is_none() {
return Err(AppError::AppNotFound(app_id.clone()));
Expand All @@ -88,11 +88,11 @@ pub async fn purge_app_handler(
(status = 200, response = inline(AppData))
)
)]
#[debug_handler]
pub async fn info_app_handler(
Path(app_id): Path<String>,
State(state): State<SharedAppState>,
) -> Result<impl IntoResponse, AppError> {
let app_id = slug::slugify(&app_id);
let app_data = state.apps.get_app(&app_id).await;
if app_data.is_none() {
return Err(AppError::AppNotFound(app_id.clone()));
Expand All @@ -108,11 +108,11 @@ pub async fn info_app_handler(
(status = 200, response = inline(RunningAppContext))
)
)]
#[debug_handler]
pub async fn rebuild_app_handler(
Path(app_id): Path<String>,
State(state): State<SharedAppState>,
) -> Result<impl IntoResponse, AppError> {
let app_id = slug::slugify(&app_id);
let app_data = state.apps.get_app(&app_id).await;
if app_data.is_none() {
return Err(AppError::AppNotFound(app_id.clone()));
Expand All @@ -130,11 +130,11 @@ pub async fn rebuild_app_handler(
(status = 400, response = inline(AppError))
)
)]
#[debug_handler]
pub async fn destroy_app_handler(
Path(app_id): Path<String>,
State(state): State<SharedAppState>,
) -> Result<impl IntoResponse, AppError> {
let app_id = slug::slugify(&app_id);
let app_data = state.apps.get_app(&app_id).await;
if app_data.is_none() {
return Err(AppError::AppNotFound(app_id.clone()));
Expand All @@ -155,11 +155,11 @@ pub async fn destroy_app_handler(
(status = 400, response = inline(AppError))
)
)]
#[debug_handler]
pub async fn adopt_app_handler(
Path(app_id): Path<String>,
State(state): State<SharedAppState>,
) -> Result<impl IntoResponse, AppError> {
let app_id = slug::slugify(&app_id);
let app_data = state.apps.get_app(&app_id).await;
if app_data.is_none() {
return Err(AppError::AppNotFound(app_id.clone()));
Expand Down

0 comments on commit d7619c8

Please sign in to comment.