mirror of
https://github.com/simple-login/app.git
synced 2024-09-28 20:51:29 +02:00
Merge pull request #884 from simple-login/ac-login-metric
Send newrelic events on login and register
This commit is contained in:
commit
0a9c103ad1
@ -19,6 +19,7 @@ from app.email_utils import (
|
|||||||
send_email,
|
send_email,
|
||||||
render,
|
render,
|
||||||
)
|
)
|
||||||
|
from app.events.auth_event import LoginEvent, RegisterEvent
|
||||||
from app.extensions import limiter
|
from app.extensions import limiter
|
||||||
from app.log import LOG
|
from app.log import LOG
|
||||||
from app.models import User, ApiKey, SocialAuth, AccountActivation
|
from app.models import User, ApiKey, SocialAuth, AccountActivation
|
||||||
@ -55,16 +56,20 @@ def auth_login():
|
|||||||
user = User.filter_by(email=email).first()
|
user = User.filter_by(email=email).first()
|
||||||
|
|
||||||
if not user or not user.check_password(password):
|
if not user or not user.check_password(password):
|
||||||
|
LoginEvent(LoginEvent.ActionType.failed, LoginEvent.Source.api).send()
|
||||||
return jsonify(error="Email or password incorrect"), 400
|
return jsonify(error="Email or password incorrect"), 400
|
||||||
elif user.disabled:
|
elif user.disabled:
|
||||||
|
LoginEvent(LoginEvent.ActionType.disabled_login, LoginEvent.Source.api).send()
|
||||||
return jsonify(error="Account disabled"), 400
|
return jsonify(error="Account disabled"), 400
|
||||||
elif not user.activated:
|
elif not user.activated:
|
||||||
|
LoginEvent(LoginEvent.ActionType.not_activated, LoginEvent.Source.api).send()
|
||||||
return jsonify(error="Account not activated"), 422
|
return jsonify(error="Account not activated"), 422
|
||||||
elif user.fido_enabled():
|
elif user.fido_enabled():
|
||||||
# allow user who has TOTP enabled to continue using the mobile app
|
# allow user who has TOTP enabled to continue using the mobile app
|
||||||
if not user.enable_otp:
|
if not user.enable_otp:
|
||||||
return jsonify(error="Currently we don't support FIDO on mobile yet"), 403
|
return jsonify(error="Currently we don't support FIDO on mobile yet"), 403
|
||||||
|
|
||||||
|
LoginEvent(LoginEvent.ActionType.success, LoginEvent.Source.api).send()
|
||||||
return jsonify(**auth_payload(user, device)), 200
|
return jsonify(**auth_payload(user, device)), 200
|
||||||
|
|
||||||
|
|
||||||
@ -88,14 +93,20 @@ def auth_register():
|
|||||||
password = data.get("password")
|
password = data.get("password")
|
||||||
|
|
||||||
if DISABLE_REGISTRATION:
|
if DISABLE_REGISTRATION:
|
||||||
|
RegisterEvent(RegisterEvent.ActionType.failed, RegisterEvent.Source.api).send()
|
||||||
return jsonify(error="registration is closed"), 400
|
return jsonify(error="registration is closed"), 400
|
||||||
if not email_can_be_used_as_mailbox(email) or personal_email_already_used(email):
|
if not email_can_be_used_as_mailbox(email) or personal_email_already_used(email):
|
||||||
|
RegisterEvent(
|
||||||
|
RegisterEvent.ActionType.invalid_email, RegisterEvent.Source.api
|
||||||
|
).send()
|
||||||
return jsonify(error=f"cannot use {email} as personal inbox"), 400
|
return jsonify(error=f"cannot use {email} as personal inbox"), 400
|
||||||
|
|
||||||
if not password or len(password) < 8:
|
if not password or len(password) < 8:
|
||||||
|
RegisterEvent(RegisterEvent.ActionType.failed, RegisterEvent.Source.api).send()
|
||||||
return jsonify(error="password too short"), 400
|
return jsonify(error="password too short"), 400
|
||||||
|
|
||||||
if len(password) > 100:
|
if len(password) > 100:
|
||||||
|
RegisterEvent(RegisterEvent.ActionType.failed, RegisterEvent.Source.api).send()
|
||||||
return jsonify(error="password too long"), 400
|
return jsonify(error="password too long"), 400
|
||||||
|
|
||||||
LOG.d("create user %s", email)
|
LOG.d("create user %s", email)
|
||||||
@ -114,6 +125,7 @@ def auth_register():
|
|||||||
render("transactional/code-activation.html", code=code),
|
render("transactional/code-activation.html", code=code),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
RegisterEvent(RegisterEvent.ActionType.success, RegisterEvent.Source.api).send()
|
||||||
return jsonify(msg="User needs to confirm their account"), 200
|
return jsonify(msg="User needs to confirm their account"), 200
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ from wtforms import StringField, validators
|
|||||||
|
|
||||||
from app.auth.base import auth_bp
|
from app.auth.base import auth_bp
|
||||||
from app.auth.views.login_utils import after_login
|
from app.auth.views.login_utils import after_login
|
||||||
|
from app.events.auth_event import LoginEvent
|
||||||
from app.extensions import limiter
|
from app.extensions import limiter
|
||||||
from app.log import LOG
|
from app.log import LOG
|
||||||
from app.models import User
|
from app.models import User
|
||||||
@ -43,18 +44,22 @@ def login():
|
|||||||
g.deduct_limit = True
|
g.deduct_limit = True
|
||||||
form.password.data = None
|
form.password.data = None
|
||||||
flash("Email or password incorrect", "error")
|
flash("Email or password incorrect", "error")
|
||||||
|
LoginEvent(LoginEvent.ActionType.failed).send()
|
||||||
elif user.disabled:
|
elif user.disabled:
|
||||||
flash(
|
flash(
|
||||||
"Your account is disabled. Please contact SimpleLogin team to re-enable your account.",
|
"Your account is disabled. Please contact SimpleLogin team to re-enable your account.",
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
|
LoginEvent(LoginEvent.ActionType.disabled_login).send()
|
||||||
elif not user.activated:
|
elif not user.activated:
|
||||||
show_resend_activation = True
|
show_resend_activation = True
|
||||||
flash(
|
flash(
|
||||||
"Please check your inbox for the activation email. You can also have this email re-sent",
|
"Please check your inbox for the activation email. You can also have this email re-sent",
|
||||||
"error",
|
"error",
|
||||||
)
|
)
|
||||||
|
LoginEvent(LoginEvent.ActionType.not_activated).send()
|
||||||
else:
|
else:
|
||||||
|
LoginEvent(LoginEvent.ActionType.success).send()
|
||||||
return after_login(user, next_url)
|
return after_login(user, next_url)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
|
@ -13,6 +13,7 @@ from app.email_utils import (
|
|||||||
email_can_be_used_as_mailbox,
|
email_can_be_used_as_mailbox,
|
||||||
personal_email_already_used,
|
personal_email_already_used,
|
||||||
)
|
)
|
||||||
|
from app.events.auth_event import RegisterEvent
|
||||||
from app.log import LOG
|
from app.log import LOG
|
||||||
from app.models import User, ActivationCode
|
from app.models import User, ActivationCode
|
||||||
from app.utils import random_string, encode_url, sanitize_email
|
from app.utils import random_string, encode_url, sanitize_email
|
||||||
@ -60,6 +61,7 @@ def register():
|
|||||||
hcaptcha_res,
|
hcaptcha_res,
|
||||||
)
|
)
|
||||||
flash("Wrong Captcha", "error")
|
flash("Wrong Captcha", "error")
|
||||||
|
RegisterEvent(RegisterEvent.ActionType.catpcha_failed).send()
|
||||||
return render_template(
|
return render_template(
|
||||||
"auth/register.html",
|
"auth/register.html",
|
||||||
form=form,
|
form=form,
|
||||||
@ -70,10 +72,11 @@ def register():
|
|||||||
email = sanitize_email(form.email.data)
|
email = sanitize_email(form.email.data)
|
||||||
if not email_can_be_used_as_mailbox(email):
|
if not email_can_be_used_as_mailbox(email):
|
||||||
flash("You cannot use this email address as your personal inbox.", "error")
|
flash("You cannot use this email address as your personal inbox.", "error")
|
||||||
|
RegisterEvent(RegisterEvent.ActionType.email_in_use).send()
|
||||||
else:
|
else:
|
||||||
if personal_email_already_used(email):
|
if personal_email_already_used(email):
|
||||||
flash(f"Email {email} already used", "error")
|
flash(f"Email {email} already used", "error")
|
||||||
|
RegisterEvent(RegisterEvent.ActionType.email_in_use).send()
|
||||||
else:
|
else:
|
||||||
LOG.d("create user %s", email)
|
LOG.d("create user %s", email)
|
||||||
user = User.create(
|
user = User.create(
|
||||||
@ -86,8 +89,10 @@ def register():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
send_activation_email(user, next_url)
|
send_activation_email(user, next_url)
|
||||||
|
RegisterEvent(RegisterEvent.ActionType.success).send()
|
||||||
except Exception:
|
except Exception:
|
||||||
flash("Invalid email, are you sure the email is correct?", "error")
|
flash("Invalid email, are you sure the email is correct?", "error")
|
||||||
|
RegisterEvent(RegisterEvent.ActionType.invalid_email).send()
|
||||||
return redirect(url_for("auth.register"))
|
return redirect(url_for("auth.register"))
|
||||||
|
|
||||||
return render_template("auth/register_waiting_activation.html")
|
return render_template("auth/register_waiting_activation.html")
|
||||||
|
46
app/events/auth_event.py
Normal file
46
app/events/auth_event.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import newrelic
|
||||||
|
|
||||||
|
from app.models import EnumE
|
||||||
|
|
||||||
|
|
||||||
|
class LoginEvent:
|
||||||
|
class ActionType(EnumE):
|
||||||
|
success = 0
|
||||||
|
failed = 1
|
||||||
|
disabled_login = 2
|
||||||
|
not_activated = 3
|
||||||
|
|
||||||
|
class Source(EnumE):
|
||||||
|
web = 0
|
||||||
|
api = 1
|
||||||
|
|
||||||
|
def __init__(self, action: ActionType, source: Source = Source.web):
|
||||||
|
self.action = action
|
||||||
|
self.source = source
|
||||||
|
|
||||||
|
def send(self):
|
||||||
|
newrelic.agent.record_custom_event(
|
||||||
|
"LoginEvent", {"action": self.action, "source": self.source}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class RegisterEvent:
|
||||||
|
class ActionType(EnumE):
|
||||||
|
success = 0
|
||||||
|
failed = 1
|
||||||
|
catpcha_failed = 2
|
||||||
|
email_in_use = 3
|
||||||
|
invalid_email = 4
|
||||||
|
|
||||||
|
class Source(EnumE):
|
||||||
|
web = 0
|
||||||
|
api = 1
|
||||||
|
|
||||||
|
def __init__(self, action: ActionType, source: Source = Source.web):
|
||||||
|
self.action = action
|
||||||
|
self.source = source
|
||||||
|
|
||||||
|
def send(self):
|
||||||
|
newrelic.agent.record_custom_event(
|
||||||
|
"RegisterEvent", {"action": self.action, "source": self.source}
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user