Skip to content

Commit 1b20196

Browse files
committed
Added Prefix management URLs and APIs
Changes to be committed: modified: config/fixtures/local_data.json modified: docs/refactor.md modified: prefix/apis.py modified: prefix/services.py modified: prefix/urls.py modified: tests/fixtures/test_data.json deleted: tests/test_views/test_api_prefixes_create.py new file: tests/test_views/test_prefixes_create.py new file: tests/test_views/test_prefixes_modify.py
1 parent 1928511 commit 1b20196

File tree

9 files changed

+607
-270
lines changed

9 files changed

+607
-270
lines changed

config/fixtures/local_data.json

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -735,54 +735,6 @@
735735
"model": "blacklistedtoken"
736736
}
737737
},
738-
{
739-
"model": "contenttypes.contenttype",
740-
"pk": 10,
741-
"fields": {
742-
"app_label": "guardian",
743-
"model": "groupobjectpermission"
744-
}
745-
},
746-
{
747-
"model": "contenttypes.contenttype",
748-
"pk": 11,
749-
"fields": {
750-
"app_label": "guardian",
751-
"model": "userobjectpermission"
752-
}
753-
},
754-
{
755-
"model": "contenttypes.contenttype",
756-
"pk": 12,
757-
"fields": {
758-
"app_label": "authentication",
759-
"model": "newuser"
760-
}
761-
},
762-
{
763-
"model": "contenttypes.contenttype",
764-
"pk": 13,
765-
"fields": {
766-
"app_label": "authentication",
767-
"model": "authentication"
768-
}
769-
},
770-
{
771-
"model": "contenttypes.contenttype",
772-
"pk": 14,
773-
"fields": {
774-
"app_label": "biocompute",
775-
"model": "bco"
776-
}
777-
},
778-
{
779-
"model": "contenttypes.contenttype",
780-
"pk": 15,
781-
"fields": {
782-
"app_label": "prefix",
783-
"model": "prefix"
784-
}
785-
},
786738
{
787739
"model": "sessions.session",
788740
"pk": "mpq9r3ogmf3pel91gaqfvhzaf0pmdl4f",

docs/refactor.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@
3939
- need tests for token
4040
- unwanted swagger endpoints
4141
- need tests for token
42+
- prefix api documentation and portal docs for prefix

prefix/apis.py

Lines changed: 208 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,33 @@
88
from rest_framework.response import Response
99
from rest_framework.views import APIView
1010
from config.services import legacy_api_converter, response_constructor
11-
from prefix.services import PrefixSerializer
11+
from prefix.services import PrefixSerializer, delete_prefix
12+
13+
PREFIX_SCHEMA = openapi.Schema(
14+
type=openapi.TYPE_ARRAY,
15+
title="Prefix Schema",
16+
items=openapi.Schema(
17+
type=openapi.TYPE_OBJECT,
18+
required=["prefix"],
19+
properties={
20+
"prefix": openapi.Schema(
21+
type=openapi.TYPE_STRING,
22+
description="Any prefix which satsifies the naming standard.",
23+
example="test"
24+
),
25+
"description": openapi.Schema(
26+
type=openapi.TYPE_STRING,
27+
description="A description of what this prefix should represent. For example, the prefix 'GLY' would be related to BCOs which were derived from GlyGen workflows.",
28+
example="Test prefix description."
29+
),
30+
"authorized_groups": openapi.Schema(
31+
type=openapi.TYPE_ARRAY,
32+
description="Groups which can access the BCOs using this prefix. If it is none then anyone can access.",
33+
items=openapi.Schema(type=openapi.TYPE_STRING, example="")
34+
)
35+
},
36+
)
37+
)
1238

1339
class PrefixesCreateApi(APIView):
1440
"""
@@ -20,38 +46,9 @@ class PrefixesCreateApi(APIView):
2046
2147
"""
2248

23-
# Permissions - prefix admins only
2449
permission_classes = [IsAuthenticated,]
2550

26-
# TYPE_ARRAY explanation
27-
# Source: https://stackoverflow.com/questions/53492889/drf-yasg-doesnt-take-type-array-as-a-valid-type
28-
29-
# TODO: Need to get the schema that is being sent here from FE
30-
request_body = openapi.Schema(
31-
type=openapi.TYPE_ARRAY,
32-
title="Prefix Creation Schema",
33-
items=openapi.Schema(
34-
type=openapi.TYPE_OBJECT,
35-
required=["prefix"],
36-
properties={
37-
"prefix": openapi.Schema(
38-
type=openapi.TYPE_STRING,
39-
description="Any prefix which satsifies the naming standard (see link...)",
40-
example="test"
41-
),
42-
"description": openapi.Schema(
43-
type=openapi.TYPE_STRING,
44-
description="A description of what this prefix should represent. For example, the prefix 'GLY' would be related to BCOs which were derived from GlyGen workflows.",
45-
example="Test prefix description."
46-
),
47-
"authorized_groups": openapi.Schema(
48-
type=openapi.TYPE_ARRAY,
49-
description="Groups which can access the BCOs using this prefix. If it is none then anyone can access.",
50-
items=openapi.Schema(type=openapi.TYPE_STRING, example="")
51-
)
52-
},
53-
)
54-
)
51+
request_body = PREFIX_SCHEMA
5552

5653
@swagger_auto_schema(
5754
request_body=request_body,
@@ -68,7 +65,7 @@ class PrefixesCreateApi(APIView):
6865
)
6966
def post(self, request) -> Response:
7067
response_data = []
71-
owner = request.user
68+
requester = request.user
7269
data = request.data
7370
rejected_requests = False
7471
accepted_requests = False
@@ -85,7 +82,7 @@ def post(self, request) -> Response:
8582
response_data.append(response_constructor(
8683
identifier=response_id,
8784
status = "SUCCESS",
88-
code= 200,
85+
code= 201,
8986
message= f"Prefix {response_id} created",
9087
))
9188
accepted_requests = True
@@ -118,4 +115,182 @@ def post(self, request) -> Response:
118115
data=response_data
119116
)
120117

118+
return Response(status=status.HTTP_201_CREATED, data=response_data)
119+
120+
class PrefixesDeleteApi(APIView):
121+
"""
122+
Delete a Prefix
123+
124+
# Deletes a prefix for BCOs.
125+
--------------------
126+
The requestor *must* be in the group prefix_admins to delete a prefix.
127+
128+
__Any object created under this prefix will have its permissions "locked out." This means that any other view which relies on object-level permissions, such as /api/objects/drafts/read/, will not allow any requestor access to particular objects.__
129+
130+
131+
"""
132+
133+
permission_classes = [IsAuthenticated]
134+
135+
request_body = openapi.Schema(
136+
type=openapi.TYPE_ARRAY,
137+
title="Prefix Deletion Schema",
138+
description="Provide a list of prefixes to delete.",
139+
items=openapi.Schema(
140+
type=openapi.TYPE_STRING,
141+
example="TEST"
142+
)
143+
)
144+
145+
@swagger_auto_schema(
146+
request_body=request_body,
147+
responses={
148+
200: "Deleting a prefix was successful.",
149+
401: "Unauthorized. Authentication credentials were not provided.",
150+
403: "Forbidden. User doesnot have permission to perform this action",
151+
404: "The prefix couldn't be found so therefore it could not be deleted.",
152+
},
153+
tags=["Prefix Management"],
154+
)
155+
156+
def post(self, request) -> Response:
157+
response_data = []
158+
requester = request.user
159+
data = request.data
160+
rejected_requests = False
161+
accepted_requests = False
162+
163+
if "POST_api_prefixes_delete" in request.data:
164+
data = legacy_api_converter(request.data)
165+
166+
for index, object in enumerate(data):
167+
response_id = object
168+
response_status = delete_prefix(object, requester)
169+
print("response_status: ", response_status)
170+
if response_status is True:
171+
response_data.append(response_constructor(
172+
identifier=response_id,
173+
status = "SUCCESS",
174+
code= 200,
175+
message= f"Prefix {response_id} deleted",
176+
))
177+
accepted_requests = True
178+
print(accepted_requests, response_data)
179+
180+
else:
181+
response_data.append(response_constructor(
182+
identifier=response_id,
183+
status = "REJECTED",
184+
code= 400,
185+
message= f"Prefix {response_id} NOT deleted",
186+
data=response_status
187+
))
188+
rejected_requests = True
189+
190+
if accepted_requests is False:
191+
return Response(
192+
status=status.HTTP_400_BAD_REQUEST,
193+
data=response_data
194+
)
195+
196+
if accepted_requests is True and rejected_requests is True:
197+
return Response(
198+
status=status.HTTP_207_MULTI_STATUS,
199+
data=response_data
200+
)
201+
202+
if accepted_requests is True and rejected_requests is False:
203+
return Response(
204+
status=status.HTTP_200_OK,
205+
data=response_data
206+
)
207+
208+
return Response(status=status.HTTP_201_CREATED, data=response_data)
209+
210+
class PrefixesModifyApi(APIView):
211+
"""
212+
Modify a Prefix
213+
214+
--------------------
215+
216+
Modify a prefix which already exists.
217+
218+
The requestor *must* be in the owner to modify a prefix.
219+
"""
220+
221+
permission_classes = [IsAuthenticated]
222+
223+
request_body = PREFIX_SCHEMA
224+
225+
@swagger_auto_schema(
226+
request_body=request_body,
227+
responses={
228+
200: "The prefix was successfully modified.",
229+
400: "Bad request because owner_user and/or owner_group do not exist.",
230+
404: "The prefix provided could not be found.",
231+
},
232+
tags=["Prefix Management"],
233+
)
234+
def post(self, request) -> Response:
235+
response_data = []
236+
requester = request.user
237+
data = request.data
238+
rejected_requests = False
239+
accepted_requests = False
240+
241+
if "POST_api_prefixes_modify" in request.data:
242+
data = legacy_api_converter(request.data)
243+
for index, object in enumerate(data):
244+
response_id = object.get("prefix", index).upper()
245+
prefix = PrefixSerializer(data=object, context={'request': request})
246+
247+
if prefix.is_valid():
248+
if requester == prefix.validated_data['owner']:
249+
prefix.update(prefix.validated_data)
250+
response_data.append(response_constructor(
251+
identifier=response_id,
252+
status = "SUCCESS",
253+
code= 200,
254+
message= f"Prefix {response_id} updated",
255+
))
256+
accepted_requests = True
257+
258+
else:
259+
response_data.append(response_constructor(
260+
identifier=response_id,
261+
status = "REJECTED",
262+
code= 400,
263+
message= f"Requester does not have permissions to modify {response_id}",
264+
data=prefix.errors
265+
))
266+
rejected_requests = True
267+
268+
else:
269+
response_data.append(response_constructor(
270+
identifier=response_id,
271+
status = "REJECTED",
272+
code= 400,
273+
message= f"Prefix {response_id} update rejected",
274+
data=prefix.errors
275+
))
276+
rejected_requests = True
277+
278+
if accepted_requests is False and rejected_requests == True:
279+
return Response(
280+
status=status.HTTP_400_BAD_REQUEST,
281+
data=response_data
282+
)
283+
284+
if accepted_requests is True and rejected_requests is True:
285+
return Response(
286+
status=status.HTTP_207_MULTI_STATUS,
287+
data=response_data
288+
)
289+
290+
if accepted_requests is True and rejected_requests is False:
291+
return Response(
292+
status=status.HTTP_200_OK,
293+
data=response_data
294+
)
295+
121296
return Response(status=status.HTTP_201_CREATED, data=response_data)

0 commit comments

Comments
 (0)