From 8e1b0fa9a5b7e959fbf430cd61a8355b9fbd56eb Mon Sep 17 00:00:00 2001
From: Alexis Koralewski <akoralewski@irap.omp.eu>
Date: Thu, 24 Nov 2022 15:13:47 +0100
Subject: [PATCH] Add login required of agents view & add get_all_cmds management

---
 CHANGELOG                                |  4 +++-
 VERSION                                  |  2 +-
 src/core/pyros_django/api/views.py       |  1 +
 src/core/pyros_django/dashboard/views.py | 65 ++++++++++++++++++++++++++++++++++++++++++-----------------------
 4 files changed, 47 insertions(+), 25 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 3eeb348..335b1c5 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
 24-11-2022 (AKo): v0.6.11.1
 	- AgentSST change names of agents when launched with simulated computer
-	
+	- Add login required of agents view & add get_all_cmds management
+	- UI changes on agent_detail view
+
 24-11-2022 (EP): v0.6.11.0
 	- Agent specific command execution in THREAD => now possible
 	- bugfix do_stop/restart => valeur de retour
diff --git a/VERSION b/VERSION
index 45a346d..3d09cb3 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.6.11
+0.6.11.1
\ No newline at end of file
diff --git a/src/core/pyros_django/api/views.py b/src/core/pyros_django/api/views.py
index 21ae6e3..18cfc82 100644
--- a/src/core/pyros_django/api/views.py
+++ b/src/core/pyros_django/api/views.py
@@ -279,6 +279,7 @@ class AgentCmdViewSet(viewsets.ModelViewSet):
             commands_recivied_by_agent = AgentCmd.get_commands_sent_to_agent(agent_name)
             agent_cmds = commands_sent_by_agent | commands_recivied_by_agent
             agent_cmds = agent_cmds.exclude(full_name="get_specific_cmds")
+            agent_cmds = agent_cmds.exclude(full_name="get_all_cmds")
             agent_cmds = agent_cmds.order_by("-s_deposit_time")
             if number:
                 number = int(number)
diff --git a/src/core/pyros_django/dashboard/views.py b/src/core/pyros_django/dashboard/views.py
index 3408e49..44c1856 100644
--- a/src/core/pyros_django/dashboard/views.py
+++ b/src/core/pyros_django/dashboard/views.py
@@ -187,32 +187,33 @@ def settings(request):
     CAN_VIEW_AGENTS_STATE = request.session.get("role") in ("Admin", "Unit-PI", "Operator")
     return(render(request, "dashboard/settings.html", locals()))
 
-def get_last_specific_cmds(agent_name):
-    last_agent_specific_cmds = None
+def get_last_all_cmds(agent_name):
+    last_agent_all_cmds = None
     last_do_stop_cmd = None
     if "AgentSST" not in agent_name:
         try:
-            last_agent_specific_cmds = AgentCmd.objects.filter(full_name="get_specific_cmds",recipient=agent_name,state__contains="CMD_EXECUTED").latest("s_deposit_time")
+            last_agent_all_cmds = AgentCmd.objects.filter(full_name="get_all_cmds",recipient=agent_name,state__contains="CMD_EXECUTED").latest("s_deposit_time")
             last_do_stop_cmd =  AgentCmd.objects.filter(full_name__contains="do_stop",recipient=agent_name).latest("s_deposit_time")
-            if last_agent_specific_cmds.s_deposit_time <= last_do_stop_cmd.s_deposit_time:
-                last_agent_specific_cmds = AgentCmd.send_cmd_from_to("System",agent_name,"get_specific_cmds")
-                while not AgentCmd.objects.get(id=last_agent_specific_cmds.id).is_executed() and not AgentCmd.objects.get(id=last_agent_specific_cmds.id).is_exec_error():
+            if last_agent_all_cmds.s_deposit_time <= last_do_stop_cmd.s_deposit_time:
+                last_agent_all_cmds = AgentCmd.send_cmd_from_to("System",agent_name,"get_all_cmds")
+                while not AgentCmd.objects.get(id=last_agent_all_cmds.id).is_executed() and not AgentCmd.objects.get(id=last_agent_all_cmds.id).is_exec_error():
                     time.sleep(0.5)
-            return AgentCmd.objects.get(id=last_agent_specific_cmds.id) 
+            return AgentCmd.objects.get(id=last_agent_all_cmds.id) 
         except AgentCmd.DoesNotExist:
-            if last_do_stop_cmd == None and last_agent_specific_cmds != None:
-                return last_agent_specific_cmds
-            last_agent_specific_cmds = AgentCmd.send_cmd_from_to("System",agent_name,"get_specific_cmds")
-            while not AgentCmd.objects.get(id=last_agent_specific_cmds.id).is_executed() and not AgentCmd.objects.get(id=last_agent_specific_cmds.id).is_exec_error():
+            if last_do_stop_cmd == None and last_agent_all_cmds != None:
+                return last_agent_all_cmds
+            last_agent_all_cmds = AgentCmd.send_cmd_from_to("System",agent_name,"get_all_cmds")
+            while not AgentCmd.objects.get(id=last_agent_all_cmds.id).is_executed() and not AgentCmd.objects.get(id=last_agent_all_cmds.id).is_exec_error():
                 time.sleep(0.5)
-            return AgentCmd.objects.get(id=last_agent_specific_cmds.id)
+            return AgentCmd.objects.get(id=last_agent_all_cmds.id)
     else:
         # AgentSST doesn't have do_stop cmd... (for the moment)
-        last_agent_specific_cmds = AgentCmd.send_cmd_from_to("System",agent_name,"get_specific_cmds")
-        while not AgentCmd.objects.get(id=last_agent_specific_cmds.id).is_executed() and not AgentCmd.objects.get(id=last_agent_specific_cmds.id).is_exec_error():
+        last_agent_all_cmds = AgentCmd.send_cmd_from_to("System",agent_name,"get_all_cmds")
+        while not AgentCmd.objects.get(id=last_agent_all_cmds.id).is_executed() and not AgentCmd.objects.get(id=last_agent_all_cmds.id).is_exec_error():
             time.sleep(0.5)
-        return AgentCmd.objects.get(id=last_agent_specific_cmds.id)
+        return AgentCmd.objects.get(id=last_agent_all_cmds.id)
 
+@login_required
 def agent_detail(request, agent_name):
     agent_log_path = os.path.join(os.environ.get("PROJECT_ROOT_PATH"),f"logs/{agent_name}/",f"{agent_name}.log")
     try:
@@ -228,11 +229,14 @@ def agent_detail(request, agent_name):
     except FileNotFoundError:
         error_message = f"Cannot find agent logs. (Agent log path tried : {agent_log_path})"
     specific_cmd_with_args = None
+    cmd_with_choices = []
     agent_general_commands = AgentCmd._AGENT_GENERAL_COMMANDS.copy()
+    if "get_all_cmds" in agent_general_commands:
+        agent_general_commands.remove("get_all_cmds")
     if "get_specific_cmds" in agent_general_commands:
         agent_general_commands.remove("get_specific_cmds")
     if not AgentSurvey.objects.get(name=agent_name).is_stopping():
-        agent_specific_cmds = get_last_specific_cmds(agent_name)
+        agent_specific_cmds = get_last_all_cmds(agent_name)
         wait_time = 0
         max_wait_time = 20
         unimplemented_command = None
@@ -254,24 +258,36 @@ def agent_detail(request, agent_name):
                     # get text between paretheses
                     args = re.findall(pattern="\(([^)]+)\)",string=specific_cmd)
                     for arg in args:
-                        arguments = arg.split(",")
-                        for arg in arguments:
-                        #arg,arg_type = arg.split(":")
-                            specific_cmd_with_args[cmd].append(arg.split(":"))
+                        if "typing.Literal" in arg:
+                            arg_name = arg.split(":")[0]
+                            values = re.findall(pattern="\[(.*?)\]",string=arg) 
+                            trim_values = []
+                            for value in values:
+                                if "'" in value:
+                                    value = value.replace("'","")
+                                    trim_values.append(value)
+                                specific_cmd_with_args[cmd].append([arg_name,trim_values])
+                            cmd_with_choices.append(cmd)
+                        else:
+                            arguments = arg.split(",")
+                            for arg in arguments:
+                                #arg,arg_type = arg.split(":")
+                                specific_cmd_with_args[cmd].append(arg.split(":"))
             if request.GET.get("cmd"):
                 if request.GET.get("cmd") != "all":
                     if request.GET.get("cmd") in list(specific_cmd_with_args.keys()):
-                        return JsonResponse(specific_cmd_with_args.get(request.GET.get("cmd")),safe=False)
+                        return JsonResponse({"specific_cmd_with_args":specific_cmd_with_args.get(request.GET.get("cmd")),"cmd_with_choices":cmd_with_choices},safe=False)
                     else:
                         return JsonResponse(None,safe=False)
                 else:
-                    return JsonResponse({"agent_general_commands":agent_general_commands,"specific_cmd_with_args":specific_cmd_with_args,"unimplemented_command":unimplemented_command},safe=False)
+                    return JsonResponse({"agent_general_commands":agent_general_commands,"specific_cmd_with_args":specific_cmd_with_args,"unimplemented_command":unimplemented_command,"cmd_with_choices":cmd_with_choices},safe=False)
         if request.GET.get("cmd"):
             return JsonResponse(None,safe=False)
     commands_sent_by_agent = AgentCmd.get_commands_sent_by_agent(agent_name)
     commands_recivied_by_agent = AgentCmd.get_commands_sent_to_agent(agent_name)
     agent_cmds = commands_sent_by_agent | commands_recivied_by_agent
     agent_cmds = agent_cmds.exclude(full_name="get_specific_cmds")
+    agent_cmds = agent_cmds.exclude(full_name="get_all_cmds")
     agent_cmds = agent_cmds.order_by("-s_deposit_time")
     paginator = Paginator(agent_cmds, pyros_settings.NB_ELEMENT_PER_PAGE)
     page_number = request.GET.get("page",1)
@@ -315,7 +331,7 @@ def agent_detail(request, agent_name):
         commands = paginator.page(paginator.num_pages)
     return render(request, "dashboard/agent_detail.html", locals())
 
-
+@login_required
 def agent_action(request):
     if request.POST:
         action = request.POST.get("action")
@@ -338,6 +354,7 @@ def agent_action(request):
             messages.add_message(request, messages.INFO, f"Error while creating command, please try again.")
         return redirect(agent_detail,agent_name=agentsst)    
 
+@login_required
 def agents_commands(request):
     agents_cmds = AgentCmd.objects.all()
     cmd_status = AgentCmd.CMD_STATUS_CODES
@@ -380,6 +397,7 @@ def agents_commands(request):
         agents_cmds = agents_cmds.filter(state=selected_cmd_status)
         url_filters = urlencode({"start_datetime":start_datetime,"end_datetime":end_datetime,"selected_cmd_status":selected_cmd_status})
     agents_cmds = agents_cmds.exclude(full_name="get_specific_cmds")
+    agents_cmds = agents_cmds.exclude(full_name="get_all_cmds")
     agents_cmds = agents_cmds.order_by("-s_deposit_time","-id")
     paginator = Paginator(agents_cmds, pyros_settings.NB_ELEMENT_PER_PAGE)
     page_number = request.GET.get("page",1)
@@ -452,6 +470,7 @@ def soft_mode(request):
     is_auto = soft_mode == Majordome.AUTO_MODE
     return render(request, "dashboard/soft_mode.html", locals())
 
+@login_required
 def agents_state(request):
     agents = AgentSurvey.objects.all()
     datetime_now = datetime.datetime.now(tz=timezone.utc)
--
libgit2 0.21.2