Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Objects_drafts_permissions_set #253

Closed
wants to merge 20 commits into from
Closed
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 .github/workflows/django.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ jobs:
pip install -r requirements.txt
- name: Run Tests
run: |
cd bco_api;python3.9 manage.py test
python3.9 manage.py test
4 changes: 2 additions & 2 deletions api/scripts/method_specific/GET_published_object_by_id.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# The BCO model
from ...models import BCO
from api.models import BCO

# Responses
from rest_framework import status
Expand Down Expand Up @@ -107,5 +107,5 @@ def GET_published_object_by_id(oi_root):
print("No objects were found for the root ID provided.")
return Response(
data="No objects were found for the root ID provided.",
status=status.HTTP_400_BAD_REQUEST,
status=status.HTTP_404_NOT_FOUND,
)
29 changes: 20 additions & 9 deletions api/scripts/method_specific/POST_api_objects_drafts_publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
from django.contrib.auth.models import Group
from django.utils import timezone
from guardian.shortcuts import get_perms
from rest_framework import status
from rest_framework import status, authtoken
from rest_framework.response import Response

from authentication.selectors import get_user_from_auth_token

def post_api_objects_drafts_publish(request):
"""Publish draft
Expand All @@ -37,13 +37,29 @@ def post_api_objects_drafts_publish(request):
returning = []
any_failed = False
db_utils = DbUtils.DbUtils()
user = UserUtils.UserUtils().user_from_request(request=request)

try:
user = UserUtils.UserUtils().user_from_request(request=request)
except authtoken.models.Token.DoesNotExist:
user = get_user_from_auth_token(request.META.get("HTTP_AUTHORIZATION").split(" ")[1])
prefix_perms = UserUtils.UserUtils().prefix_perms_for_user(
flatten=True, user_object=user
)
bulk_request = request.data["POST_api_objects_drafts_publish"]
try:
bulk_request = request.data["POST_api_objects_drafts_publish"]
except:
return Response(status=status.HTTP_400_BAD_REQUEST, data={"Request format not accepted."})

for publish_object in bulk_request:
if "draft_id" not in publish_object:
returning.append(
db_utils.messages(parameters={})[
"400_bad_request"
]
)
any_failed = True
continue

draft_exists = BCO.objects.filter(
object_id=publish_object["draft_id"], state="DRAFT"
).exists()
Expand Down Expand Up @@ -195,11 +211,6 @@ def post_api_objects_drafts_publish(request):
# # Does the requestor have delete permissions on
# # the object?

# As this view is for a bulk operation, status 200
# means that the request was successfully processed,
# but NOT necessarily each item in the request.
# For example, a table may not have been found for the first
# requested draft.
if any_failed:
return Response(status=status.HTTP_207_MULTI_STATUS, data=returning)

Expand Down
4 changes: 2 additions & 2 deletions api/scripts/utilities/UserUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def prefix_perms_for_user(

# return bco_specific

def user_from_request(self, request):
def user_from_request(self, rq):
"""Returns a user object from a request.

Parameters
Expand All @@ -263,6 +263,6 @@ def user_from_request(self, request):
"""

user_id = Token.objects.get(
key=request.META.get("HTTP_AUTHORIZATION").split(" ")[1]
key=rq.META.get("HTTP_AUTHORIZATION").split(" ")[1]
).user_id
return User.objects.get(id=user_id)
51 changes: 29 additions & 22 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
# For helper functions
from api.scripts.utilities import UserUtils

from authentication.services import CustomJSONWebTokenAuthentication

################################################################################################
# NOTES
Expand Down Expand Up @@ -800,22 +801,39 @@ def post(self, request) -> Response:
# TODO: What is the difference between this and ApiObjectsPublish?
class ApiObjectsDraftsPublish(APIView):
"""
Publish a BCO
Bulk Publish BCOs

--------------------

Publish draft BCO objects. Once published, a BCO object becomes immutable.
The `object_id` field is optional, and is used to specify if the object
should be published as a specific version, instead of the next available numeric
version.


Publish a draft BCO object. Once published, a BCO object becomes immutable.
```json
{
"POST_api_objects_drafts_publish": [
{
"prefix": "TEST",
"draft_id": "http://127.0.0.1:8000/TEST_000001",
"object_id": "http://127.0.0.1:8000/TEST_000001/1.0",
"delete_draft": false
}
]
}
"""

# TODO: This seems to be missing group, which I would expect to be part of the publication
permission_classes = [IsAuthenticated]
permission_classes = [IsAuthenticated,]
# authentication_classes = [CustomJSONWebTokenAuthentication]

POST_api_objects_drafts_publish_schema = openapi.Schema(
type=openapi.TYPE_OBJECT,
required=["draft_id", "prefix"],
properties={
"prefix": openapi.Schema(
type=openapi.TYPE_STRING, description="BCO Prefix to publish with."
type=openapi.TYPE_STRING, description="BCO Prefix to publish with."
),
"draft_id": openapi.Schema(
type=openapi.TYPE_STRING, description="BCO Object Draft ID."
Expand Down Expand Up @@ -847,13 +865,14 @@ class ApiObjectsDraftsPublish(APIView):
@swagger_auto_schema(
request_body=request_body,
responses={
200: "BCO Publication is successful.",
300: "Some requests failed.",
200: "All BCO publications successful.",
207: "Some or all publications failed.",
400: "Bad request.",
403: "Invalid token.",
403: "Authentication credentials were not provided.",
},
tags=["BCO Management"],
)

def post(self, request) -> Response:
return check_post_and_process(request, post_api_objects_drafts_publish)

Expand Down Expand Up @@ -1669,19 +1688,10 @@ def get(self, request, object_id):
class ObjectIdRootObjectId(APIView):
"""
View Published BCO by ID

--------------------

Reads and returns a published BCO based on an object ID.

Reads and returns a published BCO based on an object ID. This will return the highest versioned object.
"""

# For the success and error messages
# renderer_classes = [
# TemplateHTMLRenderer
# ]
# template_name = 'api/account_activation_message.html'

auth = []
auth.append(
openapi.Parameter(
Expand All @@ -1692,17 +1702,14 @@ class ObjectIdRootObjectId(APIView):
)
)

# Anyone can view a published object
authentication_classes = []
permission_classes = []

@swagger_auto_schema(
manual_parameters=auth,
responses={
201: "Account has been authorized.",
208: "Account has already been authorized.",
403: "Requestor's credentials were rejected.",
424: "Account has not been registered.",
200: "Object returned.",
404: "Object not found."
},
tags=["BCO Management"],
)
Expand Down
10 changes: 5 additions & 5 deletions authentication/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ class AddAuthenticationApi(APIView):
@swagger_auto_schema(
request_body=schema,
responses={
200: "Add authentication is successful.",
201: "Authentication credentials were created and added.",
200: "New authentication credentials added to existing object.",
201: "Authentication object created and added to account.",
400: "Bad request.",
403: "Authentication credentials were not provided.",
409: "That object already exists for this account.",
},
tags=["Authentication"],
Expand All @@ -140,7 +141,6 @@ def post(self, request):
return Response(status=status.HTTP_400_BAD_REQUEST, data=result)
try:
auth_object = Authentication.objects.get(username=request.user.username)

if request.data in auth_object.auth_service:
return Response(
status=status.HTTP_409_CONFLICT,
Expand All @@ -150,7 +150,7 @@ def post(self, request):
auth_object.save()
return Response(
status=status.HTTP_200_OK,
data={"message": "Authentication added to existing object"}
data={"message": "New authentication credentials added to existing object"}
)

except Authentication.DoesNotExist:
Expand All @@ -161,7 +161,7 @@ def post(self, request):
print('status=status.HTTP_201_CREATED')
return Response(
status=status.HTTP_201_CREATED,
data={"message": "Authentication object added to account"}
data={"message": "Authentication object created and added to account"}
)

except Exception as err:
Expand Down
10 changes: 8 additions & 2 deletions authentication/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,14 @@ def validate_auth_service(value):
"required": ["iss", "sub"],
"additionalProperties": False,
"properties": {
"iss": {"type": "string", "description": "The 'iss' (issuer) claim identifies the principal that issued the JWT."},
"sub": {"type": "string", "description": "The 'sub' (subject) claim identifies the principal that is the subject of the JWT."}
"iss": {
"type": "string",
"description": "The 'iss' (issuer) claim identifies the principal that issued the JWT."
},
"sub": {
"type": "string",
"description": "The 'sub' (subject) claim identifies the principal that is the subject of the JWT."
}
}
}
try:
Expand Down
17 changes: 8 additions & 9 deletions search/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@
from itertools import chain

class SearchObjectsAPI(APIView):
"""Search the BCODB **BETA**
"""
Search the BCODB

-------------------

Endpoint for use of query string based search.
"""

#TODO: multiple values in the URL will only return the last one.

authentication_classes = [CustomJSONWebTokenAuthentication]
permission_classes = [AllowAny,]

Expand Down Expand Up @@ -46,18 +51,12 @@ class SearchObjectsAPI(APIView):
)
],
responses={
201: "Account has been authorized.",
208: "Account has already been authorized.",
403: "Requestor's credentials were rejected.",
424: "Account has not been registered.",
200: ""
},
tags=["Account Management"],
tags=["BCO Management"],
)

def get(self, request) -> Response:
"""GET search
TODO: multiple values in the URL will only return the last one.
"""
return_values = [
"contents",
"last_update",
Expand Down
2 changes: 1 addition & 1 deletion server.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ production=False

# DB Version
[VERSION]
version=22.11
version=23.09

# NOTE: Valid values are True or False (note the capitalization).
# Is this a publish-only server?
Expand Down
17 changes: 15 additions & 2 deletions tests/fixtures/test_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,19 @@
"change_message": "[]"
}
},
{
"model": "authentication.authentication",
"pk": 1,
"fields": {
"username": "bco_api_user",
"auth_service": [
{
"iss": "Reeya1",
"sub": "ReeyaGupta1"
}
]
}
},
{
"model": "auth.permission",
"pk": 1,
Expand Down Expand Up @@ -1614,7 +1627,7 @@
"etag": "0275321b6011324035289a5624c635ce5490fbdec588aa5f3bcaf63b85369b4a",
"provenance_domain": {
"name": "Influenza A reference gene sequences",
"version": "1.0",
"version": "1.1",
"created": "2021-12-01T15:20:13.614Z",
"modified": "2022-06-28T23:10:12.804Z",
"review": [
Expand Down Expand Up @@ -1832,7 +1845,7 @@
"etag": "11ee4c3b8a04ad16dcca19a6f478c0870d3fe668ed6454096ab7165deb1ab8ea",
"provenance_domain": {
"name": "HCV1a ledipasvir resistance SNP detection",
"version": "1.0",
"version": "1.1",
"created": "2017-01-24T09:40:17-0500",
"modified": "2022-06-28T23:12:50.369Z",
"review": [
Expand Down
Loading
Loading