|
1 | 1 | from pydantic_settings import BaseSettings, SettingsConfigDict |
2 | 2 | from pydantic import field_validator, model_validator |
3 | 3 | from typing import Optional |
| 4 | +from urllib.parse import quote_plus |
4 | 5 | import logging |
5 | 6 |
|
6 | 7 | logger = logging.getLogger(__name__) |
@@ -70,27 +71,34 @@ def validate_and_build_urls(self): |
70 | 71 |
|
71 | 72 | # Build database_url if not provided |
72 | 73 | if not self.database_url: |
| 74 | + # URL-encode username and password to handle special characters |
| 75 | + encoded_user = quote_plus(self.postgres_user) |
| 76 | + encoded_password = quote_plus(self.postgres_password) |
73 | 77 | self.database_url = ( |
74 | | - f"postgresql://{self.postgres_user}:{self.postgres_password}" |
| 78 | + f"postgresql://{encoded_user}:{encoded_password}" |
75 | 79 | f"@{self.postgres_host}:{self.postgres_port}/{self.postgres_db}" |
76 | 80 | ) |
77 | 81 |
|
78 | 82 | return self |
79 | 83 |
|
80 | 84 | @property |
81 | 85 | def postgres_dsn(self) -> str: |
82 | | - """Returns the PostgreSQL DSN""" |
| 86 | + """Returns the PostgreSQL DSN with URL-encoded credentials""" |
| 87 | + encoded_user = quote_plus(self.postgres_user) |
| 88 | + encoded_password = quote_plus(self.postgres_password) |
83 | 89 | return ( |
84 | | - f"postgresql://{self.postgres_user}:{self.postgres_password}" |
| 90 | + f"postgresql://{encoded_user}:{encoded_password}" |
85 | 91 | f"@{self.postgres_host}:{self.postgres_port}/{self.postgres_db}" |
86 | 92 | ) |
87 | 93 |
|
88 | 94 | @property |
89 | 95 | def rabbitmq_url(self) -> str: |
90 | | - """Returns the RabbitMQ connection URL""" |
91 | | - host = self.rabbitmq_host.strip() if self.rabbitmq_host else "localhost" |
92 | | - url = f"amqp://{self.rabbitmq_user}:{self.rabbitmq_password}@{host}:{self.rabbitmq_port}/" |
93 | | - logger.debug(f"RabbitMQ URL: amqp://{self.rabbitmq_user}:***@{host}:{self.rabbitmq_port}/") |
| 96 | + """Returns the RabbitMQ connection URL with URL-encoded credentials""" |
| 97 | + # Use already-normalized host from normalize_rabbitmq_host validator |
| 98 | + encoded_user = quote_plus(self.rabbitmq_user) |
| 99 | + encoded_password = quote_plus(self.rabbitmq_password) |
| 100 | + url = f"amqp://{encoded_user}:{encoded_password}@{self.rabbitmq_host}:{self.rabbitmq_port}/" |
| 101 | + logger.debug(f"RabbitMQ URL: amqp://{encoded_user}:***@{self.rabbitmq_host}:{self.rabbitmq_port}/") |
94 | 102 | return url |
95 | 103 |
|
96 | 104 |
|
|
0 commit comments