Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 34 additions & 6 deletions api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from sqlalchemy import and_, or_, update
from sqlalchemy.orm.exc import NoResultFound
from api_utils import (
add_html_link_to_email_body,
async_email_notification,
get_api_specification,
get_html_email_body_from_template,
Expand All @@ -44,6 +45,9 @@
TESTRUN_PRESET_FILEPATH = os.path.join(currentdir, CONFIGS_FOLDER, "testrun_plugin_presets.yaml")
SETTINGS_FILEPATH = os.path.join(currentdir, CONFIGS_FOLDER, "settings.yaml")
EMAIL_TEMPLATE_PATH = os.path.join(currentdir, CONFIGS_FOLDER, "email_template.html")
EMAIL_MATRIX_FOOTER_MESSAGE = "<p>Join our <a href='" \
"https://matrix.to/#/!RoPWKbVtTKUKNouZCV:matrix.org?via=matrix.org" \
"'>BASIL Matrix chat room</a> to discuss about the tool usage and development!</p>"
TEST_RUNS_BASE_DIR = os.getenv("TEST_RUNS_BASE_DIR", "/var/test-runs")
USER_FILES_BASE_DIR = os.path.join(currentdir, "user-files") # forced under api to ensure tmt tree validity
PYPROJECT_FILEPATH = os.path.join(os.path.dirname(currentdir), "pyproject.toml")
Expand Down Expand Up @@ -5489,7 +5493,7 @@ def post(self):
# Send email notifications to admins
email_subject = "BASIL - New User"
email_body = f"{username} joined us on BASIL!"
email_footer = ""
email_footer = EMAIL_MATRIX_FOOTER_MESSAGE

admins = dbi.session.query(UserModel).filter(
UserModel.role == "ADMIN").filter(
Expand Down Expand Up @@ -5903,13 +5907,18 @@ def get(self):
dbi.session.add(target_user)
dbi.session.commit()
dbi.engine.dispose()

# Notification
settings = load_settings()
email_subject = "BASIL - Confirm password reset"
email_footer = ""
email_footer = EMAIL_MATRIX_FOOTER_MESSAGE
email_body = "<p>Your password has been reset</p>"
email_body = add_html_link_to_email_body(settings=settings, body=email_body)
email_body = get_html_email_body_from_template(EMAIL_TEMPLATE_PATH,
email_subject,
"Your password has been reset",
email_body,
email_footer)
email_notifier = EmailNotifier(settings=load_settings())
email_notifier = EmailNotifier(settings=settings)
ret = email_notifier.send_email(email, email_subject, email_body, True)
if ret:
if "redirect" in request_data.keys():
Expand Down Expand Up @@ -5940,15 +5949,16 @@ def post(self):

# generate reset_token and reset_pwd
email_subject = "BASIL - Password reset"
email_footer = ""
email_footer = EMAIL_MATRIX_FOOTER_MESSAGE

reset_pwd = secrets.token_urlsafe(10)
encoded_reset_pwd = base64.b64encode(reset_pwd.encode("utf-8")).decode("utf-8")

reset_token = secrets.token_urlsafe(90)
reset_url = f"{request.base_url}?email={email}&reset_token={reset_token}"
if "app_url" in settings.keys():
reset_url += f"&redirect={settings['app_url']}/login?from=reset-password"
if str(settings["app_url"]).strip():
reset_url += f"&redirect={settings['app_url']}/login?from=reset-password"

target_user.reset_pwd = encoded_reset_pwd
target_user.reset_token = reset_token
Expand Down Expand Up @@ -6037,6 +6047,24 @@ def put(self):
target_user.role = request_data["role"]
dbi.session.commit()

# Notification
settings = load_settings()
email_subject = "BASIL user role changed"
email_footer = EMAIL_MATRIX_FOOTER_MESSAGE
email_body = f"<p>Your BASIL user role changed to <b>{target_user.role}</b></p>"
email_body += "<p>See the <a href='" \
"https://basil-the-fusa-spice.readthedocs.io/en/latest/user_management.html#roles" \
"'>BASIL documentation</a> for a description of each role.</p>"
email_body = add_html_link_to_email_body(settings=settings, body=email_body)

async_email_notification(SETTINGS_FILEPATH,
EMAIL_TEMPLATE_PATH,
[target_user.email],
email_subject,
email_body,
email_footer,
True)

return {"email": request_data["email"]}


Expand Down
15 changes: 15 additions & 0 deletions api/api_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@
from string import Template
from urllib.error import HTTPError, URLError

LINK_BASIL_INSTANCE_HTML_MESSAGE = "Link to BASIL website"


def add_html_link_to_email_body(settings, body):
"""Append a link to BASIL instance if the app_url setting is populated"""
if not settings:
if not body:
return ""
return body

if "app_url" in settings.keys():
if str(settings["app_url"]).strip():
body += f"<p><a href='{settings['app_url']}'>{LINK_BASIL_INSTANCE_HTML_MESSAGE}</a></p>"
return body


def get_html_email_body_from_template(template_path, subject, body, footer):
"""Generate the HTML email body from a template file using
Expand Down
6 changes: 3 additions & 3 deletions api/notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ def validate_settings(self) -> bool:
print(f"Field {setting} not in settings")
return False
else:
if not self.settings[self.SMTP_SETTING_FIELD][setting]:
print(f"Setting field {setting} is not valid")
if self.settings[self.SMTP_SETTING_FIELD][setting] is None:
print(f"Settings are not valid, field {setting} is None.")
return False
if str(self.settings[self.SMTP_SETTING_FIELD][setting]).strip() == "":
print(f"Setting field {setting} is not valid")
print(f"Settings are not valid, field {setting} is empty.")
return False
return True

Expand Down
28 changes: 28 additions & 0 deletions api/test/test_api_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os
import sys

currentdir = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(1, os.path.dirname(currentdir))

import api
import api_utils


def test__add_html_link_to_email_body():
settings = None
initial_body = None
body = api_utils.add_html_link_to_email_body(settings=settings, body=initial_body)
assert body == ""
assert api_utils.LINK_BASIL_INSTANCE_HTML_MESSAGE not in body

settings = None
initial_body = ""
body = api_utils.add_html_link_to_email_body(settings=settings, body=initial_body)
assert body == ""
assert api_utils.LINK_BASIL_INSTANCE_HTML_MESSAGE not in body

settings = api.load_settings()
initial_body = ""
body = api_utils.add_html_link_to_email_body(settings=settings, body=initial_body)
assert body != ""
assert api_utils.LINK_BASIL_INSTANCE_HTML_MESSAGE in body
Loading