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

Feature/exclude user from drip #171

Merged
merged 6 commits into from
Aug 10, 2022
Merged

Conversation

jumcorredorro
Copy link
Contributor

@jumcorredorro jumcorredorro commented Aug 4, 2022

Description

  • Add the feature for allowing the user to be excluded from drip emails.
  • The library user should config DRIP_UNSUBSCRIBE_USERS = True and add drip.urls to the project path.
  • This configurations will enable a context variable in Body html template field in form as the following
    image
    This will build a url hashing user and drip data that will be valid forever. Once you open the link it will show you a dumb HTML like this, if the hashes are valid:
    image
    If the hashes are invalid it will show you the following:
    image
    Once you click the button it will show you a success page.
    image
    The library user could add the drip.urls or extend the UnsubscribeDripView and change the template names for the ones that matches the style of the user page:
template_name = "unsubscribe_drip.html"
invalid_template_name = "unsubscribe_drip_invalid.html"
success_template_name = "unsubscribe_drip_success.html"
  • For building this feature there is a new ManyToManyField unsubscribed_users and new functions for builiding context for the message and excluding this new model in querysets, based on DRIP_UNSUBSCRIBE_USERS.

Changes include

  • Bugfix (non-breaking change that solves an issue, bump the third digit of the version)
  • New feature (non-breaking change that adds functionality, bump the second digit of the version)
  • Breaking change (change that is not backwards-compatible and/or changes current functionality, bump the first digit of the version)
  • Documentation update (Don't bump the version of the project)

Other comments

@jumcorredorro jumcorredorro force-pushed the feature/exclude-user-from-drip branch from 1cabb45 to 1289ef4 Compare August 5, 2022 16:32
@jumcorredorro jumcorredorro force-pushed the feature/exclude-user-from-drip branch from 1289ef4 to 280e1d6 Compare August 5, 2022 16:34
@jumcorredorro jumcorredorro changed the base branch from develop to feature/resend-email August 5, 2022 16:35
@jumcorredorro jumcorredorro force-pushed the feature/exclude-user-from-drip branch from 280e1d6 to 923c048 Compare August 5, 2022 16:38
@jumcorredorro jumcorredorro changed the base branch from feature/resend-email to develop August 5, 2022 18:46
@jumcorredorro jumcorredorro marked this pull request as ready for review August 8, 2022 15:48
@jumcorredorro jumcorredorro requested a review from a team as a code owner August 8, 2022 15:48
@jumcorredorro jumcorredorro requested review from brunomichetti, MathiasLantean, JorgeMichelena and malexandroff1 and removed request for a team August 8, 2022 15:48
drip/tokens.py Outdated
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is None or not custom_token_generator.check_token(user, token):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need (user is None) here because if it's None it will return the user at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

Copy link
Collaborator

@brunomichetti brunomichetti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job!!!!
Approved with comments

Build hash value ignoring login_timestamp and password for keeping it valid over time
"""
email_field = user.get_email_field_name()
email = getattr(user, email_field, "") or ""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm asking because I'm not sure: do you need the or ""?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copy this code directly from Django source code but I remove the time check. I will leave it as it is right now.

email = getattr(user, email_field, "") or ""
return f"{user.pk}{timestamp}{email}"

def check_token(self, user: Optional[AbstractBaseUser], token: Optional[str]) -> bool:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a suggestion: I would change the name by something like token_is_correct just to be more easy to read in the place you use. But is a minor suggestion you can ignore it if you want

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only override already existing class methods in PasswordResetTokenGenerator class.

if getattr(settings, "DRIP_UNSUBSCRIBE_USERS", False):
urlpatterns += [
re_path(
r"^drip/(?P<drip_uidb64>\w+)/(?P<uidb64>\w+)/(?P<token>[\w-]+)/$",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a suggestion:
you can use slug here as in this example
ignore this comment if you want

drip/utils.py Outdated
Comment on lines 230 to 235
unsubscribe_link = None
try:
unsubscribe_link = reverse(path, kwargs=url_args)
except NoReverseMatch:
return unsubscribe_link
return unsubscribe_link
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
unsubscribe_link = None
try:
unsubscribe_link = reverse(path, kwargs=url_args)
except NoReverseMatch:
return unsubscribe_link
return unsubscribe_link
try:
unsubscribe_link = reverse(path, kwargs=url_args)
except NoReverseMatch:
return None
return unsubscribe_link

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore this if you want

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apply this suggestion. Thanks!

drip/views.py Outdated
Comment on lines 13 to 21
def _set_user_and_drip(self, **kwargs):
drip_uidb64 = kwargs.get("drip_uidb64", "")
uidb64 = kwargs.get("uidb64", "")
token = kwargs.get("token", "")
self.user = EmailToken.validate_user_uidb64_token(uidb64, token)
self.drip = EmailToken.validate_drip_uidb64(drip_uidb64)
self.post_sucess = False

def dispatch(self, *args, **kwargs):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have to set Any type for the args and kwargs right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apply this suggestion. Thanks!

def _set_user_and_drip(self, **kwargs):
drip_uidb64 = kwargs.get("drip_uidb64", "")
uidb64 = kwargs.get("uidb64", "")
token = kwargs.get("token", "")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if these values are ""?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will go to invalid template, but a URL with /// no data between slashes will break, so I think it is impossible to reach this case.

@jumcorredorro jumcorredorro merged commit 6372ffb into develop Aug 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants