Skip to content

Commit

Permalink
Added Prefix management URLs and APIs
Browse files Browse the repository at this point in the history
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
  • Loading branch information
HadleyKing committed Mar 20, 2024
1 parent 0361299 commit bfa636e
Show file tree
Hide file tree
Showing 9 changed files with 607 additions and 270 deletions.
48 changes: 0 additions & 48 deletions config/fixtures/local_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -735,54 +735,6 @@
"model": "blacklistedtoken"
}
},
{
"model": "contenttypes.contenttype",
"pk": 10,
"fields": {
"app_label": "guardian",
"model": "groupobjectpermission"
}
},
{
"model": "contenttypes.contenttype",
"pk": 11,
"fields": {
"app_label": "guardian",
"model": "userobjectpermission"
}
},
{
"model": "contenttypes.contenttype",
"pk": 12,
"fields": {
"app_label": "authentication",
"model": "newuser"
}
},
{
"model": "contenttypes.contenttype",
"pk": 13,
"fields": {
"app_label": "authentication",
"model": "authentication"
}
},
{
"model": "contenttypes.contenttype",
"pk": 14,
"fields": {
"app_label": "biocompute",
"model": "bco"
}
},
{
"model": "contenttypes.contenttype",
"pk": 15,
"fields": {
"app_label": "prefix",
"model": "prefix"
}
},
{
"model": "sessions.session",
"pk": "mpq9r3ogmf3pel91gaqfvhzaf0pmdl4f",
Expand Down
1 change: 1 addition & 0 deletions docs/refactor.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@
- need tests for token
- unwanted swagger endpoints
- need tests for token
- prefix api documentation and portal docs for prefix
241 changes: 208 additions & 33 deletions prefix/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,33 @@
from rest_framework.response import Response
from rest_framework.views import APIView
from config.services import legacy_api_converter, response_constructor
from prefix.services import PrefixSerializer
from prefix.services import PrefixSerializer, delete_prefix

PREFIX_SCHEMA = openapi.Schema(
type=openapi.TYPE_ARRAY,
title="Prefix Schema",
items=openapi.Schema(
type=openapi.TYPE_OBJECT,
required=["prefix"],
properties={
"prefix": openapi.Schema(
type=openapi.TYPE_STRING,
description="Any prefix which satsifies the naming standard.",
example="test"
),
"description": openapi.Schema(
type=openapi.TYPE_STRING,
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.",
example="Test prefix description."
),
"authorized_groups": openapi.Schema(
type=openapi.TYPE_ARRAY,
description="Groups which can access the BCOs using this prefix. If it is none then anyone can access.",
items=openapi.Schema(type=openapi.TYPE_STRING, example="")
)
},
)
)

class PrefixesCreateApi(APIView):
"""
Expand All @@ -20,38 +46,9 @@ class PrefixesCreateApi(APIView):
"""

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

# TYPE_ARRAY explanation
# Source: https://stackoverflow.com/questions/53492889/drf-yasg-doesnt-take-type-array-as-a-valid-type

# TODO: Need to get the schema that is being sent here from FE
request_body = openapi.Schema(
type=openapi.TYPE_ARRAY,
title="Prefix Creation Schema",
items=openapi.Schema(
type=openapi.TYPE_OBJECT,
required=["prefix"],
properties={
"prefix": openapi.Schema(
type=openapi.TYPE_STRING,
description="Any prefix which satsifies the naming standard (see link...)",
example="test"
),
"description": openapi.Schema(
type=openapi.TYPE_STRING,
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.",
example="Test prefix description."
),
"authorized_groups": openapi.Schema(
type=openapi.TYPE_ARRAY,
description="Groups which can access the BCOs using this prefix. If it is none then anyone can access.",
items=openapi.Schema(type=openapi.TYPE_STRING, example="")
)
},
)
)
request_body = PREFIX_SCHEMA

@swagger_auto_schema(
request_body=request_body,
Expand All @@ -68,7 +65,7 @@ class PrefixesCreateApi(APIView):
)
def post(self, request) -> Response:
response_data = []
owner = request.user
requester = request.user
data = request.data
rejected_requests = False
accepted_requests = False
Expand All @@ -85,7 +82,7 @@ def post(self, request) -> Response:
response_data.append(response_constructor(
identifier=response_id,
status = "SUCCESS",
code= 200,
code= 201,
message= f"Prefix {response_id} created",
))
accepted_requests = True
Expand Down Expand Up @@ -118,4 +115,182 @@ def post(self, request) -> Response:
data=response_data
)

return Response(status=status.HTTP_201_CREATED, data=response_data)

class PrefixesDeleteApi(APIView):
"""
Delete a Prefix
# Deletes a prefix for BCOs.
--------------------
The requestor *must* be in the group prefix_admins to delete a prefix.
__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.__
"""

permission_classes = [IsAuthenticated]

request_body = openapi.Schema(
type=openapi.TYPE_ARRAY,
title="Prefix Deletion Schema",
description="Provide a list of prefixes to delete.",
items=openapi.Schema(
type=openapi.TYPE_STRING,
example="TEST"
)
)

@swagger_auto_schema(
request_body=request_body,
responses={
200: "Deleting a prefix was successful.",
401: "Unauthorized. Authentication credentials were not provided.",
403: "Forbidden. User doesnot have permission to perform this action",
404: "The prefix couldn't be found so therefore it could not be deleted.",
},
tags=["Prefix Management"],
)

def post(self, request) -> Response:
response_data = []
requester = request.user
data = request.data
rejected_requests = False
accepted_requests = False

if "POST_api_prefixes_delete" in request.data:
data = legacy_api_converter(request.data)

for index, object in enumerate(data):
response_id = object
response_status = delete_prefix(object, requester)
print("response_status: ", response_status)
if response_status is True:
response_data.append(response_constructor(
identifier=response_id,
status = "SUCCESS",
code= 200,
message= f"Prefix {response_id} deleted",
))
accepted_requests = True
print(accepted_requests, response_data)

else:
response_data.append(response_constructor(
identifier=response_id,
status = "REJECTED",
code= 400,
message= f"Prefix {response_id} NOT deleted",
data=response_status
))
rejected_requests = True

if accepted_requests is False:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data=response_data
)

if accepted_requests is True and rejected_requests is True:
return Response(
status=status.HTTP_207_MULTI_STATUS,
data=response_data
)

if accepted_requests is True and rejected_requests is False:
return Response(
status=status.HTTP_200_OK,
data=response_data
)

return Response(status=status.HTTP_201_CREATED, data=response_data)

class PrefixesModifyApi(APIView):
"""
Modify a Prefix
--------------------
Modify a prefix which already exists.
The requestor *must* be in the owner to modify a prefix.
"""

permission_classes = [IsAuthenticated]

request_body = PREFIX_SCHEMA

@swagger_auto_schema(
request_body=request_body,
responses={
200: "The prefix was successfully modified.",
400: "Bad request because owner_user and/or owner_group do not exist.",
404: "The prefix provided could not be found.",
},
tags=["Prefix Management"],
)
def post(self, request) -> Response:
response_data = []
requester = request.user
data = request.data
rejected_requests = False
accepted_requests = False

if "POST_api_prefixes_modify" in request.data:
data = legacy_api_converter(request.data)
for index, object in enumerate(data):
response_id = object.get("prefix", index).upper()
prefix = PrefixSerializer(data=object, context={'request': request})

if prefix.is_valid():
if requester == prefix.validated_data['owner']:
prefix.update(prefix.validated_data)
response_data.append(response_constructor(
identifier=response_id,
status = "SUCCESS",
code= 200,
message= f"Prefix {response_id} updated",
))
accepted_requests = True

else:
response_data.append(response_constructor(
identifier=response_id,
status = "REJECTED",
code= 400,
message= f"Requester does not have permissions to modify {response_id}",
data=prefix.errors
))
rejected_requests = True

else:
response_data.append(response_constructor(
identifier=response_id,
status = "REJECTED",
code= 400,
message= f"Prefix {response_id} update rejected",
data=prefix.errors
))
rejected_requests = True

if accepted_requests is False and rejected_requests == True:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data=response_data
)

if accepted_requests is True and rejected_requests is True:
return Response(
status=status.HTTP_207_MULTI_STATUS,
data=response_data
)

if accepted_requests is True and rejected_requests is False:
return Response(
status=status.HTTP_200_OK,
data=response_data
)

return Response(status=status.HTTP_201_CREATED, data=response_data)
Loading

0 comments on commit bfa636e

Please sign in to comment.