Skip to content
This repository was archived by the owner on Apr 29, 2022. It is now read-only.

Commit 827078e

Browse files
committed
cleaned things up a bit and added check for content type to ensure that we only process JSON data
1 parent 96324ef commit 827078e

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

conference/api.py

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class ApiError(Enum):
4040
INPUT_ERROR = 3
4141
UNAUTHORIZED = 4
4242
WRONG_SCHEME = 5
43+
BAD_REQUEST = 6
4344

4445

4546
def _error(error: ApiError, msg: str) -> JsonResponse:
@@ -66,30 +67,40 @@ def get_client_ip(request) -> str:
6667
return ip
6768

6869

69-
def ensure_https_in_ops(fn):
70+
# Checkers
71+
def request_checker(checker, error_msg):
7072
"""
71-
Ensure that the view is called via an HTTPS request and return a JSON error
72-
payload if not.
73+
Generic sanity check decorator on views.
7374
74-
If DEBUG = True, it has no effect.
75+
It accepts two parameters:
76+
`checker`: a function that accepts a request and returns True if valid
77+
`error_msg`: what to return as error message if request is invalid
78+
79+
In case of invalid requests, it returns a BAD_REQUEST error.
7580
"""
76-
@wraps(fn)
77-
def wrapper(request, *args, **kwargs):
78-
if not DEBUG and not request.is_secure():
79-
return _error(ApiError.WRONG_SCHEME, 'please use HTTPS')
80-
return fn(request, *args, **kwargs)
81-
return wrapper
81+
def decorator(fn):
82+
@wraps(fn)
83+
def wrapper(request, *args, **kwargs):
84+
if not checker(request):
85+
return _error(ApiError.BAD_REQUEST, error_msg)
86+
return fn(request, *args, **kwargs)
87+
return wrapper
88+
return decorator
89+
90+
91+
# Ensure that the view is called via an HTTPS request and return a JSON error
92+
# payload if not. If DEBUG = True, it has no effect.
93+
ensure_https_in_ops = request_checker(
94+
lambda r: DEBUG or r.is_secure(), 'please user HTTPS'
95+
)
8296

97+
# We use this instead of the bult-in decorator to return a JSON error
98+
# payload instead of a simple 405.
99+
ensure_post = request_checker(lambda r: r.method == 'POST', 'please use POST')
83100

84-
def ensure_post(fn):
85-
# We use this instead of the bult-in decorator to return a JSON error
86-
# payload instead of a simple 405.
87-
@wraps(fn)
88-
def wrapper(request, *args, **kwargs):
89-
if request.method != 'POST':
90-
return _error(ApiError.WRONG_SCHEME, 'please use POST')
91-
return fn(request, *args, **kwargs)
92-
return wrapper
101+
ensure_json_content_type = request_checker(
102+
lambda r: r.content_type == 'application/json', 'please send JSON'
103+
)
93104

94105

95106
def restrict_client_ip_to_allowed_list(fn):
@@ -107,6 +118,7 @@ def wrapper(request, *args, **kwargs):
107118
@csrf_exempt
108119
@ensure_post
109120
@ensure_https_in_ops
121+
@ensure_json_content_type
110122
@restrict_client_ip_to_allowed_list
111123
def isauth(request):
112124
"""

0 commit comments

Comments
 (0)