Merge pull request #7 from knylbyte/codex/revert-content-security-policies-to-content_security_policy

Use content_security_policy key in web UI config
This commit is contained in:
knylbyte
2025-08-18 17:38:53 +02:00
committed by GitHub
6 changed files with 18 additions and 22 deletions
+2 -2
View File
@@ -323,7 +323,7 @@ log:
### 1.10 `web_ui`
- enabled: default is true, if set to false the web_ui is disabled
- user_ui_enabled, true or false, for user bouquet editor
- content-security-policies: configure Content-Security-Policy headers. When `enabled` is true, the default directives `default-src 'self'`, `script-src 'self' nonce-{nonce_b64}`, and `frame-ancestors 'none'` are applied. Additional directives can be added via `custom-attributes`. Enabling CSP may block external images/logos unless allowed via directives like `img-src`.
- content_security_policy: configure Content-Security-Policy headers. When `enabled` is true, the default directives `default-src 'self'`, `script-src 'self' nonce-{nonce_b64}`, and `frame-ancestors 'none'` are applied. Additional directives can be added via `custom-attributes`. Enabling CSP may block external images/logos unless allowed via directives like `img-src`.
- path is for web_ui path like `/ui` for reverse proxy integration if necessary.
- auth for authentication settings
- `enabled` can be deactivated if `enabled` is set to `false`. If not set default is `true`.
@@ -335,7 +335,7 @@ log:
web_ui:
enabled: true
user_ui_enabled: true
content-security-policies:
content_security_policy:
enabled: true
custom-attributes:
- "default-src 'self'"
+1 -1
View File
@@ -167,7 +167,7 @@ async fn index(
if let Some(csp) = config
.web_ui
.as_ref()
.and_then(|w| w.content_security_policies.as_ref())
.and_then(|w| w.content_security_policy.as_ref())
.filter(|c| c.enabled)
{
let mut attrs = vec![
+10 -10
View File
@@ -1,9 +1,9 @@
use shared::error::TuliproxError;
use shared::model::{ContentSecurityPoliciesConfigDto, WebUiConfigDto};
use shared::model::{ContentSecurityPolicyConfigDto, WebUiConfigDto};
use crate::model::{macros, WebAuthConfig};
#[derive(Debug, Clone)]
pub struct ContentSecurityPoliciesConfig {
pub struct ContentSecurityPolicyConfig {
pub enabled: bool,
pub custom_attributes: Vec<String>,
}
@@ -12,7 +12,7 @@ pub struct ContentSecurityPoliciesConfig {
pub struct WebUiConfig {
pub enabled: bool,
pub user_ui_enabled: bool,
pub content_security_policies: Option<ContentSecurityPoliciesConfig>,
pub content_security_policy: Option<ContentSecurityPolicyConfig>,
pub path: Option<String>,
pub auth: Option<WebAuthConfig>,
pub player_server: Option<String>,
@@ -31,14 +31,14 @@ impl WebUiConfig {
}
}
macros::from_impl!(ContentSecurityPoliciesConfig);
impl From<&ContentSecurityPoliciesConfigDto> for ContentSecurityPoliciesConfig {
fn from(dto: &ContentSecurityPoliciesConfigDto) -> Self {
macros::from_impl!(ContentSecurityPolicyConfig);
impl From<&ContentSecurityPolicyConfigDto> for ContentSecurityPolicyConfig {
fn from(dto: &ContentSecurityPolicyConfigDto) -> Self {
Self { enabled: dto.enabled, custom_attributes: dto.custom_attributes.clone() }
}
}
impl From<&ContentSecurityPoliciesConfig> for ContentSecurityPoliciesConfigDto {
fn from(instance: &ContentSecurityPoliciesConfig) -> Self {
impl From<&ContentSecurityPolicyConfig> for ContentSecurityPolicyConfigDto {
fn from(instance: &ContentSecurityPolicyConfig) -> Self {
Self { enabled: instance.enabled, custom_attributes: instance.custom_attributes.clone() }
}
}
@@ -49,7 +49,7 @@ impl From<&WebUiConfigDto> for WebUiConfig {
Self {
enabled: dto.enabled,
user_ui_enabled: dto.user_ui_enabled,
content_security_policies: dto.content_security_policies.as_ref().map(Into::into),
content_security_policy: dto.content_security_policy.as_ref().map(Into::into),
path: dto.path.clone(),
auth: dto.auth.as_ref().map(Into::into),
player_server: dto.player_server.clone(),
@@ -61,7 +61,7 @@ impl From<&WebUiConfig> for WebUiConfigDto {
Self {
enabled: instance.enabled,
user_ui_enabled: instance.user_ui_enabled,
content_security_policies: instance.content_security_policies.as_ref().map(Into::into),
content_security_policy: instance.content_security_policy.as_ref().map(Into::into),
path: instance.path.clone(),
auth: instance.auth.as_ref().map(Into::into),
player_server: instance.player_server.clone(),
+1 -1
View File
@@ -27,7 +27,7 @@ update_on_boot: false # best not to hammer upstream during testing
web_ui:
enabled: true
user_ui_enabled: true
content-security-policies:
content_security_policy:
enabled: true
custom-attributes:
- "default-src 'self'"
@@ -57,7 +57,7 @@ pub fn WebUiConfigView() -> Html {
{ config_field_bool!(web_ui, translate.t("LABEL.USER_UI_ENABLED"), user_ui_enabled) }
{ config_field_child!(translate.t("LABEL.CONTENT_SECURITY_POLICY"), {
html! {
match web_ui.content_security_policies.as_ref() {
match web_ui.content_security_policy.as_ref() {
Some(csp) => html! {
<>
{ config_field_bool!(csp, translate.t("LABEL.ENABLED"), enabled) }
+3 -7
View File
@@ -23,7 +23,7 @@ const RESERVED_PATHS: &[&str] = &[
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default, PartialEq)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
pub struct ContentSecurityPoliciesConfigDto {
pub struct ContentSecurityPolicyConfigDto {
#[serde(default)]
pub enabled: bool,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
@@ -37,12 +37,8 @@ pub struct WebUiConfigDto {
pub enabled: bool,
#[serde(default = "default_as_true")]
pub user_ui_enabled: bool,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "content-security-policies"
)]
pub content_security_policies: Option<ContentSecurityPoliciesConfigDto>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub content_security_policy: Option<ContentSecurityPolicyConfigDto>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]