fix lint issues across codebase
This commit is contained in:
@@ -13,11 +13,13 @@ from app.config import VERSION, config
|
|||||||
def setup_logging(app: Flask) -> None:
|
def setup_logging(app: Flask) -> None:
|
||||||
"""Configure structured logging."""
|
"""Configure structured logging."""
|
||||||
log_level = logging.DEBUG if app.debug else logging.INFO
|
log_level = logging.DEBUG if app.debug else logging.INFO
|
||||||
log_format = (
|
if app.debug:
|
||||||
"%(asctime)s %(levelname)s [%(name)s] %(message)s"
|
log_format = "%(asctime)s %(levelname)s [%(name)s] %(message)s"
|
||||||
if app.debug
|
else:
|
||||||
else '{"time":"%(asctime)s","level":"%(levelname)s","logger":"%(name)s","message":"%(message)s"}'
|
log_format = (
|
||||||
)
|
'{"time":"%(asctime)s","level":"%(levelname)s",'
|
||||||
|
'"logger":"%(name)s","message":"%(message)s"}'
|
||||||
|
)
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level=log_level,
|
level=log_level,
|
||||||
@@ -112,7 +114,9 @@ def setup_error_handlers(app: Flask) -> None:
|
|||||||
def rate_limit_exceeded(error):
|
def rate_limit_exceeded(error):
|
||||||
app.logger.warning(
|
app.logger.warning(
|
||||||
"Rate limit exceeded: %s from %s [rid=%s]",
|
"Rate limit exceeded: %s from %s [rid=%s]",
|
||||||
request.path, request.remote_addr, getattr(g, "request_id", "-")
|
request.path,
|
||||||
|
request.remote_addr,
|
||||||
|
getattr(g, "request_id", "-"),
|
||||||
)
|
)
|
||||||
return Response(
|
return Response(
|
||||||
json.dumps({"error": "Rate limit exceeded", "retry_after": error.description}),
|
json.dumps({"error": "Rate limit exceeded", "retry_after": error.description}),
|
||||||
@@ -124,7 +128,9 @@ def setup_error_handlers(app: Flask) -> None:
|
|||||||
def internal_error(error):
|
def internal_error(error):
|
||||||
app.logger.error(
|
app.logger.error(
|
||||||
"Internal error: %s - %s [rid=%s]",
|
"Internal error: %s - %s [rid=%s]",
|
||||||
request.path, str(error), getattr(g, "request_id", "-")
|
request.path,
|
||||||
|
str(error),
|
||||||
|
getattr(g, "request_id", "-"),
|
||||||
)
|
)
|
||||||
return Response(
|
return Response(
|
||||||
json.dumps({"error": "Internal server error"}),
|
json.dumps({"error": "Internal server error"}),
|
||||||
@@ -135,8 +141,7 @@ def setup_error_handlers(app: Flask) -> None:
|
|||||||
@app.errorhandler(Exception)
|
@app.errorhandler(Exception)
|
||||||
def handle_exception(error):
|
def handle_exception(error):
|
||||||
app.logger.exception(
|
app.logger.exception(
|
||||||
"Unhandled exception: %s [rid=%s]",
|
"Unhandled exception: %s [rid=%s]", str(error), getattr(g, "request_id", "-")
|
||||||
str(error), getattr(g, "request_id", "-")
|
|
||||||
)
|
)
|
||||||
return Response(
|
return Response(
|
||||||
json.dumps({"error": "Internal server error"}),
|
json.dumps({"error": "Internal server error"}),
|
||||||
|
|||||||
@@ -37,14 +37,14 @@ class TestContentDedup:
|
|||||||
# First 3 submissions should succeed
|
# First 3 submissions should succeed
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
response = strict_client.post("/", data=content)
|
response = strict_client.post("/", data=content)
|
||||||
assert response.status_code == 201, f"Submission {i+1} failed"
|
assert response.status_code == 201, f"Submission {i + 1} failed"
|
||||||
|
|
||||||
def test_duplicate_exceeds_threshold_rejected(self, strict_client):
|
def test_duplicate_exceeds_threshold_rejected(self, strict_client):
|
||||||
"""Fourth duplicate within window should be rejected."""
|
"""Fourth duplicate within window should be rejected."""
|
||||||
content = b"unique content 3"
|
content = b"unique content 3"
|
||||||
|
|
||||||
# First 3 succeed
|
# First 3 succeed
|
||||||
for i in range(3):
|
for _ in range(3):
|
||||||
response = strict_client.post("/", data=content)
|
response = strict_client.post("/", data=content)
|
||||||
assert response.status_code == 201
|
assert response.status_code == 201
|
||||||
|
|
||||||
@@ -144,8 +144,7 @@ class TestContentHashDatabase:
|
|||||||
# Query database directly
|
# Query database directly
|
||||||
db = get_db()
|
db = get_db()
|
||||||
row = db.execute(
|
row = db.execute(
|
||||||
"SELECT hash, count FROM content_hashes WHERE hash = ?",
|
"SELECT hash, count FROM content_hashes WHERE hash = ?", (content_hash,)
|
||||||
(content_hash,)
|
|
||||||
).fetchone()
|
).fetchone()
|
||||||
|
|
||||||
assert row is not None
|
assert row is not None
|
||||||
@@ -179,10 +178,7 @@ class TestContentHashCleanup:
|
|||||||
|
|
||||||
# Verify removed
|
# Verify removed
|
||||||
db = get_db()
|
db = get_db()
|
||||||
row = db.execute(
|
row = db.execute("SELECT * FROM content_hashes WHERE hash = ?", (content_hash,)).fetchone()
|
||||||
"SELECT * FROM content_hashes WHERE hash = ?",
|
|
||||||
(content_hash,)
|
|
||||||
).fetchone()
|
|
||||||
assert row is None
|
assert row is None
|
||||||
|
|
||||||
def test_cleanup_keeps_recent(self, app_context):
|
def test_cleanup_keeps_recent(self, app_context):
|
||||||
@@ -193,14 +189,11 @@ class TestContentHashCleanup:
|
|||||||
check_content_hash(content_hash)
|
check_content_hash(content_hash)
|
||||||
|
|
||||||
# Cleanup should not remove it
|
# Cleanup should not remove it
|
||||||
deleted = cleanup_expired_hashes()
|
cleanup_expired_hashes()
|
||||||
|
|
||||||
# Verify still present
|
# Verify still present
|
||||||
db = get_db()
|
db = get_db()
|
||||||
row = db.execute(
|
row = db.execute("SELECT * FROM content_hashes WHERE hash = ?", (content_hash,)).fetchone()
|
||||||
"SELECT * FROM content_hashes WHERE hash = ?",
|
|
||||||
(content_hash,)
|
|
||||||
).fetchone()
|
|
||||||
assert row is not None
|
assert row is not None
|
||||||
|
|
||||||
|
|
||||||
@@ -268,6 +261,7 @@ class TestEntropyEnforcement:
|
|||||||
def test_random_data_accepted(self, entropy_client):
|
def test_random_data_accepted(self, entropy_client):
|
||||||
"""Random/encrypted data should pass entropy check."""
|
"""Random/encrypted data should pass entropy check."""
|
||||||
import os
|
import os
|
||||||
|
|
||||||
random_data = os.urandom(512) # High entropy random bytes
|
random_data = os.urandom(512) # High entropy random bytes
|
||||||
|
|
||||||
response = entropy_client.post(
|
response = entropy_client.post(
|
||||||
|
|||||||
@@ -254,9 +254,7 @@ class TestDeletePaste:
|
|||||||
data = json.loads(response.data)
|
data = json.loads(response.data)
|
||||||
assert "error" in data
|
assert "error" in data
|
||||||
|
|
||||||
def test_delete_paste_wrong_owner(
|
def test_delete_paste_wrong_owner(self, client, sample_text, auth_header, other_auth_header):
|
||||||
self, client, sample_text, auth_header, other_auth_header
|
|
||||||
):
|
|
||||||
"""Delete paste owned by another user fails."""
|
"""Delete paste owned by another user fails."""
|
||||||
create = client.post(
|
create = client.post(
|
||||||
"/",
|
"/",
|
||||||
|
|||||||
@@ -67,9 +67,8 @@ class TestCleanupExpiredPastes:
|
|||||||
# Mock time to simulate expiry (paste expiry + 1 second)
|
# Mock time to simulate expiry (paste expiry + 1 second)
|
||||||
future_time = time.time() + app.config["PASTE_EXPIRY_SECONDS"] + 1
|
future_time = time.time() + app.config["PASTE_EXPIRY_SECONDS"] + 1
|
||||||
|
|
||||||
with patch("time.time", return_value=future_time):
|
with patch("time.time", return_value=future_time), app.app_context():
|
||||||
with app.app_context():
|
deleted = cleanup_expired_pastes()
|
||||||
deleted = cleanup_expired_pastes()
|
|
||||||
|
|
||||||
assert deleted >= 1
|
assert deleted >= 1
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ def solve_pow(nonce, difficulty):
|
|||||||
if byte == 0:
|
if byte == 0:
|
||||||
zero_bits += 8
|
zero_bits += 8
|
||||||
else:
|
else:
|
||||||
zero_bits += (8 - byte.bit_length())
|
zero_bits += 8 - byte.bit_length()
|
||||||
break
|
break
|
||||||
|
|
||||||
if zero_bits >= difficulty:
|
if zero_bits >= difficulty:
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ class TestProxyTrustValidation:
|
|||||||
)
|
)
|
||||||
assert response.status_code == 201
|
assert response.status_code == 201
|
||||||
import json
|
import json
|
||||||
|
|
||||||
data = json.loads(response.data)
|
data = json.loads(response.data)
|
||||||
assert "owner" in data
|
assert "owner" in data
|
||||||
|
|
||||||
@@ -124,6 +125,7 @@ class TestProxyTrustValidation:
|
|||||||
)
|
)
|
||||||
assert response.status_code == 201
|
assert response.status_code == 201
|
||||||
import json
|
import json
|
||||||
|
|
||||||
data = json.loads(response.data)
|
data = json.loads(response.data)
|
||||||
# Owner should NOT be set because proxy wasn't trusted
|
# Owner should NOT be set because proxy wasn't trusted
|
||||||
assert "owner" not in data
|
assert "owner" not in data
|
||||||
@@ -148,6 +150,7 @@ class TestProxyTrustValidation:
|
|||||||
)
|
)
|
||||||
assert response.status_code == 201
|
assert response.status_code == 201
|
||||||
import json
|
import json
|
||||||
|
|
||||||
data = json.loads(response.data)
|
data = json.loads(response.data)
|
||||||
assert "owner" in data
|
assert "owner" in data
|
||||||
finally:
|
finally:
|
||||||
@@ -259,9 +262,7 @@ class TestSizeLimits:
|
|||||||
class TestOwnershipEnforcement:
|
class TestOwnershipEnforcement:
|
||||||
"""Tests for paste ownership and access control."""
|
"""Tests for paste ownership and access control."""
|
||||||
|
|
||||||
def test_cannot_delete_others_paste(
|
def test_cannot_delete_others_paste(self, client, sample_text, auth_header, other_auth_header):
|
||||||
self, client, sample_text, auth_header, other_auth_header
|
|
||||||
):
|
|
||||||
"""Users cannot delete pastes they don't own."""
|
"""Users cannot delete pastes they don't own."""
|
||||||
create = client.post(
|
create = client.post(
|
||||||
"/",
|
"/",
|
||||||
|
|||||||
Reference in New Issue
Block a user