Spaces:
Sleeping
Sleeping
suhail commited on
Commit ·
64edec2
1
Parent(s): ae8175d
fris
Browse files- .env +1 -1
- src/core/__pycache__/security.cpython-313.pyc +0 -0
- src/core/security.py +14 -31
- src/mcp/__init__.py +2 -1
- src/mcp/__pycache__/__init__.cpython-313.pyc +0 -0
.env
CHANGED
|
@@ -6,7 +6,7 @@ DATABASE_URL=postgresql://neondb_owner:npg_MmFvJBHT8Y0k@ep-silent-thunder-ab0rbv
|
|
| 6 |
# Application Settings
|
| 7 |
APP_NAME=Task CRUD API
|
| 8 |
DEBUG=True
|
| 9 |
-
CORS_ORIGINS=
|
| 10 |
|
| 11 |
# Authentication
|
| 12 |
BETTER_AUTH_SECRET=zMdW1P03wJvWJnLKzQ8YYO26vHeinqmR
|
|
|
|
| 6 |
# Application Settings
|
| 7 |
APP_NAME=Task CRUD API
|
| 8 |
DEBUG=True
|
| 9 |
+
CORS_ORIGINS=https://hacathoon-ii-phase2-deployment.vercel.app
|
| 10 |
|
| 11 |
# Authentication
|
| 12 |
BETTER_AUTH_SECRET=zMdW1P03wJvWJnLKzQ8YYO26vHeinqmR
|
src/core/__pycache__/security.cpython-313.pyc
CHANGED
|
Binary files a/src/core/__pycache__/security.cpython-313.pyc and b/src/core/__pycache__/security.cpython-313.pyc differ
|
|
|
src/core/security.py
CHANGED
|
@@ -109,7 +109,6 @@ Security utilities for authentication and authorization.
|
|
| 109 |
"""
|
| 110 |
from datetime import datetime, timedelta
|
| 111 |
from typing import Dict, Any
|
| 112 |
-
import hashlib
|
| 113 |
|
| 114 |
import jwt
|
| 115 |
from passlib.context import CryptContext
|
|
@@ -119,7 +118,7 @@ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
|
| 119 |
from src.core.config import settings
|
| 120 |
|
| 121 |
# =========================
|
| 122 |
-
# Password hashing (bcrypt
|
| 123 |
# =========================
|
| 124 |
|
| 125 |
pwd_context = CryptContext(
|
|
@@ -129,46 +128,33 @@ pwd_context = CryptContext(
|
|
| 129 |
|
| 130 |
security = HTTPBearer()
|
| 131 |
|
|
|
|
| 132 |
|
| 133 |
-
|
|
|
|
| 134 |
"""
|
| 135 |
-
|
| 136 |
-
|
| 137 |
"""
|
| 138 |
-
return
|
| 139 |
|
| 140 |
|
| 141 |
def hash_password(password: str) -> str:
|
| 142 |
"""
|
| 143 |
-
Hash password safely (
|
| 144 |
"""
|
| 145 |
-
return pwd_context.hash(
|
| 146 |
|
| 147 |
|
| 148 |
def verify_password(plain_password: str, hashed_password: str) -> bool:
|
| 149 |
"""
|
| 150 |
-
Verify password
|
| 151 |
"""
|
| 152 |
try:
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
)
|
| 157 |
-
|
| 158 |
-
if pwd_context.verify(normalized, hashed_password):
|
| 159 |
-
return True
|
| 160 |
-
|
| 161 |
-
except Exception:
|
| 162 |
-
pass
|
| 163 |
-
|
| 164 |
-
# 🔁 Legacy fallback (OLD system)
|
| 165 |
-
try:
|
| 166 |
-
legacy = hashlib.sha256(
|
| 167 |
-
plain_password.encode("utf-8")
|
| 168 |
-
).hexdigest()
|
| 169 |
-
|
| 170 |
-
return pwd_context.verify(legacy, hashed_password)
|
| 171 |
-
|
| 172 |
except Exception:
|
| 173 |
return False
|
| 174 |
|
|
@@ -230,9 +216,6 @@ def verify_jwt_token(token: str, secret: str) -> dict:
|
|
| 230 |
def get_current_user(
|
| 231 |
credentials: HTTPAuthorizationCredentials = Depends(security)
|
| 232 |
) -> Dict[str, Any]:
|
| 233 |
-
"""
|
| 234 |
-
Extract and validate JWT token from Authorization header.
|
| 235 |
-
"""
|
| 236 |
token = credentials.credentials
|
| 237 |
payload = verify_jwt_token(token, settings.BETTER_AUTH_SECRET)
|
| 238 |
|
|
|
|
| 109 |
"""
|
| 110 |
from datetime import datetime, timedelta
|
| 111 |
from typing import Dict, Any
|
|
|
|
| 112 |
|
| 113 |
import jwt
|
| 114 |
from passlib.context import CryptContext
|
|
|
|
| 118 |
from src.core.config import settings
|
| 119 |
|
| 120 |
# =========================
|
| 121 |
+
# Password hashing (bcrypt SAFE)
|
| 122 |
# =========================
|
| 123 |
|
| 124 |
pwd_context = CryptContext(
|
|
|
|
| 128 |
|
| 129 |
security = HTTPBearer()
|
| 130 |
|
| 131 |
+
MAX_BCRYPT_BYTES = 72
|
| 132 |
|
| 133 |
+
|
| 134 |
+
def _bcrypt_safe(password: str) -> bytes:
|
| 135 |
"""
|
| 136 |
+
bcrypt supports MAX 72 bytes.
|
| 137 |
+
Always truncate BEFORE hashing or verifying.
|
| 138 |
"""
|
| 139 |
+
return password.encode("utf-8")[:MAX_BCRYPT_BYTES]
|
| 140 |
|
| 141 |
|
| 142 |
def hash_password(password: str) -> str:
|
| 143 |
"""
|
| 144 |
+
Hash password safely (NO crashes).
|
| 145 |
"""
|
| 146 |
+
return pwd_context.hash(_bcrypt_safe(password))
|
| 147 |
|
| 148 |
|
| 149 |
def verify_password(plain_password: str, hashed_password: str) -> bool:
|
| 150 |
"""
|
| 151 |
+
Verify password safely (NO crashes).
|
| 152 |
"""
|
| 153 |
try:
|
| 154 |
+
return pwd_context.verify(
|
| 155 |
+
_bcrypt_safe(plain_password),
|
| 156 |
+
hashed_password
|
| 157 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
except Exception:
|
| 159 |
return False
|
| 160 |
|
|
|
|
| 216 |
def get_current_user(
|
| 217 |
credentials: HTTPAuthorizationCredentials = Depends(security)
|
| 218 |
) -> Dict[str, Any]:
|
|
|
|
|
|
|
|
|
|
| 219 |
token = credentials.credentials
|
| 220 |
payload = verify_jwt_token(token, settings.BETTER_AUTH_SECRET)
|
| 221 |
|
src/mcp/__init__.py
CHANGED
|
@@ -35,7 +35,8 @@ def load_tool_contract(tool_name: str) -> dict:
|
|
| 35 |
# Get the project root directory
|
| 36 |
current_file = Path(__file__)
|
| 37 |
project_root = current_file.parent.parent.parent # backend/src/mcp -> backend
|
| 38 |
-
contract_path =
|
|
|
|
| 39 |
|
| 40 |
if not contract_path.exists():
|
| 41 |
raise FileNotFoundError(f"Contract file not found: {contract_path}")
|
|
|
|
| 35 |
# Get the project root directory
|
| 36 |
current_file = Path(__file__)
|
| 37 |
project_root = current_file.parent.parent.parent # backend/src/mcp -> backend
|
| 38 |
+
contract_path = Path("C:/Users/Pcw/OneDrive/Desktop/phase-2-backend/taskflow-api/specs/001-openai-agent-mcp-tools/contracts") / f"{tool_name}.json"
|
| 39 |
+
|
| 40 |
|
| 41 |
if not contract_path.exists():
|
| 42 |
raise FileNotFoundError(f"Contract file not found: {contract_path}")
|
src/mcp/__pycache__/__init__.cpython-313.pyc
CHANGED
|
Binary files a/src/mcp/__pycache__/__init__.cpython-313.pyc and b/src/mcp/__pycache__/__init__.cpython-313.pyc differ
|
|
|