Add possibility for signed firmware updates
All checks were successful
ci/woodpecker/push/docker Pipeline was successful

This commit is contained in:
Oliver Traber 2025-03-23 14:52:44 +00:00
parent 1aece4b56c
commit c1dd2e48ea
Signed by: Bluemedia
GPG key ID: C0674B105057136C
5 changed files with 44 additions and 4 deletions

View file

@ -0,0 +1,32 @@
"""Add signature fields to firmware_update table
Revision ID: 506cc8d086c9
Revises: 00edfb13e611
Create Date: 2025-03-23 14:49:42.662564+00:00
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '506cc8d086c9'
down_revision: Union[str, None] = '00edfb13e611'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('firmware_updates', sa.Column('signing_certificate', sa.Text(), nullable=True))
op.add_column('firmware_updates', sa.Column('signature', sa.String(), nullable=True))
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('firmware_updates', 'signature')
op.drop_column('firmware_updates', 'signing_certificate')
# ### end Alembic commands ###

View file

@ -1,5 +1,5 @@
import uuid import uuid
from sqlalchemy import Column, DateTime, Enum, ForeignKey, Integer, String, Uuid from sqlalchemy import Column, DateTime, Enum, ForeignKey, Integer, String, Text, Uuid
from app.database import Base from app.database import Base
from app.schemas.firmware_update import FirmwareUpdateStatus from app.schemas.firmware_update import FirmwareUpdateStatus
@ -16,5 +16,7 @@ class FirmwareUpdate(Base):
location = Column(String) location = Column(String)
retrieve_date_time = Column(DateTime) retrieve_date_time = Column(DateTime)
install_date_time = Column(DateTime, nullable=True) install_date_time = Column(DateTime, nullable=True)
signing_certificate = Column(Text, nullable=True)
signature = Column(String, nullable=True)
chargepoint_id = Column(Uuid, ForeignKey("chargepoints.id"), index=True) chargepoint_id = Column(Uuid, ForeignKey("chargepoints.id"), index=True)

View file

@ -357,6 +357,6 @@ async def submit_firmware_update(
raise HTTPException(status_code=503, detail="Chargepoint not connected.") raise HTTPException(status_code=503, detail="Chargepoint not connected.")
try: try:
firmware_update, status = await firmware_service.submit_firmware_update(firmware_update_id) firmware_update, status = await firmware_service.submit_firmware_update(firmware_update_id)
return FirmwareUpdateSubmissionResponse(firmware_update, status) return FirmwareUpdateSubmissionResponse(firmware_update=firmware_update, status=status)
except TimeoutError: except TimeoutError:
raise HTTPException(status_code=503, detail="Chargepoint didn't respond in time.") raise HTTPException(status_code=503, detail="Chargepoint didn't respond in time.")

View file

@ -28,6 +28,8 @@ class FirmwareUpdateBase(BaseModel):
location: str location: str
retrieve_date_time: datetime retrieve_date_time: datetime
install_date_time: Optional[datetime] install_date_time: Optional[datetime]
signing_certificate: Optional[str]
signature: Optional[str]
class FirmwareUpdate(FirmwareUpdateBase): class FirmwareUpdate(FirmwareUpdateBase):
id: UUID id: UUID

View file

@ -23,7 +23,9 @@ async def create_firmware_update(chargepoint_id: UUID, firmware_update: Firmware
location=firmware_update.location, location=firmware_update.location,
retrieve_date_time=firmware_update.retrieve_date_time, retrieve_date_time=firmware_update.retrieve_date_time,
install_date_time=firmware_update.install_date_time, install_date_time=firmware_update.install_date_time,
chargepoint_id=db_chargepoint.id chargepoint_id=db_chargepoint.id,
signing_certificate=firmware_update.signing_certificate,
signature=firmware_update.signature
) )
db.add(db_firmware_update) db.add(db_firmware_update)
db.commit() db.commit()
@ -43,7 +45,9 @@ async def submit_firmware_update(firmware_update_id: UUID) -> tuple[FirmwareUpda
firmware=FirmwareType( firmware=FirmwareType(
location=db_firmware_update.location, location=db_firmware_update.location,
retrieve_date_time=db_firmware_update.retrieve_date_time.isoformat(), retrieve_date_time=db_firmware_update.retrieve_date_time.isoformat(),
install_date_time=db_firmware_update.install_date_time.isoformat() install_date_time=db_firmware_update.install_date_time.isoformat(),
signing_certificate=db_firmware_update.signing_certificate,
signature=db_firmware_update.signature
) )
)) ))
if result.status == "Accepted" or result.status == "AcceptedCanceled": if result.status == "Accepted" or result.status == "AcceptedCanceled":