diff --git a/evidence-artifacts/federal/aws/lists/README.md b/evidence-artifacts/federal/aws/lists/README.md new file mode 100644 index 0000000..e69de29 diff --git a/evidence-artifacts/federal/github/README.md b/evidence-artifacts/federal/github/README.md new file mode 100644 index 0000000..e69de29 diff --git a/evidence-artifacts/federal/okta/README.md b/evidence-artifacts/federal/okta/README.md new file mode 100644 index 0000000..e69de29 diff --git a/evidence-artifacts/federal/splunk/README.md b/evidence-artifacts/federal/splunk/README.md new file mode 100644 index 0000000..e69de29 diff --git a/evidence-artifacts/federal/tenable/README.md b/evidence-artifacts/federal/tenable/README.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/evidence-artifacts/federal/tenable/README.md @@ -0,0 +1 @@ + diff --git a/evidence-artifacts/personnel/2024/10/employee_list.csv b/evidence-artifacts/personnel/2024/10/employee_list.csv new file mode 100644 index 0000000..95ef23b --- /dev/null +++ b/evidence-artifacts/personnel/2024/10/employee_list.csv @@ -0,0 +1,57 @@ +employeeId,firstName,lastName,businessTitle,employeeType,supervisorId,citizenshipStatus,birthdate,gender,departmentId,departmentName +00001266632,,,Principal Engineer,Full Time,,,,,Unknown,Unknown +00001274360,,,Senior DevOps Engineer,Full Time,,,,,Unknown,Unknown +00001290372,,,VP of Payer Relations,Full Time,,,,,Unknown,Unknown +00001406637,,,Staff Software Engineer,Full Time,,,,,Unknown,Unknown +00001409697,,,Director of Engineering,Full Time,,,,,Unknown,Unknown +00001756986,,,Sr. DevOps Engineer,Full Time,,,,,Unknown,Unknown +00001786385,,,COO,Full Time,,,,,Unknown,Unknown +00001855502,,,SVP of Finance,Full Time,,,,,Unknown,Unknown +00001868319,,,Senior Engineering Manager,Full Time,,,,,Unknown,Unknown +00001922444,,,Lead Analytics Engineer,Full Time,,,,,Unknown,Unknown +00001967259,,,Medical Director,Part Time,,,,,Unknown,Unknown +00002021386,,,VP Clinical Ops & Primary Ca,Full Time,,,,,Unknown,Unknown +00002113606,,,Mobile Engineer,Full Time,,,,,Unknown,Unknown +00002274042,,,"Vice President, Sales",Full Time,,,,,Unknown,Unknown +00002368310,,,Trusted Advisor,Part Time,,,,,Unknown,Unknown +00002410105,,,Client Solution Design Dir,Full Time,,,,,Unknown,Unknown +00002423855,,,"SVP, Client Success & Ops",Full Time,,,,,Unknown,Unknown +00002428345,,,Digital Marketing Director,Full Time,,,,,Unknown,Unknown +00002437531,,,Administrative Office Manager,Full Time,,,,,Unknown,Unknown +00002451067,,,"Sr. Manager, Data & Analytics",Full Time,,,,,Unknown,Unknown +00002463387,,,Director of Member Engagement,Full Time,,,,,Unknown,Unknown +00002484983,,,Senior Software Engineer,Full Time,,,,,Unknown,Unknown +00002485256,,,VP of Client Success,Full Time,,,,,Unknown,Unknown +00002517570,,,Sr Director Finance & Ops,Full Time,,,,,Unknown,Unknown +00002544891,,,Sr. Client Success Manager,Full Time,,,,,Unknown,Unknown +00002597973,,,Engineering Manager,Full Time,,,,,Unknown,Unknown +00002609142,,,Staff Software Engineer,Full Time,,,,,Unknown,Unknown +00010005756,,,"Vice President, Sales",Full Time,,,,,Unknown,Unknown +00010102629,,,Sr. Client Success Manager,Full Time,,,,,Unknown,Unknown +00010102754,,,iOS Engineer,Full Time,,,,,Unknown,Unknown +00010144311,,,Senior Software Engineer,Full Time,,,,,Unknown,Unknown +00010166878,,,Member Support Supervisor,Full Time,,,,,Unknown,Unknown +00010199835,,,Manager of Clinical Licensing,Full Time,,,,,Unknown,Unknown +00010203400,,,Data Analyst,Full Time,,,,,Unknown,Unknown +00010219580,,,VP of Client Success,Full Time,,,,,Unknown,Unknown +00010285926,,,Sr. Client Success Manager,Full Time,,,,,Unknown,Unknown +00010293521,,,IT and Security Administrator,Full Time,,,,,Unknown,Unknown +00010426613,,,Trusted Advisor,Part Time,,,,,Unknown,Unknown +00010441496,,,Trusted Advisor,Part Time,,,,,Unknown,Unknown +00010449856,,,"Sr. Dir, Product Mgmt & Innova",Full Time,,,,,Unknown,Unknown +00010485384,,,President & CEO,Full Time,,,,,Unknown,Unknown +00010497098,,,Sr iOS Engineer,Full Time,,,,,Unknown,Unknown +00010561795,,,Health Coach,Full Time,,,,,Unknown,Unknown +00010575688,,,"SVP, Mktg and Brand Strategy",Full Time,,,,,Unknown,Unknown +00010575998,,,SVP Product Mgmt & Innovation,Full Time,,,,,Unknown,Unknown +00010584088,,,Art Director,Full Time,,,,,Unknown,Unknown +00010608788,,,Health Coach,Full Time,,,,,Unknown,Unknown +00010610689,,,Product Designer,Full Time,,,,,Unknown,Unknown +00010616738,,,Cybersecurity Program Manager,Full Time,,,,,Unknown,Unknown +00010640489,,,Product Manager,Full Time,,,,,Unknown,Unknown +00010649725,,,Product Manager,Full Time,,,,,Unknown,Unknown +00010654997,,,Licensing and Credentialing Sp,Full Time,,,,,Unknown,Unknown +00010655099,,,Lead Data Engineer,Full Time,,,,,Unknown,Unknown +00010659705,,,QA Engineer,Full Time,,,,,Unknown,Unknown +00010670145,,,Senior Software Engineer ,Full Time,,,,,Unknown,Unknown +00010770029,,,Platform ML Engineer,Full Time,,,,,Unknown,Unknown diff --git a/evidence-artifacts/personnel/2024/10/organization_chart b/evidence-artifacts/personnel/2024/10/organization_chart new file mode 100644 index 0000000..6ee34f0 --- /dev/null +++ b/evidence-artifacts/personnel/2024/10/organization_chart @@ -0,0 +1,59 @@ +digraph EmployeeChart { + // Node definitions with hidden employee IDs and supervisor IDs + " " [label=" \nPrincipal Engineer", employeeId="00001266632", supervisorId=""]; + " " [label=" \nSenior DevOps Engineer", employeeId="00001274360", supervisorId=""]; + " " [label=" \nVP of Payer Relations", employeeId="00001290372", supervisorId=""]; + " " [label=" \nStaff Software Engineer", employeeId="00001406637", supervisorId=""]; + " " [label=" \nDirector of Engineering", employeeId="00001409697", supervisorId=""]; + " " [label=" \nSr. DevOps Engineer", employeeId="00001756986", supervisorId=""]; + " " [label=" \nCOO", employeeId="00001786385", supervisorId=""]; + " " [label=" \nSVP of Finance", employeeId="00001855502", supervisorId=""]; + " " [label=" \nSenior Engineering Manager", employeeId="00001868319", supervisorId=""]; + " " [label=" \nLead Analytics Engineer", employeeId="00001922444", supervisorId=""]; + " " [label=" \nMedical Director", employeeId="00001967259", supervisorId=""]; + " " [label=" \nVP Clinical Ops & Primary Ca", employeeId="00002021386", supervisorId=""]; + " " [label=" \nMobile Engineer", employeeId="00002113606", supervisorId=""]; + " " [label=" \nVice President, Sales", employeeId="00002274042", supervisorId=""]; + " " [label=" \nTrusted Advisor", employeeId="00002368310", supervisorId=""]; + " " [label=" \nClient Solution Design Dir", employeeId="00002410105", supervisorId=""]; + " " [label=" \nSVP, Client Success & Ops", employeeId="00002423855", supervisorId=""]; + " " [label=" \nDigital Marketing Director", employeeId="00002428345", supervisorId=""]; + " " [label=" \nAdministrative Office Manager", employeeId="00002437531", supervisorId=""]; + " " [label=" \nSr. Manager, Data & Analytics", employeeId="00002451067", supervisorId=""]; + " " [label=" \nDirector of Member Engagement", employeeId="00002463387", supervisorId=""]; + " " [label=" \nSenior Software Engineer", employeeId="00002484983", supervisorId=""]; + " " [label=" \nVP of Client Success", employeeId="00002485256", supervisorId=""]; + " " [label=" \nSr Director Finance & Ops", employeeId="00002517570", supervisorId=""]; + " " [label=" \nSr. Client Success Manager", employeeId="00002544891", supervisorId=""]; + " " [label=" \nEngineering Manager", employeeId="00002597973", supervisorId=""]; + " " [label=" \nStaff Software Engineer", employeeId="00002609142", supervisorId=""]; + " " [label=" \nVice President, Sales", employeeId="00010005756", supervisorId=""]; + " " [label=" \nSr. Client Success Manager", employeeId="00010102629", supervisorId=""]; + " " [label=" \niOS Engineer", employeeId="00010102754", supervisorId=""]; + " " [label=" \nSenior Software Engineer", employeeId="00010144311", supervisorId=""]; + " " [label=" \nMember Support Supervisor", employeeId="00010166878", supervisorId=""]; + " " [label=" \nManager of Clinical Licensing", employeeId="00010199835", supervisorId=""]; + " " [label=" \nData Analyst", employeeId="00010203400", supervisorId=""]; + " " [label=" \nVP of Client Success", employeeId="00010219580", supervisorId=""]; + " " [label=" \nSr. Client Success Manager", employeeId="00010285926", supervisorId=""]; + " " [label=" \nIT and Security Administrator", employeeId="00010293521", supervisorId=""]; + " " [label=" \nTrusted Advisor", employeeId="00010426613", supervisorId=""]; + " " [label=" \nTrusted Advisor", employeeId="00010441496", supervisorId=""]; + " " [label=" \nSr. Dir, Product Mgmt & Innova", employeeId="00010449856", supervisorId=""]; + " " [label=" \nPresident & CEO", employeeId="00010485384", supervisorId=""]; + " " [label=" \nSr iOS Engineer", employeeId="00010497098", supervisorId=""]; + " " [label=" \nHealth Coach", employeeId="00010561795", supervisorId=""]; + " " [label=" \nSVP, Mktg and Brand Strategy", employeeId="00010575688", supervisorId=""]; + " " [label=" \nSVP Product Mgmt & Innovation", employeeId="00010575998", supervisorId=""]; + " " [label=" \nArt Director", employeeId="00010584088", supervisorId=""]; + " " [label=" \nHealth Coach", employeeId="00010608788", supervisorId=""]; + " " [label=" \nProduct Designer", employeeId="00010610689", supervisorId=""]; + " " [label=" \nCybersecurity Program Manager", employeeId="00010616738", supervisorId=""]; + " " [label=" \nProduct Manager", employeeId="00010640489", supervisorId=""]; + " " [label=" \nProduct Manager", employeeId="00010649725", supervisorId=""]; + " " [label=" \nLicensing and Credentialing Sp", employeeId="00010654997", supervisorId=""]; + " " [label=" \nLead Data Engineer", employeeId="00010655099", supervisorId=""]; + " " [label=" \nQA Engineer", employeeId="00010659705", supervisorId=""]; + " " [label=" \nSenior Software Engineer", employeeId="00010670145", supervisorId=""]; + " " [label=" \nPlatform ML Engineer", employeeId="00010770029", supervisorId=""]; +} diff --git a/evidence-artifacts/personnel/README.md b/evidence-artifacts/personnel/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/populations/personnel/current-employees.py b/src/populations/personnel/current-employees.py new file mode 100644 index 0000000..ea116e8 --- /dev/null +++ b/src/populations/personnel/current-employees.py @@ -0,0 +1,155 @@ +import requests +import os +import csv +import base64 +from datetime import datetime + + +API_KEY = os.getenv('TRINET_API_KEY') +API_SECRET = os.getenv('TRINET_API_SECRET') +COMPANY_ID = "CJ6" +TOKEN_URL = "https://api.trinet.com/oauth/accesstoken?grant_type=client_credentials" +EMPLOYEE_LIST_URL_TEMPLATE = "https://api.trinet.com/v1/company/{companyId}/employees" +BASE_DIR = "evidence-artifacts/personnel" # Base directory for storing the employee list + + +# Helper function to get access token +def get_access_token(api_key, api_secret): + client_credentials = f"{api_key}:{api_secret}" + encoded_credentials = base64.b64encode(client_credentials.encode('utf-8')).decode('utf-8') + headers = { + 'Authorization': f'Basic {encoded_credentials}' + } + response = requests.get(TOKEN_URL, headers=headers) + if response.status_code == 200: + token_data = response.json() + return token_data['access_token'] + else: + raise Exception(f"Error getting access token: {response.text}") + +# Helper function to fetch employee list +def get_employee_list(access_token, company_id=COMPANY_ID, limit=100, offset=None): + headers = { + 'Authorization': f'Bearer {access_token}', + 'Content-Type': 'application/json', + 'grant_type': 'client_credentials' + } + url = EMPLOYEE_LIST_URL_TEMPLATE.format(companyId=company_id) + params = {"limit": limit} + if offset is not None: + params["offset"] = offset + response = requests.get(url, headers=headers, params=params) + if response.status_code == 200: + return response.json() + else: + raise Exception(f"Error fetching employee list: {response.status_code} - {response.text}") + +# Helper function to extract relevant fields from employee data +def extract_employee_data(employee): + # Exclude terminated employees + employment_status = employee.get('employmentInfo', {}).get('employmentStatus', '') + if employment_status == 'T': # Assuming 'T' represents terminated employees + return None + + # Extract primary name from the names array + names = employee.get('names', []) + first_name, last_name = "", "" + if names: + primary_name = names[0] # Assuming the first entry is the primary name + first_name = primary_name.get('firstName', '') + last_name = primary_name.get('lastName', '') + + # Extract job title and department info + business_title = employee.get('employmentInfo', {}).get('businessTitle', 'Unknown') + employee_type = employee.get('employmentInfo', {}).get('employeeType', 'Unknown') + + # Extract department details + department_info = employee.get('departmentSplit', []) + department_id = department_name = "Unknown" + if department_info: + department_id = department_info[0].get('deptId', 'Unknown') + department_name = department_info[0].get('departmentName', 'Unknown') + + # Extract other relevant fields + employee_id = employee.get('employeeId', '') + supervisor_id = employee.get('supervisorId', '') + citizenship_status = employee.get('workEligibility', {}).get('citizenshipStatus', '') + birthdate = employee.get('bioInfo', {}).get('birthdate', '') + gender = employee.get('bioInfo', {}).get('gender', '') + + return { + 'employeeId': employee_id, + 'firstName': first_name, + 'lastName': last_name, + 'businessTitle': business_title, # Adding job title + 'employeeType': employee_type, # Adding employee type + 'supervisorId': supervisor_id, + 'citizenshipStatus': citizenship_status, + 'birthdate': birthdate, + 'gender': gender, + 'departmentId': department_id, # Adding department ID + 'departmentName': department_name # Adding department name + } + +# Function to save employee data to a CSV file +def save_employee_list_to_csv(employee_data): + # Get current year and month + current_year = datetime.now().year + current_month = datetime.now().month + + # Create directory if it doesn't exist + output_dir = os.path.join(BASE_DIR, str(current_year), str(current_month)) + os.makedirs(output_dir, exist_ok=True) + + # Path for the CSV file + output_csv_path = os.path.join(output_dir, 'employee_list.csv') + + # Extract and flatten relevant employee data, excluding terminated employees + flattened_data = [extract_employee_data(employee) for employee in employee_data if extract_employee_data(employee)] + + # Define the CSV columns + fieldnames = ['employeeId', 'firstName', 'lastName', 'businessTitle', 'employeeType', 'supervisorId', + 'citizenshipStatus', 'birthdate', 'gender', 'departmentId', 'departmentName'] + + # Write to the CSV file + with open(output_csv_path, 'w', newline='') as csvfile: + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + writer.writeheader() + writer.writerows(flattened_data) + + print(f"Employee list saved to {output_csv_path}") + +# Main function to fetch data and generate CSV +def main(): + try: + # Use environment variables or input API key and secret directly + api_key = API_KEY or input("Enter your API Key: ") + api_secret = API_SECRET or input("Enter your API Secret: ") + + token = get_access_token(api_key, api_secret) + + # Paginate through the employee list + offset = None # Start with no offset + has_more = True + all_employees = [] + + while has_more: + response_data = get_employee_list(token, company_id=COMPANY_ID, offset=offset) + employee_data = response_data.get('data', {}).get('employeeData', []) + all_employees.extend(employee_data) + + # Check if there are more employees to fetch + has_more = response_data.get('data', {}).get('hasMore', False) + + # Set offset for the next request only if there are more employees + if has_more: + offset = offset + 100 if offset is not None else 101 # Start at 101 for second request + + # Once we have all the employees, generate the CSV + save_employee_list_to_csv(all_employees) + + except Exception as e: + print(e) + +if __name__ == "__main__": + main()