Add toggle to check if a user is premium without the partner subscription (#1739)

* Add toggle to check if a user is premium without the partner subscription

* fix test

* Parter created users do not have a newsletter alias id

---------

Co-authored-by: Adrià Casajús <adria.casajus@proton.ch>
This commit is contained in:
Adrià Casajús 2023-05-15 12:34:58 +02:00 committed by GitHub
parent e4d4317988
commit 3de83f2f05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 26 deletions

View File

@ -580,19 +580,6 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle):
Session.flush() Session.flush()
user.default_mailbox_id = mb.id user.default_mailbox_id = mb.id
# create a first alias mail to show user how to use when they login
alias = Alias.create_new(
user,
prefix="simplelogin-newsletter",
mailbox_id=mb.id,
note="This is your first alias. It's used to receive SimpleLogin communications "
"like new features announcements, newsletters.",
)
Session.flush()
user.newsletter_alias_id = alias.id
Session.flush()
# generate an alternative_id if needed # generate an alternative_id if needed
if "alternative_id" not in kwargs: if "alternative_id" not in kwargs:
user.alternative_id = str(uuid.uuid4()) user.alternative_id = str(uuid.uuid4())
@ -611,6 +598,19 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle):
Session.flush() Session.flush()
return user return user
# create a first alias mail to show user how to use when they login
alias = Alias.create_new(
user,
prefix="simplelogin-newsletter",
mailbox_id=mb.id,
note="This is your first alias. It's used to receive SimpleLogin communications "
"like new features announcements, newsletters.",
)
Session.flush()
user.newsletter_alias_id = alias.id
Session.flush()
if config.DISABLE_ONBOARDING: if config.DISABLE_ONBOARDING:
LOG.d("Disable onboarding emails") LOG.d("Disable onboarding emails")
return user return user
@ -636,7 +636,7 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle):
return user return user
def get_active_subscription( def get_active_subscription(
self, self, include_partner_subscription: bool = True
) -> Optional[ ) -> Optional[
Union[ Union[
Subscription Subscription
@ -664,19 +664,24 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle):
if coinbase_subscription and coinbase_subscription.is_active(): if coinbase_subscription and coinbase_subscription.is_active():
return coinbase_subscription return coinbase_subscription
partner_sub: PartnerSubscription = PartnerSubscription.find_by_user_id(self.id) if include_partner_subscription:
if partner_sub and partner_sub.is_active(): partner_sub: PartnerSubscription = PartnerSubscription.find_by_user_id(
return partner_sub self.id
)
if partner_sub and partner_sub.is_active():
return partner_sub
return None return None
# region Billing # region Billing
def lifetime_or_active_subscription(self) -> bool: def lifetime_or_active_subscription(
self, include_partner_subscription: bool = True
) -> bool:
"""True if user has lifetime licence or active subscription""" """True if user has lifetime licence or active subscription"""
if self.lifetime: if self.lifetime:
return True return True
return self.get_active_subscription() is not None return self.get_active_subscription(include_partner_subscription) is not None
def is_paid(self) -> bool: def is_paid(self) -> bool:
"""same as _lifetime_or_active_subscription but not include free manual subscription""" """same as _lifetime_or_active_subscription but not include free manual subscription"""
@ -705,14 +710,14 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle):
return True return True
def is_premium(self) -> bool: def is_premium(self, include_partner_subscription: bool = True) -> bool:
""" """
user is premium if they: user is premium if they:
- have a lifetime deal or - have a lifetime deal or
- in trial period or - in trial period or
- active subscription - active subscription
""" """
if self.lifetime_or_active_subscription(): if self.lifetime_or_active_subscription(include_partner_subscription):
return True return True
if self.trial_end and arrow.now() < self.trial_end: if self.trial_end and arrow.now() < self.trial_end:

View File

@ -5,7 +5,7 @@ from app.models import User, ResetPasswordCode
from tests.utils import create_new_user, random_token from tests.utils import create_new_user, random_token
def test_reset_password(flask_client): def test_successful_reset_password(flask_client):
user = create_new_user() user = create_new_user()
original_pass_hash = user.password original_pass_hash = user.password
user_id = user.id user_id = user.id
@ -19,8 +19,8 @@ def test_reset_password(flask_client):
data={"password": "1231idsfjaads"}, data={"password": "1231idsfjaads"},
) )
assert r.status_code == 200 assert r.status_code == 302
assert len(ResetPasswordCode.get_by(user_id=user_id).all()) == 0 assert ResetPasswordCode.get_by(user_id=user_id) is None
user = User.get(user_id) user = User.get(user_id)
assert user.password != original_pass_hash assert user.password != original_pass_hash

View File

@ -1,7 +1,9 @@
import arrow
from app import config from app import config
from app.db import Session from app.db import Session
from app.models import User, Job from app.models import User, Job, PartnerSubscription, PartnerUser, ManualSubscription
from tests.utils import random_email from app.proton.utils import get_proton_partner
from tests.utils import random_email, random_token
def test_create_from_partner(flask_client): def test_create_from_partner(flask_client):
@ -11,6 +13,7 @@ def test_create_from_partner(flask_client):
) )
assert user.notification is False assert user.notification is False
assert user.trial_end is None assert user.trial_end is None
assert user.newsletter_alias_id is None
job = Session.query(Job).order_by(Job.id.desc()).first() job = Session.query(Job).order_by(Job.id.desc()).first()
assert job is not None assert job is not None
assert job.name == config.JOB_SEND_PROTON_WELCOME_1 assert job.name == config.JOB_SEND_PROTON_WELCOME_1
@ -23,3 +26,23 @@ def test_user_created_by_partner(flask_client):
regular_user = User.create(email=random_email()) regular_user = User.create(email=random_email())
assert regular_user.created_by_partner is False assert regular_user.created_by_partner is False
def test_user_is_premium(flask_client):
user = User.create(email=random_email(), from_partner=True)
assert not user.is_premium()
partner_user = PartnerUser.create(
user_id=user.id,
partner_id=get_proton_partner().id,
partner_email=user.email,
external_user_id=random_token(),
flush=True,
)
ps = PartnerSubscription.create(
partner_user_id=partner_user.id, end_at=arrow.now().shift(years=1), flush=True
)
assert user.is_premium()
assert not user.is_premium(include_partner_subscription=False)
ManualSubscription.create(user_id=user.id, end_at=ps.end_at)
assert user.is_premium()
assert user.is_premium(include_partner_subscription=False)