Skip to content

Commit 5c21b0b

Browse files
committed
Swagger UI config issue solved + refactoring the report feature ressources
1 parent 6bc68b5 commit 5c21b0b

File tree

9 files changed

+76
-59
lines changed

9 files changed

+76
-59
lines changed

backend/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from routes.report_routes import report_bp
2121

2222
from flasgger import Swagger
23-
from utils.api_spec import swagger_template, swagger_config
23+
from utils.api_spec import swagger_template
2424

2525
# Load environment variables
2626
load_dotenv()
@@ -30,7 +30,7 @@
3030
bcrypt = Bcrypt(app)
3131

3232
# Initialize Swagger
33-
swagger = Swagger(app, template=swagger_template,config=swagger_config)
33+
swagger = Swagger(app, template=swagger_template)
3434

3535
# JWT configuration
3636
app.config["JWT_SECRET_KEY"] = os.getenv("JWT_SECRET_KEY")

backend/models/user_preference.py

Lines changed: 0 additions & 8 deletions
This file was deleted.

backend/routes/notifications.py

Lines changed: 0 additions & 39 deletions
This file was deleted.

backend/routes/report_routes.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
from models.user import User
66
from services.report_service import generate_csv_for_scan, send_csv_report_email
77

8+
from flasgger import swag_from
9+
810
report_bp = Blueprint("reports", __name__)
911

1012
@report_bp.route("/reports/<int:scan_id>/csv", methods=["GET"])
1113
@jwt_required()
14+
@swag_from("../specs/reports_specs.yml")
1215
def download_report_csv(scan_id: int):
1316
user_id = int(get_jwt_identity())
1417
scan: ScanHistory = db.session.get(ScanHistory, scan_id)
@@ -30,4 +33,4 @@ def download_report_csv(scan_id: int):
3033

3134
return send_file(csv_path, mimetype="text/csv", as_attachment=True, download_name=csv_filename)
3235
except Exception as e:
33-
return jsonify({"error": str(e)}), 500
36+
return jsonify({"error": str(e)}), 500

backend/schemas/risks_dto.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
1-
from pydantic import BaseModel
1+
from pydantic import BaseModel, validator, field_validator
22
from typing import Optional, List
33

44
class RiskSummary(BaseModel):
55
name: str
66
level: int
77

8+
@field_validator('level')
9+
@classmethod
10+
def validate_level(cls, v: int):
11+
if v < 0:
12+
raise ValueError("Risk summary level must be struct greater than zero.")
13+
return v
14+
815
class RiskDetail(BaseModel):
916
severity: str
10-
check_id: Optional[str]
11-
file_path: Optional[str]
12-
message: Optional[str]
13-
suggestion: Optional[str]
14-
scan_type: Optional[str]
17+
check_id: Optional[str] = None
18+
file_path: Optional[str] = None
19+
message: Optional[str] = None
20+
suggestion: Optional[str] = None
21+
scan_type: Optional[str] = None
1522

1623
class RisksResponse(BaseModel):
1724
risks: List[RiskSummary]

backend/services/notification_service.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ def _mark_failed(n: Notification, error_text: str):
112112
db.session.commit()
113113

114114
def _email_allowed(user_id: int) -> bool:
115-
pref = db.session.query(UserPreference).filter_by(user_id=user_id).first()
116-
# Par défaut: autorisé
115+
pref = db.session.query(User).filter_by(id=user_id).first()
117116
return True if pref is None else bool(pref.email_notifications_enabled)
118117

119118
# ----------------------------

backend/specs/reports_specs.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
tags:
2+
- Reports
3+
summary: Download CSV report for a scan
4+
description: Generates and downloads a CSV report for the specified scan ID. Optional email delivery. Requires JWT.
5+
produces:
6+
- text/csv
7+
parameters:
8+
- name: scan_id
9+
in: path
10+
type: integer
11+
required: true
12+
description: ID of the scan to report
13+
- name: email
14+
in: query
15+
type: boolean
16+
required: false
17+
description: "If true, emails the CSV to user (default: false)"
18+
security:
19+
- Bearer: []
20+
responses:
21+
200:
22+
description: CSV report downloaded successfully
23+
headers:
24+
Content-Disposition:
25+
type: string
26+
description: Attachment filename (e.g., report_scan_{scan_id}.csv)
27+
schema:
28+
type: string
29+
format: binary
30+
403:
31+
description: Forbidden (not owner or admin)
32+
schema:
33+
type: object
34+
properties:
35+
error:
36+
type: string
37+
404:
38+
description: Scan not found
39+
schema:
40+
type: object
41+
properties:
42+
error:
43+
type: string
44+
500:
45+
description: Server error
46+
schema:
47+
type: object
48+
properties:
49+
error:
50+
type: string

backend/utils/api_spec.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,5 +152,9 @@
152152
{
153153
"name": "Checkov Scan",
154154
"description": "IaC scans with Checkov (file, repo, content)."
155+
},
156+
{
157+
"name": "Reports",
158+
"description": "CSV report downloads and email delivery for scans."
155159
}
156160
]

backend/utils/db.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ def create_default_admin():
4545
name=admin_name,
4646
email=admin_email,
4747
password=hashed_password,
48-
role="admin"
48+
role="admin",
49+
verified=False,
4950
)
5051
db.session.add(admin_user)
5152
db.session.commit()

0 commit comments

Comments
 (0)