User session tracking #93587
No reviewers
Labels
No Label
legacy project
Infrastructure: blender.org
legacy project
Infrastructure: Websites
Priority
High
Priority
Low
Priority
Normal
Status
Archived
Status::Confirmed
Status
Duplicate
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Report
Type
To Do
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: infrastructure/blender-id#93587
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "user-session"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Motivation
A user needs to know how their account is being accessed/used.
At the very minimum, we need to display information about recent sign-ins and active sessions.
This PR adds:
Implementation
Builtin django sessions are lacking some essential features:
This PR adds a cross table
bid_main_user_session
that links to bothdjango_session
andbid_main_user
tables, and also stores info about sign-in timestamp, last activity timestamp, IP and User-Agent.A
UserSession
object is updated (or created, for new sessions and for active sessions existing before the rollout) on every authenticated request to update thelast_active_at
field.This is done in a new
user_session_middleware
.A further improvement (intentionally excluded from the PR): use geoip2 to display an IP-based location in the Active Sessions listing and the email.
WIP: User session trackingto User session tracking@ -260,0 +277,4 @@
recipient_list=[email],
fail_silently=False,
)
except (smtplib.SMTPException, OSError):
might be better to make this a background task instead of wrapping into except.
@ -649,0 +689,4 @@
def device(self):
if self.user_agent:
return user_agents.parse(self.user_agent)
else:
superfluous else
@ -38,1 +38,3 @@
if user.has_confirmed_email:
try:
email.send_new_user_session(user_session)
should be a call of a task
@ -432,0 +448,4 @@
class TerminateSessionView(LoginRequiredMixin, View):
def post(self, request, *args, **kwargs):
if user_session := self.request.user.sessions.filter(pk=kwargs.get('pk', 0)).first():
getting the
pk
(pk = kwargs['pk']
: it's fine to expect it to be present at this point) and filtering the session on the separate line would make this more readable.LGTM