Skip to content

Commit

Permalink
feat: add password reset flow
Browse files Browse the repository at this point in the history
  • Loading branch information
somehowchris committed Jun 11, 2024
1 parent b15baec commit 8a0b50a
Show file tree
Hide file tree
Showing 18 changed files with 1,263 additions and 23 deletions.
22 changes: 21 additions & 1 deletion src/riskmatrix/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
from pyramid.config import Configurator
from pyramid_beaker import session_factory_from_settings
from typing import Any
from email.headerregistry import Address
from pyramid.settings import asbool
from .mail import PostmarkMailer

from riskmatrix.flash import MessageQueue
from riskmatrix.i18n import LocaleNegotiator
Expand All @@ -24,6 +27,19 @@
def includeme(config: Configurator) -> None:
settings = config.registry.settings

default_sender = settings.get(
'email.default_sender',
'[email protected]'
)
token = settings.get('mail.postmark_token', '')
stream = settings.get('mail.postmark_stream', 'development')
blackhole = asbool(settings.get('mail.postmark_blackhole', False))
config.registry.registerUtility(PostmarkMailer(
Address(addr_spec=default_sender),
token,
stream,
blackhole=blackhole
))
config.include('pyramid_beaker')
config.include('pyramid_chameleon')
config.include('pyramid_layout')
Expand Down Expand Up @@ -67,8 +83,12 @@ def main(
environment=sentry_environment,
integrations=[PyramidIntegration(), SqlalchemyIntegration()],
traces_sample_rate=1.0,
profiles_sample_rate=0.25,
profiles_sample_rate=1.0,
enable_tracing=True,
send_default_pii=True
)
print("configured sentry")
print(sentry_dsn)

with Configurator(settings=settings, root_factory=root_factory) as config:
includeme(config)
Expand Down
15 changes: 15 additions & 0 deletions src/riskmatrix/mail/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from .exceptions import InactiveRecipient
from .exceptions import MailConnectionError
from .exceptions import MailError
from .interfaces import IMailer
from .mailer import PostmarkMailer
from .types import MailState

__all__ = (
'IMailer',
'InactiveRecipient',
'MailConnectionError',
'MailError',
'MailState',
'PostmarkMailer',
)
10 changes: 10 additions & 0 deletions src/riskmatrix/mail/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class MailError(Exception):
pass


class MailConnectionError(MailError, ConnectionError):
pass


class InactiveRecipient(MailError):
pass
91 changes: 91 additions & 0 deletions src/riskmatrix/mail/interfaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
from typing import Any, TYPE_CHECKING
from zope.interface import Interface

if TYPE_CHECKING:
from collections.abc import Sequence
from email.headerregistry import Address
from .types import MailState
from .types import MailParams
from .types import TemplateMailParams
from ..certificate.interfaces import ITemplate
from ..models import Organization
from ..types import JSONObject
MailID = Any


class IMailer(Interface): # pragma: no cover

# NOTE: We would like to say that kwargs is OptionalMailParams
# however there is no way in mypy to express that yet.
def send(sender: 'Address | None',
receivers: 'Address | Sequence[Address]',
subject: str,
content: str,
**kwargs: Any) -> 'MailID':
"""
Send a single email.
Returns a message uuid.
"""
pass

def bulk_send(mails: list['MailParams']
) -> list['MailID | MailState']:
"""
Send multiple emails. "mails" is a list of dicts containing
the arguments to an individual send call.
Returns a list of message uuids and their success/failure states
in the same order as the sending list.
"""
pass

# NOTE: We would like to say that kwargs is OptionalTemplateMailParams
# however there is no way in mypy to express that yet.
def send_template(sender: 'Address | None',
receivers: 'Address | Sequence[Address]',
template: str,
data: 'JSONObject',
**kwargs: Any) -> 'MailID':
"""
Send a single email using a template using its id/name.
"data" contains the template specific data.
Returns a message uuid.
"""
pass

def bulk_send_template(mails: list['TemplateMailParams'],
default_template: str | None = None,
) -> list['MailID | MailState']:
"""
Send multiple template emails using the same template.
Returns a list of message uuids. If a message failed to be sent
the uuid will be replaced by a MailState value.
"""
pass

def template_exists(alias: str) -> bool:
"""
Returns whether a template by the given alias exists.
"""
pass

def create_or_update_template(
template: 'ITemplate',
organization: 'Organization | None' = None,
) -> list[str]:
"""
Creates or updates a mailer template based on a certificate template.
Returns a list of errors. If the list is empty, it was successful.
"""
pass

def delete_template(template: 'ITemplate') -> list[str]:
"""
Deletes a mailer template based on a certificate template.
Returns a list of errors. If the list is empty, it was successful.
"""
Loading

0 comments on commit 8a0b50a

Please sign in to comment.