-
Notifications
You must be signed in to change notification settings - Fork 313
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
324 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
#! python3 | ||
from typing import Required | ||
import click | ||
import requests | ||
import yaml | ||
from rich import print | ||
import sys, os | ||
import pandas as pd | ||
|
||
cli_cfg = dict() | ||
auth_data = dict() | ||
|
||
API_URL = "" | ||
TOKEN = "" | ||
GLOBAL_FOLDER_ID = None | ||
|
||
with open("cli_config.yaml", "r") as yfile: | ||
cli_cfg = yaml.safe_load(yfile) | ||
|
||
try: | ||
API_URL = cli_cfg["rest"]["url"] | ||
except: | ||
print("Missing API URL. Check the yaml file") | ||
sys.exit(1) | ||
|
||
with open(".tmp.yaml", "r") as yfile: | ||
auth_data = yaml.safe_load(yfile) | ||
|
||
try: | ||
TOKEN = auth_data["token"] | ||
except: | ||
print("Missing a valid token. Try the auth command.") | ||
sys.exit(1) | ||
|
||
|
||
@click.group() | ||
def cli(): | ||
"""A CLI tool to interact with CISO Assistant REST API.""" | ||
pass | ||
|
||
|
||
@click.command() | ||
@click.option("--user-id", default=1, help="User ID to fetch data for.") | ||
def get_user(user_id): | ||
"""Get user details by user ID.""" | ||
response = requests.get(f"{API_URL}/users/{user_id}") | ||
|
||
if response.status_code == 200: | ||
user = response.json() | ||
click.echo(f"Name: {user['name']}") | ||
click.echo(f"Username: {user['username']}") | ||
click.echo(f"Email: {user['email']}") | ||
else: | ||
click.echo("Failed to retrieve user.") | ||
|
||
|
||
@click.command() | ||
@click.option("--email", required=True) | ||
@click.option("--password", required=True) | ||
def auth(email, password): | ||
"""Authenticate to get a temp token""" | ||
url = f"{API_URL}/iam/login/" | ||
data = {"username": email, "password": password} | ||
headers = {"accept": "application/json", "Content-Type": "application/json"} | ||
|
||
res = requests.post(url, data, headers) | ||
with open(".tmp.yaml", "w") as yfile: | ||
yaml.safe_dump(res.json(), yfile) | ||
|
||
|
||
@click.command() | ||
def get_folders(): | ||
"""Get folders""" | ||
url = f"{API_URL}/folders/" | ||
headers = {"Authorization": f"Token {TOKEN}"} | ||
res = requests.get(url, headers=headers) | ||
# TODO: should we handle pagination for this one? | ||
if res.status_code == 200: | ||
output = res.json() | ||
for folder in output["results"]: | ||
if folder["content_type"] == "GLOBAL": | ||
GLOBAL_FOLDER_ID = folder["id"] | ||
break | ||
print(res.json()) | ||
|
||
|
||
@click.command() | ||
@click.option("--ifile", required=True, help="Path of the csv file with assets") | ||
def import_assets(ifile): | ||
"""import assets from a csv""" | ||
df = pd.read_csv(ifile) | ||
url = f"{API_URL}/assets/" | ||
headers = { | ||
"Authorization": f"Token {TOKEN}", | ||
} | ||
for id, row in df.iterrows(): | ||
asset_type = "SP" | ||
name = row["name"] | ||
if row["type"]: | ||
asset_type = row["type"] | ||
|
||
data = { | ||
"name": "titi", | ||
"folder": "2e9fb22c-c521-4f16-839d-c16b6ed0670d", | ||
"type": "SP", | ||
} | ||
res = requests.post(url, data=data, headers=headers) | ||
if res.status_code != 200: | ||
click.echo("something went wrong") | ||
|
||
|
||
# Add commands to the CLI group | ||
cli.add_command(get_folders) | ||
cli.add_command(auth) | ||
cli.add_command(import_assets) | ||
|
||
if __name__ == "__main__": | ||
cli() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.tmp.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
#! python3 | ||
import click | ||
import requests | ||
import yaml | ||
from rich import print | ||
import sys, os | ||
import pandas as pd | ||
from pathlib import Path | ||
|
||
cli_cfg = dict() | ||
auth_data = dict() | ||
|
||
API_URL = "" | ||
GLOBAL_FOLDER_ID = None | ||
TOKEN = "" | ||
USERNAME = "" | ||
PASSWORD = "" | ||
|
||
with open("cli_config.yaml", "r") as yfile: | ||
cli_cfg = yaml.safe_load(yfile) | ||
|
||
try: | ||
API_URL = cli_cfg["rest"]["url"] | ||
except: | ||
print("Missing API URL. Check the yaml file") | ||
sys.exit(1) | ||
|
||
try: | ||
USERNAME = cli_cfg["credentials"]["username"] | ||
PASSWORD = cli_cfg["credentials"]["password"] | ||
except: | ||
print( | ||
"Missing credentials in the config file. You need to pass them to the CLI in this case." | ||
) | ||
|
||
|
||
def check_auth(): | ||
if Path(".tmp.yaml").exists(): | ||
click.echo("Found auth data. Trying them") | ||
with open(".tmp.yaml", "r") as yfile: | ||
auth_data = yaml.safe_load(yfile) | ||
return auth_data["token"] | ||
else: | ||
click.echo("Could not find authentication data.") | ||
|
||
|
||
TOKEN = check_auth() | ||
|
||
|
||
@click.group() | ||
def cli(): | ||
"""A CLI tool to interact with CISO Assistant REST API.""" | ||
pass | ||
|
||
|
||
@click.command() | ||
@click.option("--email", required=False) | ||
@click.option("--password", required=False) | ||
def auth(email, password): | ||
"""Authenticate to get a temp token""" | ||
url = f"{API_URL}/iam/login/" | ||
if email and password: | ||
data = {"username": email, "password": password} | ||
else: | ||
print("trying credentials from the config file") | ||
data = {"username": USERNAME, "password": PASSWORD} | ||
headers = {"accept": "application/json", "Content-Type": "application/json"} | ||
|
||
res = requests.post(url, data, headers) | ||
print(res.status_code) | ||
with open(".tmp.yaml", "w") as yfile: | ||
yaml.safe_dump(res.json(), yfile) | ||
print("Looks good, you can move to other commands.") | ||
|
||
|
||
def _get_folders(): | ||
url = f"{API_URL}/folders/" | ||
headers = {"Authorization": f"Token {TOKEN}"} | ||
res = requests.get(url, headers=headers) | ||
# TODO: should we handle pagination for this one? | ||
if res.status_code == 200: | ||
output = res.json() | ||
for folder in output["results"]: | ||
if folder["content_type"] == "GLOBAL": | ||
GLOBAL_FOLDER_ID = folder["id"] | ||
return GLOBAL_FOLDER_ID | ||
|
||
|
||
@click.command() | ||
def get_folders(): | ||
"""Get folders""" | ||
GLOBAL_FOLDER_ID = _get_folders() | ||
print("GLOBAL_FOLDER_ID: ", GLOBAL_FOLDER_ID) | ||
|
||
|
||
@click.command() | ||
@click.option("--ifile", required=True, help="Path of the csv file with assets") | ||
def import_assets(ifile): | ||
"""import assets from a csv""" | ||
GLOBAL_FOLDER_ID = _get_folders() | ||
df = pd.read_csv(ifile) | ||
url = f"{API_URL}/assets/" | ||
headers = { | ||
"Authorization": f"Token {TOKEN}", | ||
} | ||
for _, row in df.iterrows(): | ||
asset_type = "SP" | ||
name = row["name"] | ||
if row["type"].lower() == "primary": | ||
asset_type = "PR" | ||
else: | ||
asset_type = "SP" | ||
|
||
data = { | ||
"name": name, | ||
"folder": GLOBAL_FOLDER_ID, | ||
"type": asset_type, | ||
} | ||
res = requests.post(url, json=data, headers=headers) | ||
if res.status_code != 201: | ||
click.echo("❌ something went wrong") | ||
print(res.json()) | ||
else: | ||
print(f"✅ {name} created") | ||
|
||
|
||
@click.command() | ||
@click.option( | ||
"--ifile", required=True, help="Path of the csv file with applied controls" | ||
) | ||
def import_controls(ifile): | ||
"""import applied controls""" | ||
df = pd.read_csv(ifile) | ||
GLOBAL_FOLDER_ID = _get_folders() | ||
url = f"{API_URL}/applied-controls/" | ||
headers = { | ||
"Authorization": f"Token {TOKEN}", | ||
} | ||
print(GLOBAL_FOLDER_ID) | ||
for _, row in df.iterrows(): | ||
name = row["name"] | ||
description = row["description"] | ||
csf_function = row["csf_function"] | ||
category = row["category"] | ||
|
||
data = { | ||
"name": name, | ||
"folder": GLOBAL_FOLDER_ID, | ||
"description": description, | ||
"csf_function": csf_function.lower(), | ||
"category": category.lower(), | ||
} | ||
res = requests.post(url, json=data, headers=headers) | ||
if res.status_code != 201: | ||
click.echo("❌ something went wrong") | ||
print(res.json()) | ||
else: | ||
print(f"✅ {name} created") | ||
|
||
|
||
# Add commands to the CLI group | ||
cli.add_command(get_folders) | ||
cli.add_command(auth) | ||
cli.add_command(import_assets) | ||
cli.add_command(import_controls) | ||
|
||
if __name__ == "__main__": | ||
cli() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
rest: | ||
url: http://localhost:8000/api # don't put a trailing slash | ||
credentials: | ||
username: (some username) | ||
password: (some password) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
pandas | ||
rich | ||
requests | ||
click |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
name,description,domain,type | ||
asset1,relevant information,Global,Primary | ||
asset2,relevant information,Global,Support |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
name,description,category,csf_function | ||
Firewall,Monitors and controls incoming and outgoing network traffic.,Technical,Protect | ||
Disaster Recovery Plan,Provides steps for recovering from a major disaster.,Policy,Recover | ||
Vulnerability Scanning,Identifies vulnerabilities in systems and applications.,Process,Identify | ||
Security Information and Event Management (SIEM),Aggregates and analyzes security activity.,Technical,Detect | ||
Encryption,Secures data by converting it into unreadable code.,Technical,Protect | ||
Door and Facility Locks,Restricts physical access to sensitive areas.,Physical,Protect | ||
Business Continuity Plan,Ensures that critical business functions continue during a disaster.,Policy,Recover | ||
Multi-Factor Authentication (MFA),Requires two or more verification methods for access.,Process,Protect | ||
Physical Security Controls,Secures physical access to critical systems.,Physical,Protect | ||
Access Control Policy,Defines access privileges for employees.,Policy,Protect | ||
Intrusion Detection System (IDS),Detects suspicious activity and anomalies in the network.,Technical,Detect | ||
Incident Response Plan,Provides guidelines for responding to security incidents.,Policy,Respond | ||
Backup and Restore Procedures,Outlines steps to back up and restore data.,Process,Recover | ||
Patch Management,Regularly updates software to fix security vulnerabilities.,Process,Protect | ||
Network Segmentation,Divides networks into segments to limit access.,Technical,Protect | ||
Data Loss Prevention (DLP),Prevents sensitive data from being accessed or leaked.,Technical,Protect | ||
Intrusion Prevention System (IPS),Automatically blocks suspicious activity in the network.,Technical,Protect | ||
Endpoint Detection and Response (EDR),Provides real-time monitoring and response to endpoint threats.,Technical,Detect | ||
Anti-Virus Software,Detects and removes malicious software.,Technical,Protect | ||
Security Awareness Training,Educates employees on security best practices.,Process,Protect |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
rest: | ||
url: http://localhost:8000/api # don't put a trailing slash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
name,description,domain,type | ||
asset1,relevant information,Global,Primary |