diff --git a/app/app/account_linking.py b/app/app/account_linking.py index 61fcc9a..ea0451d 100644 --- a/app/app/account_linking.py +++ b/app/app/account_linking.py @@ -5,10 +5,11 @@ from typing import Optional from arrow import Arrow from newrelic import agent +from sqlalchemy import or_ from app.db import Session from app.email_utils import send_welcome_email -from app.utils import sanitize_email +from app.utils import sanitize_email, canonicalize_email from app.errors import ( AccountAlreadyLinkedToAnotherPartnerException, AccountIsUsingAliasAsEmail, @@ -131,8 +132,9 @@ class ClientMergeStrategy(ABC): class NewUserStrategy(ClientMergeStrategy): def process(self) -> LinkResult: # Will create a new SL User with a random password + canonical_email = canonicalize_email(self.link_request.email) new_user = User.create( - email=self.link_request.email, + email=canonical_email, name=self.link_request.name, password=random_string(20), activated=True, @@ -213,11 +215,21 @@ def process_login_case( partner_id=partner.id, external_user_id=link_request.external_user_id ) if partner_user is None: + canonical_email = canonicalize_email(link_request.email) # We didn't find any SimpleLogin user registered with that partner user id # Make sure they aren't using an alias as their link email check_alias(link_request.email) + check_alias(canonical_email) # Try to find it using the partner's e-mail address - user = User.get_by(email=link_request.email) + users = User.filter( + or_(User.email == link_request.email, User.email == canonical_email) + ).all() + if len(users) > 1: + user = [user for user in users if user.email == canonical_email][0] + elif len(users) == 1: + user = users[0] + else: + user = None return get_login_strategy(link_request, user, partner).process() else: # We found the SL user registered with that partner user id diff --git a/app/app/admin_model.py b/app/app/admin_model.py index 4f7e6d0..36c69c7 100644 --- a/app/app/admin_model.py +++ b/app/app/admin_model.py @@ -611,6 +611,26 @@ class NewsletterAdmin(SLModelView): else: flash(error_msg, "error") + @action( + "clone_newsletter", + "Clone this newsletter", + ) + def clone_newsletter(self, newsletter_ids): + if len(newsletter_ids) != 1: + flash("you can only select 1 newsletter", "error") + return + + newsletter_id = newsletter_ids[0] + newsletter: Newsletter = Newsletter.get(newsletter_id) + new_newsletter = Newsletter.create( + subject=newsletter.subject, + html=newsletter.html, + plain_text=newsletter.plain_text, + commit=True, + ) + + flash(f"Newsletter {new_newsletter.subject} has been cloned", "success") + class NewsletterUserAdmin(SLModelView): column_searchable_list = ["id"] diff --git a/app/app/models.py b/app/app/models.py index 9293617..69f825e 100644 --- a/app/app/models.py +++ b/app/app/models.py @@ -3517,7 +3517,7 @@ class PartnerSubscription(Base, ModelMixin): class Newsletter(Base, ModelMixin): __tablename__ = "newsletter" - subject = sa.Column(sa.String(), nullable=False, unique=True, index=True) + subject = sa.Column(sa.String(), nullable=False, index=True) html = sa.Column(sa.Text) plain_text = sa.Column(sa.Text) diff --git a/app/migrations/versions/2023_110714_4bc54632d9aa_.py b/app/migrations/versions/2023_110714_4bc54632d9aa_.py new file mode 100644 index 0000000..874b494 --- /dev/null +++ b/app/migrations/versions/2023_110714_4bc54632d9aa_.py @@ -0,0 +1,31 @@ +"""empty message + +Revision ID: 4bc54632d9aa +Revises: 46ecb648a47e +Create Date: 2023-11-07 14:02:17.610226 + +""" +import sqlalchemy_utils +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '4bc54632d9aa' +down_revision = '46ecb648a47e' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index('ix_newsletter_subject', table_name='newsletter') + op.create_index(op.f('ix_newsletter_subject'), 'newsletter', ['subject'], unique=False) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_newsletter_subject'), table_name='newsletter') + op.create_index('ix_newsletter_subject', 'newsletter', ['subject'], unique=True) + # ### end Alembic commands ### diff --git a/app/static/images/coupon.png b/app/static/images/coupon.png index c7cccbf..99f21aa 100644 Binary files a/app/static/images/coupon.png and b/app/static/images/coupon.png differ diff --git a/app/templates/base.html b/app/templates/base.html index 59c88b5..3a94b82 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -86,6 +86,12 @@