Skip to content

Commit

Permalink
Add use_starttls config (#7)
Browse files Browse the repository at this point in the history
* update template

* implement use_starttls config

* fix example config

* version bump

* relocate ssl context creation
  • Loading branch information
dontseyit authored Jul 28, 2023
1 parent fab13b0 commit 8af81c2
Show file tree
Hide file tree
Showing 14 changed files with 100 additions and 14 deletions.
1 change: 1 addition & 0 deletions .devcontainer/.dev_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ smtp_port: 587
login_user: "test@test.com"
login_password: test
from_address: "test@test.com"
use_starttls: false
2 changes: 1 addition & 1 deletion .github/workflows/cd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
name: Verify tag format
# format must be compatible with semantic versioning
run: |
SEMVER_REGEX="^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
SEMVER_REGEX="^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(?:-((?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
if echo "${{ steps.get_version_tag.outputs.version }}" | grep -Eq "$SEMVER_REGEX"; then
echo "Tag format is valid"
else
Expand Down
2 changes: 2 additions & 0 deletions .static_files
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
scripts/script_utils/__init__.py
scripts/script_utils/cli.py

scripts/__init__.py
scripts/update_all.py
scripts/license_checker.py
scripts/get_package_name.py
scripts/update_config_docs.py
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ We recommend using the provided Docker container.

A pre-build version is available at [docker hub](https://hub.docker.com/repository/docker/ghga/notification-service):
```bash
docker pull ghga/notification-service:0.1.1
docker pull ghga/notification-service:0.1.2
```

Or you can build the container yourself from the [`./Dockerfile`](./Dockerfile):
```bash
# Execute in the repo's root dir:
docker build -t ghga/notification-service:0.1.1 .
docker build -t ghga/notification-service:0.1.2 .
```

For production-ready deployment, we recommend using Kubernetes, however,
for simple use cases, you could execute the service using docker
on a single server:
```bash
# The entrypoint is preconfigured:
docker run -p 8080:8080 ghga/notification-service:0.1.1 --help
docker run -p 8080:8080 ghga/notification-service:0.1.2 --help
```

If you prefer not to use containers, you may install the service from source:
Expand Down Expand Up @@ -77,6 +77,8 @@ The service requires the following configuration parameters:

- **`login_password`** *(string)*: The login password.

- **`use_starttls`** *(boolean)*: Boolean flag indicating the use of STARTTLS. Default: `True`.

- **`notification_event_topic`** *(string)*: Name of the event topic used to track notification events.

- **`notification_event_type`** *(string)*: The type to use for events containing content to be sent.
Expand Down
9 changes: 9 additions & 0 deletions config_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@
],
"type": "string"
},
"use_starttls": {
"title": "Use Starttls",
"description": "Boolean flag indicating the use of STARTTLS",
"default": true,
"env_names": [
"ns_use_starttls"
],
"type": "boolean"
},
"notification_event_topic": {
"title": "Notification Event Topic",
"description": "Name of the event topic used to track notification events",
Expand Down
1 change: 1 addition & 0 deletions example_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ service_instance_id: '1'
service_name: ns
smtp_host: 127.0.0.1
smtp_port: 587
use_starttls: false
2 changes: 1 addition & 1 deletion ns/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@

"""The Notification Service (NS) handles notification kafka events. """

__version__ = "0.1.1"
__version__ = "0.1.2"
13 changes: 7 additions & 6 deletions ns/adapters/outbound/smtp_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,24 @@ class SmtpClientConfig(BaseSettings):
smtp_port: int = Field(..., description="The port for the mail server connection")
login_user: str = Field(..., description="The login username or email")
login_password: str = Field(..., description="The login password")
use_starttls: bool = Field(
default=True, description="Boolean flag indicating the use of STARTTLS"
)


class SmtpClient(SmtpClientPort):
"""Concrete implementation of an SmtpClientPort"""

def __init__(self, config: SmtpClientConfig, debugging: bool = False):
def __init__(self, config: SmtpClientConfig):
"""Assign config, which should contain all needed info"""
self._config = config
self._debugging = debugging

def send_email_message(self, message: EmailMessage):
# create ssl security context per Python's Security considerations
context = ssl.create_default_context()

try:
with smtplib.SMTP(self._config.smtp_host, self._config.smtp_port) as server:
if not self._debugging:
if self._config.use_starttls:
# create ssl security context per Python's Security considerations
context = ssl.create_default_context()
server.starttls(context=context)
try:
server.login(self._config.login_user, self._config.login_password)
Expand Down
17 changes: 17 additions & 0 deletions scripts/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2021 - 2023 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln
# for the German Human Genome-Phenome Archive (GHGA)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""Scripts and utils used during development or in CI pipelines."""
51 changes: 51 additions & 0 deletions scripts/update_all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env python3

# Copyright 2021 - 2023 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln
# for the German Human Genome-Phenome Archive (GHGA)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""Run all update scripts that are present in the repository in the correct order"""

try:
from scripts.update_template_files import main as update_template
except ImportError:
pass
else:
print("Pulling in updates from template repository")
update_template()

try:
from scripts.update_config_docs import main as update_config
except ImportError:
pass
else:
print("Updating config docs")
update_config()

try:
from scripts.update_openapi_docs import main as update_openapi
except ImportError:
pass
else:
print("Updating OpenAPI docs")
update_openapi()

try:
from scripts.update_readme import main as update_readme
except ImportError:
pass
else:
print("Updating README")
update_readme()
2 changes: 1 addition & 1 deletion scripts/update_template_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
try:
from script_utils.cli import echo_failure, echo_success, run
except ImportError:
echo_failure = echo_success = print # type: ignore
echo_failure = echo_success = print

def run(main_fn):
"""Run main function without cli tools (typer)."""
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ def get_config(
smtp_port=get_free_port(),
login_user="test@example.com",
login_password="test123",
use_starttls=False,
)
1 change: 1 addition & 0 deletions tests/fixtures/test_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ smtp_host: 127.0.0.1
smtp_port: 587
login_user: "test@test.com"
login_password: test
use_starttls: false
from_address: "test@test.com"
4 changes: 2 additions & 2 deletions tests/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ async def test_transmission(notification_details):
config = get_config([SMTP_TEST_CONFIG])
notification = make_notification(notification_details)

smtp_client = SmtpClient(config=config, debugging=True)
smtp_client = SmtpClient(config=config)
server = DummyServer(config=config)

notifier = Notifier(config=config, smtp_client=smtp_client)
Expand All @@ -103,7 +103,7 @@ async def test_failed_authentication():
server.login = "bob@bobswebsite.com"
server.password = "notCorrect"
notification = make_notification(sample_notification)
smtp_client = SmtpClient(config=config, debugging=True)
smtp_client = SmtpClient(config=config)
notifier = Notifier(config=config, smtp_client=smtp_client)
expected_email = notifier._construct_email(
notification=notification
Expand Down

0 comments on commit 8af81c2

Please sign in to comment.