From af1e782a12894612b3710e3154a919ba3c67b52d Mon Sep 17 00:00:00 2001
From: atlurie <atlurie@uab.edu>
Date: Fri, 10 Jun 2022 15:07:27 -0500
Subject: [PATCH] ssh_access agent passes the msg to and from group_member
 agent.

Previously to block ssh access, user is put in nossh group by ssh_access
agent. This new design will make use of group_member agent that is part
of group management framework which puts a user in a group list provided.
---
 prod_rmq_agents/ssh_access.py | 99 ++++++++++++++++++++++++++---------
 1 file changed, 74 insertions(+), 25 deletions(-)

diff --git a/prod_rmq_agents/ssh_access.py b/prod_rmq_agents/ssh_access.py
index e289e57..34f3274 100644
--- a/prod_rmq_agents/ssh_access.py
+++ b/prod_rmq_agents/ssh_access.py
@@ -2,8 +2,9 @@
 import os
 import json
 import pika
+import uuid
 import rc_util
-from os import popen
+from subprocess import Popen,PIPE
 from pathlib import Path
 from rc_rmq import RCRMQ
 import rabbit_config as rcfg
@@ -16,47 +17,95 @@ logger = rc_util.get_logger(args)
 # Instantiate rabbitmq object
 rc_rmq = RCRMQ({"exchange": rcfg.Exchange, "exchange_type": "topic"})
 
+print("ssh_agent entered")
 
 def ssh_access(ch, method, properties, body):
     msg = json.loads(body)
+    routing_key = method.routing_key
     username = msg["username"]
     action = msg["action"]
     msg["task"] = task
-    corr_id = properties.correlation_id
-    reply_to = properties.reply_to
+    queuename = msg["queuename"]
+    state = msg["state"]
+    lock_groups = rcfg.lock_groups
 
+    global corr_id
     try:
-        block_ssh_cmd = f'/cm/local/apps/cmd/bin/cmsh -n -c "group; use nossh; append members {username}; commit;"'
-        unblock_ssh_cmd = f'/cm/local/apps/cmd/bin/cmsh -n -c "group; use nossh; removefrom members {username}; commit;"'
-
-        if action == 'lock':
-            block_ssh = popen(block_ssh_cmd).read().rstrip()
-        elif action == 'unlock':
-            unblock_ssh = popen(unblock_ssh_cmd).read().rstrip()
-
-        msg["success"] = True
-        logger.info(f"User {username} is added to nossh group")
-
+    # check if it's a response from group_member_agent
+        if routing_key == task:
+            print("routing_key matches")
+            print(f"corr_id sent by group_member agent: {properties.correlation_id}")
+            if corr_id == properties.correlation_id:
+                print(f'group_member agent confirmation msg["success"]: {msg["success"]}')
+                # forward confirmation response to acct_mgmt_workflow agent
+                rc_rmq.publish_msg(
+                   {
+                    "routing_key": f'acctmgr.done.{queuename}',
+                    "msg": msg
+                   }
+                )
+                logger.debug(f'User {username} confirmation sent for {action}ing {task}')
+                
+        else:
+            corr_id = str(uuid.uuid4())
+            print(f'corr_id generated: {corr_id}')
+
+            if state == 'certification':
+                msg["action"] = "add"
+                msg["groupnames"] = [lock_groups[state]]
+
+            elif state == 'hold':
+                msg["action"] = "add"
+                msg["groupnames"] = [lock_groups[state]]
+
+            elif state == 'pre_certification':
+                msg["action"] = "add"
+                msg["groupnames"] = [lock_groups[state]]
+
+            elif state == 'ok':
+                msg["action"] = "remove"
+                proc = Popen(['/usr/bin/groups', username], stdout=PIPE, stderr=PIPE)
+                out,err = proc.communicate()
+ 
+                user_group_list = out.decode().strip().split(":")[1].split()
+ 
+                """
+                  Filter the lock group a user is in and assign to msg["groupnames"]
+                  lambda function returns common elements between two lists. For all
+                  the true values by returned lambda function for common elements 
+                  corresponding values are included as a list by filter function.
+                """
+                msg["groupnames"] = list(filter(lambda x:x in list(lock_groups.values()),user_group_list))
+ 
+            #msg["success"] = True
+ 
+            # send a message to group_member.py agent
+            logger.info(f"Request sent to add user {username} to {msg['groupnames']} group")
+            print(f"sending msg to group agent {msg}")
+            rc_rmq.publish_msg(
+                {
+                   "routing_key": f'group_member.{queuename}',
+                   "props": pika.BasicProperties(
+                                correlation_id = corr_id,
+                                reply_to = task,
+                                ),
+                   "msg": msg
+                }
+            )
+ 
     except Exception:
         msg["success"] = False
-        msg["errmsg"] = "Exception raised, while blocking user's ssh access, check the logs for stack trace"
+        msg["errmsg"] = "Exception raised in ssh_access agent, check the logs for stack trace"
         logger.error("", exc_info=True)
 
-    # send response to callback queue with it's correlation ID
-    rc_rmq.publish_msg(
-        {
-         "routing_key": f'acctmgr.done.{queuename}',
-         "msg": msg
-        }
-    )
-
-    logger.debug(f"User {username} confirmation sent for {action}ing {task}")
-
     ch.basic_ack(delivery_tag=method.delivery_tag)
 
 
 logger.info(f"Start listening to queue: {task}")
+rc_rmq.bind_queue(queue=task, routing_key='lock.*', durable=True)
+rc_rmq.bind_queue(queue=task, routing_key='unlock.*', durable=True)
 rc_rmq.bind_queue(queue=task, routing_key='ssh.*', durable=True)
+rc_rmq.bind_queue(queue=task, routing_key=task, durable=True)
 
 rc_rmq.start_consume(
     {"queue": task, "cb": ssh_access}
-- 
GitLab