Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docker/configs/settings_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@
APP_API_TOKENS = {
"ietf.api.views.rpc_person" : ["devtoken"],
"ietf.api.views.submitted_to_rpc" : ["devtoken"],
"ietf.api.views.create_demo_person" : ["devtoken"]
"ietf.api.views.create_demo_resources" : ["devtoken"], # remove for production!
}
15 changes: 15 additions & 0 deletions ietf/api/ietf_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
# This is not utils.py because Tastypie implicitly consumes ietf.api.utils.
# See ietf.api.__init__.py for details.

from functools import wraps

from django.conf import settings
from django.http import HttpResponseForbidden


def is_valid_token(endpoint, token):
# This is where we would consider integration with vault
Expand All @@ -13,3 +17,14 @@ def is_valid_token(endpoint, token):
if endpoint in token_store and token in token_store[endpoint]:
return True
return False

def requires_api_token(endpoint):
def decorate(f):
@wraps(f)
def wrapped(request, *args, **kwargs):
authtoken = request.META.get("HTTP_X_API_KEY", None)
if authtoken is None or not is_valid_token(endpoint, authtoken):
return HttpResponseForbidden()
return f(request, *args, **kwargs)
return wrapped
return decorate
28 changes: 7 additions & 21 deletions ietf/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from ietf.person.models import Person, Email
from ietf.api import _api_list
from ietf.api.serializer import JsonExportMixin
from ietf.api.ietf_utils import is_valid_token
from ietf.api.ietf_utils import is_valid_token, requires_api_token
from ietf.doc.factories import WgDraftFactory # DO NOT MERGE INTO MAIN
from ietf.doc.models import Document
from ietf.doc.utils import fuzzy_find_documents
Expand Down Expand Up @@ -441,24 +441,18 @@ def directauth(request):
return HttpResponse(status=405)

@csrf_exempt
@requires_api_token("ietf.api.views.rpc_person")
def rpc_person(request, person_id):
authtoken = request.META.get("HTTP_X_API_KEY", None)
if authtoken is None or not is_valid_token("ietf.api.views.rpc_person", authtoken):
return HttpResponseForbidden()
person = get_object_or_404(Person, pk=person_id)
return JsonResponse({
"id": person.id,
"plain_name": person.plain_name(),
})

@csrf_exempt
@requires_api_token("ietf.api.views.rpc_person")
def rpc_persons(request):
""" Get a batch of rpc person names

"""
authtoken = request.META.get("HTTP_X_API_KEY", None)
if authtoken is None or not is_valid_token("ietf.api.views.rpc_person", authtoken):
return HttpResponseForbidden()
""" Get a batch of rpc person names"""
if request.method != "POST":
return HttpResponseForbidden()

Expand All @@ -470,14 +464,12 @@ def rpc_persons(request):


@csrf_exempt
@requires_api_token("ietf.api.views.submitted_to_rpc")
def submitted_to_rpc(request):
""" Return documents in datatracker that have been submitted to the RPC but are not yet in the queue

Those queries overreturn - there may be things, particularly not from the IETF stream that are already in the queue.
"""
authtoken = request.META.get("HTTP_X_API_KEY", None)
if authtoken is None or not is_valid_token("ietf.api.views.submitted_to_rpc", authtoken):
return HttpResponseForbidden()
ietf_docs = Q(states__type_id="draft-iesg",states__slug__in=["ann"])
irtf_iab_ise_docs = Q(states__type_id__in=["draft-stream-iab","draft-stream-irtf","draft-stream-ise"],states__slug__in=["rfc-edit"])
#TODO: Need a way to talk about editorial stream docs
Expand All @@ -490,13 +482,11 @@ def submitted_to_rpc(request):


@csrf_exempt
@requires_api_token("ietf.api.views.create_demo_resources")
def create_demo_person(request):
""" Helper for creating rpc demo objects - SHOULD NOT MAKE IT INTO PRODUCTION

"""
authtoken = request.META.get("HTTP_X_API_KEY", None)
if authtoken is None or not is_valid_token("ietf.api.views.submitted_to_rpc", authtoken):
return HttpResponseForbidden()
if request.method != "POST":
return HttpResponseForbidden()

Expand All @@ -507,13 +497,11 @@ def create_demo_person(request):


@csrf_exempt
@requires_api_token("ietf.api.views.create_demo_resources")
def create_demo_draft(request):
""" Helper for creating rpc demo objects - SHOULD NOT MAKE IT INTO PRODUCTION

"""
authtoken = request.META.get("HTTP_X_API_KEY", None)
if authtoken is None or not is_valid_token("ietf.api.views.submitted_to_rpc", authtoken):
return HttpResponseForbidden()
if request.method != "POST":
return HttpResponseForbidden()

Expand All @@ -540,5 +528,3 @@ def create_demo_draft(request):
if not doc.docevent_set.filter(type=event_type).exists(): # Not using get_or_create here on purpose - these are wobbly facades we're creating
doc.docevent_set.create(type=event_type, by_id=1, desc="Sent off to the RPC")
return JsonResponse({ "doc_id":doc.pk, "name":doc.name })