diff --git a/AirlockTools.py b/AirlockTools.py index 8e115c2..2615096 100644 --- a/AirlockTools.py +++ b/AirlockTools.py @@ -16,8 +16,10 @@ import argparse import dotenv import os import pandas as pd + import urllib3 import utils.allowlist +import utils.clientfunctions import utils.getdeviceevents import utils.hashfunctions import utils.otpfunctions @@ -26,6 +28,7 @@ import utils.policyfunctions import utils.pretty as ct + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) dotenv.load_dotenv() @@ -48,15 +51,15 @@ def main(): args = parser.parse_args() if args.monitorOTP: - # Non-interactive logic + + + # Non-interactive logic + if not os.path.exists("parquet"): os.makedirs("parquet") apivalidation() print(f"Running non-interactively to start monitoring OTP") - - utils.otpfunctions.getOTPHistory(url, 0) - utils.otpfunctions.getOTPHistory(url, 1) - utils.otpfunctions.getOTPHistory(url, 2) - utils.otpfunctions.getOTPHistory(url, 3) + utils.clientfunctions.getClientsPolicy(url) + # Process input here else: # Interactive logic diff --git a/parquet/newOTP b/parquet/newOTP new file mode 100644 index 0000000..f80e99c Binary files /dev/null and b/parquet/newOTP differ diff --git a/parquet/newest_active_OTP b/parquet/newest_active_OTP new file mode 100644 index 0000000..f80e99c Binary files /dev/null and b/parquet/newest_active_OTP differ diff --git a/parquet/old_active_OTP b/parquet/old_active_OTP new file mode 100644 index 0000000..f80e99c Binary files /dev/null and b/parquet/old_active_OTP differ diff --git a/parquet/otp_activities b/parquet/otp_activities new file mode 100644 index 0000000..6b2160c Binary files /dev/null and b/parquet/otp_activities differ diff --git a/utils/clientfunctions.py b/utils/clientfunctions.py new file mode 100644 index 0000000..32c009c --- /dev/null +++ b/utils/clientfunctions.py @@ -0,0 +1,60 @@ +import json +import requests +import os +import pandas as pd +import utils.pretty as ct + + +def getClientsPolicy(url, clientid="0dcddaf3-d017-4ced-9227-ceeca3117286"): + + endpoint = url + '/v1/agent/find' + payload = { + "agentid" : f"{clientid}" + } + + headers = {"X-APIKey": os.getenv('APIKEY')} + payload = json.dumps(payload) + + + response = requests.post(endpoint, headers=headers, data=payload, verify=False) + result = json.loads(response.text) + data = pd.DataFrame(result["response"]["agents"]) + + policyname = getPolicyName(url,data.loc[0, "groupid"]) + allowlists = getPolicyAllowlists(url,data.loc[0, "groupid"]) + allowlists = allowlists['name'].tolist() + print(policyname) + print(allowlists) + + + +def getPolicyAllowlists(url, groupid): + + endpoint = url + '/v1/group/policies' + payload = { + "groupid" : f"{groupid}" + } + + headers = {"X-APIKey": os.getenv('APIKEY')} + payload = json.dumps(payload) + + response = requests.post(endpoint, headers=headers, data=payload, verify=False) + result = json.loads(response.text) + data = pd.DataFrame(result["response"]["applications"]) + return data + +def getPolicyName(url, groupid): + + endpoint = url + '/v1/group/' + payload = { + + } + + headers = {"X-APIKey": os.getenv('APIKEY')} + payload = json.dumps(payload) + + response = requests.post(endpoint, headers=headers, data=payload, verify=False) + result = json.loads(response.text) + data = pd.DataFrame(result["response"]["groups"]) + name = data.loc[data['groupid'] == f"{groupid}", 'name'].values[0] + return name \ No newline at end of file diff --git a/utils/otpfunctions.py b/utils/otpfunctions.py index 509aa96..ab1c05a 100644 --- a/utils/otpfunctions.py +++ b/utils/otpfunctions.py @@ -1,21 +1,63 @@ import json import requests import os +import pandas as pd +import utils.pretty as ct +import shutil +def getActiveOTP(url): -def getOTPHistory(url, type): - - endpoint = url + '/v1/otp/usage' + endpoint = url + f'/v1/otp/usage' payload = { - "status" : type - } + "status" : "0" + } headers = {"X-APIKey": os.getenv('APIKEY')} payload = json.dumps(payload) response = requests.post(endpoint, headers=headers, data=payload, verify=False) - data = response.json() - results = data.get("response", {}).get("otpusage", []) + result = json.loads(response.text) + otp = pd.DataFrame(result["response"]["otpusage"]) + otp.to_parquet("parquet\\newest_active_OTP.parquet", index=False) + if not otp.empty: + ct.style_dataframe_dark(otp, f"newest_active_OTP.html") + - print(results) \ No newline at end of file + +def getOTPActivities(url, otpid): + + endpoint = url + f'/v1/otp/activities' + payload = { + "otpid" : f"{otpid}" + } + + headers = {"X-APIKey": os.getenv('APIKEY')} + payload = json.dumps(payload) + + response = requests.post(endpoint, headers=headers, data=payload, verify=False) + result = json.loads(response.text) + otp = pd.DataFrame(result["response"]["otpactivities"]) + otp.to_parquet("parquet/otp_activities.parquet", index=False) + if not otp.empty: + ct.style_dataframe_dark(otp, f"OTP_activities_{otpid}.html") + + +def compareOTPHistory(): + + if not os.path.exists("parquet\\old_active_OTP"): + shutil.copy2("parquet\\newest_active_OTP.parquet", "parquet\\old_active_OTP.parquet") + + old_active_OTP = pd.read_parquet("parquet\\old_active_OTP.parquet") + current_active_OTP = pd.read_parquet("parquet\\newest_active_OTP.parquet") + + newly_added = current_active_OTP[~current_active_OTP['otpid'].isin(old_active_OTP['otpid'])] + still_in_OTP = old_active_OTP[old_active_OTP['otpid'].isin(current_active_OTP['otpid'])] + no_longer_OTP = old_active_OTP[~old_active_OTP['otpid'].isin(current_active_OTP['otpid'])] + + + + for _, row in newly_added.iterrows(): + pid = row['otpid'] + # Access other columns via row['column_name'] + print(f"Processing PID: {pid} with other data: {row}")