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
1410from rest_framework import status
1511from 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 )
0 commit comments