mirror of
https://github.com/simple-login/app.git
synced 2025-09-27 00:48:30 +08:00
chore: fix regex warnings on python 3.12 (#2400)
* deps: update some dependencies to fix warnings * chore: move from sl.local to sl.lan for local development * fix: mark string as regex * chore: move facebook import to handler so its not global * test: fix tests * style: lint fixes * test: move all .test and .local to .lan * ci: do not use setup-python in lint
This commit is contained in:
parent
f5de78f2e1
commit
59957ec08b
31 changed files with 139 additions and 108 deletions
5
.github/workflows/main.yml
vendored
5
.github/workflows/main.yml
vendored
|
@ -27,11 +27,6 @@ jobs:
|
|||
sudo apt update
|
||||
sudo apt install -y libre2-dev libpq-dev
|
||||
|
||||
- name: "Set up Python"
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version-file: "pyproject.toml"
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.setup-uv.outputs.cache-hit != 'true'
|
||||
run: uv sync --locked --all-extras
|
||||
|
|
|
@ -215,7 +215,7 @@ python email_handler.py
|
|||
4) Send a test email
|
||||
|
||||
```bash
|
||||
swaks --to e1@sl.local --from hey@google.com --server 127.0.0.1:20381
|
||||
swaks --to e1@sl.lan --from hey@google.com --server 127.0.0.1:20381
|
||||
```
|
||||
|
||||
Now open http://localhost:1080/ (or http://localhost:1080/ for MailHog), you should see the forwarded email.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import secrets
|
||||
import string
|
||||
|
||||
import facebook
|
||||
import google.oauth2.credentials
|
||||
import googleapiclient.discovery
|
||||
from flask import jsonify, request
|
||||
|
@ -261,6 +260,8 @@ def auth_facebook():
|
|||
}
|
||||
|
||||
"""
|
||||
import facebook
|
||||
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify(error="request body cannot be empty"), 400
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""List of clients"""
|
||||
|
||||
from flask import render_template
|
||||
from flask_login import current_user, login_required
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""Email headers"""
|
||||
|
||||
MESSAGE_ID = "Message-ID"
|
||||
IN_REPLY_TO = "In-Reply-To"
|
||||
REFERENCES = "References"
|
||||
|
|
|
@ -1355,7 +1355,9 @@ def get_queue_id(msg: Message) -> Optional[str]:
|
|||
search_result = re.search(r"with E?SMTP[AS]? id ([0-9a-zA-Z]{1,})", received_header)
|
||||
if search_result:
|
||||
return search_result.group(1)
|
||||
search_result = re.search("\(Postfix\)\r\n\tid ([a-zA-Z0-9]{1,});", received_header)
|
||||
search_result = re.search(
|
||||
r"\(Postfix\)\r\n\tid ([a-zA-Z0-9]{1,});", received_header
|
||||
)
|
||||
if search_result:
|
||||
return search_result.group(1)
|
||||
return None
|
||||
|
|
|
@ -90,7 +90,7 @@ def fake_data():
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="hey@google.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
commit=True,
|
||||
)
|
||||
EmailLog.create(
|
||||
|
@ -166,7 +166,7 @@ def fake_data():
|
|||
# user_id=user.id,
|
||||
# alias_id=a.id,
|
||||
# website_email=f"contact{i}@example.com",
|
||||
# reply_email=f"rep{i}@sl.local",
|
||||
# reply_email=f"rep{i}@sl.lan",
|
||||
# )
|
||||
# Session.commit()
|
||||
# for _ in range(3):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Inspired from
|
||||
https://github.com/petermat/spamassassin_client
|
||||
"""
|
||||
|
||||
import logging
|
||||
import socket
|
||||
from io import BytesIO
|
||||
|
|
16
docs/api.md
16
docs/api.md
|
@ -369,8 +369,8 @@ For ex:
|
|||
"is_premium": false
|
||||
},
|
||||
{
|
||||
"signed_suffix": ".yeah@sl.local.X6_7OQ.i8XL4xsMsn7dxDEWU8eF-Zap0qo",
|
||||
"suffix": ".yeah@sl.local",
|
||||
"signed_suffix": ".yeah@sl.lan.X6_7OQ.i8XL4xsMsn7dxDEWU8eF-Zap0qo",
|
||||
"suffix": ".yeah@sl.lan",
|
||||
"is_custom": true,
|
||||
"is_premium": false
|
||||
}
|
||||
|
@ -465,7 +465,7 @@ Here's an example:
|
|||
{
|
||||
"creation_date": "2020-04-06 17:57:14+00:00",
|
||||
"creation_timestamp": 1586195834,
|
||||
"email": "prefix1.cat@sl.local",
|
||||
"email": "prefix1.cat@sl.lan",
|
||||
"name": "A Name",
|
||||
"enabled": true,
|
||||
"id": 3,
|
||||
|
@ -518,7 +518,7 @@ Alias info, use the same format as in /api/v2/aliases. For example:
|
|||
{
|
||||
"creation_date": "2020-04-06 17:57:14+00:00",
|
||||
"creation_timestamp": 1586195834,
|
||||
"email": "prefix1.cat@sl.local",
|
||||
"email": "prefix1.cat@sl.lan",
|
||||
"name": "A Name",
|
||||
"enabled": true,
|
||||
"id": 3,
|
||||
|
@ -608,7 +608,7 @@ If success, 200 with the list of activities, for example:
|
|||
"activities": [
|
||||
{
|
||||
"action": "reply",
|
||||
"from": "yes_meo_chat@sl.local",
|
||||
"from": "yes_meo_chat@sl.lan",
|
||||
"timestamp": 1580903760,
|
||||
"to": "marketing@example.com",
|
||||
"reverse_alias": "\"marketing at example.com\" <reply@a.b>",
|
||||
|
@ -703,7 +703,7 @@ Return 200 and `existed=true` if contact is already added.
|
|||
"creation_timestamp": 1584186761,
|
||||
"last_email_sent_date": null,
|
||||
"last_email_sent_timestamp": null,
|
||||
"reverse_alias": "First Last first@example.com <ra+qytyzjhrumrreuszrbjxqjlkh@sl.local>",
|
||||
"reverse_alias": "First Last first@example.com <ra+qytyzjhrumrreuszrbjxqjlkh@sl.lan>",
|
||||
"reverse_alias_address": "reply+bzvpazcdedcgcpztehxzgjgzmxskqa@sl.co",
|
||||
"existed": false
|
||||
}
|
||||
|
@ -992,7 +992,7 @@ Return user setting.
|
|||
{
|
||||
"alias_generator": "word",
|
||||
"notification": true,
|
||||
"random_alias_default_domain": "sl.local",
|
||||
"random_alias_default_domain": "sl.lan",
|
||||
"sender_format": "AT",
|
||||
"random_alias_suffix": "random_string"
|
||||
}
|
||||
|
@ -1029,7 +1029,7 @@ Return domains that user can use to create random alias
|
|||
"is_custom": false
|
||||
},
|
||||
{
|
||||
"domain": "sl.local",
|
||||
"domain": "sl.lan",
|
||||
"is_custom": false
|
||||
},
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@ It should contain the following info:
|
|||
|
||||
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import email
|
||||
import time
|
||||
|
@ -1668,7 +1669,7 @@ def handle_bounce_reply_phase(envelope, msg: Message, email_log: EmailLog):
|
|||
)
|
||||
Notification.create(
|
||||
user_id=user.id,
|
||||
title=f"Email cannot be sent to { contact.email } from your alias { alias.email }",
|
||||
title=f"Email cannot be sent to {contact.email} from your alias {alias.email}",
|
||||
message=Notification.render(
|
||||
"notification/bounce-reply-phase.html",
|
||||
alias=alias,
|
||||
|
@ -1681,7 +1682,7 @@ def handle_bounce_reply_phase(envelope, msg: Message, email_log: EmailLog):
|
|||
user,
|
||||
ALERT_BOUNCE_EMAIL_REPLY_PHASE,
|
||||
mailbox.email,
|
||||
f"Email cannot be sent to { contact.email } from your alias { alias.email }",
|
||||
f"Email cannot be sent to {contact.email} from your alias {alias.email}",
|
||||
render(
|
||||
"transactional/bounce/bounce-email-reply-phase.txt",
|
||||
user=user,
|
||||
|
|
|
@ -19,7 +19,7 @@ URL=http://localhost:7777
|
|||
NOT_SEND_EMAIL=true
|
||||
|
||||
# domain used to create alias
|
||||
EMAIL_DOMAIN=sl.local
|
||||
EMAIL_DOMAIN=sl.lan
|
||||
|
||||
# Allow SimpleLogin to enforce SPF by using the extra headers from postfix
|
||||
# ENFORCE_SPF=true
|
||||
|
@ -37,18 +37,18 @@ EMAIL_DOMAIN=sl.local
|
|||
# FIRST_ALIAS_DOMAIN = another-domain.com
|
||||
|
||||
# transactional email is sent from this email address
|
||||
SUPPORT_EMAIL=support@sl.local
|
||||
SUPPORT_EMAIL=support@sl.lan
|
||||
SUPPORT_NAME=Son from SimpleLogin
|
||||
|
||||
# To use VERP
|
||||
# prefix must end with + and suffix must start with +
|
||||
# BOUNCE_PREFIX = "bounces+"
|
||||
# BOUNCE_SUFFIX = "+@sl.local"
|
||||
# BOUNCE_SUFFIX = "+@sl.lan"
|
||||
# same as BOUNCE_PREFIX but used for reply phase. Note it doesn't have the plus sign (+) at the end.
|
||||
# BOUNCE_PREFIX_FOR_REPLY_PHASE = "bounce_reply"
|
||||
|
||||
# to receive general stats.
|
||||
# ADMIN_EMAIL=admin@sl.local
|
||||
# ADMIN_EMAIL=admin@sl.lan
|
||||
|
||||
# Max number emails user can generate for free plan
|
||||
# Set to 5 by default
|
||||
|
|
|
@ -5,6 +5,7 @@ The step-to-step guide can be found on https://simplelogin.io/docs/siwsl/app/
|
|||
This example is based on
|
||||
https://requests-oauthlib.readthedocs.io/en/latest/examples/real_world_example.html
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from flask import Flask, request, redirect, session, url_for
|
||||
|
|
|
@ -34,4 +34,4 @@ for i in range(tests):
|
|||
|
||||
end = time.time()
|
||||
time_taken = end - start
|
||||
print(f"Took {time_taken} -> {time_taken/tests} per test")
|
||||
print(f"Took {time_taken} -> {time_taken / tests} per test")
|
||||
|
|
|
@ -26,7 +26,7 @@ dependencies = [
|
|||
"sqlalchemy_utils ~= 0.36.8",
|
||||
"psycopg2-binary ~= 2.9.10",
|
||||
"sentry_sdk ~= 2.20.0",
|
||||
"blinker ~= 1.4",
|
||||
"blinker ~= 1.9.0",
|
||||
"arrow ~= 0.16.0",
|
||||
"Flask-WTF ~= 0.14.3",
|
||||
"boto3 ~= 1.35.37",
|
||||
|
@ -41,7 +41,7 @@ dependencies = [
|
|||
"requests_oauthlib ~= 1.3.0",
|
||||
"pyopenssl ~= 19.1.0",
|
||||
"aiosmtpd ~= 1.2",
|
||||
"dnspython==2.0.0",
|
||||
"dnspython ~= 2.7.0",
|
||||
"coloredlogs ~= 14.0",
|
||||
"pycryptodome ~= 3.9.8",
|
||||
"phpserialize ~= 1.3",
|
||||
|
@ -53,11 +53,14 @@ dependencies = [
|
|||
"google-auth-httplib2 ~= 0.0.4",
|
||||
"python-gnupg ~= 0.4.6",
|
||||
"webauthn ~= 0.4.7",
|
||||
"pyspf ~= 2.0.14",
|
||||
|
||||
# Git dependency until pyspf creates a new release
|
||||
"pyspf @ git+https://github.com/sdgathman/pyspf.git@665a6df079485a9824be0829e7d71088453db7f6",
|
||||
|
||||
"Flask-Limiter == 1.4",
|
||||
"memory_profiler ~= 0.57.0",
|
||||
"gevent ~= 24.11.1",
|
||||
"email-validator ~= 1.1.3",
|
||||
"email-validator ~= 2.2.0",
|
||||
"PGPy == 0.5.4",
|
||||
"coinbase-commerce ~= 1.0.1",
|
||||
"requests ~= 2.25.1",
|
||||
|
@ -103,8 +106,9 @@ exclude = '''
|
|||
'''
|
||||
|
||||
[tool.ruff]
|
||||
ignore-init-module-imports = true
|
||||
exclude = [".venv", "migrations", "app/events/generated"]
|
||||
[tool.ruff.lint]
|
||||
ignore-init-module-imports = true
|
||||
|
||||
[tool.djlint]
|
||||
indent = 2
|
||||
|
|
|
@ -647,8 +647,8 @@ def test_get_alias(flask_client):
|
|||
|
||||
|
||||
def test_is_reverse_alias(flask_client):
|
||||
assert is_reverse_alias("ra+abcd@sl.local")
|
||||
assert is_reverse_alias("reply+abcd@sl.local")
|
||||
assert is_reverse_alias("ra+abcd@sl.lan")
|
||||
assert is_reverse_alias("reply+abcd@sl.lan")
|
||||
|
||||
assert not is_reverse_alias("ra+abcd@test.org")
|
||||
assert not is_reverse_alias("reply+abcd@test.org")
|
||||
|
|
|
@ -17,7 +17,7 @@ def test_with_hostname(flask_client):
|
|||
)
|
||||
|
||||
assert r.status_code == 201
|
||||
assert r.json["alias"].endswith("d1.test")
|
||||
assert r.json["alias"].endswith("d1.lan")
|
||||
|
||||
# make sure alias starts with the suggested prefix
|
||||
assert r.json["alias"].startswith("test")
|
||||
|
|
|
@ -112,14 +112,14 @@ def test_get_alias_infos_with_pagination_v3_no_duplicate_when_empty_contact(
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
)
|
||||
|
||||
Contact.create(
|
||||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact2@example.com",
|
||||
reply_email="rep2@sl.local",
|
||||
reply_email="rep2@sl.lan",
|
||||
)
|
||||
|
||||
alias_infos = get_alias_infos_with_pagination_v3(user)
|
||||
|
|
|
@ -15,7 +15,7 @@ def test_get_setting(flask_client):
|
|||
assert r.json == {
|
||||
"alias_generator": "word",
|
||||
"notification": True,
|
||||
"random_alias_default_domain": "sl.local",
|
||||
"random_alias_default_domain": "sl.lan",
|
||||
"sender_format": "AT",
|
||||
"random_alias_suffix": "word",
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ def test_update_settings_random_alias_default_domain(flask_client):
|
|||
custom_domain = CustomDomain.create(
|
||||
domain=random_domain(), verified=True, user_id=user.id, flush=True
|
||||
)
|
||||
assert user.default_random_alias_domain() == "sl.local"
|
||||
assert user.default_random_alias_domain() == "sl.lan"
|
||||
|
||||
r = flask_client.patch(
|
||||
"/api/setting", json={"random_alias_default_domain": "invalid"}
|
||||
|
@ -55,10 +55,10 @@ def test_update_settings_random_alias_default_domain(flask_client):
|
|||
assert r.status_code == 400
|
||||
|
||||
r = flask_client.patch(
|
||||
"/api/setting", json={"random_alias_default_domain": "d1.test"}
|
||||
"/api/setting", json={"random_alias_default_domain": "d1.lan"}
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert user.default_random_alias_domain() == "d1.test"
|
||||
assert user.default_random_alias_domain() == "d1.lan"
|
||||
|
||||
r = flask_client.patch(
|
||||
"/api/setting", json={"random_alias_default_domain": custom_domain.domain}
|
||||
|
|
|
@ -23,7 +23,7 @@ from init_app import add_sl_domains, add_proton_partner
|
|||
app = create_app()
|
||||
app.config["TESTING"] = True
|
||||
app.config["WTF_CSRF_ENABLED"] = False
|
||||
app.config["SERVER_NAME"] = "sl.test"
|
||||
app.config["SERVER_NAME"] = "sl.lan"
|
||||
|
||||
# enable pg_trgm extension
|
||||
with engine.connect() as conn:
|
||||
|
|
|
@ -28,7 +28,7 @@ def test_rate_limited_forward_phase_for_alias(flask_client):
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
)
|
||||
Session.commit()
|
||||
for _ in range(MAX_ACTIVITY_DURING_MINUTE_PER_ALIAS + 1):
|
||||
|
@ -52,7 +52,7 @@ def test_rate_limited_forward_phase_for_mailbox(flask_client):
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
)
|
||||
Session.commit()
|
||||
for _ in range(MAX_ACTIVITY_DURING_MINUTE_PER_MAILBOX + 1):
|
||||
|
@ -90,7 +90,7 @@ def test_rate_limited_reply_phase(flask_client):
|
|||
alias = Alias.create_new_random(user)
|
||||
Session.commit()
|
||||
|
||||
reply_email = f"reply-{random.random()}@sl.local"
|
||||
reply_email = f"reply-{random.random()}@sl.lan"
|
||||
contact = Contact.create(
|
||||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
|
|
|
@ -37,7 +37,7 @@ def prepare_complaint(
|
|||
contact = Contact.create(
|
||||
user_id=alias.user.id,
|
||||
alias_id=alias.id,
|
||||
website_email=f"contact{random.random()}@mailbox.test",
|
||||
website_email=f"contact{random.random()}@mailbox.lan",
|
||||
reply_email="d@e.f",
|
||||
commit=True,
|
||||
)
|
||||
|
|
|
@ -27,7 +27,7 @@ def generate_unsub_block_contact_data() -> Iterable:
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
commit=True,
|
||||
)
|
||||
|
||||
|
@ -86,7 +86,7 @@ def generate_unsub_disable_alias_data() -> Iterable:
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
commit=True,
|
||||
)
|
||||
|
||||
|
@ -145,7 +145,7 @@ def generate_unsub_preserve_original_data() -> Iterable:
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
commit=True,
|
||||
)
|
||||
|
||||
|
@ -215,7 +215,7 @@ def test_unsub_preserves_sl_unsubscriber():
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
commit=True,
|
||||
)
|
||||
message = Message()
|
||||
|
|
|
@ -49,7 +49,7 @@ def test_old_subject_block_contact():
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email=f"{random()}@sl.local",
|
||||
reply_email=f"{random()}@sl.lan",
|
||||
block_forward=False,
|
||||
commit=True,
|
||||
)
|
||||
|
@ -92,7 +92,7 @@ def test_new_subject_block_contact():
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email=f"{random()}@sl.local",
|
||||
reply_email=f"{random()}@sl.lan",
|
||||
block_forward=False,
|
||||
commit=True,
|
||||
)
|
||||
|
@ -172,7 +172,7 @@ def test_request_disable_contact(flask_client):
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email=f"{random()}@sl.local",
|
||||
reply_email=f"{random()}@sl.lan",
|
||||
block_forward=False,
|
||||
commit=True,
|
||||
)
|
||||
|
|
|
@ -140,13 +140,13 @@ def test_get_metrics():
|
|||
records=[
|
||||
UpcloudRecord(
|
||||
db_role="master",
|
||||
label="test-1 " "(master)",
|
||||
label="test-1 (master)",
|
||||
time="2022-01-21T13:12:00Z",
|
||||
value=3.275132296130991,
|
||||
),
|
||||
UpcloudRecord(
|
||||
db_role="standby",
|
||||
label="test-2 " "(standby)",
|
||||
label="test-2 (standby)",
|
||||
time="2022-01-21T13:12:00Z",
|
||||
value=4.196249043309251,
|
||||
),
|
||||
|
@ -157,13 +157,13 @@ def test_get_metrics():
|
|||
records=[
|
||||
UpcloudRecord(
|
||||
db_role="master",
|
||||
label="test-1 " "(master)",
|
||||
label="test-1 (master)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=5.654416415900109,
|
||||
),
|
||||
UpcloudRecord(
|
||||
db_role="standby",
|
||||
label="test-2 " "(standby)",
|
||||
label="test-2 (standby)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=5.58959125727556,
|
||||
),
|
||||
|
@ -174,13 +174,13 @@ def test_get_metrics():
|
|||
records=[
|
||||
UpcloudRecord(
|
||||
db_role="master",
|
||||
label="test-1 " "(master)",
|
||||
label="test-1 (master)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=0,
|
||||
),
|
||||
UpcloudRecord(
|
||||
db_role="standby",
|
||||
label="test-2 " "(standby)",
|
||||
label="test-2 (standby)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=0,
|
||||
),
|
||||
|
@ -191,13 +191,13 @@ def test_get_metrics():
|
|||
records=[
|
||||
UpcloudRecord(
|
||||
db_role="master",
|
||||
label="test-1 " "(master)",
|
||||
label="test-1 (master)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=4,
|
||||
),
|
||||
UpcloudRecord(
|
||||
db_role="standby",
|
||||
label="test-2 " "(standby)",
|
||||
label="test-2 (standby)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=3,
|
||||
),
|
||||
|
@ -208,13 +208,13 @@ def test_get_metrics():
|
|||
records=[
|
||||
UpcloudRecord(
|
||||
db_role="master",
|
||||
label="test-1 " "(master)",
|
||||
label="test-1 (master)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=0.14,
|
||||
),
|
||||
UpcloudRecord(
|
||||
db_role="standby",
|
||||
label="test-2 " "(standby)",
|
||||
label="test-2 (standby)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=0.09,
|
||||
),
|
||||
|
@ -225,13 +225,13 @@ def test_get_metrics():
|
|||
records=[
|
||||
UpcloudRecord(
|
||||
db_role="master",
|
||||
label="test-1 " "(master)",
|
||||
label="test-1 (master)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=11.488581675749048,
|
||||
),
|
||||
UpcloudRecord(
|
||||
db_role="standby",
|
||||
label="test-2 " "(standby)",
|
||||
label="test-2 (standby)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=12.272260458006759,
|
||||
),
|
||||
|
@ -242,13 +242,13 @@ def test_get_metrics():
|
|||
records=[
|
||||
UpcloudRecord(
|
||||
db_role="master",
|
||||
label="test-1 " "(master)",
|
||||
label="test-1 (master)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=466,
|
||||
),
|
||||
UpcloudRecord(
|
||||
db_role="standby",
|
||||
label="test-2 " "(standby)",
|
||||
label="test-2 (standby)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=458,
|
||||
),
|
||||
|
@ -259,13 +259,13 @@ def test_get_metrics():
|
|||
records=[
|
||||
UpcloudRecord(
|
||||
db_role="master",
|
||||
label="test-1 " "(master)",
|
||||
label="test-1 (master)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=694,
|
||||
),
|
||||
UpcloudRecord(
|
||||
db_role="standby",
|
||||
label="test-2 " "(standby)",
|
||||
label="test-2 (standby)",
|
||||
time="2022-01-21T13:11:30Z",
|
||||
value=573,
|
||||
),
|
||||
|
|
|
@ -5,9 +5,9 @@ LOCAL_FILE_UPLOAD=1
|
|||
# Email related settings
|
||||
# Only print email content, not sending it
|
||||
NOT_SEND_EMAIL=true
|
||||
EMAIL_DOMAIN=sl.local
|
||||
OTHER_ALIAS_DOMAINS=["d1.test", "d2.test", "sl.local"]
|
||||
SUPPORT_EMAIL=support@sl.local
|
||||
EMAIL_DOMAIN=sl.lan
|
||||
OTHER_ALIAS_DOMAINS=["d1.lan", "d2.lan", "sl.lan"]
|
||||
SUPPORT_EMAIL=support@sl.lan
|
||||
ADMIN_EMAIL=to_fill
|
||||
# Max number emails user can generate for free plan
|
||||
MAX_NB_EMAIL_FREE_PLAN=3
|
||||
|
|
|
@ -214,7 +214,7 @@ def test_avoid_add_to_header_already_present_in_cc():
|
|||
def test_email_sent_to_noreply(flask_client):
|
||||
msg = EmailMessage()
|
||||
envelope = Envelope()
|
||||
envelope.mail_from = "from@domain.test"
|
||||
envelope.mail_from = "from@domain.lan"
|
||||
envelope.rcpt_tos = [config.NOREPLY]
|
||||
result = email_handler.handle(envelope, msg)
|
||||
assert result == status.E200
|
||||
|
@ -223,10 +223,10 @@ def test_email_sent_to_noreply(flask_client):
|
|||
def test_email_sent_to_noreplies(flask_client):
|
||||
msg = EmailMessage()
|
||||
envelope = Envelope()
|
||||
envelope.mail_from = "from@domain.test"
|
||||
config.NOREPLIES = ["other-no-reply@sl.test"]
|
||||
envelope.mail_from = "from@domain.lan"
|
||||
config.NOREPLIES = ["other-no-reply@sl.lan"]
|
||||
|
||||
envelope.rcpt_tos = ["other-no-reply@sl.test"]
|
||||
envelope.rcpt_tos = ["other-no-reply@sl.lan"]
|
||||
result = email_handler.handle(envelope, msg)
|
||||
assert result == status.E200
|
||||
|
||||
|
|
|
@ -78,17 +78,17 @@ def test_get_email_domain_part():
|
|||
|
||||
def test_email_belongs_to_alias_domains():
|
||||
# default alias domain
|
||||
assert can_create_directory_for_address("ab@sl.local")
|
||||
assert not can_create_directory_for_address("ab@not-exist.local")
|
||||
assert can_create_directory_for_address("ab@sl.lan")
|
||||
assert not can_create_directory_for_address("ab@not-exist.lan")
|
||||
|
||||
assert can_create_directory_for_address("hey@d1.test")
|
||||
assert not can_create_directory_for_address("hey@d3.test")
|
||||
assert can_create_directory_for_address("hey@d1.lan")
|
||||
assert not can_create_directory_for_address("hey@d3.lan")
|
||||
|
||||
|
||||
def test_can_be_used_as_personal_email(flask_client):
|
||||
# default alias domain
|
||||
assert not email_can_be_used_as_mailbox("ab@sl.local")
|
||||
assert not email_can_be_used_as_mailbox("hey@d1.test")
|
||||
assert not email_can_be_used_as_mailbox("ab@sl.lan")
|
||||
assert not email_can_be_used_as_mailbox("hey@d1.lan")
|
||||
|
||||
# custom domain as SL domain
|
||||
domain = random_domain()
|
||||
|
@ -115,7 +115,7 @@ def test_can_be_used_as_personal_email(flask_client):
|
|||
|
||||
|
||||
def test_disabled_user_prevents_email_from_being_used_as_mailbox():
|
||||
email = f"user_{random_token(10)}@mailbox.test"
|
||||
email = f"user_{random_token(10)}@mailbox.lan"
|
||||
assert email_can_be_used_as_mailbox(email)
|
||||
user = create_new_user(email)
|
||||
user.disabled = True
|
||||
|
@ -124,7 +124,7 @@ def test_disabled_user_prevents_email_from_being_used_as_mailbox():
|
|||
|
||||
|
||||
def test_disabled_user_with_secondary_mailbox_prevents_email_from_being_used_as_mailbox():
|
||||
email = f"user_{random_token(10)}@mailbox.test"
|
||||
email = f"user_{random_token(10)}@mailbox.lan"
|
||||
assert email_can_be_used_as_mailbox(email)
|
||||
user = create_new_user()
|
||||
Mailbox.create(user_id=user.id, email=email)
|
||||
|
@ -592,8 +592,8 @@ def test_generate_reply_email_include_sender_in_reverse_alias(flask_client):
|
|||
|
||||
|
||||
def test_normalize_reply_email(flask_client):
|
||||
assert normalize_reply_email("re+abcd@sl.local") == "re+abcd@sl.local"
|
||||
assert normalize_reply_email('re+"ab cd"@sl.local') == "re+_ab_cd_@sl.local"
|
||||
assert normalize_reply_email("re+abcd@sl.lan") == "re+abcd@sl.lan"
|
||||
assert normalize_reply_email('re+"ab cd"@sl.lan') == "re+_ab_cd_@sl.lan"
|
||||
|
||||
|
||||
def test_get_encoding():
|
||||
|
@ -669,7 +669,7 @@ def test_should_disable(flask_client):
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
commit=True,
|
||||
)
|
||||
for _ in range(20):
|
||||
|
@ -702,7 +702,7 @@ def test_should_disable_bounces_every_day(flask_client):
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
commit=True,
|
||||
)
|
||||
for i in range(9):
|
||||
|
@ -730,7 +730,7 @@ def test_should_disable_bounces_account(flask_client):
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
commit=True,
|
||||
)
|
||||
|
||||
|
@ -758,7 +758,7 @@ def test_should_disable_bounce_consecutive_days(flask_client):
|
|||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email="contact@example.com",
|
||||
reply_email="rep@sl.local",
|
||||
reply_email="rep@sl.lan",
|
||||
commit=True,
|
||||
)
|
||||
|
||||
|
|
|
@ -36,7 +36,9 @@ def test_generate_email(flask_client):
|
|||
def test_profile_picture_url(flask_client):
|
||||
user = create_new_user()
|
||||
|
||||
assert user.profile_picture_url() == "http://sl.test/static/default-avatar.png"
|
||||
assert (
|
||||
user.profile_picture_url() == f"http://{EMAIL_DOMAIN}/static/default-avatar.png"
|
||||
)
|
||||
|
||||
|
||||
def test_suggested_emails_for_user_who_cannot_create_new_alias(flask_client):
|
||||
|
@ -303,7 +305,7 @@ def test_create_contact_for_noreply(flask_client):
|
|||
Contact.create(
|
||||
user_id=user.id,
|
||||
alias_id=alias.id,
|
||||
website_email=f"{random.random()}@contact.test",
|
||||
website_email=f"{random.random()}@contact.lan",
|
||||
reply_email=NOREPLY,
|
||||
commit=True,
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import arrow
|
||||
|
||||
from app.config import EMAIL_DOMAIN
|
||||
from app.db import Session
|
||||
from app.models import CoinbaseSubscription
|
||||
from app.payments.coinbase import handle_coinbase_event
|
||||
|
@ -11,7 +12,7 @@ def test_redirect_login_page(flask_client):
|
|||
|
||||
rv = flask_client.get("/")
|
||||
assert rv.status_code == 302
|
||||
assert rv.location == "http://sl.test/auth/login"
|
||||
assert rv.location == f"http://{EMAIL_DOMAIN}/auth/login"
|
||||
|
||||
|
||||
def test_coinbase_webhook(flask_client):
|
||||
|
|
|
@ -16,7 +16,7 @@ from app.utils import random_string
|
|||
|
||||
def create_new_user(email: Optional[str] = None, name: Optional[str] = None) -> User:
|
||||
if not email:
|
||||
email = f"user_{random_token(10)}@mailbox.test"
|
||||
email = f"user_{random_token(10)}@mailbox.lan"
|
||||
if not name:
|
||||
name = "Test User"
|
||||
# new user has a different email address
|
||||
|
@ -60,7 +60,7 @@ def login(flask_client, user: Optional[User] = None) -> User:
|
|||
|
||||
|
||||
def random_domain() -> str:
|
||||
return random_token() + ".test"
|
||||
return random_token() + ".lan"
|
||||
|
||||
|
||||
def random_token(length: int = 10) -> str:
|
||||
|
|
51
uv.lock
generated
51
uv.lock
generated
|
@ -179,6 +179,12 @@ wheels = [
|
|||
{ url = "https://files.pythonhosted.org/packages/14/df/479736ae1ef59842f512548bacefad1abed705e400212acba43f9b0fa556/attrs-20.2.0-py2.py3-none-any.whl", hash = "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc", size = 48140 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "authres"
|
||||
version = "1.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6a/29/e28209b5d3d56c102845cca5a4a3abaf2724f79e83476a52b94d775ecce6/authres-1.2.0.tar.gz", hash = "sha256:93d1b995ad7ce21e62db649f361048125dd6022563a0ae8a23909465f1fd25b7", size = 23226 }
|
||||
|
||||
[[package]]
|
||||
name = "backcall"
|
||||
version = "0.2.0"
|
||||
|
@ -227,9 +233,12 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "blinker"
|
||||
version = "1.4"
|
||||
version = "1.9.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1b/51/e2a9f3b757eb802f61dc1f2b09c8c99f6eb01cf06416c0671253536517b6/blinker-1.4.tar.gz", hash = "sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6", size = 111476 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "boto3"
|
||||
|
@ -497,11 +506,11 @@ sdist = { url = "https://files.pythonhosted.org/packages/b5/33/9c60f3a34d4d7237e
|
|||
|
||||
[[package]]
|
||||
name = "dnspython"
|
||||
version = "2.0.0"
|
||||
version = "2.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/67/d0/639a9b5273103a18c5c68a7a9fc02b01cffa3403e72d553acec444f85d5b/dnspython-2.0.0.zip", hash = "sha256:044af09374469c3a39eeea1a146e8cac27daec951f1f1f157b1962fc7cb9d1b7", size = 324706 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b5/4a/263763cb2ba3816dd94b08ad3a33d5fdae34ecb856678773cc40a3605829/dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1", size = 345197 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/90/49/cb426577c28ca3e35332815b795a99e467523843fc83cc85ca0d6be2515a/dnspython-2.0.0-py3-none-any.whl", hash = "sha256:40bb3c24b9d4ec12500f0124288a65df232a3aa749bb0c39734b782873a2544d", size = 208262 },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -515,15 +524,15 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "email-validator"
|
||||
version = "1.1.3"
|
||||
version = "2.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "dnspython" },
|
||||
{ name = "idna" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/25/f3/017ab4619ee83e79fc1c9572ac601671cf9cfb33a0523021b46851b4d9a4/email_validator-1.1.3.tar.gz", hash = "sha256:aa237a65f6f4da067119b7df3f13e89c25c051327b2b5b66dc075f33d62480d7", size = 24484 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/e4/e01e92092fdac940f10fa4c8ac3481bf70fc74023a76f5c72020c9445e68/email_validator-1.1.3-py2.py3-none-any.whl", hash = "sha256:5675c8ceb7106a37e40e2698a57c056756bf3f272cfa8682a4f87ebd95d8440b", size = 18318 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1487,6 +1496,15 @@ wheels = [
|
|||
{ url = "https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378", size = 98708 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "py3dns"
|
||||
version = "4.0.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/76/67/d7e745a5248bd7ecf2b76d3a1c8280255cbbdcb21174b171cf3c87740836/py3dns-4.0.2.tar.gz", hash = "sha256:98652e80ecec143c60f78f0e6b341631ca9a7560edd8dddfc864c02902618a39", size = 33982 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/43/1ff28f5302a0f423d4210cacc1f12fb416b6ba1f4c7107e020d264acb625/py3dns-4.0.2-py3-none-any.whl", hash = "sha256:36bffe62b59a72cfa09c03f0bd3473e0126f20ee4285d14c07415dbf6f5fd571", size = 29589 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyasn1"
|
||||
version = "0.4.8"
|
||||
|
@ -1604,9 +1622,12 @@ sdist = { url = "https://files.pythonhosted.org/packages/bc/7c/d724ef1ec3ab2125f
|
|||
|
||||
[[package]]
|
||||
name = "pyspf"
|
||||
version = "2.0.14"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d4/dc/5b3838ff90474e21fe0914920c53430f73402e07d6598ea228e61b74963e/pyspf-2.0.14.tar.gz", hash = "sha256:57a7ef01bda090173aafb6af0106251686ed73f03db4e911fcd34c57fc347186", size = 69446 }
|
||||
version = "2.1.0"
|
||||
source = { git = "https://github.com/sdgathman/pyspf.git?rev=665a6df079485a9824be0829e7d71088453db7f6#665a6df079485a9824be0829e7d71088453db7f6" }
|
||||
dependencies = [
|
||||
{ name = "authres" },
|
||||
{ name = "py3dns" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
|
@ -1960,15 +1981,15 @@ requires-dist = [
|
|||
{ name = "alembic", specifier = "~=1.4.3" },
|
||||
{ name = "arrow", specifier = "~=0.16.0" },
|
||||
{ name = "bcrypt", specifier = "~=3.2.0" },
|
||||
{ name = "blinker", specifier = "~=1.4" },
|
||||
{ name = "blinker", specifier = "~=1.9.0" },
|
||||
{ name = "boto3", specifier = "~=1.35.37" },
|
||||
{ name = "coinbase-commerce", specifier = "~=1.0.1" },
|
||||
{ name = "coloredlogs", specifier = "~=14.0" },
|
||||
{ name = "cryptography", specifier = "~=37.0.1" },
|
||||
{ name = "deprecated", specifier = "~=1.2.13" },
|
||||
{ name = "dkimpy", specifier = "~=1.0.5" },
|
||||
{ name = "dnspython", specifier = "==2.0.0" },
|
||||
{ name = "email-validator", specifier = "~=1.1.3" },
|
||||
{ name = "dnspython", specifier = "~=2.7.0" },
|
||||
{ name = "email-validator", specifier = "~=2.2.0" },
|
||||
{ name = "facebook-sdk", specifier = "~=3.1.0" },
|
||||
{ name = "flanker", specifier = "~=0.9.11" },
|
||||
{ name = "flask", specifier = "~=1.1.2" },
|
||||
|
@ -2000,7 +2021,7 @@ requires-dist = [
|
|||
{ name = "pyopenssl", specifier = "~=19.1.0" },
|
||||
{ name = "pyotp", specifier = "~=2.4.0" },
|
||||
{ name = "pyre2", specifier = "~=0.3.6" },
|
||||
{ name = "pyspf", specifier = "~=2.0.14" },
|
||||
{ name = "pyspf", git = "https://github.com/sdgathman/pyspf.git?rev=665a6df079485a9824be0829e7d71088453db7f6#665a6df079485a9824be0829e7d71088453db7f6" },
|
||||
{ name = "python-dotenv", specifier = "~=0.14.0" },
|
||||
{ name = "python-gnupg", specifier = "~=0.4.6" },
|
||||
{ name = "redis", specifier = "==4.6.0" },
|
||||
|
|
Loading…
Add table
Reference in a new issue