### taegis_createAPICredentials_20241111.py

#
# Creates API client credentials for use with the Taegis XDR API

# Last edited 2024-11-11 Version 1.0

#

import json
import re
import requests #pip3 install requests
import pyperclip #pip3 install pyperclip

# Prompt the user for an access token

access_prompt = input('Please copy your Taegis access_token to your clipboard, then press Enter to import it into the script...')
access_token = pyperclip.paste()

###
### TENANT ID

###
while True:
    tenantId = input('Enter desired tenant ID for API client: ')
    if tenantId is None or tenantId == '':
        print("Tenant ID is required, please try again")
    elif len(re.findall("[^0-9]", tenantId)) == 0:
        break
    else:
        print("Tenant ID must be an integer, please try again")


###
### API ENVIRONMENT

###
print("\nPlease select your Taegis environment.")
print("1. US1 (ctpx.secureworks.com)")
print("2. US2 (delta.taegis.secureworks.com)")
print("3. US3 (foxtrot.taegis.secureworks.com)")
print("4. EU (echo.taegis.secureworks.com)")

# Get the chosen environment and validate the input

while True:
    userenv = input('Please enter the number of environment (1-4): ')
    if userenv in ['1', '2', '3', '4']:
        break
    else:
        print("Invalid input. Please enter a number between 1 and 4.")

# Map the chosen number to an environment

urls = {
    '1': 'https://api.ctpx.secureworks.com/graphql',
    '2': 'https://api.delta.taegis.secureworks.com/graphql',
    '3': 'https://api.foxtrot.taegis.secureworks.com/graphql',
    '4': 'https://api.echo.taegis.secureworks.com/graphql'
}

url = urls[userenv]


###
### CREDENTIAL USER ROLE

###
print("\nPlease choose a role (use least privilege required!)")
print("1. Tenant Auditor (Read Only)")
print("2. Tenant Responder")
print("3. Tenant Analyst")
print("4. Tenant Administrator")

# Get desired role and validate the input

while True:
    choice = input('Please enter the number of desired role (1-4): ')
    if choice in ['1', '2', '3', '4']:
        break
    else:
        print("Invalid input. Please enter a number between 1 and 4.")

# Map the chosen number to a role ID

roles = {
    '1': 'ace1cae4-59fd-4fd1-9500-40077dc529a7',
    '2': 'a72dace7-4536-4dbc-947d-015a8eb65f4d',
    '3': 'a4903f9f-465b-478f-a24e-82fa2e129d2e',
    '4': 'ba0fdcbd-e87d-4bdd-ae7d-ca6118b25068'
}
desired_role = roles[choice]


###
### APPLICATION NAME

###
while True:
    app_name = input('\nPlease enter a descriptive name for your new API credential (i.e. jsmith_reporting): ')
    if app_name is None or app_name == '':
        print("Application name is required, please try again")
    elif len(re.findall("[^a-zA-Z0-9_]", app_name)) == 0:
        break
    else:
        print("Name must only contain alphanumerics or underscores, please choose again")


###
### SUMMARIZE INPUTS

###
print("\nUsing the following parameters...")
print(f"Access Token: {access_token[0:25]}... (redacted)")
print(f"Tenant ID: {tenantId}")
print(f"Environment URL: {url}")
print(f"Role ID: {desired_role}")
print(f"Client Credential Name: {app_name}")


###
### REQUEST PARAMETERS

###
# Define the headers of the web request

headers = {
        'Authorization': 'Bearer ' + access_token,
        'Content-Type': 'application/json',
        'X-Tenant-Context': tenantId
}
# Define the GraphQL mutation

query = """
mutation createClient($name: String!, $roles: [ID!]) {
    createClient(name: $name, roles: $roles) {
        client {
            id
            name
            client_id
            roles
            role_assignments {
                id
                tenant_id
                role_id
                role_name
                expires_at
            }
            tenant_id
            created_at
            updated_at
            created_by
            updated_by
            environment
        }
        client_secret
    }
}
"""
# Define the payload body

variables = {"name": app_name, "roles": desired_role}
payload = {
    "query": query,
    "variables": variables
}
# Convert the payload to JSON

payload_json = json.dumps(payload)



###
### REQUEST EXECUTION

### 
continuePrompt = input('\nWould you like to proceed? (y/n): ')
if continuePrompt == 'y':
    # Send the request and get the response
    print("Creating API client with supplied access_token, name, and role...\n")
    
    response = requests.post(url, headers=headers, data=payload_json)
    
    # Check the status of the response
    if response.status_code == 200:
        # Success
        # Decode the JSON response and print it
        print(json.dumps(response.json(), indent=4))
    else:
        # Something went wrong
        print('Request failed - response: ', response.status_code, response.text)
    
else:
    print("Exiting...")