Send notifications about login with new client or country (#4032)

* Send notifications about login with new client or country

* Rebase migration

* Remove immediately

* Fix isort

* Text update
This commit is contained in:
Raphael Michel
2024-04-03 11:19:20 +02:00
committed by GitHub
parent 48493c517b
commit a3139944f6
9 changed files with 205 additions and 1 deletions

View File

@@ -26,9 +26,15 @@ import time
from django.conf import settings
from django.contrib.gis.geoip2 import GeoIP2
from django.core.cache import cache
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_countries.fields import Country
from geoip2.errors import AddressNotFoundError
from pretix.base.i18n import language
from pretix.base.services.mail import SendMailException, mail
from pretix.helpers.http import get_client_ip
from pretix.helpers.urls import build_absolute_uri
logger = logging.getLogger(__name__)
@@ -119,3 +125,55 @@ def assert_session_valid(request):
raise Session2FASetupRequired()
return True
def handle_login_source(user, request):
from ua_parser import user_agent_parser
parsed_string = user_agent_parser.Parse(request.headers.get("User-Agent", ""))
country = None
if settings.HAS_GEOIP:
client_ip = get_client_ip(request)
hashed_client_ip = hashlib.sha256(client_ip.encode()).hexdigest()
country = cache.get_or_set(f'geoip_country_{hashed_client_ip}', lambda: _get_country(request), timeout=300)
if country == "None":
country = None
src, created = user.known_login_sources.update_or_create(
agent_type=parsed_string.get("user_agent").get("family"),
os_type=parsed_string.get("os").get("family"),
device_type=parsed_string.get("device").get("family"),
country=country,
defaults={
"last_seen": now(),
}
)
if created:
user.log_action('pretix.control.auth.user.new_source', user=user, data={
"agent_type": src.agent_type,
"os_type": src.os_type,
"device_type": src.device_type,
"country": str(src.country) if src.country else "?",
})
if user.known_login_sources.count() > 1:
# Do not send on first login or first login after introduction of this feature:
try:
with language(user.locale):
mail(
user.email,
_('Login from new source detected'),
'pretixcontrol/email/login_notice.txt',
{
'source': src,
'country': Country(str(country)).name if country else _('Unknown country'),
'instance': settings.PRETIX_INSTANCE_NAME,
'url': build_absolute_uri('control:user.settings')
},
event=None,
user=user,
locale=user.locale
)
except SendMailException:
pass # Not much we can do