This commit is contained in:
Eugene Pankov
2021-07-16 20:25:00 +02:00
parent 6d4ae3b4c3
commit 2c95a15609
18 changed files with 379 additions and 137 deletions

View File

@@ -5,8 +5,8 @@ from django.conf import settings
from django.contrib.auth import logout
from dataclasses import dataclass
from pathlib import Path
from rest_framework import fields
from rest_framework.exceptions import PermissionDenied, NotFound
from rest_framework import fields, status
from rest_framework.exceptions import APIException, PermissionDenied, NotFound
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, UpdateModelMixin
@@ -145,6 +145,12 @@ class InstanceInfoViewSet(RetrieveModelMixin, GenericViewSet):
}
class NoGatewaysError(APIException):
status_code = status.HTTP_503_SERVICE_UNAVAILABLE
default_detail ='No connection gateways available.'
default_code = 'no_gateways'
class ChooseGatewayViewSet(RetrieveModelMixin, GenericViewSet):
queryset = Gateway.objects.filter(enabled=True)
serializer_class = GatewaySerializer
@@ -158,12 +164,19 @@ class ChooseGatewayViewSet(RetrieveModelMixin, GenericViewSet):
def get_object(self):
gateways = list(self.queryset)
random.shuffle(gateways)
if not len(gateways):
raise NotFound()
gw = random.choice(gateways)
loop = asyncio.new_event_loop()
gw.auth_token = loop.run_until_complete(self._authorize_client(gw))
loop.close()
try:
for gw in gateways:
try:
gw.auth_token = loop.run_until_complete(self._authorize_client(gw))
except ConnectionError:
continue
return gw
return gw
raise NoGatewaysError()
finally:
loop.close()

View File

@@ -33,7 +33,10 @@ class GatewayConnection:
async def connect(self):
self.context = websockets.connect(self.url, ssl=GatewayConnection._ssl_context)
self.socket = await self.context.__aenter__()
try:
self.socket = await self.context.__aenter__()
except OSError:
raise ConnectionError()
async def send(self, data):
await self.socket.send(data)
@@ -69,7 +72,10 @@ class GatewayAdminConnection:
async def connect(self):
self.context = websockets.connect(self.url, ssl=GatewayAdminConnection._ssl_context)
self.socket = await self.context.__aenter__()
try:
self.socket = await self.context.__aenter__()
except OSError:
raise ConnectionError()
async def authorize_client(self) -> str:
token = secrets.token_hex(32)

20
tabby/middleware.py Normal file
View File

@@ -0,0 +1,20 @@
import logging
from django.conf import settings
from pyga.requests import Tracker, Page, Session, Visitor
class GAMiddleware:
def __init__(self, get_response):
self.get_response = get_response
if settings.GA_ID:
self.tracker = Tracker(settings.GA_ID, settings.GA_DOMAIN)
def __call__(self, request):
response = self.get_response(request)
if settings.GA_ID and request.path in ['/', '/app']:
try:
self.tracker.track_pageview(Page(request.path), Session(), Visitor())
except Exception:
logging.exception()
return response

View File

@@ -46,6 +46,7 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'tabby.middleware.GAMiddleware',
]
ROOT_URLCONF = 'tabby.urls'
@@ -184,6 +185,8 @@ for key in [
'GITHUB_SPONSORS_MIN_PAYMENT',
'GITHUB_TOKEN',
'ENABLE_LOGIN',
'GA_ID',
'GA_DOMAIN',
]:
globals()[key] = os.getenv(key)
@@ -197,7 +200,7 @@ for key in [
for key in [
'ENABLE_LOGIN',
]:
globals()[key] = int(globals()[key]) if globals()[key] else None
globals()[key] = bool(globals()[key]) if globals()[key] else None
for key in [