Skip to content

Commit 0516a90

Browse files
committed
Merge branch 'main' into feat-group-mark-revoked
2 parents 316485c + c42c247 commit 0516a90

14 files changed

+677
-206
lines changed

Access/accessrequest_helper.py

Lines changed: 311 additions & 54 deletions
Large diffs are not rendered by default.

Access/background_task_manager.py

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
from Access import helpers
1010
from bootprocess import general
1111
from BrowserStackAutomation.settings import AUTOMATED_EXEC_IDENTIFIER
12-
from Access.models import UserAccessMapping, User
12+
from Access.models import UserAccessMapping, ApprovalType
1313
from Access import notifications
1414

1515
logger = logging.getLogger(__name__)
1616

17+
1718
with open("config.json") as data_file:
1819
background_task_manager_type = json.load(data_file)["background_task_manager"][
1920
"type"
@@ -30,7 +31,8 @@ def background_task(func, *args):
3031
elif func == "run_accept_request":
3132
run_accept_request.delay(*args)
3233
elif func == "run_access_revoke":
33-
run_access_revoke.delay(*args)
34+
request_id = args[0]
35+
run_access_revoke.delay(request_id)
3436
else:
3537
if func == "run_access_grant":
3638
request_id = args[0]
@@ -56,7 +58,7 @@ def background_task(func, *args):
5658
)
5759
def run_access_grant(request_id):
5860
user_access_mapping = UserAccessMapping.get_access_request(request_id=request_id)
59-
access_type = user_access_mapping.access.access_tag
61+
access_tag = user_access_mapping.access.access_tag
6062
user = user_access_mapping.user_identity.user
6163
approver = user_access_mapping.approver_1.user.username
6264
message = ""
@@ -75,6 +77,10 @@ def run_access_grant(request_id):
7577
user_access_mapping.grant_fail_access(
7678
fail_reason="Failed since identity is blank for user identity"
7779
)
80+
notifications.send_mail_for_request_granted_failure(
81+
user, approver, access_tag, request_id
82+
)
83+
7884
logger.debug(
7985
{
8086
"requestId": request_id,
@@ -85,7 +91,7 @@ def run_access_grant(request_id):
8591
)
8692
return False
8793

88-
access_module = helpers.get_available_access_module_from_tag(access_type)
94+
access_module = helpers.get_available_access_module_from_tag(access_tag)
8995
if not access_module:
9096
return False
9197

@@ -132,10 +138,10 @@ def run_access_grant(request_id):
132138
}
133139
)
134140
try:
135-
destination = access_module.access_mark_revoke_permission(access_type)
141+
destination = access_module.access_mark_revoke_permission(access_tag)
136142
notifications.send_mail_for_access_grant_failed(
137143
destination,
138-
access_type.upper(),
144+
access_tag.upper(),
139145
user.email,
140146
request_id=request_id,
141147
message=message,
@@ -157,37 +163,36 @@ def run_access_grant(request_id):
157163
@shared_task(
158164
autoretry_for=(Exception,), retry_kwargs={"max_retries": 3, "countdown": 5}
159165
)
160-
def run_access_revoke(data):
161-
data = json.loads(data)
162-
access_mapping = UserAccessMapping.get_access_request(data["request_id"])
166+
def run_access_revoke(request_id):
167+
access_mapping = UserAccessMapping.get_access_request(request_id=request_id)
163168
if not access_mapping:
164169
# TODO: Have to add the email targets for failure
165170
targets = []
166171
message = "Request not found"
167172
notifications.send_revoke_failure_mail(
168-
targets, data["request_id"], data["revoker_email"], 0, message
173+
targets, request_id, access_mapping.revoker.email, 0, message
169174
)
170-
return {"status": False}
175+
return False
171176
elif access_mapping.status == "Revoked":
172-
return {"status": True}
177+
return True
173178
access = access_mapping.access
174179
user_identity = access_mapping.user_identity
175180

176-
revoker = User.get_user_by_email(data["revoker_email"])
181+
revoker = access_mapping.revoker
177182
if not revoker:
178183
# TODO: Have to add the email targets for failure
179184
targets = []
180185
message = "Revoker not found"
181186
notifications.send_revoke_failure_mail(
182187
targets,
183-
data["request_id"],
184-
data["revoker_email"],
188+
request_id,
189+
access_mapping.revoker.email,
185190
0,
186191
message,
187192
access.access_tag,
188193
)
189194
user_identity.mark_revoke_failed_for_approved_access_mapping(access)
190-
return {"status": False}
195+
return False
191196

192197
access_modules = helpers.get_available_access_modules()
193198

@@ -227,7 +232,7 @@ def run_access_revoke(data):
227232
user_identity.mark_revoke_failed_for_approved_access_mapping(access)
228233
raise Exception("Failed to revoke the access due to: " + str(message))
229234

230-
return {"status": True}
235+
return True
231236

232237

233238
@task_success.connect(sender=run_access_grant)
@@ -278,6 +283,7 @@ def run_accept_request(data):
278283
result = background_task("run_access_grant", request_id)
279284
if result:
280285
return {"status": True}
286+
281287
notifications.send_mail_for_request_granted_failure(
282288
user, approver, access_type, request_id
283289
)
@@ -291,3 +297,32 @@ def run_accept_request(data):
291297
)
292298

293299
return {"status": False}
300+
301+
302+
def accept_request(user_access_mapping, approval_type, approver):
303+
result = None
304+
if approval_type != ApprovalType.Primary and approval_type != ApprovalType.Secondary:
305+
raise Exception("Invalid Approval Type")
306+
307+
user_access_mapping.processing(approval_type = approval_type, approver=approver)
308+
try:
309+
result = run_access_grant.delay(user_access_mapping.request_id)
310+
except Exception:
311+
user_access_mapping.grant_fail_access(fail_reason="Task could not be queued")
312+
313+
if result:
314+
return True
315+
return False
316+
317+
def revoke_request(user_access_mapping, revoker=None):
318+
result = None
319+
# change the status to revoke processing
320+
user_access_mapping.revoking(revoker)
321+
try:
322+
result = run_access_revoke.delay(user_access_mapping.request_id)
323+
except Exception:
324+
user_access_mapping.RevokeFailed(fail_reason="Task could not be queued")
325+
326+
if result:
327+
return True
328+
return False

Access/group_helper.py

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from Access.views_helper import execute_group_access
77
from BrowserStackAutomation.settings import MAIL_APPROVER_GROUPS, PERMISSION_CONSTANTS
88
from . import helpers as helper
9-
from Access.background_task_manager import background_task
9+
from Access.background_task_manager import background_task, revoke_request
1010
import json
1111

1212
logger = logging.getLogger(__name__)
@@ -24,6 +24,9 @@
2424
"msg": "Error Occured while loading the page. Please contact admin",
2525
}
2626

27+
USER_UNAUTHORIZED_MESSAGE = "User unauthorised to perform the action."
28+
GROUP_ACCESS_MAPPING_NOT_FOUND = "Group Access Mapping not found in the database."
29+
2730
NEW_GROUP_CREATE_ERROR_GROUP_EXISTS = {
2831
"error_msg": "Invalid Group Name",
2932
"msg": "A group with name {group_name} already exists. Please choose a new name.",
@@ -172,7 +175,7 @@ def get_generic_access(group_mapping):
172175
return access_details
173176

174177

175-
def get_group_access_list(request, group_name):
178+
def get_group_access_list(auth_user, group_name):
176179
context = {}
177180
group = GroupV2.get_active_group_by_name(group_name)
178181
if not group:
@@ -186,7 +189,7 @@ def get_group_access_list(request, group_name):
186189
return context
187190

188191
group_members = group.get_all_members().filter(status="Approved")
189-
auth_user = request.user
192+
auth_user = auth_user
190193

191194
if not auth_user.user.is_allowed_admin_actions_on_group(group):
192195
logger.debug("Permission denied, requester is non owner")
@@ -304,7 +307,7 @@ def check_user_is_group_owner(user_name, group):
304307
return False
305308

306309

307-
def approve_new_group_request(request, group_id):
310+
def approve_new_group_request(auth_user, group_id):
308311
try:
309312
group = GroupV2.get_pending_group(group_id=group_id)
310313
except Exception as e:
@@ -316,7 +319,7 @@ def approve_new_group_request(request, group_id):
316319
context["error"] = REQUEST_NOT_FOUND_ERROR
317320
return context
318321
try:
319-
if group.is_self_approval(approver=request.user.user):
322+
if group.is_self_approval(approver=auth_user.user):
320323
context = {}
321324
context["error"] = SELF_APPROVAL_ERROR
322325
return context
@@ -325,8 +328,8 @@ def approve_new_group_request(request, group_id):
325328
context["msg"] = REQUEST_PROCESSING.format(requestId=group_id)
326329

327330
with transaction.atomic():
328-
group.approve(approved_by=request.user.user)
329-
group.approve_all_pending_users(approved_by=request.user.user)
331+
group.approve(approved_by=auth_user.user)
332+
group.approve_all_pending_users(approved_by=auth_user.user)
330333
initial_members = group.get_all_members()
331334
initial_member_names = [user.user.name for user in initial_members]
332335
try:
@@ -344,7 +347,7 @@ def approve_new_group_request(request, group_id):
344347
"Approved group creation for - "
345348
+ group_id
346349
+ " - Approver="
347-
+ request.user.username
350+
+ auth_user.username
348351
)
349352
if initial_members:
350353
logger.debug(
@@ -502,7 +505,7 @@ def is_user_in_group(user_email, group_members_email):
502505
return user_email in group_members_email
503506

504507

505-
def accept_member(request, requestId, shouldRender=True):
508+
def accept_member(auth_user, requestId, shouldRender=True):
506509
try:
507510
membership = MembershipV2.get_membership(membership_id=requestId)
508511
except Exception as e:
@@ -511,25 +514,25 @@ def accept_member(request, requestId, shouldRender=True):
511514
context["error"] = REQUEST_NOT_FOUND_ERROR + str(e)
512515
return context
513516
try:
514-
if membership.is_already_processed():
517+
if not membership.is_pending():
515518
logger.warning(
516519
"An Already Approved/Declined/Processing Request was accessed by - "
517-
+ request.user.username
520+
+ auth_user.username
518521
)
519522
context = {}
520523
context["error"] = REQUEST_PROCESSED_BY.format(
521524
requestId=requestId, user=membership.approver.user.username
522525
)
523526
return context
524-
elif membership.is_self_approval(approver=request.user.user):
527+
elif membership.is_self_approval(approver=auth_user.user):
525528
context = {}
526529
context["error"] = SELF_APPROVAL_ERROR
527530
return context
528531
else:
529532
context = {}
530533
context["msg"] = REQUEST_PROCESSING.format(requestId=requestId)
531534
with transaction.atomic():
532-
membership.approve(request.user.user)
535+
membership.approve(auth_user.user)
533536
group = membership.group
534537
user = membership.user
535538
user_mappings_list = views_helper.generate_user_mappings(
@@ -545,7 +548,7 @@ def accept_member(request, requestId, shouldRender=True):
545548
"Process has been started for the Approval of request - "
546549
+ requestId
547550
+ " - Approver="
548-
+ request.user.username
551+
+ auth_user.username
549552
)
550553
return context
551554
except Exception as e:
@@ -700,21 +703,10 @@ def validate_group_access_create_request(group, auth_user):
700703
return None
701704

702705

703-
def revoke_user_access(user, access, revoker_email):
706+
def revoke_user_access(user, access, revoker, decline_message):
704707
user_identity = user.get_active_identity(access.access_tag)
705-
user_identity.decline_non_approved_access_mapping(access)
706-
user_identity.offboarding_approved_access_mapping(access)
707-
background_task(
708-
"run_access_revoke",
709-
json.dumps(
710-
{
711-
"request_id": user_identity.get_granted_access_mapping(access)
712-
.first()
713-
.request_id,
714-
"revoker_email": revoker_email,
715-
}
716-
),
717-
)
708+
user_identity.decline_non_approved_access_mapping(access, decline_message)
709+
revoke_request(user_identity.get_granted_access_mapping(access).first(), revoker)
718710

719711
def remove_member(request):
720712
try:
@@ -747,7 +739,8 @@ def remove_member(request):
747739
revoke_accesses = list(set(revoke_group_accesses) - set(other_group_accesses))
748740

749741
for access in revoke_accesses:
750-
revoke_user_access(user, access, request.user.user.email)
742+
with transaction.atomic():
743+
revoke_user_access(user, access, request.user.user, "User removed from the group")
751744

752745
membership.revoke_membership()
753746

@@ -771,26 +764,27 @@ def revoke_access_from_group(request):
771764
request_id = request.POST.get("request_id")
772765
if not request_id:
773766
logger.debug("Cannot find request_id in the http request.")
774-
raise Exception("Request id not found in the request.")
767+
return {"error": ERROR_MESSAGE}
775768

776769
mapping = GroupAccessMapping.get_by_id(request_id)
777770
if not mapping:
778771
logger.debug("Group Access Mapping not found in the database")
779-
raise Exception("Group Access Mapping not found in the database")
772+
return {"error": GROUP_ACCESS_MAPPING_NOT_FOUND}
780773
except Exception as e:
781774
logger.exception(str(e))
782775
return {"error": ERROR_MESSAGE}
783776

784777
group = mapping.group
785778
auth_user = request.user
786779
if not (auth_user.user.has_permission("ALLOW_USER_OFFBOARD") and group.member_is_owner(auth_user.user)):
787-
raise Exception("User Unauthorized to perfrom the action")
780+
return {"error": USER_UNAUTHORIZED_MESSAGE}
788781

789782
for membership in group.get_all_approved_members():
790783
if access_exist_in_other_groups_of_user(membership, group, mapping.access):
791784
continue
792785

793-
revoke_user_access(membership.user, mapping.access, auth_user.user.email)
786+
with transaction.atomic():
787+
revoke_user_access(membership.user, mapping.access, auth_user.user, "Access revoked for the group")
794788

795789
mapping.mark_revoked(auth_user.user)
796790

0 commit comments

Comments
 (0)