fix: Reorder election routes to fix blockchain endpoint routing
Moved specific routes (/blockchain, /debug/all, /active, /completed, /upcoming)
BEFORE generic routes (/{election_id}, /{election_id}/results, etc) so that
specific paths are matched first and don't get caught by the {election_id}
path parameter matcher.
Also removed duplicate /completed and /upcoming route definitions.
Routes now in correct order:
1. Specific paths: /debug/all, /active, /blockchain
2. Specific subpaths: /{id}/blockchain-verify, /{id}/candidates, /{id}/results
3. Generic: /{id}
This commit is contained in:
parent
1fd71e71e1
commit
9f5aee8b93
@ -71,31 +71,50 @@ def get_active_elections(db: Session = Depends(get_db)):
|
|||||||
return active
|
return active
|
||||||
|
|
||||||
|
|
||||||
@router.get("/completed")
|
@router.get("/blockchain")
|
||||||
def get_completed_elections(db: Session = Depends(get_db)):
|
def get_elections_blockchain():
|
||||||
"""Récupérer tous les votes passés/terminés"""
|
"""
|
||||||
|
Retrieve the complete elections blockchain.
|
||||||
|
|
||||||
from datetime import datetime
|
Returns all election records stored immutably with cryptographic verification.
|
||||||
elections = db.query(services.models.Election).filter(
|
Useful for auditing election creation and verifying no tampering occurred.
|
||||||
services.models.Election.end_date < datetime.utcnow(),
|
"""
|
||||||
services.models.Election.results_published == True
|
return get_elections_blockchain_data()
|
||||||
).all()
|
|
||||||
|
|
||||||
return elections
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/upcoming")
|
@router.get("/{election_id}/blockchain-verify")
|
||||||
def get_upcoming_elections(db: Session = Depends(get_db)):
|
def verify_election_blockchain(election_id: int, db: Session = Depends(get_db)):
|
||||||
"""Récupérer tous les votes à venir"""
|
"""
|
||||||
|
Verify an election's blockchain integrity.
|
||||||
|
|
||||||
from datetime import datetime
|
Returns verification report:
|
||||||
elections = db.query(services.models.Election).filter(
|
- hash_valid: Block hash matches computed hash
|
||||||
services.models.Election.start_date > datetime.utcnow()
|
- chain_valid: Entire chain integrity is valid
|
||||||
).all()
|
- signature_valid: Block is properly signed
|
||||||
|
- verified: All checks passed
|
||||||
|
"""
|
||||||
|
# First verify it exists in database
|
||||||
|
election = services.ElectionService.get_election(db, election_id)
|
||||||
|
if not election:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Election not found in database"
|
||||||
|
)
|
||||||
|
|
||||||
return elections
|
# Then verify it's in blockchain
|
||||||
|
verification = verify_election_in_blockchain(election_id)
|
||||||
|
|
||||||
|
if not verification.get("verified"):
|
||||||
|
# Still return data but mark as unverified
|
||||||
|
return {
|
||||||
|
**verification,
|
||||||
|
"warning": "Election blockchain verification failed - possible tampering"
|
||||||
|
}
|
||||||
|
|
||||||
|
return verification
|
||||||
|
|
||||||
|
|
||||||
|
# Routes with path parameters must come AFTER specific routes
|
||||||
@router.get("/active/results")
|
@router.get("/active/results")
|
||||||
def get_active_election_results(db: Session = Depends(get_db)):
|
def get_active_election_results(db: Session = Depends(get_db)):
|
||||||
"""Récupérer les résultats de l'élection active"""
|
"""Récupérer les résultats de l'élection active"""
|
||||||
@ -128,21 +147,6 @@ def get_election_candidates(election_id: int, db: Session = Depends(get_db)):
|
|||||||
return election.candidates
|
return election.candidates
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{election_id}", response_model=schemas.ElectionResponse)
|
|
||||||
def get_election(election_id: int, db: Session = Depends(get_db)):
|
|
||||||
"""Récupérer une élection par son ID"""
|
|
||||||
|
|
||||||
election = services.ElectionService.get_election(db, election_id)
|
|
||||||
|
|
||||||
if not election:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
|
||||||
detail="Election not found"
|
|
||||||
)
|
|
||||||
|
|
||||||
return election
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{election_id}/results", response_model=schemas.ElectionResultResponse)
|
@router.get("/{election_id}/results", response_model=schemas.ElectionResultResponse)
|
||||||
def get_election_results(
|
def get_election_results(
|
||||||
election_id: int,
|
election_id: int,
|
||||||
@ -206,71 +210,16 @@ def publish_results(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/completed", response_model=list[schemas.ElectionResponse])
|
@router.get("/{election_id}", response_model=schemas.ElectionResponse)
|
||||||
def get_completed_elections(db: Session = Depends(get_db)):
|
def get_election(election_id: int, db: Session = Depends(get_db)):
|
||||||
"""Récupérer toutes les élections terminées (archives)"""
|
"""Récupérer une élection par son ID"""
|
||||||
from datetime import datetime
|
|
||||||
from .. import models
|
|
||||||
|
|
||||||
completed = db.query(models.Election).filter(
|
|
||||||
models.Election.end_date < datetime.utcnow(),
|
|
||||||
models.Election.results_published == True
|
|
||||||
).all()
|
|
||||||
|
|
||||||
return completed
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/upcoming", response_model=list[schemas.ElectionResponse])
|
|
||||||
def get_upcoming_elections(db: Session = Depends(get_db)):
|
|
||||||
"""Récupérer toutes les élections futures"""
|
|
||||||
from datetime import datetime
|
|
||||||
from .. import models
|
|
||||||
|
|
||||||
upcoming = db.query(models.Election).filter(
|
|
||||||
models.Election.start_date > datetime.utcnow()
|
|
||||||
).all()
|
|
||||||
|
|
||||||
return upcoming
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/blockchain")
|
|
||||||
def get_elections_blockchain():
|
|
||||||
"""
|
|
||||||
Retrieve the complete elections blockchain.
|
|
||||||
|
|
||||||
Returns all election records stored immutably with cryptographic verification.
|
|
||||||
Useful for auditing election creation and verifying no tampering occurred.
|
|
||||||
"""
|
|
||||||
return get_elections_blockchain_data()
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{election_id}/blockchain-verify")
|
|
||||||
def verify_election_blockchain(election_id: int, db: Session = Depends(get_db)):
|
|
||||||
"""
|
|
||||||
Verify an election's blockchain integrity.
|
|
||||||
|
|
||||||
Returns verification report:
|
|
||||||
- hash_valid: Block hash matches computed hash
|
|
||||||
- chain_valid: Entire chain integrity is valid
|
|
||||||
- signature_valid: Block is properly signed
|
|
||||||
- verified: All checks passed
|
|
||||||
"""
|
|
||||||
# First verify it exists in database
|
|
||||||
election = services.ElectionService.get_election(db, election_id)
|
election = services.ElectionService.get_election(db, election_id)
|
||||||
|
|
||||||
if not election:
|
if not election:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
detail="Election not found in database"
|
detail="Election not found"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Then verify it's in blockchain
|
return election
|
||||||
verification = verify_election_in_blockchain(election_id)
|
|
||||||
|
|
||||||
if not verification.get("verified"):
|
|
||||||
# Still return data but mark as unverified
|
|
||||||
return {
|
|
||||||
**verification,
|
|
||||||
"warning": "Election blockchain verification failed - possible tampering"
|
|
||||||
}
|
|
||||||
|
|
||||||
return verification
|
|
||||||
Loading…
x
Reference in New Issue
Block a user