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-
31- REQUEST_ACCESS_AUTO_APPROVED_MSG = {
32- "title" : "{request_id} Request Approved" ,
33- "msg" : "Once granted you will receive the update" ,
34- }
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-
6233REQUEST_ACCESS_AUTO_APPROVED_MSG = {
6334 "title" : "{request_id} Request Approved" ,
6435 "msg" : "Once granted you will receive the update" ,
6536}
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 = {}
@@ -475,3 +506,182 @@ def validate_access_labels(access_labels_json, access_type):
475506 )
476507 )
477508 return access_labels
509+
510+
511+ def _get_approver_permissions (access_type , access_label = None ):
512+ json_response = {}
513+
514+ access_module = helper .get_available_access_module_from_tag (access_type )
515+ approver_permissions = []
516+ approver_permissions = access_module .fetch_approver_permissions (access_label )
517+
518+ json_response ["approver_permissions" ] = approver_permissions
519+ if len (json_response ) == 0 :
520+ raise Exception ("Approver Permissions not found for module %s " % access_module )
521+ return json_response
522+
523+
524+ def is_request_valid (request_id , access_mapping ):
525+ if access_mapping .is_already_processed ():
526+ logger .warning (
527+ USER_REQUEST_IN_PROCESS_ERR_MSG .format (
528+ request_id = request_id ,
529+ )
530+ )
531+ return False
532+
533+ return True
534+
535+
536+ def accept_user_access_requests (request , access_type , request_id ):
537+ json_response = {}
538+ access_mapping = UserAccessMapping .get_access_request (request_id )
539+ if not is_request_valid (request_id , access_mapping ):
540+ json_response ["error" ] = USER_REQUEST_IN_PROCESS_ERR_MSG .format (
541+ request_id = request_id ,
542+ )
543+ return json_response
544+
545+ requester = access_mapping .user_identity .user .email
546+ if request .user .username == requester :
547+ json_response ["error" ] = USER_REQUEST_PERMISSION_DENIED_ERR_MSG
548+ return json_response
549+
550+ access_label = access_mapping .access .access_label
551+
552+ try :
553+ permissions = _get_approver_permissions (access_type , access_label )
554+ approver_permissions = permissions ["approver_permissions" ]
555+ if not helper .check_user_permissions (
556+ request .user , list (approver_permissions .values ())
557+ ):
558+ logger .debug (USER_REQUEST_PERMISSION_DENIED_ERR_MSG )
559+ json_response ["error" ] = USER_REQUEST_PERMISSION_DENIED_ERR_MSG
560+ return json_response
561+
562+ is_primary_approver = (
563+ access_mapping .is_pending ()
564+ and request .user .user .has_permission (approver_permissions ["1" ])
565+ )
566+ is_secondary_approver = (
567+ access_mapping .is_secondary_pending ()
568+ and request .user .user .has_permission (approver_permissions ["2" ])
569+ )
570+
571+ if not (is_primary_approver or is_secondary_approver ):
572+ logger .debug (USER_REQUEST_PERMISSION_DENIED_ERR_MSG )
573+ json_response ["error" ] = USER_REQUEST_PERMISSION_DENIED_ERR_MSG
574+ return json_response
575+ if is_primary_approver and "2" in approver_permissions :
576+ access_mapping .approver_1 = request .user .user
577+ access_mapping .update_access_status ("SecondaryPending" )
578+ json_response ["msg" ] = USER_REQUEST_SECONDARY_PENDING_MSG .format (
579+ request_id = request_id , approved_by = request .user .username
580+ )
581+ logger .debug (
582+ USER_REQUEST_SECONDARY_PENDING_MSG .format (
583+ request_id = request_id , approved_by = request .user .username
584+ )
585+ )
586+ else :
587+ json_response = run_accept_request_task (
588+ is_primary_approver ,
589+ access_mapping ,
590+ request ,
591+ request_id ,
592+ access_type ,
593+ access_label ,
594+ )
595+ except Exception as e :
596+ return process_error_response (e )
597+
598+ return json_response
599+
600+
601+ def run_accept_request_task (
602+ is_primary_approver , access_mapping , request , request_id , access_type , access_label
603+ ):
604+ json_response = {}
605+ json_response ["status" ] = []
606+ if is_primary_approver :
607+ access_mapping .approver_1 = request .user .user
608+ else :
609+ access_mapping .approver_2 = request .user .user
610+ json_response ["msg" ] = REQUEST_PROCESS_MSG .format (request_id = request_id )
611+
612+ with transaction .atomic ():
613+ try :
614+ access_mapping .update_access_status ("Processing" )
615+
616+ background_task (
617+ "run_accept_request" ,
618+ json .dumps ({"request_id" : request_id , "access_type" : access_type }),
619+ )
620+ except Exception as e :
621+ logger .exception (e )
622+ raise Exception (
623+ "Error in accepting the request - {request_id}. Please try again." .format (
624+ request_id = request_id
625+ )
626+ )
627+
628+ json_response ["status" ].append (
629+ {
630+ "title" : REQUEST_SUCCESS_MSG ["title" ].format (request_id = request_id ),
631+ "msg" : REQUEST_SUCCESS_MSG ["msg" ].format (
632+ access_label = json .dumps (access_label )
633+ ),
634+ }
635+ )
636+
637+ return json_response
638+
639+
640+ def decline_individual_access (request , access_type , request_id , reason ):
641+ json_response = {}
642+ access_mapping = UserAccessMapping .get_access_request (request_id )
643+ if not is_request_valid (request_id , access_mapping ):
644+ json_response ["error" ] = USER_REQUEST_IN_PROCESS_ERR_MSG .format (
645+ request_id = request_id ,
646+ )
647+ return json_response
648+
649+ json_response = validate_approver_permissions (
650+ access_mapping , access_type , request , request_id
651+ )
652+ if "error" in json_response :
653+ return json_response
654+
655+ with transaction .atomic ():
656+ access_mapping .decline_access (reason )
657+ if hasattr (access_mapping , "approver_1" ):
658+ access_mapping .decline_reason = reason
659+ if access_mapping .approver_1 is not None :
660+ access_mapping .approver_2 = request .user .user
661+ else :
662+ access_mapping .approver_1 = request .user .user
663+ else :
664+ access_mapping .reason = reason
665+ access_mapping .approver = request .user .username
666+
667+ access_mapping .save ()
668+
669+ access_module = helper .get_available_access_module_from_tag (access_type )
670+ access_labels = [access_mapping .access .access_label ]
671+ description = access_module .combine_labels_desc (access_labels )
672+ notifications .send_mail_for_request_decline (
673+ request , description , request_id , reason , access_type
674+ )
675+
676+ logger .debug (
677+ USER_REQUEST_DECLINE_MSG .format (
678+ request_id = request_id ,
679+ decline_reason = reason ,
680+ )
681+ )
682+ json_response = {}
683+ json_response ["msg" ] = USER_REQUEST_DECLINE_MSG .format (
684+ request_id = request_id ,
685+ decline_reason = reason ,
686+ )
687+ return json_response
0 commit comments