Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/config mail send #183

Merged
merged 3 commits into from
Mar 7, 2022
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
10 changes: 5 additions & 5 deletions rest_registration/api/views/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
get_user_setting
)
from rest_registration.utils.verification import verify_signer_or_bad_request
from rest_registration.verification_notifications import (
send_register_verification_email_notification
)


@api_view_serializer_class_getter(
Expand Down Expand Up @@ -51,7 +48,8 @@ def register(request):
with transaction.atomic():
user = serializer.save(**kwargs)
if registration_settings.REGISTER_VERIFICATION_ENABLED:
send_register_verification_email_notification(request, user)
email_sender = registration_settings.REGISTER_VERIFICATION_EMAIL_SENDER
email_sender(request, user)

signals.user_registered.send(sender=None, user=user, request=request)
output_serializer_class = registration_settings.REGISTER_OUTPUT_SERIALIZER_CLASS
Expand Down Expand Up @@ -97,7 +95,9 @@ def process_verify_registration_data(input_data, serializer_context=None):
serializer.is_valid(raise_exception=True)

data = serializer.validated_data
signer = RegisterSigner(data)
# We use the signer only for verification, therefore we don't need a base_url and
# may set strict=False
signer = RegisterSigner(data, strict=False)
verify_signer_or_bad_request(signer)

verification_flag_field = get_user_setting('VERIFICATION_FLAG_FIELD')
Expand Down
11 changes: 5 additions & 6 deletions rest_registration/api/views/register_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
user_with_email_exists
)
from rest_registration.utils.verification import verify_signer_or_bad_request
from rest_registration.verification_notifications import (
send_register_email_verification_email_notification
)


@api_view_serializer_class_getter(
Expand All @@ -53,8 +50,8 @@ def register_email(request: Request) -> Response:
email_already_used = is_user_email_field_unique() and user_with_email_exists(email)

if registration_settings.REGISTER_EMAIL_VERIFICATION_ENABLED:
send_register_email_verification_email_notification(
request, user, email, email_already_used=email_already_used)
email_sender = registration_settings.REGISTER_EMAIL_VERIFICATION_EMAIL_SENDER
email_sender(request, user, email, email_already_used=email_already_used)
else:
if email_already_used:
raise EmailAlreadyRegistered()
Expand Down Expand Up @@ -103,7 +100,9 @@ def process_verify_email_data(
serializer.is_valid(raise_exception=True)

data = serializer.validated_data
signer = RegisterEmailSigner(data)
# We use the signer only for verification, therefore we don't need a base_url and
# may set strict=False
signer = RegisterEmailSigner(data, strict=False)
verify_signer_or_bad_request(signer)
request = serializer_context.get('request')
new_email = data['email']
Expand Down
10 changes: 5 additions & 5 deletions rest_registration/api/views/reset_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@
validate_user_password_confirm
)
from rest_registration.utils.verification import verify_signer_or_bad_request
from rest_registration.verification_notifications import (
send_reset_password_verification_email_notification
)


@api_view_serializer_class_getter(
Expand All @@ -48,7 +45,8 @@ def send_reset_password_link(request):
if registration_settings.RESET_PASSWORD_FAIL_WHEN_USER_NOT_FOUND:
raise
return get_ok_response(success_message)
send_reset_password_verification_email_notification(request, user)
email_sender = registration_settings.RESET_PASSWORD_VERIFICATION_EMAIL_SENDER
email_sender(request, user)
return get_ok_response(success_message)


Expand Down Expand Up @@ -95,7 +93,9 @@ def process_reset_password_data(input_data, serializer_context=None):
data = serializer.validated_data.copy()
password = data.pop('password')
data.pop('password_confirm', None)
signer = ResetPasswordSigner(data)
# We use the signer only for verification, therefore we don't need a base_url and
# may set strict=False
signer = ResetPasswordSigner(data, strict=False)
verify_signer_or_bad_request(signer)

user = get_user_by_verification_id(data['user_id'], require_verified=False)
Expand Down
47 changes: 36 additions & 11 deletions rest_registration/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ def auth_installed_check() -> bool:
ErrorCode.NO_RESET_PASSWORD_VER_URL,
)
def reset_password_verification_url_check() -> bool:
sends_emails = (registration_settings.RESET_PASSWORD_VERIFICATION_ENABLED
and registration_settings.is_default(
'RESET_PASSWORD_VERIFICATION_EMAIL_SENDER'))
return implies(
registration_settings.RESET_PASSWORD_VERIFICATION_ENABLED,
sends_emails,
registration_settings.RESET_PASSWORD_VERIFICATION_URL,
)

Expand All @@ -50,8 +53,11 @@ def reset_password_verification_url_check() -> bool:
ErrorCode.NO_REGISTER_VER_URL,
)
def register_verification_url_check() -> bool:
sends_emails = (registration_settings.REGISTER_VERIFICATION_ENABLED
and registration_settings.is_default(
'REGISTER_VERIFICATION_EMAIL_SENDER'))
return implies(
registration_settings.REGISTER_VERIFICATION_ENABLED,
sends_emails,
registration_settings.REGISTER_VERIFICATION_URL,
)

Expand All @@ -63,8 +69,11 @@ def register_verification_url_check() -> bool:
ErrorCode.NO_REGISTER_EMAIL_VER_URL,
)
def register_email_verification_url_check() -> bool:
sends_emails = (registration_settings.REGISTER_EMAIL_VERIFICATION_ENABLED
and registration_settings.is_default(
'REGISTER_EMAIL_VERIFICATION_EMAIL_SENDER'))
return implies(
registration_settings.REGISTER_EMAIL_VERIFICATION_ENABLED,
sends_emails,
registration_settings.REGISTER_EMAIL_VERIFICATION_URL,
)

Expand All @@ -75,12 +84,19 @@ def register_email_verification_url_check() -> bool:
ErrorCode.NO_VER_FROM_EMAIL,
)
def verification_from_check() -> bool:
sends_emails = any([
registration_settings.REGISTER_VERIFICATION_ENABLED
and registration_settings.is_default(
'REGISTER_VERIFICATION_EMAIL_SENDER'),
registration_settings.REGISTER_EMAIL_VERIFICATION_ENABLED
and registration_settings.is_default(
'REGISTER_EMAIL_VERIFICATION_EMAIL_SENDER'),
registration_settings.RESET_PASSWORD_VERIFICATION_ENABLED
and registration_settings.is_default(
'RESET_PASSWORD_VERIFICATION_EMAIL_SENDER'),
])
return implies(
any([
registration_settings.REGISTER_VERIFICATION_ENABLED,
registration_settings.REGISTER_EMAIL_VERIFICATION_ENABLED,
registration_settings.RESET_PASSWORD_VERIFICATION_ENABLED,
]),
sends_emails,
registration_settings.VERIFICATION_FROM_EMAIL,
)

Expand Down Expand Up @@ -156,8 +172,11 @@ def register_verification_one_time_auto_login_check() -> bool:
ErrorCode.INVALID_EMAIL_TEMPLATE_CONFIG,
)
def valid_register_verification_email_template_config_check() -> None:
sends_emails = (registration_settings.REGISTER_VERIFICATION_ENABLED
and registration_settings.is_default(
'REGISTER_VERIFICATION_EMAIL_SENDER'))
_validate_email_template_config(
registration_settings.REGISTER_VERIFICATION_ENABLED,
sends_emails,
registration_settings.REGISTER_VERIFICATION_EMAIL_TEMPLATES,
)

Expand All @@ -168,8 +187,11 @@ def valid_register_verification_email_template_config_check() -> None:
ErrorCode.INVALID_EMAIL_TEMPLATE_CONFIG,
)
def valid_reset_password_verification_email_template_config_check() -> None:
sends_emails = (registration_settings.RESET_PASSWORD_VERIFICATION_ENABLED
and registration_settings.is_default(
'RESET_PASSWORD_VERIFICATION_EMAIL_SENDER'))
_validate_email_template_config(
registration_settings.RESET_PASSWORD_VERIFICATION_ENABLED,
sends_emails,
registration_settings.RESET_PASSWORD_VERIFICATION_EMAIL_TEMPLATES,
)

Expand All @@ -180,8 +202,11 @@ def valid_reset_password_verification_email_template_config_check() -> None:
ErrorCode.INVALID_EMAIL_TEMPLATE_CONFIG,
)
def valid_register_email_verification_email_template_config_check() -> None:
sends_emails = (registration_settings.REGISTER_EMAIL_VERIFICATION_ENABLED
and registration_settings.is_default(
'REGISTER_EMAIL_VERIFICATION_EMAIL_SENDER'))
_validate_email_template_config(
registration_settings.REGISTER_EMAIL_VERIFICATION_ENABLED,
sends_emails,
registration_settings.REGISTER_EMAIL_VERIFICATION_EMAIL_TEMPLATES,
)

Expand Down
33 changes: 33 additions & 0 deletions rest_registration/settings_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ def __new__(
will be sent to the user email (specified by ``USER_EMAIL_FIELD``).
"""),
),
Field(
'REGISTER_VERIFICATION_EMAIL_SENDER',
default='rest_registration.verification_notifications.send_register_verification_email_notification', # noqa: E501
import_string=True,
help=dedent("""\
By default the email sender function will work with the build-in email
sending mechanism.

You can handle email sending all by yourself by overriding this setting.
"""),
),
Field(
'REGISTER_VERIFICATION_PERIOD',
default=datetime.timedelta(days=7),
Expand Down Expand Up @@ -274,6 +285,17 @@ def __new__(
""")
),
Field('RESET_PASSWORD_VERIFICATION_ENABLED', default=True),
Field(
'RESET_PASSWORD_VERIFICATION_EMAIL_SENDER',
default='rest_registration.verification_notifications.send_reset_password_verification_email_notification', # noqa: E501
import_string=True,
help=dedent("""\
By default the email sender function will work with the build-in email
sending mechanism.

You can handle email sending all by yourself by overriding this setting.
"""),
),
Field(
'RESET_PASSWORD_VERIFICATION_PERIOD',
default=datetime.timedelta(days=1),
Expand Down Expand Up @@ -316,6 +338,17 @@ def __new__(
"""),
),
Field('REGISTER_EMAIL_VERIFICATION_ENABLED', default=True),
Field(
'REGISTER_EMAIL_VERIFICATION_EMAIL_SENDER',
default='rest_registration.verification_notifications.send_register_email_verification_email_notification', # noqa: E501
import_string=True,
help=dedent("""\
By default the email sender function will work with the build-in email
sending mechanism.

You can handle email sending all by yourself by overriding this setting.
"""),
),
Field(
'REGISTER_EMAIL_VERIFICATION_PERIOD',
default=datetime.timedelta(days=7),
Expand Down
5 changes: 5 additions & 0 deletions rest_registration/utils/nested_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ def reset_attr_cache(self) -> None:
if hasattr(self, key):
delattr(self, key)

def is_default(self, attr: str) -> bool:
if attr not in self.user_settings:
return True
return self.user_settings[attr] == self.defaults[attr]

def __getattr__(self, attr: str) -> Any:
if attr not in self.defaults.keys():
raise AttributeError(
Expand Down