Skip to content

Commit

Permalink
feature: add IMailCraft interface
Browse files Browse the repository at this point in the history
  • Loading branch information
mutantsan committed Sep 15, 2023
1 parent 499e894 commit 06c07f6
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 81 deletions.
13 changes: 13 additions & 0 deletions ckanext/mailcraft/interfaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import Type

from ckan.plugins.interfaces import Interface

from ckanext.mailcraft.mailer import Mailer, DefaultMailer


class IMailCraft(Interface):
"""Allow to register a custom mailer instead of a default one"""

def get_mailer(self) -> Type[Mailer]:
"""Return the mailer class"""
return DefaultMailer
1 change: 1 addition & 0 deletions ckanext/mailcraft/logic/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ def mc_mail_list(context, data_dict):
def mc_mail_show(context, data_dict):
return {"success": False}


def mc_mail_delete(context, data_dict):
return {"success": False}
38 changes: 23 additions & 15 deletions ckanext/mailcraft/mailer.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
log = logging.getLogger(__name__)


class AbstractMailer(ABC):
class Mailer(ABC):
def __init__(self):
# TODO: replace with ext config, instead of using core ones
self.server = tk.config["smtp.server"]
self.start_tls = tk.config["smtp.starttls"]
self.user = tk.config["smtp.user"]
Expand Down Expand Up @@ -81,8 +82,16 @@ def mail_user(
def send_reset_link(self, user: model.User) -> None:
pass

@abstractmethod
def create_reset_key(self, user: model.User) -> None:
pass

@abstractmethod
def verify_reset_link(self, user: model.User, key: Optional[str]) -> bool:
pass

class DefaultMailer(AbstractMailer):

class DefaultMailer(Mailer):
def mail_recipients(
self,
subject: str,
Expand Down Expand Up @@ -120,7 +129,6 @@ def mail_recipients(
self.add_attachments(msg, attachments)

try:
# print(msg.get_body(("html",)).get_content()) # type: ignore
if mc_config.stop_outgoing_emails():
self._save_email(
msg, body_html, mc_model.Email.State.stopped, dict(msg.items())
Expand Down Expand Up @@ -246,8 +254,8 @@ def mail_user(
def send_reset_link(self, user: model.User) -> None:
self.create_reset_key(user)

body = self.get_reset_link_body(user)
body_html = self.get_reset_link_body(user, html=True)
body = self._get_reset_link_body(user)
body_html = self._get_reset_link_body(user, html=True)

# Make sure we only use the first line
subject = tk.render(
Expand All @@ -258,15 +266,14 @@ def send_reset_link(self, user: model.User) -> None:
self.mail_user(user.name, subject, body, body_html=body_html)

def create_reset_key(self, user: model.User):
user.reset_key = self.make_key()
user.reset_key = codecs.encode(os.urandom(16), "hex").decode()
model.repo.commit_and_remove()

def make_key(self):
return codecs.encode(os.urandom(16), "hex").decode()

def get_reset_link_body(self, user: model.User, html: bool = False) -> str:
def _get_reset_link_body(self, user: model.User, html: bool = False) -> str:
extra_vars = {
"reset_link": self.get_reset_link(user),
"reset_link": tk.url_for(
"user.perform_reset", id=user.id, key=user.reset_key, qualified=True
),
"site_title": self.site_title,
"site_url": self.site_url,
"user_name": user.name,
Expand All @@ -281,7 +288,8 @@ def get_reset_link_body(self, user: model.User, html: bool = False) -> str:
extra_vars,
)

def get_reset_link(self, user: model.User) -> str:
return tk.url_for(
"user.perform_reset", id=user.id, key=user.reset_key, qualified=True
)
def verify_reset_link(self, user: model.User, key: Optional[str]) -> bool:
if not key or not user.reset_key or len(user.reset_key) < 5:
return False

return key.strip() == user.reset_key
15 changes: 9 additions & 6 deletions ckanext/mailcraft/migration/mailcraft/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ def run_migrations_offline():
"""

url = config.get_main_option(u"sqlalchemy.url")
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url, target_metadata=target_metadata, literal_binds=True,
version_table=u'{}_alembic_version'.format(name)
url=url,
target_metadata=target_metadata,
literal_binds=True,
version_table="{}_alembic_version".format(name),
)

with context.begin_transaction():
Expand All @@ -61,14 +63,15 @@ def run_migrations_online():
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix=u'sqlalchemy.',
poolclass=pool.NullPool)
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)

with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
version_table=u'{}_alembic_version'.format(name)
version_table="{}_alembic_version".format(name),
)

with context.begin_transaction():
Expand Down
8 changes: 5 additions & 3 deletions ckanext/mailcraft/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,17 @@ def all(cls) -> list[dict[str, Any]]:
return [mail.dictize({}) for mail in query.all()]

@classmethod
def save_mail(cls, msg: EmailMessage, body_html: str, state: str, extras: dict[str, Any]) -> Email:
def save_mail(
cls, msg: EmailMessage, body_html: str, state: str, extras: dict[str, Any]
) -> Email:
mail = cls(
subject=msg["Subject"],
timestamp=msg["Date"],
sender=msg["From"],
recipient=msg["To"],
message=body_html,
state=state,
extras=extras
extras=extras,
)

model.Session.add(mail)
Expand All @@ -67,7 +69,7 @@ def dictize(self, context):
"recipient": self.recipient,
"message": self.message,
"state": self.state,
"extras": self.extras or {}
"extras": self.extras or {},
}

@classmethod
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{% extends "mailcraft/emails/base.html" %}

{% block main_text %}

{% trans %}
<p>Dear {{ user_name }},</p>

<p>You have requested your password on {{ site_title }} to be reset.</p>

<p>Please click the following link to confirm this request:</p>

<p>{{ reset_link }}</p>

<p>Have a nice day.</p>
{% endtrans %}

{% endblock %}

This file was deleted.

Loading

0 comments on commit 06c07f6

Please sign in to comment.