reduce subdomain/directory quota when user create/delete subdomain/directory

This commit is contained in:
Son 2021-11-18 10:33:15 +01:00
parent 85c6e791bc
commit 38ecb227b0
8 changed files with 95 additions and 11 deletions

View File

@ -114,7 +114,7 @@ def directory():
flash("Only premium plan can add directory", "warning")
return redirect(url_for("dashboard.directory"))
if current_user.nb_directory() >= MAX_NB_DIRECTORY:
if current_user.directory_quota <= 0:
flash(
f"You cannot have more than {MAX_NB_DIRECTORY} directories",
"warning",

View File

@ -28,7 +28,7 @@ def subdomain_route():
flash("Only premium plan can add subdomain", "warning")
return redirect(request.url)
if len(subdomains) >= MAX_NB_SUBDOMAIN:
if current_user.subdomain_quota <= 0:
flash(
f"You can't create more than {MAX_NB_SUBDOMAIN} subdomains", "error"
)
@ -88,5 +88,4 @@ def subdomain_route():
sl_domains=sl_domains,
errors=errors,
subdomains=subdomains,
can_create=len(subdomains) < MAX_NB_SUBDOMAIN,
)

View File

@ -2016,6 +2016,11 @@ class CustomDomain(Base, ModelMixin):
domain.ownership_txt_token = random_string(30)
Session.commit()
if domain.is_sl_subdomain:
user = domain.user
user._subdomain_quota -= 1
Session.flush()
return domain
@classmethod
@ -2024,6 +2029,10 @@ class CustomDomain(Base, ModelMixin):
if obj.is_sl_subdomain:
DeletedSubdomain.create(domain=obj.domain)
user = obj.user
user._subdomain_quota -= 1
Session.flush()
return super(CustomDomain, cls).delete(obj_id)
@property
@ -2166,7 +2175,14 @@ class Directory(Base, ModelMixin):
if DeletedDirectory.get_by(name=name):
raise DirectoryInTrashError
return super(Directory, cls).create(*args, **kwargs)
directory = super(Directory, cls).create(*args, **kwargs)
Session.flush()
user = directory.user
user._directory_quota -= 1
Session.flush()
return directory
@classmethod
def delete(cls, obj_id):
@ -2180,6 +2196,10 @@ class Directory(Base, ModelMixin):
DeletedDirectory.create(name=obj.name)
cls.filter(cls.id == obj_id).delete()
user = obj.user
user._directory_quota -= 1
Session.commit()
def __repr__(self):

View File

@ -139,7 +139,7 @@
{% endfor %}
</div>
<div class="row">
<div class="row {% if current_user.directory_quota <= 0 %} disabled-content {% endif %}">
<div class="col">
<div class="card">
<div class="card-body">
@ -148,7 +148,10 @@
{{ new_dir_form.csrf_token }}
<input type="hidden" name="form-name" value="create">
<h2 class="h4">New Directory</h2>
<h2 class="h4 mb-1">New Directory</h2>
<div class="small-text mb-4">
You can create up to {{ current_user.directory_quota }} directories.
</div>
{{ new_dir_form.name(class="form-control", placeholder="my-directory",
pattern="[0-9a-z-_]{3,}",
@ -195,7 +198,8 @@
let directory = $(this).parent().find(".dir-name").val();
let that = $(this);
let message = `All aliases associated with <b>${directory}</b> directory will also be deleted, ` +
let message = `All aliases associated with <b>${directory}</b> directory will also be deleted. ` +
`Your directory quota will be {{ current_user.directory_quota - 1 }} after the deletion, ` +
" please confirm.";
bootbox.confirm({

View File

@ -128,11 +128,24 @@
</div>
<hr>
<h3 class="mb-1">Delete Domain</h3>
<h3 class="mb-1">
{% if custom_domain.is_sl_subdomain %}
Delete Subdomain
{% else %}
Delete Domain
{% endif %}
</h3>
<div class="mb-3">This operation is <b>irreversible</b>.
All aliases associated with this domain will be deleted.
{% if custom_domain.is_sl_subdomain %}
<br>
After deletion, your subdomain quota will be {{ current_user.subdomain_quota - 1 }}.
{% endif %}
</div>
<form method="post">
<input type="hidden" name="form-name" value="delete">
<span class="delete-custom-domain btn btn-danger">Delete domain</span>

View File

@ -29,7 +29,8 @@
<div class="alert alert-primary collapse {% if not subdomains %} show {% endif %}" id="howtouse" role="alert">
You can use subdomain to quickly create email aliases without opening SimpleLogin app. <br>
Handy when you need to quickly give out an email address, for example on a phone call, in a meeting or just anywhere you want. <br>
Handy when you need to quickly give out an email address, for example on a phone call, in a meeting or just
anywhere you want. <br>
After choosing a subdomain, simply use <b>anything@my-subdomain.simplelogin.co</b>
next time you need an alias:
it'll be <b>automatically created</b> the first time it receives an email. <br>
@ -61,12 +62,15 @@
{% endfor %}
</div>
<div class="row {% if not can_create %} disabled-content {% endif %}" id="new-subdomain" >
<div class="row {% if current_user.subdomain_quota <= 0 %} disabled-content {% endif %}" id="new-subdomain">
<div class="col">
<div class="card">
<div class="card-body">
<h2 class="h4">New Subdomain</h2>
<h2 class="h4 mb-1">New Subdomain</h2>
<div class="small-text mb-4">
You can create up to {{ current_user.subdomain_quota }} subdomains.
</div>
<form method="post" class="mt-2" data-parsley-validate>
<input type="hidden" name="form-name" value="create">

View File

@ -1,5 +1,6 @@
from flask import url_for
from app.config import MAX_NB_DIRECTORY
from app.models import Directory
from tests.utils import login
@ -56,3 +57,21 @@ def test_create_directory_in_trash(flask_client):
assert r.status_code == 200
assert "test has been used before and cannot be reused" in r.data.decode()
def test_create_directory_out_of_quota(flask_client):
user = login(flask_client)
for i in range(MAX_NB_DIRECTORY):
Directory.create(name=f"test{i}", user_id=user.id, commit=True)
assert Directory.count() == MAX_NB_DIRECTORY
flask_client.post(
url_for("dashboard.directory"),
data={"form-name": "create", "name": "test"},
follow_redirects=True,
)
# no new directory is created
assert Directory.count() == MAX_NB_DIRECTORY

View File

@ -1,5 +1,6 @@
from flask import url_for
from app.config import MAX_NB_SUBDOMAIN
from app.db import Session
from app.models import SLDomain, CustomDomain, Job
from tests.utils import login
@ -81,3 +82,27 @@ def test_create_subdomain_in_trash(flask_client):
f"test.{sl_domain.domain} has been used before and cannot be reused"
in r.data.decode()
)
def test_create_subdomain_out_of_quota(flask_client):
user = login(flask_client)
sl_domain = setup_sl_domain()
for i in range(MAX_NB_SUBDOMAIN):
CustomDomain.create(
domain=f"test{i}.{sl_domain.domain}",
user_id=user.id,
is_sl_subdomain=True,
commit=True,
)
assert CustomDomain.count() == MAX_NB_SUBDOMAIN
r = flask_client.post(
url_for("dashboard.subdomain_route"),
data={"form-name": "create", "subdomain": "test", "domain": sl_domain.domain},
follow_redirects=True,
)
# no new subdomain is created
assert CustomDomain.count() == MAX_NB_SUBDOMAIN