Fix server error upon processing user with revoked github token (#783)

* Don't use an auth token to fetch details if we don't have to

* Try to use the user token as much as possible

* Force users with bad tokens to log in again

* Fix invalid token session deletion

* GitHubUser.details shouldn't make network requests

---------

Co-authored-by: ConorBobbleHat <c.github@firstpartners.net>
This commit is contained in:
ConorB
2023-07-03 13:50:43 +01:00
committed by GitHub
parent fb34dbf4cb
commit aded2ee902

View File

@@ -8,11 +8,12 @@ import requests
from django.conf import settings
from django.contrib.auth import login
from django.contrib.auth.models import User
from django.contrib.sessions.models import Session
from django.core.cache import cache
from django.db import models, transaction
from django.dispatch import receiver
from django.utils.timezone import now
from github import Github
from github import Github, BadCredentialsException
from github.NamedUser import NamedUser
from github.Repository import Repository
from rest_framework import status
@@ -65,13 +66,31 @@ class GitHubUser(models.Model):
if cached:
return cached
details = Github(self.access_token).get_user_by_id(self.github_id)
try:
details = Github(self.access_token).get_user_by_id(self.github_id)
except BadCredentialsException:
# Uh oh - the user we're getting details for has an invalid token
# Revoke their session to force them to log in again ...
all_sessions = Session.objects.filter(expire_date__gte=now())
user_sessions = [
i.pk
for i in all_sessions
if i.get_decoded().get("_auth_user_id") == str(self.user.id)
]
Session.objects.filter(pk__in=user_sessions).delete()
# ... and fallback to using the github api unauthenticated
# This *does* have a much stricter rate limit of 60 requests per minute,
# which is why we tried using an auth token first
details = Github().get_user_by_id(self.github_id)
cache.set(cache_key, details, API_CACHE_TIMEOUT)
return details
def __str__(self) -> str:
return "@" + self.details().login
return "@" + self.user.username
@staticmethod
@transaction.atomic