Skip to content

Commit 28ab1b5

Browse files
authored
Merge pull request #8 from WHOIGit/codex/protect-api-endpoints-with-token-authentication
Secure admin endpoints with token auth
2 parents e7e9187 + d4363ca commit 28ab1b5

File tree

4 files changed

+31
-24
lines changed

4 files changed

+31
-24
lines changed

api/core/auth.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1+
from ninja.security import HttpBearer
12
from rest_framework.authentication import TokenAuthentication
23
from rest_framework.exceptions import AuthenticationFailed
34
from ninja.errors import HttpError
45

5-
6-
class TokenAuthenticator:
6+
class TokenAuthenticator(HttpBearer):
77
def __init__(self):
88
self.auth = TokenAuthentication()
9+
super().__init__() # Make sure to call parent init!
910

10-
def __call__(self, request):
11+
def authenticate(self, request, token):
12+
# This ensures the DRF token auth will see the header
13+
request.META['HTTP_AUTHORIZATION'] = f"Token {token}"
1114
try:
12-
user = self.auth.authenticate(request)
13-
if user is None:
14-
raise AuthenticationFailed('Unauthorized')
15-
return user
16-
except AuthenticationFailed:
15+
user_auth_tuple = self.auth.authenticate(request)
16+
except AuthenticationFailed as e:
17+
raise HttpError(401, 'Unauthorized') from e
18+
if user_auth_tuple is None:
1719
raise HttpError(401, 'Unauthorized')
20+
user, _ = user_auth_tuple
21+
return user

api/ctd/api.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import List
22
from ninja import Router
3+
from core.auth import TokenAuthenticator
34

45
from .services import CtdService, NiskinInput, VesselOutput, AddVesselInput, \
56
UpdateVesselInput, CruiseOutput, AddCruiseInput, \
@@ -18,15 +19,15 @@ def get_vessel(request, vessel_name: str):
1819
return CtdService.get_vessel(vessel_name)
1920

2021

21-
@router.post('/vessels/create', tags=["Admin"])
22+
@router.post('/vessels/create', tags=["Admin"], auth=TokenAuthenticator())
2223
def create_vessel(request, input: AddVesselInput):
2324
try:
2425
new_vessel = CtdService.create_vessel(input)
2526
return {"status": "success", "vessel": new_vessel}
2627
except ValueError as e:
2728
return {"status": "error", "message": str(e)}
2829

29-
@router.post('/vessels/update/{vessel_name}', tags=["Admin"])
30+
@router.post('/vessels/update/{vessel_name}', tags=["Admin"], auth=TokenAuthenticator())
3031
def update_vessel(request, vessel_name: str, input: UpdateVesselInput):
3132
try:
3233
result = CtdService.update_vessel(vessel_name, input)
@@ -44,7 +45,7 @@ def get_cruises(request):
4445
def get_cruise(request, cruise_name: str):
4546
return CtdService.get_cruise(cruise_name)
4647

47-
@router.post('/cruises/create', tags=["Admin"])
48+
@router.post('/cruises/create', tags=["Admin"], auth=TokenAuthenticator())
4849
def create_cruise(request, input: AddCruiseInput):
4950
try:
5051
new_cruise = CtdService.create_cruise(input)
@@ -53,7 +54,7 @@ def create_cruise(request, input: AddCruiseInput):
5354
return {"status": "error", "message": str(e)}
5455

5556

56-
@router.post('/cruises/update/{cruise_name}', tags=["Admin"])
57+
@router.post('/cruises/update/{cruise_name}', tags=["Admin"], auth=TokenAuthenticator())
5758
def update_cruise(request, cruise_name: str, input: UpdateCruiseInput):
5859
try:
5960
result = CtdService.update_cruise(cruise_name, input)
@@ -62,7 +63,7 @@ def update_cruise(request, cruise_name: str, input: UpdateCruiseInput):
6263
return {"status": "error", "message": str(e)}
6364

6465

65-
@router.delete('/cruises/delete/{cruise_name}', tags=["Admin"])
66+
@router.delete('/cruises/delete/{cruise_name}', tags=["Admin"], auth=TokenAuthenticator())
6667
def delete_cruise(request, cruise_name: str):
6768
try:
6869
result = CtdService.delete_cruise(cruise_name)
@@ -80,15 +81,15 @@ def get_casts(request, cruise_name: str):
8081
def get_cast(request, cruise_name: str, cast_number: str):
8182
return CtdService.get_cast(cruise_name, cast_number)
8283

83-
@router.post('/casts/create', tags=["Admin"])
84+
@router.post('/casts/create', tags=["Admin"], auth=TokenAuthenticator())
8485
def create_cast(request, input: CastInput):
8586
try:
8687
new_cast = CtdService.create_cast(input)
8788
return {"status": "success", "cast": new_cast}
8889
except ValueError as e:
8990
return {"status": "error", "message": str(e)}
9091

91-
@router.post('/casts/update/{cruise_name}/{cast_number}', tags=["Admin"])
92+
@router.post('/casts/update/{cruise_name}/{cast_number}', tags=["Admin"], auth=TokenAuthenticator())
9293
def update_cast(request, cruise_name: str, cast_number: str, input: UpdateCastInput):
9394
try:
9495
cast = CtdService.update_cast(cruise_name, cast_number, input)
@@ -97,7 +98,7 @@ def update_cast(request, cruise_name: str, cast_number: str, input: UpdateCastIn
9798
return {"status": "error", "message": str(e)}
9899

99100

100-
@router.delete('/casts/delete/{cruise_name}/{cast_number}', tags=["Admin"])
101+
@router.delete('/casts/delete/{cruise_name}/{cast_number}', tags=["Admin"], auth=TokenAuthenticator())
101102
def delete_cast(request, cruise_name: str, cast_number: str):
102103
try:
103104
result = CtdService.delete_cast(cruise_name, cast_number)
@@ -106,7 +107,7 @@ def delete_cast(request, cruise_name: str, cast_number: str):
106107
return {"status": "error", "message": str(e)}
107108

108109

109-
@router.post('/niskins/create', tags=["Admin"])
110+
@router.post('/niskins/create', tags=["Admin"], auth=TokenAuthenticator())
110111
def create_niskin(request, input: NiskinInput):
111112
try:
112113
niskin = CtdService.create_niskin(input)
@@ -126,15 +127,15 @@ def get_niskin(request, cruise_name: str, cast_number: str, niskin_number: int):
126127
return CtdService.get_niskin(cruise_name, cast_number, niskin_number)
127128

128129

129-
@router.post('/niskins/update/{cruise_name}/{cast_number}/{niskin_number}', tags=["Admin"])
130+
@router.post('/niskins/update/{cruise_name}/{cast_number}/{niskin_number}', tags=["Admin"], auth=TokenAuthenticator())
130131
def update_niskin(request, cruise_name: str, cast_number: str, niskin_number: str, input: UpdateNiskinInput):
131132
try:
132133
niskin = CtdService.update_niskin(cruise_name, cast_number, niskin_number, input)
133134
return {"status": "success", "niskin updated": niskin}
134135
except ValueError as e:
135136
return {"status": "error", "message": str(e)}
136137

137-
@router.delete('/niksins/delete/{cruise_name}/{cast_number}/{niskin_number}', tags=["Admin"])
138+
@router.delete('/niskins/delete/{cruise_name}/{cast_number}/{niskin_number}', tags=["Admin"], auth=TokenAuthenticator())
138139
def delete_niskin(request, cruise_name: str, cast_number: str, niskin_number: int):
139140
try:
140141
result = CtdService.delete_niskin(cruise_name, cast_number, niskin_number)

api/events/api.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import List
22
from datetime import datetime
33
from ninja import Router
4+
from core.auth import TokenAuthenticator
45

56
from .services import EventService, EventOutput, FilterEventInput, EditEventInput
67

@@ -15,7 +16,7 @@ def get_events(request, cruise_name: str):
1516
def filter_events(request, cruise_name: str, input: FilterEventInput):
1617
return EventService.filter_events(cruise_name, input)
1718

18-
@router.post("/edit/{cruise_name}/{message_id}", response=EventOutput, tags=["Admin"])
19+
@router.post("/edit/{cruise_name}/{message_id}", response=EventOutput, tags=["Admin"], auth=TokenAuthenticator())
1920
def edit_events(request, cruise_name: str, message_id: int, input: EditEventInput):
2021
return EventService.edit_events(cruise_name, message_id, input)
2122

@@ -25,7 +26,7 @@ def history_events(request, cruise_name: str):
2526
return EventService.history_events(cruise_name)
2627

2728

28-
@router.delete('/delete/{cruise_name}', tags=["Admin"])
29+
@router.delete('/delete/{cruise_name}', tags=["Admin"], auth=TokenAuthenticator())
2930
def delete_events(request, cruise_name: str):
3031
try:
3132
result = EventService.delete_events(cruise_name)

api/stations/api.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from datetime import datetime
33

44
from ninja import Router
5+
from core.auth import TokenAuthenticator
56
from django.http import FileResponse
67

78
from .services import StationService, StationInput, StationLocationInput, StationQueryOutput, \
@@ -28,13 +29,13 @@ def get_stations_file(request):
2829
# return StationService.get_nearest_station(query)
2930

3031

31-
@router.post('/create', tags=["Admin"])
32+
@router.post('/create', tags=["Admin"], auth=TokenAuthenticator())
3233
def create_station(request, input: StationInput):
3334
StationService.create_station(input)
3435
return 204
3536

3637

37-
@router.post('/set_location', tags=["Admin"])
38+
@router.post('/set_location', tags=["Admin"], auth=TokenAuthenticator())
3839
def set_location(request, input: StationLocationInput):
3940
StationService.set_location(input)
4041
return 204
@@ -46,4 +47,4 @@ def add_nearest_station(request, input: AddNearestStationInput):
4647
latitude=input.latitude,
4748
longitude=input.longitude,
4849
timestamp=input.timestamp
49-
)
50+
)

0 commit comments

Comments
 (0)