Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mephenor committed Dec 10, 2024
1 parent 16ecde7 commit 4b3786c
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 32 deletions.
55 changes: 42 additions & 13 deletions services/ekss/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,31 @@ components:
type: array
title: HTTPValidationError
type: object
HttpDecodingError:
additionalProperties: false
properties:
data:
$ref: '#/components/schemas/HttpDecodingErrorData'
description:
description: A human readable message to the client explaining the cause
of the exception.
title: Description
type: string
exception_id:
const: decodingError
title: Exception Id
type: string
required:
- data
- description
- exception_id
title: HttpDecodingError
type: object
HttpDecodingErrorData:
additionalProperties: true
properties: {}
title: HttpDecodingErrorData
type: object
HttpEnvelopeDecryptionError:
additionalProperties: false
properties:
Expand Down Expand Up @@ -244,37 +269,40 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/InboundEnvelopeContent'
description: ''
description: Successfully created and stored secret for re-encryption.
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/HttpMalformedOrMissingEnvelopeError'
description: Bad Request
description: Crypt4GH header envelope is either missing or malformed in
the provided payload.
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/HttpEnvelopeDecryptionError'
description: Forbidden
description: Could not decrypt Crypt4GH header envelope with the given key
pair.
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
$ref: '#/components/schemas/HttpDecodingError'
description: One of the inputs provided to the API could not be decoded
as base64 string.
'502':
content:
application/json:
schema:
$ref: '#/components/schemas/HttpSecretInsertionError'
description: Bad Gateway
description: Failed to successfully inset secret into vault.
'504':
content:
application/json:
schema:
$ref: '#/components/schemas/HttpVaultConnectionError'
description: Gateway Timeout
description: Failed to establish a connection to vault.
summary: Extract file encryption/decryption secret and file content offset from
enevelope
tags:
Expand All @@ -293,13 +321,13 @@ paths:
type: string
responses:
'204':
description: ''
description: Succesfully deleted secret.
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HttpSecretNotFoundError'
description: Not Found
description: Could not find a secret for the given secret ID.
'422':
content:
application/json:
Expand Down Expand Up @@ -333,19 +361,20 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/OutboundEnvelopeContent'
description: ''
description: Created personalized Crypt4GH envelope.
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/HttpSecretNotFoundError'
description: Not Found
description: Could not find a secret for the given secret ID.
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
$ref: '#/components/schemas/HttpDecodingError'
description: One of the inputs provided to the API could not be decoded
as base64 string.
summary: Get personalized envelope containing Crypt4GH file encryption/decryption
key
tags:
Expand Down
2 changes: 1 addition & 1 deletion services/ekss/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "ekss"
version = "1.4.4"
version = "1.5.0"
description = "Encryption Key Store Service - providing crypt4gh file secret extraction, storage and envelope generation"
readme = "README.md"
authors = [
Expand Down
24 changes: 19 additions & 5 deletions services/ekss/src/ekss/adapters/inbound/fastapi_/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@


class HttpMalformedOrMissingEnvelopeError(HttpCustomExceptionBase):
"""Thrown when envelope decryption fails due to a missing or malformed envelope."""
"""Raised when envelope decryption fails due to a missing or malformed envelope."""

exception_id = "malformedOrMissingEnvelopeError"

Expand All @@ -36,7 +36,7 @@ def __init__(self, *, status_code: int = 400):


class HttpEnvelopeDecryptionError(HttpCustomExceptionBase):
"""Thrown when no available secret crypt4GH key can successfully decrypt the file envelope."""
"""Raised when no available secret crypt4GH key can successfully decrypt the file envelope."""

exception_id = "envelopeDecryptionError"

Expand All @@ -53,7 +53,7 @@ def __init__(self, *, status_code: int = 403):


class HttpSecretInsertionError(HttpCustomExceptionBase):
"""Thrown when a secret could not be inserted into the vault"""
"""Raised when a secret could not be inserted into the vault"""

exception_id = "secretInsertionError"

Expand All @@ -70,7 +70,7 @@ def __init__(self, *, status_code: int = 502):


class HttpVaultConnectionError(HttpCustomExceptionBase):
"""Thrown when the EKSS could not connect to the vault"""
"""Raised when the EKSS could not connect to the vault"""

exception_id = "vaultConnectionError"

Expand All @@ -87,7 +87,7 @@ def __init__(self, *, status_code: int = 504):


class HttpSecretNotFoundError(HttpCustomExceptionBase):
"""Thrown when no secret with the given id could be found"""
"""Raised when no secret with the given id could be found"""

exception_id = "secretNotFoundError"

Expand All @@ -101,3 +101,17 @@ def __init__(self, *, status_code: int = 404):
description="The secret for the given id was not found.",
data={},
)


class HttpDecodingError(HttpCustomExceptionBase):
"""Raised when a byte string could not be decoded using base64"""

exception_id = "decodingError"

def __init__(self, *, affected: str, status_code: int = 422):
"""Construct message and init the exception."""
super().__init__(
status_code=status_code,
description=f"Could not decode the the given string as base64: {affected}",
data={},
)
48 changes: 35 additions & 13 deletions services/ekss/src/ekss/adapters/inbound/fastapi_/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,35 @@
router = APIRouter(tags=["EncryptionKeyStoreService"])
ERROR_RESPONSES = {
"malformedOrMissingEnvelope": {
"description": (""),
"description": (
"Crypt4GH header envelope is either missing or malformed in the provided payload."
),
"model": exceptions.HttpMalformedOrMissingEnvelopeError.get_body_model(),
},
"envelopeDecryptionError": {
"description": (""),
"description": (
"Could not decrypt Crypt4GH header envelope with the given key pair."
),
"model": exceptions.HttpEnvelopeDecryptionError.get_body_model(),
},
"secretInsertionError": {
"description": (""),
"description": ("Failed to successfully inset secret into vault."),
"model": exceptions.HttpSecretInsertionError.get_body_model(),
},
"vaultConnectionError": {
"description": (""),
"description": ("Failed to establish a connection to vault."),
"model": exceptions.HttpVaultConnectionError.get_body_model(),
},
"secretNotFoundError": {
"description": (""),
"description": ("Could not find a secret for the given secret ID."),
"model": exceptions.HttpSecretNotFoundError.get_body_model(),
},
"decodingError": {
"description": (
"One of the inputs provided to the API could not be decoded as base64 string."
),
"model": exceptions.HttpDecodingError.get_body_model(),
},
}


Expand All @@ -71,10 +81,11 @@ async def health():
operation_id="postEncryptionData",
status_code=status.HTTP_200_OK,
response_model=models.InboundEnvelopeContent,
response_description="",
response_description="Successfully created and stored secret for re-encryption.",
responses={
status.HTTP_400_BAD_REQUEST: ERROR_RESPONSES["malformedOrMissingEnvelope"],
status.HTTP_403_FORBIDDEN: ERROR_RESPONSES["envelopeDecryptionError"],
status.HTTP_422_UNPROCESSABLE_ENTITY: ERROR_RESPONSES["decodingError"],
status.HTTP_502_BAD_GATEWAY: ERROR_RESPONSES["secretInsertionError"],
status.HTTP_504_GATEWAY_TIMEOUT: ERROR_RESPONSES["vaultConnectionError"],
},
Expand All @@ -87,8 +98,16 @@ async def post_encryption_secrets(
"""Extract file encryption/decryption secret, create secret ID and extract
file content offset
"""
client_pubkey = base64.b64decode(envelope_query.public_key)
file_part = base64.b64decode(envelope_query.file_part)
try:
client_pubkey = base64.b64decode(envelope_query.public_key)
except Exception as error:
raise exceptions.HttpDecodingError(affected="client public key") from error

try:
file_part = base64.b64decode(envelope_query.file_part)
except Exception as error:
raise exceptions.HttpDecodingError(affected="file part") from error

try:
submitter_secret, offset = await extract_envelope_content(
file_part=file_part,
Expand Down Expand Up @@ -123,20 +142,23 @@ async def post_encryption_secrets(
operation_id="getEncryptionData",
status_code=status.HTTP_200_OK,
response_model=models.OutboundEnvelopeContent,
response_description="",
response_description="Created personalized Crypt4GH envelope.",
responses={
status.HTTP_404_NOT_FOUND: ERROR_RESPONSES["secretNotFoundError"],
status.HTTP_422_UNPROCESSABLE_ENTITY: ERROR_RESPONSES["decodingError"],
},
)
async def get_header_envelope(
*, secret_id: str, client_pk: str, vault: VaultAdapter = Depends(get_vault)
):
"""Create header envelope for the file secret with given ID encrypted with a given public key"""
try:
client_pubkey = base64.urlsafe_b64decode(client_pk)
except Exception as error:
raise exceptions.HttpDecodingError(affected="client public key") from error
try:
header_envelope = await get_envelope(
secret_id=secret_id,
client_pubkey=base64.urlsafe_b64decode(client_pk),
vault=vault,
secret_id=secret_id, client_pubkey=client_pubkey, vault=vault
)
except SecretRetrievalError as error:
raise exceptions.HttpSecretNotFoundError() from error
Expand All @@ -151,7 +173,7 @@ async def get_header_envelope(
summary="Delete the associated secret",
operation_id="deleteSecret",
status_code=status.HTTP_204_NO_CONTENT,
response_description="",
response_description="Succesfully deleted secret.",
responses={
status.HTTP_404_NOT_FOUND: ERROR_RESPONSES["secretNotFoundError"],
},
Expand Down

0 comments on commit 4b3786c

Please sign in to comment.