diff options
author | Christian Cleberg <hello@cleberg.net> | 2025-04-05 13:43:01 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-05 13:43:01 -0500 |
commit | bee22b97b652cd04fa470d7f31c3b917e44f3ab9 (patch) | |
tree | e1ec29a3388b94a8d41e3b28ca1f2357f3efaec7 | |
parent | 3041472781997ff66c5f9fa80a7f5ffbd284a438 (diff) | |
download | audit-tools-bee22b97b652cd04fa470d7f31c3b917e44f3ab9.tar.gz audit-tools-bee22b97b652cd04fa470d7f31c3b917e44f3ab9.tar.bz2 audit-tools-bee22b97b652cd04fa470d7f31c3b917e44f3ab9.zip |
migrate from pylint to ruff (#1)
* migrate from pylint to ruff
* Commit from GitHub Actions (Pylint)
* rename pylint.yml to ruff.yml
* only run ruff-action when python files change
---------
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
-rw-r--r-- | .github/workflows/pylint.yml | 23 | ||||
-rw-r--r-- | .github/workflows/ruff.yml | 37 | ||||
-rw-r--r-- | applications/github/github_admins.py | 31 | ||||
-rw-r--r-- | applications/github/github_audit_log.py | 26 | ||||
-rw-r--r-- | applications/github/github_branch_protections.py | 28 | ||||
-rw-r--r-- | applications/github/github_commits.py | 52 | ||||
-rw-r--r-- | applications/gitlab/gitlab_admins.py | 6 | ||||
-rw-r--r-- | databases/passwords/sql/test.py | 53 | ||||
-rw-r--r-- | project_management/dash/app.py | 79 |
9 files changed, 193 insertions, 142 deletions
diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml deleted file mode 100644 index 2eaeecd..0000000 --- a/.github/workflows/pylint.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Pylint - -on: [push] - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.8", "3.9", "3.10"] - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install pylint pandas dash plotly.express - - name: Analysing the code with pylint - run: | - pylint -d R0801 $(git ls-files '*.py') diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml new file mode 100644 index 0000000..e7212d3 --- /dev/null +++ b/.github/workflows/ruff.yml @@ -0,0 +1,37 @@ +name: Ruff + +on: + push: + paths: + - '**.py' + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.x"] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + ref: ${{ github.event.pull_request.head.ref }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pandas dash plotly.express + - name: Install Ruff + uses: astral-sh/ruff-action@v3.2.2 + - name: Ruff Actions + run: | + ruff check --fix + ruff format + - name: Add and Commit + uses: EndBug/add-and-commit@v9 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + default_author: github_actions + pathspec_error_handling: ignore
\ No newline at end of file diff --git a/applications/github/github_admins.py b/applications/github/github_admins.py index d737887..b6db534 100644 --- a/applications/github/github_admins.py +++ b/applications/github/github_admins.py @@ -5,54 +5,59 @@ and list each user's permission per repo. import requests -GITHUB_TOKEN = 'your_personal_access_token' -ORGANIZATION = 'your_organization' +GITHUB_TOKEN = "your_personal_access_token" +ORGANIZATION = "your_organization" TIMEOUT = 30 # Headers for authentication headers = { - 'Authorization': f'token {GITHUB_TOKEN}', - 'Accept': 'application/vnd.github.v3+json' + "Authorization": f"token {GITHUB_TOKEN}", + "Accept": "application/vnd.github.v3+json", } + def get_org_members(org): """ Get members of an organization """ - url = f'https://api.github.com/orgs/{org}/members' + url = f"https://api.github.com/orgs/{org}/members" response = requests.get(url, headers=headers, timeout=TIMEOUT) response.raise_for_status() return response.json() + def get_org_repos(org): """ Get repositories of an organization """ - url = f'https://api.github.com/orgs/{org}/repos' + url = f"https://api.github.com/orgs/{org}/repos" response = requests.get(url, headers=headers, timeout=TIMEOUT) response.raise_for_status() return response.json() + def get_repo_collaborators(org, repo): """ Get collaborators of a repository with their permissions """ - url = f'https://api.github.com/repos/{org}/{repo}/collaborators' + url = f"https://api.github.com/repos/{org}/{repo}/collaborators" response = requests.get(url, headers=headers, timeout=TIMEOUT) response.raise_for_status() return response.json() + def get_user_permissions(org, repo, user): """ Get a user's permissions for a repository """ - url = f'https://api.github.com/repos/{org}/{repo}/collaborators/{user}/permission' + url = f"https://api.github.com/repos/{org}/{repo}/collaborators/{user}/permission" response = requests.get(url, headers=headers, timeout=TIMEOUT) response.raise_for_status() return response.json() + # Main script -if __name__ == '__main__': +if __name__ == "__main__": # Get organization members members = get_org_members(ORGANIZATION) print(f"Members of the organization '{ORGANIZATION}':") @@ -67,10 +72,12 @@ if __name__ == '__main__': # Get collaborators for each repository and their permissions for repository in repositories: - repository_name = repository['name'] + repository_name = repository["name"] collaborators = get_repo_collaborators(ORGANIZATION, repository_name) print(f"\nCollaborators for the repository '{repository_name}':") for collaborator in collaborators: - user_login = collaborator['login'] - permissions = get_user_permissions(ORGANIZATION, repository_name, user_login) + user_login = collaborator["login"] + permissions = get_user_permissions( + ORGANIZATION, repository_name, user_login + ) print(f"- {user_login}: {permissions['permission']}") diff --git a/applications/github/github_audit_log.py b/applications/github/github_audit_log.py index 0937764..dd00535 100644 --- a/applications/github/github_audit_log.py +++ b/applications/github/github_audit_log.py @@ -6,16 +6,17 @@ NOTE: REQUIRES A GITHUB ENTERPRISE SUBSCRIPTION TO ACCESS THE API. import requests -GITHUB_TOKEN = 'your_personal_access_token' -ORGANIZATION = 'your_organization' +GITHUB_TOKEN = "your_personal_access_token" +ORGANIZATION = "your_organization" TIMEOUT = 30 # Headers for authentication headers = { - 'Authorization': f'token {GITHUB_TOKEN}', - 'Accept': 'application/vnd.github.v3+json' + "Authorization": f"token {GITHUB_TOKEN}", + "Accept": "application/vnd.github.v3+json", } + def get_audit_log_events(org, actions): """ Get audit log events for specific actions @@ -23,8 +24,10 @@ def get_audit_log_events(org, actions): events = [] page = 1 while True: - url = (f'https://api.github.com/orgs/{org}/audit-log?page={page}&per_page=100' - f'&action={",".join(actions)}') + url = ( + f"https://api.github.com/orgs/{org}/audit-log?page={page}&per_page=100" + f"&action={','.join(actions)}" + ) response = requests.get(url, headers=headers, timeout=TIMEOUT) response.raise_for_status() page_events = response.json() @@ -34,12 +37,15 @@ def get_audit_log_events(org, actions): page += 1 return events -if __name__ == '__main__': + +if __name__ == "__main__": try: # Define the actions to filter - action_filters = ['protected_branch', - 'repository_branch_protection_evaluation', - 'repository_ruleset'] + action_filters = [ + "protected_branch", + "repository_branch_protection_evaluation", + "repository_ruleset", + ] # Get audit log events for the specified actions audit_log_events = get_audit_log_events(ORGANIZATION, action_filters) diff --git a/applications/github/github_branch_protections.py b/applications/github/github_branch_protections.py index 73c94b6..705e498 100644 --- a/applications/github/github_branch_protections.py +++ b/applications/github/github_branch_protections.py @@ -4,16 +4,17 @@ Gathers branch protection rules for a repository. import requests -GITHUB_TOKEN = 'your_personal_access_token' -ORGANIZATION = 'your_organization' -REPOSITORY = 'your_repository' +GITHUB_TOKEN = "your_personal_access_token" +ORGANIZATION = "your_organization" +REPOSITORY = "your_repository" TIMEOUT = 30 headers = { - 'Authorization': f'token {GITHUB_TOKEN}', - 'Accept': 'application/vnd.github.v3+json' + "Authorization": f"token {GITHUB_TOKEN}", + "Accept": "application/vnd.github.v3+json", } + def get_all_branches(org, repo): """ Get all branches in a repository @@ -21,7 +22,7 @@ def get_all_branches(org, repo): all_branches = [] page = 1 while True: - url = f'https://api.github.com/repos/{org}/{repo}/branches?page={page}&per_page=100' + url = f"https://api.github.com/repos/{org}/{repo}/branches?page={page}&per_page=100" response = requests.get(url, headers=headers, timeout=TIMEOUT) response.raise_for_status() page_branches = response.json() @@ -31,27 +32,30 @@ def get_all_branches(org, repo): page += 1 return all_branches + def get_branch_protection(org, repo, repo_branch): """ Get branch protection settings """ - url = f'https://api.github.com/repos/{org}/{repo}/branches/{repo_branch}/protection' + url = f"https://api.github.com/repos/{org}/{repo}/branches/{repo_branch}/protection" response = requests.get(url, headers=headers, timeout=TIMEOUT) if response.status_code == 404: return None # No protection settings for this branch response.raise_for_status() return response.json() + def get_repository_rulesets(org, repo): """ Get repository rulesets """ - url = f'https://api.github.com/repos/{org}/{repo}/rulesets' + url = f"https://api.github.com/repos/{org}/{repo}/rulesets" response = requests.get(url, headers=headers, timeout=TIMEOUT) response.raise_for_status() return response.json() -if __name__ == '__main__': + +if __name__ == "__main__": try: # Get all branches in the repository branches = get_all_branches(ORGANIZATION, REPOSITORY) @@ -59,8 +63,10 @@ if __name__ == '__main__': # Get protection settings for each branch for branch in branches: - branch_name = branch['name'] - protection_settings = get_branch_protection(ORGANIZATION, REPOSITORY, branch_name) + branch_name = branch["name"] + protection_settings = get_branch_protection( + ORGANIZATION, REPOSITORY, branch_name + ) print(f"\nBranch: {branch_name}") if protection_settings: print(f"Protection settings: {protection_settings}") diff --git a/applications/github/github_commits.py b/applications/github/github_commits.py index f35d5d6..7581ff1 100644 --- a/applications/github/github_commits.py +++ b/applications/github/github_commits.py @@ -4,20 +4,21 @@ Gather all commits from a specific branch of a repository in a GitHub organizati import requests -GITHUB_TOKEN = 'your_personal_access_token' -ORGANIZATION = 'your_organization' -REPOSITORY = 'your_repository' -BRANCH = 'your_branch' +GITHUB_TOKEN = "your_personal_access_token" +ORGANIZATION = "your_organization" +REPOSITORY = "your_repository" +BRANCH = "your_branch" # Headers for authentication headers = { - 'Authorization': f'token {GITHUB_TOKEN}', - 'Accept': 'application/vnd.github.v3+json' + "Authorization": f"token {GITHUB_TOKEN}", + "Accept": "application/vnd.github.v3+json", } # Define a timeout value (in seconds) TIMEOUT = 10 + def get_commit_log(org, repo, branch): """ Get the full commit log for a repository branch @@ -25,8 +26,10 @@ def get_commit_log(org, repo, branch): commits = [] page = 1 while True: - url = (f'https://api.github.com/repos/{org}/{repo}/commits?sha={branch}' - f'&page={page}&per_page=100') + url = ( + f"https://api.github.com/repos/{org}/{repo}/commits?sha={branch}" + f"&page={page}&per_page=100" + ) response = requests.get(url, headers=headers, timeout=TIMEOUT) response.raise_for_status() page_commits = response.json() @@ -36,39 +39,46 @@ def get_commit_log(org, repo, branch): page += 1 return commits + def get_commit_details(org, repo, sha): """ Get detailed information for a specific commit """ - url = f'https://api.github.com/repos/{org}/{repo}/commits/{sha}' + url = f"https://api.github.com/repos/{org}/{repo}/commits/{sha}" response = requests.get(url, headers=headers, timeout=TIMEOUT) response.raise_for_status() return response.json() -if __name__ == '__main__': + +if __name__ == "__main__": try: # Get the full commit log for the specified branch commit_log = get_commit_log(ORGANIZATION, REPOSITORY, BRANCH) - print(f"Total commits in the repository '{REPOSITORY}' on branch " - f"'{BRANCH}': {len(commit_log)}") + print( + f"Total commits in the repository '{REPOSITORY}' on branch " + f"'{BRANCH}': {len(commit_log)}" + ) # Get detailed information for each commit for commit in commit_log: - sha_hash = commit['sha'] - commit_details = get_commit_details(ORGANIZATION, REPOSITORY, - sha_hash) + sha_hash = commit["sha"] + commit_details = get_commit_details(ORGANIZATION, REPOSITORY, sha_hash) print(f"\nCommit SHA: {commit_details['sha']}") - print(f"Author: {commit_details['commit']['author']['name']} " - f"<{commit_details['commit']['author']['email']}>") + print( + f"Author: {commit_details['commit']['author']['name']} " + f"<{commit_details['commit']['author']['email']}>" + ) print(f"Date: {commit_details['commit']['author']['date']}") print(f"Message: {commit_details['commit']['message']}") print(f"URL: {commit_details['html_url']}") print("Files changed:") - for file in commit_details['files']: + for file in commit_details["files"]: print(f" - {file['filename']} ({file['status']})") - print(f" Additions: {file['additions']}, " - f"Deletions: {file['deletions']}, " - f"Changes: {file['changes']}") + print( + f" Additions: {file['additions']}, " + f"Deletions: {file['deletions']}, " + f"Changes: {file['changes']}" + ) except requests.exceptions.Timeout: print("The request timed out") except requests.exceptions.RequestException as e: diff --git a/applications/gitlab/gitlab_admins.py b/applications/gitlab/gitlab_admins.py index 7fb2c78..091032c 100644 --- a/applications/gitlab/gitlab_admins.py +++ b/applications/gitlab/gitlab_admins.py @@ -12,12 +12,14 @@ TIMEOUT = 30 URL = f"{BASE_URL}/groups/{GROUP_ID}/members" HEADERS = {"PRIVATE-TOKEN": PRIVATE_TOKEN} -if __name__ == '__main__': +if __name__ == "__main__": # Get group members response = requests.get(URL, headers=HEADERS, timeout=TIMEOUT) if response.status_code == 200: members = response.json() for member in members: - print(f"Username: {member['username']}, Access Level: {member['access_level']}") + print( + f"Username: {member['username']}, Access Level: {member['access_level']}" + ) else: print(f"Failed to fetch group members: {response.status_code}, {response.text}") diff --git a/databases/passwords/sql/test.py b/databases/passwords/sql/test.py index bfacb20..81c1138 100644 --- a/databases/passwords/sql/test.py +++ b/databases/passwords/sql/test.py @@ -6,7 +6,8 @@ Checks SQL Server user data for compliance with Windows policies. import pandas as pd # Load the data into a pandas DataFrame -df_input = pd.read_csv('./data.csv') +df_input = pd.read_csv("./data.csv") + # Function to apply rules and generate report def apply_rules_and_report(df): @@ -22,45 +23,46 @@ def apply_rules_and_report(df): report = [] for _, row in df.iterrows(): result = { - 'Name': row['name'], - 'Type Check': '', - 'Policy Check': '', - 'Expiration Check': '', - 'Reason': '' + "Name": row["name"], + "Type Check": "", + "Policy Check": "", + "Expiration Check": "", + "Reason": "", } # Check the type_desc - if row['type_desc'] == 'SQL_LOGIN': - result['Type Check'] = 'SQL_LOGIN' - elif row['type_desc'] == 'WINDOWS_LOGIN': - result['Type Check'] = 'N/A' - result['Reason'] = 'Refer to Windows password policy.' + if row["type_desc"] == "SQL_LOGIN": + result["Type Check"] = "SQL_LOGIN" + elif row["type_desc"] == "WINDOWS_LOGIN": + result["Type Check"] = "N/A" + result["Reason"] = "Refer to Windows password policy." else: - result['Type Check'] = 'Manual Review' - result['Reason'] = 'Reviewer to manually review.' + result["Type Check"] = "Manual Review" + result["Reason"] = "Reviewer to manually review." # Check if password policy is enforced - if row['is_policy_checked'] == 1: - result['Policy Check'] = 'PASS' - result['Reason'] += '''Password policy is enforced. Reviewer to - check the assigned policy.''' + if row["is_policy_checked"] == 1: + result["Policy Check"] = "PASS" + result["Reason"] += """Password policy is enforced. Reviewer to + check the assigned policy.""" else: - result['Policy Check'] = 'FAIL' - result['Reason'] += 'Password policy is not enforced.' + result["Policy Check"] = "FAIL" + result["Reason"] += "Password policy is not enforced." # Check if password expiration is enforced - if row['is_expiration_checked'] == 1: - result['Expiration Check'] = 'PASS' - result['Reason'] += '''Password expiration is enforced. Reviewer to - check the expiration policy.''' + if row["is_expiration_checked"] == 1: + result["Expiration Check"] = "PASS" + result["Reason"] += """Password expiration is enforced. Reviewer to + check the expiration policy.""" else: - result['Expiration Check'] = 'FAIL' - result['Reason'] += 'Password expiration is not enforced.' + result["Expiration Check"] = "FAIL" + result["Reason"] += "Password expiration is not enforced." report.append(result) return report + # Main function to run the script def main(): """ @@ -73,5 +75,6 @@ def main(): # Print the report print(report_df) + if __name__ == "__main__": main() diff --git a/project_management/dash/app.py b/project_management/dash/app.py index 2a01911..ea530a6 100644 --- a/project_management/dash/app.py +++ b/project_management/dash/app.py @@ -8,51 +8,54 @@ import pandas as pd import plotly.express as px # Incorporate data -df = pd.read_excel('project_data.xlsx') +df = pd.read_excel("project_data.xlsx") # Initialize the app app = Dash() # App layout app.layout = [ - html.H1(children='Project Dashboard', style={'textAlign':'center'}), - html.Div(children = [ - dcc.Graph( - figure=px.histogram( - df, - x='Preparer', - color='High Priority?', - title='Control Count by Preparer' - ), - style = {'flex-grow':'1'} - ), - dcc.Graph( - figure=px.histogram( - df, - x='Preparer', - y='Projected Hours ', - color='Status ', - title='Project Hours by Preparer' - ), - style = {'flex-grow':'1'} - ) - ], - style = { - 'display':'flex', - 'flex-wrap':'wrap', - 'justify-content':'space-between', -'align-items':'center'}), - dcc.Graph( - figure=px.pie( - df, - values = df['Preparer'].value_counts().values, - names=df['Reviewer'].value_counts().index, - title='Reviewer Breakdown', - hole=0.5 - ) - ) + html.H1(children="Project Dashboard", style={"textAlign": "center"}), + html.Div( + children=[ + dcc.Graph( + figure=px.histogram( + df, + x="Preparer", + color="High Priority?", + title="Control Count by Preparer", + ), + style={"flex-grow": "1"}, + ), + dcc.Graph( + figure=px.histogram( + df, + x="Preparer", + y="Projected Hours ", + color="Status ", + title="Project Hours by Preparer", + ), + style={"flex-grow": "1"}, + ), + ], + style={ + "display": "flex", + "flex-wrap": "wrap", + "justify-content": "space-between", + "align-items": "center", + }, + ), + dcc.Graph( + figure=px.pie( + df, + values=df["Preparer"].value_counts().values, + names=df["Reviewer"].value_counts().index, + title="Reviewer Breakdown", + hole=0.5, + ) + ), ] # Run the app -if __name__ == '__main__': +if __name__ == "__main__": app.run(debug=True) |