-
Notifications
You must be signed in to change notification settings - Fork 15
/
views.py
94 lines (74 loc) · 3.44 KB
/
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from django.http.response import HttpResponse, HttpResponseForbidden, JsonResponse
from django.views.generic import View
from requests.exceptions import ConnectionError, HTTPError
from .exceptions import ApiException
import logging
from logging import getLevelName
import json
logger = logging.getLogger(__name__)
class BaseApiView(View):
def dispatch(self, request, *args, **kwargs):
"""
Dispatch override to centralize error handling.
If the error is instance of :class: `ApiException <designsafe.apps.api.exceptions.ApiException>`.
An extra dictionary object will be used when calling `logger.error()`.
This allows to use any information in the `extra` dictionary object on the
logger output.
"""
try:
return super(BaseApiView, self).dispatch(request, *args, **kwargs)
except ApiException as e:
status = e.response.status_code
message = e.response.reason
extra = e.extra
logger.error('{}'.format(message), exc_info=True, extra=extra)
except (ConnectionError, HTTPError) as e:
if e.response:
status = e.response.status_code
message = e.response.reason
if status not in [403, 404]:
logger.error('%s: %s', message, e.response.text,
exc_info=True,
extra={'username': request.user.username,
'sessionId': request.session.session_key})
else:
logger.warning('%s: %s', message, e.response.text,
exc_info=True,
extra={'username': request.user.username,
'sessionId': request.session.session_key})
else:
logger.error('%s', e, exc_info=True)
message = str(e)
status = 500
resp = {'message': message}
return HttpResponse(json.dumps(resp),
status=status, content_type='application/json')
class AuthenticatedApiView(BaseApiView):
def dispatch(self, request, *args, **kwargs):
"""Returns 401 if user is not authenticated."""
if not request.user.is_authenticated:
return JsonResponse({"message": "Unauthenticated user"}, status=401)
return super(AuthenticatedApiView, self).dispatch(request, *args, **kwargs)
class LoggerApi(BaseApiView):
"""
Logger API for capturing logs from the front-end.
@see ng-designsafe/services/logging-service.js
"""
def post(self, request):
"""
Accepts a log message from the front end. Attempts to determine the level at
which the message should be logged, and the name of the front-end logger. It
then logs the message JSON as appropriate.
Args:
request: {django.http.HttpRequest} the HTTP request
Returns: HTTP 202
"""
log_json = request.body.decode('utf-8')
log_data = json.loads(log_json)
level = getLevelName(log_data.pop('level', 'INFO'))
name = log_data.pop('name');
logger.log(level, '%s: %s', name, json.dumps(log_data), extra={
'user': request.user.username,
'referer': request.META.get('HTTP_REFERER')
})
return HttpResponse('OK', status=202)