From 96db2f46a2eceb6b3eb6090e4b029ef2690a98cc Mon Sep 17 00:00:00 2001 From: Ninh Dinh Date: Sun, 22 Dec 2019 16:49:06 +0100 Subject: [PATCH 01/17] Create pythonpackage.yml add test workflow --- .github/workflows/pythonpackage.yml | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/pythonpackage.yml diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml new file mode 100644 index 00000000..bc2f6416 --- /dev/null +++ b/.github/workflows/pythonpackage.yml @@ -0,0 +1,34 @@ +name: Python package + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: [2.7, 3.5, 3.6, 3.7] + + steps: + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Lint with flake8 + run: | + pip install flake8 + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + pip install pytest + pytest From 8aab3b10eababf42f04959fea64ab20ced6d1ea4 Mon Sep 17 00:00:00 2001 From: Ninh Dinh Date: Sun, 22 Dec 2019 16:53:15 +0100 Subject: [PATCH 02/17] Update pythonpackage.yml remove unsupported version of python. Remove flake8 --- .github/workflows/pythonpackage.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index bc2f6416..49ba7901 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -9,7 +9,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [2.7, 3.5, 3.6, 3.7] + python-version: [3.6, 3.7] steps: - uses: actions/checkout@v1 @@ -21,13 +21,6 @@ jobs: run: | python -m pip install --upgrade pip pip install -r requirements.txt - - name: Lint with flake8 - run: | - pip install flake8 - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test with pytest run: | pip install pytest From 8323dfbfe0b0ca64fde6899d9b6d40f09a42cf56 Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 15:41:37 +0000 Subject: [PATCH 03/17] better UI for new alias page --- .../templates/dashboard/custom_alias.html | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/app/dashboard/templates/dashboard/custom_alias.html b/app/dashboard/templates/dashboard/custom_alias.html index dfa57f24..7cf3c95b 100644 --- a/app/dashboard/templates/dashboard/custom_alias.html +++ b/app/dashboard/templates/dashboard/custom_alias.html @@ -17,22 +17,22 @@
-
+
{% if custom_domains %} -
+
{% endif %}
-
+
-
+

.{{ email_suffix }}@{{ EMAIL_DOMAIN }} @@ -40,13 +40,13 @@

-
+
You can use letter, number or dash. Alias cannot be empty.
-
+
@@ -56,29 +56,31 @@ {% if custom_domains %}

OR with your custom domains

- {% for custom_domain in custom_domains %} - - - +
+ {% for custom_domain in custom_domains %} + + + -
-
- -
-
- - - @{{ custom_domain.domain }} - - -
-
+
+
+ +
+ + @{{ custom_domain.domain }} + +
+
+
+ +
-
- - {% endfor %} + + + {% endfor %} +
{% endif %}
From e9a58b89ad46b3a4dcc2b8dac8dee40b952156d9 Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 15:58:07 +0000 Subject: [PATCH 04/17] only print out plaintext when NOT_SEND_EMAIL --- app/email_utils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/email_utils.py b/app/email_utils.py index b1e5b468..ef961a21 100644 --- a/app/email_utils.py +++ b/app/email_utils.py @@ -104,11 +104,10 @@ def send_test_email_alias(email, name): def send_email(to_email, subject, plaintext, html): if NOT_SEND_EMAIL: LOG.d( - "send email with subject %s to %s, plaintext: %s, html:%s", + "send email with subject %s to %s, plaintext: %s", subject, to_email, plaintext, - html, ) return From 4a97c797dff4e19ed0a7ac1ad6d132c3ca92e015 Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 15:59:00 +0000 Subject: [PATCH 05/17] use flash to display error in login --- app/auth/templates/auth/login.html | 4 ---- app/auth/views/login.py | 13 +++++++------ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app/auth/templates/auth/login.html b/app/auth/templates/auth/login.html index d708a23a..fb8fa783 100644 --- a/app/auth/templates/auth/login.html +++ b/app/auth/templates/auth/login.html @@ -15,10 +15,6 @@ {% endblock %} {% block single_content %} - {% if error %} -
{{ error }}
- {% endif %} -

Welcome back!

diff --git a/app/auth/views/login.py b/app/auth/views/login.py index cfd5ad3f..da7ce6fa 100644 --- a/app/auth/views/login.py +++ b/app/auth/views/login.py @@ -1,4 +1,4 @@ -from flask import request, render_template, redirect, url_for +from flask import request, render_template, redirect, url_for, flash from flask_login import login_user, current_user from flask_wtf import FlaskForm from wtforms import StringField, validators @@ -21,19 +21,21 @@ def login(): form = LoginForm(request.form) next_url = request.args.get("next") - error = "" show_resend_activation = False if form.validate_on_submit(): user = User.filter_by(email=form.email.data).first() if not user: - error = "Email not exist in our system" + flash("Email not exist in our system", "error") elif not user.check_password(form.password.data): - error = "Wrong password" + flash("Wrong password", "error") elif not user.activated: show_resend_activation = True - error = "Please check your inbox for the activation email. You can also have this email re-sent" + flash( + "Please check your inbox for the activation email. You can also have this email re-sent", + "error", + ) else: LOG.debug("log user %s in", user) login_user(user) @@ -51,5 +53,4 @@ def login(): form=form, next_url=next_url, show_resend_activation=show_resend_activation, - error=error, ) From 7e9418cd100f8fb0ab81f696dc65e86f136b2f1c Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 15:59:41 +0000 Subject: [PATCH 06/17] Fix wording --- .../dashboard/alias_contact_manager.html | 2 +- app/dashboard/templates/dashboard/api_key.html | 2 +- .../templates/dashboard/custom_domain.html | 2 +- app/dashboard/templates/dashboard/index.html | 15 +++++++-------- app/dashboard/templates/dashboard/setting.html | 3 ++- .../templates/dashboard/unsubscribe.html | 2 +- app/developer/templates/developer/index.html | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/dashboard/templates/dashboard/alias_contact_manager.html b/app/dashboard/templates/dashboard/alias_contact_manager.html index fad8039b..9cdb77b9 100644 --- a/app/dashboard/templates/dashboard/alias_contact_manager.html +++ b/app/dashboard/templates/dashboard/alias_contact_manager.html @@ -88,7 +88,7 @@ $(".delete-forward-email").on("click", function (e) { notie.confirm({ text: "Activity history associated with this reverse-alias will be deleted, " + - " please confirm", + " please confirm.", cancelCallback: () => { // nothing to do }, diff --git a/app/dashboard/templates/dashboard/api_key.html b/app/dashboard/templates/dashboard/api_key.html index f876d174..c459ba25 100644 --- a/app/dashboard/templates/dashboard/api_key.html +++ b/app/dashboard/templates/dashboard/api_key.html @@ -90,7 +90,7 @@ $(".delete-api-key").on("click", function (e) { notie.confirm({ text: "If this api key is currently in use, you need to replace it with another api key, " + - " please confirm", + " please confirm.", cancelCallback: () => { // nothing to do }, diff --git a/app/dashboard/templates/dashboard/custom_domain.html b/app/dashboard/templates/dashboard/custom_domain.html index 10626116..40ade6e6 100644 --- a/app/dashboard/templates/dashboard/custom_domain.html +++ b/app/dashboard/templates/dashboard/custom_domain.html @@ -149,7 +149,7 @@ $(".delete-custom-domain").on("click", function (e) { notie.confirm({ text: "All aliases associated with this domain will be also deleted, " + - " please confirm", + " please confirm.", cancelCallback: () => { // nothing to do }, diff --git a/app/dashboard/templates/dashboard/index.html b/app/dashboard/templates/dashboard/index.html index 1c55680a..aee2795f 100644 --- a/app/dashboard/templates/dashboard/index.html +++ b/app/dashboard/templates/dashboard/index.html @@ -134,10 +134,8 @@ - Delete -     - - + Delete    +
@@ -243,7 +241,7 @@ notie.confirm({ text: "Once an alias is deleted, people/apps " + "who used to contact you via this email address cannot reach you any more," + - " please confirm", + " please confirm.", cancelCallback: () => { // nothing to do }, @@ -255,7 +253,8 @@ $(".trigger-email").on("click", function (e) { notie.confirm({ - text: "SimpleLogin server will send an email to this alias and it will arrive to your inbox, please confirm", + text: "SimpleLogin server will send an email to this alias " + + "and it will arrive to your inbox, please confirm.", cancelCallback: () => { // nothing to do }, @@ -269,9 +268,9 @@ var message = ""; if (e.target.checked) { - message = `After this, you will start receiving email sent to this alias, please confirm`; + message = `After this, you will start receiving email sent to this alias, please confirm.`; } else { - message = `After this, you will stop receiving email sent to this alias, please confirm`; + message = `After this, you will stop receiving email sent to this alias, please confirm.`; } notie.confirm({ diff --git a/app/dashboard/templates/dashboard/setting.html b/app/dashboard/templates/dashboard/setting.html index 7603a962..7da137ef 100644 --- a/app/dashboard/templates/dashboard/setting.html +++ b/app/dashboard/templates/dashboard/setting.html @@ -50,7 +50,8 @@
-

Change password

+

Change password

+
You will receive an email containing instructions on how to change password.
diff --git a/app/dashboard/templates/dashboard/unsubscribe.html b/app/dashboard/templates/dashboard/unsubscribe.html index 8125f206..f4f8ada9 100644 --- a/app/dashboard/templates/dashboard/unsubscribe.html +++ b/app/dashboard/templates/dashboard/unsubscribe.html @@ -16,7 +16,7 @@ You are about to block the alias {{alias}}

- After this, you will stop receiving all emails sent to this alias, please confirm + After this, you will stop receiving all emails sent to this alias, please confirm.

diff --git a/app/developer/templates/developer/index.html b/app/developer/templates/developer/index.html index f093bb0b..d0ec5b2f 100644 --- a/app/developer/templates/developer/index.html +++ b/app/developer/templates/developer/index.html @@ -70,7 +70,7 @@ $(".custom-switch-input").change(function (e) { // Only ask for confirmation when publishing, not when un-publishing if (e.target.checked) { - var message = `After this, your app/website will made available in "Discover", please confirm`; + var message = `After this, your app/website will made available in "Discover", please confirm.`; notie.confirm({ text: message, From 85db1f3f5cb474e8e2060684b6dde4b4aa80ed20 Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 16:00:04 +0000 Subject: [PATCH 07/17] create custom domain in fake_data --- server.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server.py b/server.py index be22017b..c908acb3 100644 --- a/server.py +++ b/server.py @@ -38,7 +38,7 @@ from app.models import ( Subscription, PlanEnum, ApiKey, -) + CustomDomain) from app.monitor.base import monitor_bp from app.oauth.base import oauth_bp @@ -121,6 +121,10 @@ def fake_data(): GenEmail.create_custom_alias(user.id, "e2@") GenEmail.create_custom_alias(user.id, "e3@") + CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) + CustomDomain.create(user_id=user.id, domain="very-long-domain.com.net.org", verified=True) + db.session.commit() + # Create a client client1 = Client.create_new(name="Demo", user_id=user.id) client1.oauth_client_id = "client-id" From ee0a398ae3fc24f7cf99bfde32c8a2c29f772297 Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 16:03:40 +0000 Subject: [PATCH 08/17] Add Delete Account in setting --- .../templates/dashboard/setting.html | 28 +++++++++++++++++++ app/dashboard/views/setting.py | 9 +++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/app/dashboard/templates/dashboard/setting.html b/app/dashboard/templates/dashboard/setting.html index 7da137ef..f7c3337b 100644 --- a/app/dashboard/templates/dashboard/setting.html +++ b/app/dashboard/templates/dashboard/setting.html @@ -57,7 +57,35 @@ +
+

Delete Account

+
Please note that this operation is irreversible. + +
+
+ + +
+
{% endblock %} +{% block script %} + +{% endblock %} + diff --git a/app/dashboard/views/setting.py b/app/dashboard/views/setting.py index b6379936..d73100eb 100644 --- a/app/dashboard/views/setting.py +++ b/app/dashboard/views/setting.py @@ -2,7 +2,7 @@ from io import BytesIO import arrow from flask import render_template, request, redirect, url_for, flash -from flask_login import login_required, current_user +from flask_login import login_required, current_user, logout_user from flask_wtf import FlaskForm from flask_wtf.file import FileField from wtforms import StringField, validators @@ -111,6 +111,13 @@ def setting(): elif request.form.get("form-name") == "change-password": send_reset_password_email(current_user) + elif request.form.get("form-name") == "delete-account": + User.delete(current_user.id) + db.session.commit() + flash("Your account has been deleted", "success") + logout_user() + return redirect(url_for("auth.register")) + return redirect(url_for("dashboard.setting")) return render_template( From 2b66f9b0aa8f8a1af3b0eca416078c7222a4c74a Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 16:03:58 +0000 Subject: [PATCH 09/17] Fix wording --- app/dashboard/templates/dashboard/custom_alias.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dashboard/templates/dashboard/custom_alias.html b/app/dashboard/templates/dashboard/custom_alias.html index 7cf3c95b..b87b985b 100644 --- a/app/dashboard/templates/dashboard/custom_alias.html +++ b/app/dashboard/templates/dashboard/custom_alias.html @@ -55,7 +55,7 @@ {% if custom_domains %}
-

OR with your custom domains

+

Or with your custom domains

{% for custom_domain in custom_domains %}
From c5f7d2abf91ffc4af41cfa2889844dbaef28b3b4 Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 16:04:14 +0000 Subject: [PATCH 10/17] Increase visibility for small-text --- static/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/style.css b/static/style.css index 73c396eb..285df487 100644 --- a/static/style.css +++ b/static/style.css @@ -59,7 +59,7 @@ em { .small-text { font-size: 12px; - font-weight: lighter; + font-weight: 300; margin-bottom: 0px; } From 2764c9d0e4debae8d61bab6bd9b031f5ab4e14af Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 16:20:56 +0000 Subject: [PATCH 11/17] User can export their data --- .../templates/dashboard/setting.html | 10 ++++++ app/dashboard/views/setting.py | 33 ++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/app/dashboard/templates/dashboard/setting.html b/app/dashboard/templates/dashboard/setting.html index f7c3337b..dd064264 100644 --- a/app/dashboard/templates/dashboard/setting.html +++ b/app/dashboard/templates/dashboard/setting.html @@ -57,6 +57,16 @@ +
+

Export Data

+
+ You can download all aliases you have created on SimpleLogin along with other data. +
+
+ + +
+

Delete Account

Please note that this operation is irreversible. diff --git a/app/dashboard/views/setting.py b/app/dashboard/views/setting.py index d73100eb..168012a6 100644 --- a/app/dashboard/views/setting.py +++ b/app/dashboard/views/setting.py @@ -1,7 +1,8 @@ +import json from io import BytesIO import arrow -from flask import render_template, request, redirect, url_for, flash +from flask import render_template, request, redirect, url_for, flash, Response from flask_login import login_required, current_user, logout_user from flask_wtf import FlaskForm from flask_wtf.file import FileField @@ -20,6 +21,8 @@ from app.models import ( User, GenEmail, DeletedAlias, + CustomDomain, + Client, ) from app.utils import random_string @@ -118,6 +121,34 @@ def setting(): logout_user() return redirect(url_for("auth.register")) + elif request.form.get("form-name") == "export-data": + data = { + "email": current_user.email, + "name": current_user.name, + "aliases": [], + "apps": [], + "custom_domains": [], + } + + for alias in GenEmail.filter_by( + user_id=current_user.id + ).all(): # type: GenEmail + data["aliases"].append(dict(email=alias.email, enabled=alias.enabled)) + + for custom_domain in CustomDomain.filter_by(user_id=current_user.id).all(): + data["custom_domains"].append(custom_domain.domain) + + for app in Client.filter_by(user_id=current_user.id): # type: Client + data["apps"].append( + dict(name=app.name, home_url=app.home_url, published=app.published) + ) + + return Response( + json.dumps(data), + mimetype="text/json", + headers={"Content-Disposition": "attachment;filename=data.json"}, + ) + return redirect(url_for("dashboard.setting")) return render_template( From 647ccc7609ae767707f90c0beb6fe29a55fb0516 Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 16:21:02 +0000 Subject: [PATCH 12/17] delete unused method --- app/models.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/models.py b/app/models.py index 2dec271d..a693063f 100644 --- a/app/models.py +++ b/app/models.py @@ -398,11 +398,6 @@ class GenEmail(db.Model, ModelMixin): user = db.relationship(User) - @classmethod - def create_new_gen_email(cls, user_id, custom=False): - random_email = generate_email() - return GenEmail.create(user_id=user_id, email=random_email, custom=custom) - @classmethod def create_custom_alias(cls, user_id, prefix): if not prefix: From 9eff73f81b587bbe5a9505727b7f1f377e7af59a Mon Sep 17 00:00:00 2001 From: Ninh Dinh Date: Sun, 22 Dec 2019 17:42:02 +0100 Subject: [PATCH 13/17] Update pythonpackage.yml remove python 3.6 --- .github/workflows/pythonpackage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 49ba7901..8e639fd9 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -9,7 +9,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [3.6, 3.7] + python-version: [3.7] steps: - uses: actions/checkout@v1 From 61c1ed10d73702eba8cd2df6e516c7943508da77 Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 16:27:55 +0000 Subject: [PATCH 14/17] rename can_create_new_custom_alias -> can_create_new_alias --- app/api/views/alias_options.py | 2 +- app/api/views/new_custom_alias.py | 2 +- app/dashboard/views/custom_alias.py | 2 +- app/dashboard/views/index.py | 2 +- app/models.py | 4 ++-- app/oauth/templates/oauth/authorize.html | 2 +- app/oauth/views/authorize.py | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/api/views/alias_options.py b/app/api/views/alias_options.py index acd52299..07b21c09 100644 --- a/app/api/views/alias_options.py +++ b/app/api/views/alias_options.py @@ -31,7 +31,7 @@ def options(): ret = { "existing": [ge.email for ge in GenEmail.query.filter_by(user_id=user.id)], - "can_create_custom": user.can_create_new_custom_alias(), + "can_create_custom": user.can_create_new_alias(), } # recommendation alias if exist diff --git a/app/api/views/new_custom_alias.py b/app/api/views/new_custom_alias.py index 3c242812..b2ce5387 100644 --- a/app/api/views/new_custom_alias.py +++ b/app/api/views/new_custom_alias.py @@ -26,7 +26,7 @@ def new_custom_alias(): """ user = g.user - if not user.can_create_new_custom_alias(): + if not user.can_create_new_alias(): LOG.d("user %s cannot create custom alias", user) return ( jsonify( diff --git a/app/dashboard/views/custom_alias.py b/app/dashboard/views/custom_alias.py index c0819f50..90d34cbc 100644 --- a/app/dashboard/views/custom_alias.py +++ b/app/dashboard/views/custom_alias.py @@ -13,7 +13,7 @@ from app.utils import convert_to_id, random_word @login_required def custom_alias(): # check if user has the right to create custom alias - if not current_user.can_create_new_custom_alias(): + if not current_user.can_create_new_alias(): # notify admin LOG.error("user %s tries to create custom alias", current_user) flash("ony premium user can choose custom alias", "warning") diff --git a/app/dashboard/views/index.py b/app/dashboard/views/index.py index 0a23a9ce..e2df2e3a 100644 --- a/app/dashboard/views/index.py +++ b/app/dashboard/views/index.py @@ -50,7 +50,7 @@ def index(): ) elif request.form.get("form-name") == "create-custom-email": - if current_user.can_create_new_custom_alias(): + if current_user.can_create_new_alias(): return redirect(url_for("dashboard.custom_alias")) else: flash( diff --git a/app/models.py b/app/models.py index a693063f..7dc438d7 100644 --- a/app/models.py +++ b/app/models.py @@ -130,7 +130,7 @@ class User(db.Model, ModelMixin, UserMixin): return False - def can_create_new_custom_alias(self): + def can_create_new_alias(self): if self.is_premium(): return True @@ -160,7 +160,7 @@ class User(db.Model, ModelMixin, UserMixin): website_name = convert_to_id(website_name) all_gen_emails = [ge.email for ge in GenEmail.filter_by(user_id=self.id)] - if self.can_create_new_custom_alias(): + if self.can_create_new_alias(): suggested_gen_email = GenEmail.create_custom_alias( self.id, prefix=website_name ).email diff --git a/app/oauth/templates/oauth/authorize.html b/app/oauth/templates/oauth/authorize.html index 267822ab..c1143b1b 100644 --- a/app/oauth/templates/oauth/authorize.html +++ b/app/oauth/templates/oauth/authorize.html @@ -90,7 +90,7 @@ {% endfor %} - {% if current_user.can_create_new_custom_alias() %} + {% if current_user.can_create_new_alias() %}
OR
Date: Sun, 22 Dec 2019 16:28:13 +0000 Subject: [PATCH 15/17] add some stats directly to email subject when sending stats --- cron.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cron.py b/cron.py index ae4f8389..a7ea2367 100644 --- a/cron.py +++ b/cron.py @@ -74,7 +74,7 @@ def stats(): send_email( ADMIN_EMAIL, - subject=f"SimpleLogin Stats for {today}", + subject=f"SimpleLogin Stats for {today}, {nb_user} users, {nb_gen_email} aliases, {nb_forward} forwards", plaintext="", html=f""" Stats for {today}
From 55bccf8f849edaae8feb41599721b59aff3ffbec Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 16:32:55 +0000 Subject: [PATCH 16/17] remove GenEmail.custom column --- app/api/views/new_custom_alias.py | 2 +- app/config.py | 2 +- app/dashboard/views/custom_alias.py | 3 +-- app/models.py | 10 ++-------- app/oauth/views/authorize.py | 4 +--- migrations/versions/18e934d58f55_.py | 29 ++++++++++++++++++++++++++++ server.py | 16 +++++++-------- 7 files changed, 42 insertions(+), 24 deletions(-) create mode 100644 migrations/versions/18e934d58f55_.py diff --git a/app/api/views/new_custom_alias.py b/app/api/views/new_custom_alias.py index b2ce5387..de23bdd4 100644 --- a/app/api/views/new_custom_alias.py +++ b/app/api/views/new_custom_alias.py @@ -74,7 +74,7 @@ def new_custom_alias(): LOG.d("full alias already used %s", full_alias) return jsonify(error=f"alias {full_alias} already exists"), 409 - gen_email = GenEmail.create(user_id=user.id, email=full_alias, custom=True) + gen_email = GenEmail.create(user_id=user.id, email=full_alias) db.session.commit() if hostname: diff --git a/app/config.py b/app/config.py index e1684eaf..18e2d3af 100644 --- a/app/config.py +++ b/app/config.py @@ -63,7 +63,7 @@ DKIM_SELECTOR = b"dkim" with open(DKIM_PRIVATE_KEY_PATH) as f: DKIM_PRIVATE_KEY = f.read() -DKIM_HEADERS = [b'from', b'to', b'subject'] +DKIM_HEADERS = [b"from", b"to", b"subject"] # Database DB_URI = os.environ["DB_URI"] diff --git a/app/dashboard/views/custom_alias.py b/app/dashboard/views/custom_alias.py index 90d34cbc..034746a1 100644 --- a/app/dashboard/views/custom_alias.py +++ b/app/dashboard/views/custom_alias.py @@ -42,7 +42,7 @@ def custom_alias(): "create custom alias %s for user %s", full_email, current_user ) gen_email = GenEmail.create( - email=full_email, user_id=current_user.id, custom=True + email=full_email, user_id=current_user.id ) db.session.commit() @@ -79,7 +79,6 @@ def custom_alias(): gen_email = GenEmail.create( email=full_email, user_id=current_user.id, - custom=True, custom_domain_id=custom_domain.id, ) db.session.commit() diff --git a/app/models.py b/app/models.py index 7dc438d7..1f506a38 100644 --- a/app/models.py +++ b/app/models.py @@ -134,10 +134,7 @@ class User(db.Model, ModelMixin, UserMixin): if self.is_premium(): return True - return ( - GenEmail.filter_by(user_id=self.id, custom=True).count() - < MAX_NB_EMAIL_FREE_PLAN - ) + return GenEmail.filter_by(user_id=self.id).count() < MAX_NB_EMAIL_FREE_PLAN def set_password(self, password): salt = bcrypt.gensalt() @@ -389,9 +386,6 @@ class GenEmail(db.Model, ModelMixin): enabled = db.Column(db.Boolean(), default=True, nullable=False) - # this email has been customized by user, i.e. not generated randomly - custom = db.Column(db.Boolean(), default=False, nullable=False, server_default="0") - custom_domain_id = db.Column( db.ForeignKey("custom_domain.id", ondelete="cascade"), nullable=True ) @@ -411,7 +405,7 @@ class GenEmail(db.Model, ModelMixin): if not cls.get_by(email=email): break - return GenEmail.create(user_id=user_id, email=email, custom=True) + return GenEmail.create(user_id=user_id, email=email) def __repr__(self): return f"" diff --git a/app/oauth/views/authorize.py b/app/oauth/views/authorize.py index 4adde860..7ba3a49a 100644 --- a/app/oauth/views/authorize.py +++ b/app/oauth/views/authorize.py @@ -163,9 +163,7 @@ def authorize(): flash(f"alias {email} already used", "error") return redirect(request.url) - gen_email = GenEmail.create( - email=email, user_id=current_user.id, custom=True - ) + gen_email = GenEmail.create(email=email, user_id=current_user.id) db.session.flush() else: # user picks an email from suggestion if chosen_email != current_user.email: diff --git a/migrations/versions/18e934d58f55_.py b/migrations/versions/18e934d58f55_.py new file mode 100644 index 00000000..0ff96645 --- /dev/null +++ b/migrations/versions/18e934d58f55_.py @@ -0,0 +1,29 @@ +"""empty message + +Revision ID: 18e934d58f55 +Revises: 0c7f1a48aac9 +Create Date: 2019-12-22 16:31:33.531138 + +""" +import sqlalchemy_utils +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '18e934d58f55' +down_revision = '0c7f1a48aac9' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('gen_email', 'custom') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('gen_email', sa.Column('custom', sa.BOOLEAN(), server_default=sa.text('false'), autoincrement=False, nullable=False)) + # ### end Alembic commands ### diff --git a/server.py b/server.py index c908acb3..b2bae7af 100644 --- a/server.py +++ b/server.py @@ -38,16 +38,14 @@ from app.models import ( Subscription, PlanEnum, ApiKey, - CustomDomain) + CustomDomain, +) from app.monitor.base import monitor_bp from app.oauth.base import oauth_bp if SENTRY_DSN: LOG.d("enable sentry") - sentry_sdk.init( - dsn=SENTRY_DSN, - integrations=[FlaskIntegration()], - ) + sentry_sdk.init(dsn=SENTRY_DSN, integrations=[FlaskIntegration()]) # the app is served behin nginx which uses http and not https os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1" @@ -122,7 +120,9 @@ def fake_data(): GenEmail.create_custom_alias(user.id, "e3@") CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) - CustomDomain.create(user_id=user.id, domain="very-long-domain.com.net.org", verified=True) + CustomDomain.create( + user_id=user.id, domain="very-long-domain.com.net.org", verified=True + ) db.session.commit() # Create a client @@ -263,9 +263,7 @@ def jinja2_filter(app): @app.context_processor def inject_stage_and_region(): - return dict( - YEAR=arrow.now().year, URL=URL, SENTRY_DSN=SENTRY_DSN, VERSION=SHA1 - ) + return dict(YEAR=arrow.now().year, URL=URL, SENTRY_DSN=SENTRY_DSN, VERSION=SHA1) def setup_paddle_callback(app: Flask): From 084f835bfea655bc23e91c5a49130df073f22646 Mon Sep 17 00:00:00 2001 From: Son NK Date: Sun, 22 Dec 2019 16:34:10 +0000 Subject: [PATCH 17/17] rename create_custom_alias -> create_new --- app/models.py | 6 +++--- server.py | 6 +++--- tests/api/test_alias_options.py | 2 +- tests/api/test_new_custom_alias.py | 6 +++--- tests/test_models.py | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/models.py b/app/models.py index 1f506a38..e545e9e2 100644 --- a/app/models.py +++ b/app/models.py @@ -109,7 +109,7 @@ class User(db.Model, ModelMixin, UserMixin): db.session.flush() # create a first alias mail to show user how to use when they login - GenEmail.create_custom_alias(user.id, prefix="my-first-alias") + GenEmail.create_new(user.id, prefix="my-first-alias") db.session.flush() return user @@ -158,7 +158,7 @@ class User(db.Model, ModelMixin, UserMixin): all_gen_emails = [ge.email for ge in GenEmail.filter_by(user_id=self.id)] if self.can_create_new_alias(): - suggested_gen_email = GenEmail.create_custom_alias( + suggested_gen_email = GenEmail.create_new( self.id, prefix=website_name ).email else: @@ -393,7 +393,7 @@ class GenEmail(db.Model, ModelMixin): user = db.relationship(User) @classmethod - def create_custom_alias(cls, user_id, prefix): + def create_new(cls, user_id, prefix): if not prefix: raise Exception("alias prefix cannot be empty") diff --git a/server.py b/server.py index b2bae7af..cc2d1e39 100644 --- a/server.py +++ b/server.py @@ -115,9 +115,9 @@ def fake_data(): api_key = ApiKey.create(user_id=user.id, name="Chrome") api_key.code = "code" - GenEmail.create_custom_alias(user.id, "e1@") - GenEmail.create_custom_alias(user.id, "e2@") - GenEmail.create_custom_alias(user.id, "e3@") + GenEmail.create_new(user.id, "e1@") + GenEmail.create_new(user.id, "e2@") + GenEmail.create_new(user.id, "e3@") CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) CustomDomain.create( diff --git a/tests/api/test_alias_options.py b/tests/api/test_alias_options.py index 3d9dc54c..6f14901e 100644 --- a/tests/api/test_alias_options.py +++ b/tests/api/test_alias_options.py @@ -39,7 +39,7 @@ def test_different_scenarios(flask_client): assert r.json["custom"]["suggestion"] == "test" # <<< with recommendation >>> - alias = GenEmail.create_custom_alias(user.id, prefix="test") + alias = GenEmail.create_new(user.id, prefix="test") db.session.commit() AliasUsedOn.create(gen_email_id=alias.id, hostname="www.test.com") db.session.commit() diff --git a/tests/api/test_new_custom_alias.py b/tests/api/test_new_custom_alias.py index bff09d9c..36622be8 100644 --- a/tests/api/test_new_custom_alias.py +++ b/tests/api/test_new_custom_alias.py @@ -36,9 +36,9 @@ def test_out_of_quota(flask_client): db.session.commit() # create 3 custom alias to run out of quota - GenEmail.create_custom_alias(user.id, prefix="test") - GenEmail.create_custom_alias(user.id, prefix="test") - GenEmail.create_custom_alias(user.id, prefix="test") + GenEmail.create_new(user.id, prefix="test") + GenEmail.create_new(user.id, prefix="test") + GenEmail.create_new(user.id, prefix="test") r = flask_client.post( url_for("api.new_custom_alias", hostname="www.test.com"), diff --git a/tests/test_models.py b/tests/test_models.py index b3497c22..66cbb72e 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -27,7 +27,7 @@ def test_suggested_emails_for_user_who_cannot_create_new_email(flask_client): # make sure user runs out of quota to create new email for i in range(MAX_NB_EMAIL_FREE_PLAN): - GenEmail.create_custom_alias(user_id=user.id, prefix="test") + GenEmail.create_new(user_id=user.id, prefix="test") db.session.commit() suggested_email, other_emails = user.suggested_emails(website_name="test")