Martechsol commited on
Commit Β·
1d15f75
1
Parent(s): 1538a15
Hardening admin security: moving credentials to environment variables
Browse files- app/admin/router.py +7 -9
- app/core/config.py +2 -0
app/admin/router.py
CHANGED
|
@@ -41,9 +41,7 @@ from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse
|
|
| 41 |
logger = logging.getLogger(__name__)
|
| 42 |
settings = get_settings()
|
| 43 |
|
| 44 |
-
#
|
| 45 |
-
ADMIN_USERNAME = "martech_admin"
|
| 46 |
-
ADMIN_PASSWORD = "martech_admin_303"
|
| 47 |
|
| 48 |
# ββ Security scheme βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 49 |
security = HTTPBasic()
|
|
@@ -68,11 +66,11 @@ def verify_admin(credentials: HTTPBasicCredentials = Depends(security)) -> str:
|
|
| 68 |
"""
|
| 69 |
correct_username = secrets.compare_digest(
|
| 70 |
credentials.username.encode("utf-8"),
|
| 71 |
-
|
| 72 |
)
|
| 73 |
correct_password = secrets.compare_digest(
|
| 74 |
credentials.password.encode("utf-8"),
|
| 75 |
-
|
| 76 |
)
|
| 77 |
if not (correct_username and correct_password):
|
| 78 |
logger.warning(
|
|
@@ -104,8 +102,8 @@ async def request_otp(req: LoginRequest):
|
|
| 104 |
Verifies password and generates a 6-digit OTP.
|
| 105 |
Sends the OTP to the configured admin email.
|
| 106 |
"""
|
| 107 |
-
if not (secrets.compare_digest(req.username,
|
| 108 |
-
secrets.compare_digest(req.password,
|
| 109 |
raise HTTPException(status_code=401, detail="Invalid credentials.")
|
| 110 |
|
| 111 |
# Generate 6-digit code
|
|
@@ -188,8 +186,8 @@ def send_otp_email(to_email: str, otp_code: str):
|
|
| 188 |
async def verify_otp(req: OTPVerifyRequest):
|
| 189 |
"""Verifies both the password and the OTP code."""
|
| 190 |
# 1. Verify password first
|
| 191 |
-
if not (secrets.compare_digest(req.username,
|
| 192 |
-
secrets.compare_digest(req.password,
|
| 193 |
raise HTTPException(status_code=401, detail="Invalid credentials.")
|
| 194 |
|
| 195 |
# 2. Verify OTP
|
|
|
|
| 41 |
logger = logging.getLogger(__name__)
|
| 42 |
settings = get_settings()
|
| 43 |
|
| 44 |
+
# Credentials are now loaded from settings (environment variables)
|
|
|
|
|
|
|
| 45 |
|
| 46 |
# ββ Security scheme βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 47 |
security = HTTPBasic()
|
|
|
|
| 66 |
"""
|
| 67 |
correct_username = secrets.compare_digest(
|
| 68 |
credentials.username.encode("utf-8"),
|
| 69 |
+
settings.admin_user.encode("utf-8"),
|
| 70 |
)
|
| 71 |
correct_password = secrets.compare_digest(
|
| 72 |
credentials.password.encode("utf-8"),
|
| 73 |
+
settings.admin_pass.encode("utf-8"),
|
| 74 |
)
|
| 75 |
if not (correct_username and correct_password):
|
| 76 |
logger.warning(
|
|
|
|
| 102 |
Verifies password and generates a 6-digit OTP.
|
| 103 |
Sends the OTP to the configured admin email.
|
| 104 |
"""
|
| 105 |
+
if not (secrets.compare_digest(req.username, settings.admin_user) and
|
| 106 |
+
secrets.compare_digest(req.password, settings.admin_pass)):
|
| 107 |
raise HTTPException(status_code=401, detail="Invalid credentials.")
|
| 108 |
|
| 109 |
# Generate 6-digit code
|
|
|
|
| 186 |
async def verify_otp(req: OTPVerifyRequest):
|
| 187 |
"""Verifies both the password and the OTP code."""
|
| 188 |
# 1. Verify password first
|
| 189 |
+
if not (secrets.compare_digest(req.username, settings.admin_user) and
|
| 190 |
+
secrets.compare_digest(req.password, settings.admin_pass)):
|
| 191 |
raise HTTPException(status_code=401, detail="Invalid credentials.")
|
| 192 |
|
| 193 |
# 2. Verify OTP
|
app/core/config.py
CHANGED
|
@@ -50,6 +50,8 @@ class Settings(BaseSettings):
|
|
| 50 |
smtp_user: str = Field(default="", alias="SMTP_USER")
|
| 51 |
smtp_pass: str = Field(default="", alias="SMTP_PASS")
|
| 52 |
admin_email: str = Field(default="randomjoedown@gmail.com", alias="ADMIN_EMAIL")
|
|
|
|
|
|
|
| 53 |
|
| 54 |
|
| 55 |
@lru_cache
|
|
|
|
| 50 |
smtp_user: str = Field(default="", alias="SMTP_USER")
|
| 51 |
smtp_pass: str = Field(default="", alias="SMTP_PASS")
|
| 52 |
admin_email: str = Field(default="randomjoedown@gmail.com", alias="ADMIN_EMAIL")
|
| 53 |
+
admin_user: str = Field(default="martech_admin", alias="ADMIN_USER")
|
| 54 |
+
admin_pass: str = Field(default="martech_admin_303", alias="ADMIN_PASS")
|
| 55 |
|
| 56 |
|
| 57 |
@lru_cache
|