Do not allow free users to create reverse alias to reduce abuse (#2013)
* Do not allow free users to create reverse alias to reduce abuse * Update format * Move function under user * Update tests
This commit is contained in:
parent
44138e25a5
commit
da09db3864
|
@ -32,6 +32,7 @@ def user_to_dict(user: User) -> dict:
|
|||
"in_trial": user.in_trial(),
|
||||
"max_alias_free_plan": user.max_alias_for_free_account(),
|
||||
"connected_proton_address": None,
|
||||
"can_create_reverse_alias": user.can_create_contacts(),
|
||||
}
|
||||
|
||||
if config.CONNECT_WITH_PROTON:
|
||||
|
@ -58,6 +59,7 @@ def user_info():
|
|||
- in_trial
|
||||
- max_alias_free
|
||||
- is_connected_with_proton
|
||||
- can_create_reverse_alias
|
||||
"""
|
||||
user = g.user
|
||||
|
||||
|
|
|
@ -489,7 +489,9 @@ def setup_nameservers():
|
|||
|
||||
NAMESERVERS = setup_nameservers()
|
||||
|
||||
DISABLE_CREATE_CONTACTS_FOR_FREE_USERS = False
|
||||
DISABLE_CREATE_CONTACTS_FOR_FREE_USERS = os.environ.get(
|
||||
"DISABLE_CREATE_CONTACTS_FOR_FREE_USERS", False
|
||||
)
|
||||
PARTNER_API_TOKEN_SECRET = os.environ.get("PARTNER_API_TOKEN_SECRET") or (
|
||||
FLASK_SECRET + "partnerapitoken"
|
||||
)
|
||||
|
|
|
@ -51,14 +51,6 @@ def email_validator():
|
|||
return _check
|
||||
|
||||
|
||||
def user_can_create_contacts(user: User) -> bool:
|
||||
if user.is_premium():
|
||||
return True
|
||||
if user.flags & User.FLAG_FREE_DISABLE_CREATE_ALIAS == 0:
|
||||
return True
|
||||
return not config.DISABLE_CREATE_CONTACTS_FOR_FREE_USERS
|
||||
|
||||
|
||||
def create_contact(user: User, alias: Alias, contact_address: str) -> Contact:
|
||||
"""
|
||||
Create a contact for a user. Can be restricted for new free users by enabling DISABLE_CREATE_CONTACTS_FOR_FREE_USERS.
|
||||
|
@ -82,7 +74,7 @@ def create_contact(user: User, alias: Alias, contact_address: str) -> Contact:
|
|||
if contact:
|
||||
raise ErrContactAlreadyExists(contact)
|
||||
|
||||
if not user_can_create_contacts(user):
|
||||
if not user.can_create_contacts():
|
||||
raise ErrContactErrorUpgradeNeeded()
|
||||
|
||||
contact = Contact.create(
|
||||
|
@ -327,6 +319,6 @@ def alias_contact_manager(alias_id):
|
|||
last_page=last_page,
|
||||
query=query,
|
||||
nb_contact=nb_contact,
|
||||
can_create_contacts=user_can_create_contacts(current_user),
|
||||
can_create_contacts=current_user.can_create_contacts(),
|
||||
csrf_form=csrf_form,
|
||||
)
|
||||
|
|
|
@ -1113,6 +1113,13 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle):
|
|||
|
||||
return random_words(1)
|
||||
|
||||
def can_create_contacts(self) -> bool:
|
||||
if self.is_premium():
|
||||
return True
|
||||
if self.flags & User.FLAG_FREE_DISABLE_CREATE_ALIAS == 0:
|
||||
return True
|
||||
return not config.DISABLE_CREATE_CONTACTS_FOR_FREE_USERS
|
||||
|
||||
def __repr__(self):
|
||||
return f"<User {self.id} {self.name} {self.email}>"
|
||||
|
||||
|
|
|
@ -59,26 +59,29 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="col-12 col-lg-6 pt-1">
|
||||
<form method="post">
|
||||
<input type="hidden" name="form-name" value="create" />
|
||||
{{ new_contact_form.csrf_token }}
|
||||
{{ new_contact_form.email(class="form-control", placeholder="First Last <email@example.com>", autofocus=True) }}
|
||||
{{ render_field_errors(new_contact_form.email) }}
|
||||
<div class="small-text">Where do you want to send the email?</div>
|
||||
{% if can_create_contacts %}
|
||||
{% if can_create_contacts %}
|
||||
|
||||
<button class="btn btn-primary mt-2">Create reverse-alias</button>
|
||||
{% else %}
|
||||
<button disabled
|
||||
title="Upgrade to premium to create reverse-aliases"
|
||||
class="btn btn-primary mt-2">
|
||||
Create reverse-alias
|
||||
</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="col-12 col-lg-6 pt-1">
|
||||
<form method="post">
|
||||
<input type="hidden" name="form-name" value="create" />
|
||||
{{ new_contact_form.csrf_token }}
|
||||
{{ new_contact_form.email(class="form-control", placeholder="First Last <email@example.com>", autofocus=True) }}
|
||||
{{ render_field_errors(new_contact_form.email) }}
|
||||
<div class="small-text">Where do you want to send the email?</div>
|
||||
{% if can_create_contacts %}
|
||||
|
||||
<button class="btn btn-primary mt-2">Create reverse-alias</button>
|
||||
{% else %}
|
||||
<button disabled
|
||||
title="Upgrade to premium to create reverse-aliases"
|
||||
class="btn btn-primary mt-2">
|
||||
Create reverse-alias
|
||||
</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="col-12 col-lg-6 pt-1">
|
||||
<div class="float-right d-flex">
|
||||
<form method="post">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from flask import url_for
|
||||
|
||||
from app import config
|
||||
from app.db import Session
|
||||
from app.models import User, PartnerUser
|
||||
from app.proton.utils import get_proton_partner
|
||||
from tests.api.utils import get_new_user_and_api_key
|
||||
|
@ -23,6 +24,7 @@ def test_user_in_trial(flask_client):
|
|||
"profile_picture_url": None,
|
||||
"max_alias_free_plan": config.MAX_NB_EMAIL_FREE_PLAN,
|
||||
"connected_proton_address": None,
|
||||
"can_create_reverse_alias": True,
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,9 +54,24 @@ def test_user_linked_to_proton(flask_client):
|
|||
"profile_picture_url": None,
|
||||
"max_alias_free_plan": config.MAX_NB_EMAIL_FREE_PLAN,
|
||||
"connected_proton_address": partner_email,
|
||||
"can_create_reverse_alias": user.can_create_contacts(),
|
||||
}
|
||||
|
||||
|
||||
def test_cannot_create_reverse_alias(flask_client):
|
||||
user, api_key = get_new_user_and_api_key()
|
||||
user.trial_end = None
|
||||
Session.flush()
|
||||
config.DISABLE_CREATE_CONTACTS_FOR_FREE_USERS = True
|
||||
|
||||
r = flask_client.get(
|
||||
url_for("api.user_info"), headers={"Authentication": api_key.code}
|
||||
)
|
||||
|
||||
assert r.status_code == 200
|
||||
assert not r.json["can_create_reverse_alias"]
|
||||
|
||||
|
||||
def test_wrong_api_key(flask_client):
|
||||
r = flask_client.get(
|
||||
url_for("api.user_info"), headers={"Authentication": "Invalid code"}
|
||||
|
|
Loading…
Reference in New Issue