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