22import logging
33import time
44from . import helpers as helper
5+ from Access import notifications
56
67from BrowserStackAutomation .settings import DECLINE_REASONS
78from Access .models import UserAccessMapping , User , GroupV2 , AccessV2
89import datetime
910import json
1011from django .db import transaction
12+ from Access .background_task_manager import background_task
1113
1214logger = logging .getLogger (__name__ )
1315
1921 "title" : "{access_tag}: Duplicate Request not submitted" ,
2022 "msg" : "Access already granted or request in pending state. {access_label}" ,
2123}
24+ REQUEST_PROCESS_MSG = "The Request ({request_id}) is now being processed"
2225REQUEST_ERR_MSG = {
2326 "error_msg" : "Invalid Request" ,
2427 "msg" : "Please Contact Admin" ,
2730 "error_msg" : "The submitted form is empty. Tried direct access to reqeust access page" ,
2831 "msg" : "Error Occured while submitting your Request. Please contact the Admin" ,
2932}
30-
3133REQUEST_ACCESS_AUTO_APPROVED_MSG = {
3234 "title" : "{request_id} Request Approved" ,
3335 "msg" : "Once granted you will receive the update" ,
3436}
35-
36- REQUEST_DB_ERR_MSG = {
37- "error_msg" : "Error Saving Request" ,
38- "msg" : "Please Contact Admin" ,
39- }
40- REQUEST_IDENTITY_NOT_SETUP_ERR_MSG = {
41- "error_msg" : "Identity not setup" ,
42- "msg" : "User Identity for module {access_tag} not setup by the user" ,
43- }
44-
45- REQUEST_SUCCESS_MSG = {
46- "title" : "{request_id} Request Submitted" ,
47- "msg" : "Once approved you will receive the update. {access_label}" ,
48- }
49- REQUEST_DUPLICATE_ERR_MSG = {
50- "title" : "{access_tag}: Duplicate Request not submitted" ,
51- "msg" : "Access already granted or request in pending state. {access_label}" ,
52- }
53- REQUEST_ERR_MSG = {
54- "error_msg" : "Invalid Request" ,
55- "msg" : "Please Contact Admin" ,
56- }
57- REQUEST_EMPTY_FORM_ERR_MSG = {
58- "error_msg" : "The submitted form is empty. Tried direct access to reqeust access page" ,
59- "msg" : "Error Occured while submitting your Request. Please contact the Admin" ,
60- }
61-
62- REQUEST_ACCESS_AUTO_APPROVED_MSG = {
63- "title" : "{request_id} Request Approved" ,
64- "msg" : "Once granted you will receive the update" ,
65- }
66-
6737REQUEST_DB_ERR_MSG = {
6838 "error_msg" : "Error Saving Request" ,
6939 "msg" : "Please Contact Admin" ,
7242 "error_msg" : "Identity not setup" ,
7343 "msg" : "User Identity for module {access_tag} not setup by the user" ,
7444}
45+ USER_REQUEST_IN_PROCESS_ERR_MSG = "The Request ({request_id}) has already been processed. \
46+ Please check Access History for more information"
47+ USER_REQUEST_PERMISSION_DENIED_ERR_MSG = "Permission Denied!"
48+ USER_REQUEST_DECLINE_MSG = "Declined Request {request_id} - Reason: {decline_reason}"
49+ USER_REQUEST_SECONDARY_PENDING_MSG = "The Request ({request_id}) is approved by {approved_by} \
50+ Pending on secondary approver"
7551
7652
7753def requestAccessGet (request ):
@@ -117,6 +93,30 @@ def requestAccessGet(request):
11793 return context
11894
11995
96+ def validate_approver_permissions (access_mapping , access_type , request , request_id ):
97+ json_response = {}
98+
99+ access_label = access_mapping .access .access_label
100+ try :
101+ permissions = _get_approver_permissions (access_type , access_label )
102+ except Exception as e :
103+ return process_error_response (e )
104+
105+ approver_permissions = permissions ["approver_permissions" ]
106+ if "2" in approver_permissions and access_mapping .is_secondary_pending ():
107+ if not request .user .user .has_permission (approver_permissions ["2" ]):
108+ logger .debug (USER_REQUEST_PERMISSION_DENIED_ERR_MSG )
109+ json_response ["error" ] = USER_REQUEST_PERMISSION_DENIED_ERR_MSG
110+ return json_response
111+ elif access_mapping .is_pending ():
112+ if not request .user .user .has_permission (approver_permissions ["1" ]):
113+ logger .debug (USER_REQUEST_PERMISSION_DENIED_ERR_MSG )
114+ json_response ["error" ] = USER_REQUEST_PERMISSION_DENIED_ERR_MSG
115+ return json_response
116+
117+ return json_response
118+
119+
120120def getGrantFailedRequests (request ):
121121 try :
122122 failures = UserAccessMapping .objects .filter (
@@ -134,7 +134,7 @@ def getGrantFailedRequests(request):
134134 context = {"failures" : failures , "heading" : "Grant Failures" }
135135 return context
136136 except Exception as e :
137- return process_error_response (request , e )
137+ return process_error_response (e )
138138
139139
140140def get_pending_revoke_failures (request ):
@@ -178,7 +178,39 @@ def getPendingRequests(request):
178178
179179 return context
180180 except Exception as e :
181- return process_error_response (request , e )
181+ return process_error_response (e )
182+
183+
184+ def get_decline_access_request (request , access_type , request_id ):
185+ logger .info ("Decline Access Request call initiated" )
186+ try :
187+ context = {"response" : {}}
188+ reason = request .GET ["reason" ]
189+ request_ids = []
190+ return_ids = []
191+ if access_type .endswith ("-club" ):
192+ for value in [request_id ]:
193+ return_ids .append (value )
194+ current_ids = list (
195+ UserAccessMapping .get_pending_access_mapping (request_id = value )
196+ )
197+ request_ids .extend (current_ids )
198+ access_type = access_type .rsplit ("-" , 1 )[0 ]
199+ else :
200+ request_ids = [request_id ]
201+ for current_request_id in request_ids :
202+ response = decline_individual_access (
203+ request , access_type , current_request_id , reason
204+ )
205+ if "error" in response :
206+ response ["success" ] = False
207+ else :
208+ response ["success" ] = True
209+ context ["response" ][current_request_id ] = response
210+ context ["returnIds" ] = return_ids
211+ return context
212+ except Exception as e :
213+ return process_error_response (e )
182214
183215
184216def get_pending_accesses_from_modules (access_user ):
@@ -191,7 +223,6 @@ def get_pending_accesses_from_modules(access_user):
191223 access_module ,
192224 ) in helpers .get_available_access_modules ().items ():
193225 access_module_start_time = time .time ()
194-
195226 try :
196227 pending_accesses = access_module .get_pending_accesses (access_user )
197228 except Exception as e :
@@ -282,7 +313,7 @@ def process_group_requests(group_pending_requests, group_requests):
282313 group_requests [club_id ]["accessData" ].append (accessData )
283314
284315
285- def process_error_response (request , e ):
316+ def process_error_response (e ):
286317 logger .debug ("Error in request not found OR Invalid request type" )
287318 logger .exception (e )
288319 json_response = {}
@@ -398,7 +429,6 @@ def _create_access(auth_user, access_label, access_type, request_id, access_reas
398429 }
399430
400431 try :
401-
402432 access = _create_access_mapping (
403433 access = access ,
404434 user_identity = user_identity ,
@@ -475,3 +505,182 @@ def validate_access_labels(access_labels_json, access_type):
475505 )
476506 )
477507 return access_labels
508+
509+
510+ def _get_approver_permissions (access_type , access_label = None ):
511+ json_response = {}
512+
513+ access_module = helper .get_available_access_module_from_tag (access_type )
514+ approver_permissions = []
515+ approver_permissions = access_module .fetch_approver_permissions (access_label )
516+
517+ json_response ["approver_permissions" ] = approver_permissions
518+ if len (json_response ) == 0 :
519+ raise Exception ("Approver Permissions not found for module %s " % access_module )
520+ return json_response
521+
522+
523+ def is_request_valid (request_id , access_mapping ):
524+ if access_mapping .is_already_processed ():
525+ logger .warning (
526+ USER_REQUEST_IN_PROCESS_ERR_MSG .format (
527+ request_id = request_id ,
528+ )
529+ )
530+ return False
531+
532+ return True
533+
534+
535+ def accept_user_access_requests (request , access_type , request_id ):
536+ json_response = {}
537+ access_mapping = UserAccessMapping .get_access_request (request_id )
538+ if not is_request_valid (request_id , access_mapping ):
539+ json_response ["error" ] = USER_REQUEST_IN_PROCESS_ERR_MSG .format (
540+ request_id = request_id ,
541+ )
542+ return json_response
543+
544+ requester = access_mapping .user_identity .user .email
545+ if request .user .username == requester :
546+ json_response ["error" ] = USER_REQUEST_PERMISSION_DENIED_ERR_MSG
547+ return json_response
548+
549+ access_label = access_mapping .access .access_label
550+
551+ try :
552+ permissions = _get_approver_permissions (access_type , access_label )
553+ approver_permissions = permissions ["approver_permissions" ]
554+ if not helper .check_user_permissions (
555+ request .user , list (approver_permissions .values ())
556+ ):
557+ logger .debug (USER_REQUEST_PERMISSION_DENIED_ERR_MSG )
558+ json_response ["error" ] = USER_REQUEST_PERMISSION_DENIED_ERR_MSG
559+ return json_response
560+
561+ is_primary_approver = (
562+ access_mapping .is_pending ()
563+ and request .user .user .has_permission (approver_permissions ["1" ])
564+ )
565+ is_secondary_approver = (
566+ access_mapping .is_secondary_pending ()
567+ and request .user .user .has_permission (approver_permissions ["2" ])
568+ )
569+
570+ if not (is_primary_approver or is_secondary_approver ):
571+ logger .debug (USER_REQUEST_PERMISSION_DENIED_ERR_MSG )
572+ json_response ["error" ] = USER_REQUEST_PERMISSION_DENIED_ERR_MSG
573+ return json_response
574+ if is_primary_approver and "2" in approver_permissions :
575+ access_mapping .approver_1 = request .user .user
576+ access_mapping .update_access_status ("SecondaryPending" )
577+ json_response ["msg" ] = USER_REQUEST_SECONDARY_PENDING_MSG .format (
578+ request_id = request_id , approved_by = request .user .username
579+ )
580+ logger .debug (
581+ USER_REQUEST_SECONDARY_PENDING_MSG .format (
582+ request_id = request_id , approved_by = request .user .username
583+ )
584+ )
585+ else :
586+ json_response = run_accept_request_task (
587+ is_primary_approver ,
588+ access_mapping ,
589+ request ,
590+ request_id ,
591+ access_type ,
592+ access_label ,
593+ )
594+ except Exception as e :
595+ return process_error_response (e )
596+
597+ return json_response
598+
599+
600+ def run_accept_request_task (
601+ is_primary_approver , access_mapping , request , request_id , access_type , access_label
602+ ):
603+ json_response = {}
604+ json_response ["status" ] = []
605+ if is_primary_approver :
606+ access_mapping .approver_1 = request .user .user
607+ else :
608+ access_mapping .approver_2 = request .user .user
609+ json_response ["msg" ] = REQUEST_PROCESS_MSG .format (request_id = request_id )
610+
611+ with transaction .atomic ():
612+ try :
613+ access_mapping .update_access_status ("Processing" )
614+
615+ background_task (
616+ "run_accept_request" ,
617+ json .dumps ({"request_id" : request_id , "access_type" : access_type }),
618+ )
619+ except Exception as e :
620+ logger .exception (e )
621+ raise Exception (
622+ "Error in accepting the request - {request_id}. Please try again." .format (
623+ request_id = request_id
624+ )
625+ )
626+
627+ json_response ["status" ].append (
628+ {
629+ "title" : REQUEST_SUCCESS_MSG ["title" ].format (request_id = request_id ),
630+ "msg" : REQUEST_SUCCESS_MSG ["msg" ].format (
631+ access_label = json .dumps (access_label )
632+ ),
633+ }
634+ )
635+
636+ return json_response
637+
638+
639+ def decline_individual_access (request , access_type , request_id , reason ):
640+ json_response = {}
641+ access_mapping = UserAccessMapping .get_access_request (request_id )
642+ if not is_request_valid (request_id , access_mapping ):
643+ json_response ["error" ] = USER_REQUEST_IN_PROCESS_ERR_MSG .format (
644+ request_id = request_id ,
645+ )
646+ return json_response
647+
648+ json_response = validate_approver_permissions (
649+ access_mapping , access_type , request , request_id
650+ )
651+ if "error" in json_response :
652+ return json_response
653+
654+ with transaction .atomic ():
655+ access_mapping .decline_access (reason )
656+ if hasattr (access_mapping , "approver_1" ):
657+ access_mapping .decline_reason = reason
658+ if access_mapping .approver_1 is not None :
659+ access_mapping .approver_2 = request .user .user
660+ else :
661+ access_mapping .approver_1 = request .user .user
662+ else :
663+ access_mapping .reason = reason
664+ access_mapping .approver = request .user .username
665+
666+ access_mapping .save ()
667+
668+ access_module = helper .get_available_access_module_from_tag (access_type )
669+ access_labels = [access_mapping .access .access_label ]
670+ description = access_module .combine_labels_desc (access_labels )
671+ notifications .send_mail_for_request_decline (
672+ request , description , request_id , reason , access_type
673+ )
674+
675+ logger .debug (
676+ USER_REQUEST_DECLINE_MSG .format (
677+ request_id = request_id ,
678+ decline_reason = reason ,
679+ )
680+ )
681+ json_response = {}
682+ json_response ["msg" ] = USER_REQUEST_DECLINE_MSG .format (
683+ request_id = request_id ,
684+ decline_reason = reason ,
685+ )
686+ return json_response
0 commit comments