mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-17 07:45:36 -05:00
fix: More lenient postgres override parsing (#6712)
This commit is contained in:
@@ -43,22 +43,22 @@ class PostgresProvider(AbstractDBProvider, BaseSettings):
|
|||||||
|
|
||||||
model_config = SettingsConfigDict(arbitrary_types_allowed=True, extra="allow")
|
model_config = SettingsConfigDict(arbitrary_types_allowed=True, extra="allow")
|
||||||
|
|
||||||
|
def _parse_override_url(self, url: str) -> str:
|
||||||
|
if not url.startswith("postgresql://"):
|
||||||
|
raise ValueError("POSTGRES_URL_OVERRIDE scheme must be postgresql")
|
||||||
|
|
||||||
|
scheme, remainder = url.split("://", 1)
|
||||||
|
if "@" in remainder and ":" in remainder.split("@")[0]:
|
||||||
|
credentials, host_part = remainder.rsplit("@", 1)
|
||||||
|
user, password = credentials.split(":", 1)
|
||||||
|
return f"{scheme}://{user}:{urlparse.quote(password, safe='')}@{host_part}"
|
||||||
|
|
||||||
|
return url
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def db_url(self) -> str:
|
def db_url(self) -> str:
|
||||||
if self.POSTGRES_URL_OVERRIDE:
|
if self.POSTGRES_URL_OVERRIDE:
|
||||||
url = self.POSTGRES_URL_OVERRIDE
|
return self._parse_override_url(self.POSTGRES_URL_OVERRIDE)
|
||||||
|
|
||||||
scheme, remainder = url.split("://", 1)
|
|
||||||
if scheme != "postgresql":
|
|
||||||
raise ValueError("POSTGRES_URL_OVERRIDE scheme must be postgresql")
|
|
||||||
|
|
||||||
remainder = remainder.split(":", 1)[1]
|
|
||||||
password = remainder[: remainder.rfind("@")]
|
|
||||||
quoted_password = urlparse.quote(password)
|
|
||||||
|
|
||||||
safe_url = url.replace(password, quoted_password)
|
|
||||||
|
|
||||||
return safe_url
|
|
||||||
|
|
||||||
return str(
|
return str(
|
||||||
PostgresDsn.build(
|
PostgresDsn.build(
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -58,6 +59,14 @@ psql_validation_cases = [
|
|||||||
"postgresql://mealie:P%40ssword%21%40%23%24%25%25%5E%5E%26%26%2A%2A%28%29%2B%3B%27%22%27%3C%3E%3F%7B%7D%5B%5D@postgres:5432/mealie",
|
"postgresql://mealie:P%40ssword%21%40%23%24%25%25%5E%5E%26%26%2A%2A%28%29%2B%3B%27%22%27%3C%3E%3F%7B%7D%5B%5D@postgres:5432/mealie",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"unencoded_to_encoded_no_port_url",
|
||||||
|
[
|
||||||
|
"POSTGRES_URL_OVERRIDE",
|
||||||
|
"postgresql://mealie:P@ssword!@#$%%^^&&**()+;'\"'<>?{}[]@postgres/mealie",
|
||||||
|
"postgresql://mealie:P%40ssword%21%40%23%24%25%25%5E%5E%26%26%2A%2A%28%29%2B%3B%27%22%27%3C%3E%3F%7B%7D%5B%5D@postgres/mealie",
|
||||||
|
],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"no_encode_needed_password",
|
"no_encode_needed_password",
|
||||||
[
|
[
|
||||||
@@ -74,6 +83,54 @@ psql_validation_cases = [
|
|||||||
"postgresql://mealie:MyPassword@postgres:5432/mealie",
|
"postgresql://mealie:MyPassword@postgres:5432/mealie",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"no_password_url",
|
||||||
|
[
|
||||||
|
"POSTGRES_URL_OVERRIDE",
|
||||||
|
"postgresql://mealie@postgres:5432/mealie",
|
||||||
|
"postgresql://mealie@postgres:5432/mealie",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"no_password_no_port_url",
|
||||||
|
[
|
||||||
|
"POSTGRES_URL_OVERRIDE",
|
||||||
|
"postgresql://mealie@postgres/mealie",
|
||||||
|
"postgresql://mealie@postgres/mealie",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unix_socket_with_empty_password",
|
||||||
|
[
|
||||||
|
"POSTGRES_URL_OVERRIDE",
|
||||||
|
"postgresql://mealie:@/mealie?host=/run/postgresql",
|
||||||
|
"postgresql://mealie:@/mealie?host=/run/postgresql",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unix_socket_no_password",
|
||||||
|
[
|
||||||
|
"POSTGRES_URL_OVERRIDE",
|
||||||
|
"postgresql://mealie@/mealie?host=/run/postgresql",
|
||||||
|
"postgresql://mealie@/mealie?host=/run/postgresql",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"no_credentials_at_all",
|
||||||
|
[
|
||||||
|
"POSTGRES_URL_OVERRIDE",
|
||||||
|
"postgresql:///mealie?host=/run/postgresql",
|
||||||
|
"postgresql:///mealie?host=/run/postgresql",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"query_params_with_colon",
|
||||||
|
[
|
||||||
|
"POSTGRES_URL_OVERRIDE",
|
||||||
|
"postgresql://user@host/db?sslmode=require&connect_timeout=10",
|
||||||
|
"postgresql://user@host/db?sslmode=require&connect_timeout=10",
|
||||||
|
],
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
psql_cases = [x[1] for x in psql_validation_cases]
|
psql_cases = [x[1] for x in psql_validation_cases]
|
||||||
@@ -174,11 +231,11 @@ def test_smtp_enable_with_bad_data_tls(data: SMTPValidationCase):
|
|||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class EnvVar:
|
class EnvVar:
|
||||||
name: str
|
name: str
|
||||||
value: any
|
value: Any
|
||||||
|
|
||||||
|
|
||||||
class LDAPValidationCase:
|
class LDAPValidationCase:
|
||||||
settings = list[EnvVar]
|
settings: list[EnvVar]
|
||||||
is_valid: bool
|
is_valid: bool
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -222,7 +279,7 @@ def test_ldap_settings_validation(data: LDAPValidationCase, monkeypatch: pytest.
|
|||||||
|
|
||||||
|
|
||||||
class OIDCValidationCase:
|
class OIDCValidationCase:
|
||||||
settings = list[EnvVar]
|
settings: list[EnvVar]
|
||||||
is_valid: bool
|
is_valid: bool
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|||||||
Reference in New Issue
Block a user