Skip to content

Commit e18f342

Browse files
committed
Added 3 basic searches
Changes to be committed: modified: bco_api/api/scripts/method_specific/POST_api_objects_drafts_modify.py modified: bco_api/api/scripts/method_specific/POST_api_objects_search.py modified: bco_api/api/scripts/utilities/DbUtils.py modified: bco_api/api/views.py
1 parent 127a6f2 commit e18f342

File tree

4 files changed

+110
-154
lines changed

4 files changed

+110
-154
lines changed

bco_api/api/scripts/method_specific/POST_api_objects_drafts_modify.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
# Source: https://codeloop.org/django-rest-framework-course-for-beginners/
2020

21-
def POST_api_objects_drafts_modify(request):
21+
def post_api_objects_drafts_modify(request):
2222
""" Modify Draft
2323
2424
Take the bulk request and modify a draft object from it.
@@ -92,9 +92,10 @@ def POST_api_objects_drafts_modify(request):
9292
# *** COMPLETELY OVERWRITES CONTENTS!!! ***
9393
objected.contents = draft_object['contents']
9494

95-
if draft_object['state'] == 'DELETE':
96-
objected.state = 'DELETE'
97-
95+
if 'state' in draft_object:
96+
if draft_object['state'] == 'DELETE':
97+
objected.state = 'DELETE'
98+
9899
# Set the update time.
99100
objected.last_update = timezone.now()
100101

@@ -113,8 +114,9 @@ def POST_api_objects_drafts_modify(request):
113114
any_failed = True
114115

115116
else:
116-
returning.append(db_utils.messages(parameters = {
117-
'object_id': draft_object['object_id']}))['404_object_id']
117+
returning.append(
118+
db_utils.messages(parameters = {'object_id': draft_object['object_id']}
119+
)['404_object_id'])
118120
any_failed = True
119121
else:
120122
returning.append(
Lines changed: 90 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,95 @@
1-
# BCO model
2-
from ...models import bco
1+
#!/usr/bin/env python3
2+
"""BCO Search
33
4-
# For getting objects out of the database.
5-
from ..utilities import DbUtils
4+
"""
65

7-
# User information
8-
from ..utilities import UserUtils
9-
10-
# Permisions for objects
11-
from guardian.shortcuts import get_perms
12-
13-
# Responses
6+
from itertools import chain
7+
from api.models import bco, Prefix
8+
from api.scripts.utilities import UserUtils
9+
from guardian.shortcuts import get_objects_for_user
1410
from rest_framework import status
1511
from rest_framework.response import Response
1612

17-
18-
19-
20-
def POST_api_objects_search(
21-
incoming
22-
):
23-
24-
# View doesn't work yet...
25-
return Response(
26-
status = status.HTTP_400_BAD_REQUEST
27-
)
28-
29-
# Take the bulk request and search for objects.
30-
31-
# Instantiate any necessary imports.
32-
db = DbUtils.DbUtils()
33-
uu = UserUtils.UserUtils()
34-
35-
# The token has already been validated,
36-
# so the user is guaranteed to exist.
37-
38-
# Before any permissions, we want to actually search
39-
# for objects.
40-
41-
# Construct the search
42-
43-
# Get the User object.
44-
user = uu.user_from_request(
45-
rq = incoming
46-
)
47-
48-
# Get the user's prefix permissions.
49-
px_perms = uu.prefix_perms_for_user(
50-
flatten = True,
51-
user_object = user,
52-
specific_permission = ['view']
53-
)
54-
55-
# Define the bulk request.
56-
bulk_request = incoming.data['POST_api_objects_search']
57-
58-
# Construct an array to return the objects.
59-
returning = []
60-
61-
# Since bulk_request is an array, go over each
62-
# item in the array.
63-
for read_object in bulk_request:
64-
65-
# Get the prefix for this draft.
66-
standardized = read_object['object_id'].split('/')[-1].split('_')[0].upper()
67-
68-
# Does the requestor have view permissions for
69-
# the *prefix*?
70-
if 'view_' + standardized in px_perms:
71-
72-
# The requestor has view permissions for
73-
# the prefix, but do they have object-level
74-
# view permissions?
75-
76-
# This can be checked by seeing if the requestor
77-
# is the object owner OR they are a user with
78-
# object-level view permissions OR if they are in a
79-
# group that has object-level view permissions.
80-
81-
# To check these options, we need the actual object.
82-
if bco.objects.filter(object_id = read_object['object_id']).exists():
83-
84-
objected = bco.objects.get(
85-
object_id = read_object['object_id']
86-
)
87-
88-
# We don't care where the view permission comes from,
89-
# be it a User permission or a Group permission.
90-
all_permissions = get_perms(
91-
user,
92-
objected
93-
)
94-
95-
if user.pk == objected.owner_user.pk or 'view_' + standardized in all_permissions:
96-
97-
# Read the object.
98-
returning.append(
99-
db.messages(
100-
parameters = {
101-
'contents': objected.contents,
102-
'object_id': read_object['object_id']
103-
}
104-
)['200_OK_object_delete']
105-
)
106-
107-
else:
108-
109-
# Insufficient permissions.
110-
returning.append(
111-
db.messages(
112-
parameters = {}
113-
)['403_insufficient_permissions']
114-
)
115-
116-
else:
117-
118-
# Couldn't find the object.
119-
returning.append(
120-
db.messages(
121-
parameters = {
122-
'object_id': read_object['object_id']
123-
}
124-
)
125-
)['404_object_id']
126-
127-
else:
128-
129-
# Update the request status.
130-
returning.append(
131-
db.messages(
132-
parameters = {
133-
'prefix': standardized
134-
}
135-
)['401_prefix_unauthorized']
136-
)
137-
138-
# As this view is for a bulk operation, status 200
139-
# means that the request was successfully processed,
140-
# but NOT necessarily each item in the request.
141-
# For example, a table may not have been found for the first
142-
# requested draft.
143-
return Response(
144-
status = status.HTTP_200_OK,
145-
data = returning
146-
)
13+
def post_api_objects_search(request):
14+
"""Search for BCOs
15+
16+
Parameters
17+
----------
18+
request: rest_framework.request.Request
19+
Django request object.
20+
21+
Returns
22+
-------
23+
List of BCOs that met search criteria
24+
25+
"""
26+
27+
return_values = [
28+
'contents',
29+
'last_update',
30+
'object_class',
31+
'object_id',
32+
'owner_group',
33+
'owner_user',
34+
'prefix',
35+
'schema',
36+
'state'
37+
]
38+
39+
query = request.data['POST_api_objects_search'][0]
40+
search_type = query['type']
41+
try:
42+
search_value = query['search']
43+
except KeyError:
44+
search_value = ''
45+
user_utils = UserUtils.UserUtils()
46+
user_info = request._user
47+
48+
if search_type == 'bco_id':
49+
if user_info.username == 'anon':
50+
bco_list = bco.objects.filter(object_id__icontains=search_value, state='PUBLISHED')
51+
result_list = chain(bco_list.values(*return_values))
52+
else:
53+
user_objects = get_objects_for_user(user=user_info, perms=[], klass=bco, any_perm=True)
54+
bco_list = bco.objects.filter(object_id__icontains=search_value).exclude(state='DELETE')
55+
for i in bco_list:
56+
if i not in user_objects:
57+
bco_list.exclude(pk=i.id)
58+
result_list = chain(bco_list.values(*return_values))
59+
60+
if search_type == 'prefix':
61+
search_value = search_value.upper()
62+
user_prefixes = user_utils.prefixes_for_user(user_object=user_info)
63+
try:
64+
prefix = Prefix.objects.get(prefix=search_value).prefix
65+
66+
except Prefix.DoesNotExist:
67+
return Response(status=status.HTTP_404_NOT_FOUND, data={
68+
'request_status': 'FAILURE',
69+
'status_code' : '404',
70+
'message' : 'The prefix was not found on the server.'
71+
})
72+
73+
if prefix in user_prefixes:
74+
bco_list = bco.objects.filter(prefix=prefix).values().exclude(state='DELETE')
75+
result_list = chain(bco_list.values(*return_values))
76+
77+
else:
78+
return Response(status=status.HTTP_403_FORBIDDEN, data={
79+
'request_status': 'FAILURE',
80+
'status_code' : '403',
81+
'message' : 'The token provided does not have sufficient'\
82+
' permissions for the requested object.'
83+
}
84+
)
85+
86+
if search_type == 'mine':
87+
if user_info.username == 'anon':
88+
result_list = chain(bco.objects.filter(state='PUBLISHED').values(*return_values))
89+
90+
else:
91+
result_list = chain(bco.objects.filter(
92+
owner_user=user_info).exclude(state='DELETE'
93+
).values(*return_values))
94+
95+
return Response(status=status.HTTP_200_OK, data=result_list)

bco_api/api/scripts/utilities/DbUtils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,11 @@ def messages(
641641
'status_code' : '201',
642642
'message' : 'The prefix \'' + parameters['prefix'] + '\' was successfully created.'
643643
},
644+
'204_no_content' : {
645+
'request_status': 'SUCCESS',
646+
'status_code' : '204',
647+
'message' : 'The search you performed returned ZERO results.'
648+
},
644649
'400_bad_request' : {
645650
'request_status': 'FAILURE',
646651
'status_code' : '400',

bco_api/api/views.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@
3636
from api.scripts.method_specific.POST_api_accounts_describe import POST_api_accounts_describe
3737
from api.scripts.method_specific.POST_api_accounts_new import POST_api_accounts_new
3838
from api.scripts.method_specific.POST_api_objects_drafts_create import post_api_objects_drafts_create
39-
from api.scripts.method_specific.POST_api_objects_drafts_modify import POST_api_objects_drafts_modify
39+
from api.scripts.method_specific.POST_api_objects_drafts_modify import post_api_objects_drafts_modify
4040
from api.scripts.method_specific.POST_api_objects_drafts_permissions import POST_api_objects_drafts_permissions
4141
from api.scripts.method_specific.POST_api_objects_drafts_permissions_set import POST_api_objects_drafts_permissions_set
4242
from api.scripts.method_specific.POST_api_objects_drafts_publish import POST_api_objects_drafts_publish
4343
from api.scripts.method_specific.POST_api_objects_drafts_read import POST_api_objects_drafts_read
4444
from api.scripts.method_specific.POST_api_objects_drafts_token import POST_api_objects_drafts_token
4545
from api.scripts.method_specific.POST_api_objects_publish import POST_api_objects_publish
4646
from api.scripts.method_specific.POST_api_objects_published import POST_api_objects_published
47-
from api.scripts.method_specific.POST_api_objects_search import POST_api_objects_search
47+
from api.scripts.method_specific.POST_api_objects_search import post_api_objects_search
4848
from api.scripts.method_specific.POST_api_objects_token import POST_api_objects_token
4949
from api.scripts.method_specific.POST_api_prefixes_create import POST_api_prefixes_create
5050
from api.scripts.method_specific.POST_api_prefixes_delete import POST_api_prefixes_delete
@@ -123,9 +123,7 @@ class ApiAccountsActivateUsernameTempIdentifier(APIView):
123123
permission_classes = []
124124

125125
# For the success and error messages
126-
renderer_classes = [
127-
TemplateHTMLRenderer
128-
]
126+
renderer_classes = [TemplateHTMLRenderer]
129127
template_name = 'api/account_activation_message.html'
130128

131129
auth = []
@@ -533,7 +531,7 @@ class ApiObjectsDraftsModify(APIView):
533531
403: "Invalid token."
534532
}, tags=["BCO Management"])
535533
def post(self, request) -> Response:
536-
return check_post_and_process(request, POST_api_objects_drafts_modify)
534+
return check_post_and_process(request, post_api_objects_drafts_modify)
537535

538536

539537
class ApiObjectsDraftsPermissions(APIView):
@@ -806,6 +804,8 @@ class ApiObjectsSearch(APIView):
806804
Search for available BCO objects that match criteria.
807805
"""
808806

807+
# authentication_classes = []
808+
# permission_classes = []
809809
# TODO: Need to get the schema that is being sent here from FE
810810
request_body = openapi.Schema(
811811
type=openapi.TYPE_OBJECT,
@@ -822,7 +822,7 @@ class ApiObjectsSearch(APIView):
822822
403: "Invalid token."
823823
}, tags=["BCO Management"])
824824
def post(self, request) -> Response:
825-
return check_post_and_process(request, POST_api_objects_search)
825+
return check_post_and_process(request, post_api_objects_search)
826826

827827

828828
class ApiObjectsToken(APIView):

0 commit comments

Comments
 (0)