commit 49e1d16c6f1c197023e19a5e34324f5c04eec4bb Author: agatha Date: Fri Nov 10 19:25:45 2023 -0500 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bbb4974 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.idea/ +venv/ + +__pycache__/ +*.py[cod] diff --git a/README.md b/README.md new file mode 100644 index 0000000..15a3990 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# GitMon +Monitor GitHub events and clone repositories to search for secrets, and more. + +## Overview +GitMon allows an operator to continually monitor the GitHub Events API to collect +metadata and look for secret leakage. + +When certain events such as _CreateEvent_ or _DeleteEvent_ are observed, GitMon +will send the repository URL to a worker that will clone the repository and +search for API keys, passwords, endpoints, and more. + +GitMon will also build a table that maps commit email addresses to GitHub usernames. + +## Contributors +- agathanonymous diff --git a/gitmon/__init__.py b/gitmon/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gitmon/api.py b/gitmon/api.py new file mode 100644 index 0000000..1a9e7dd --- /dev/null +++ b/gitmon/api.py @@ -0,0 +1,46 @@ +"""GitHub API module""" +import logging +import requests +from requests.adapters import HTTPAdapter +from requests.packages.urllib3.util.retry import Retry + + +class GitHubApi: + def __init__(self, proxy=None): + self.base_url = 'https://api.github.com' + self.session = requests.Session() + + retries = Retry(total=3, backoff_factor=1) + self.session.mount('https://', HTTPAdapter(max_retries=retries)) + + if proxy: + self.session.proxies.update(proxy) + + def __get(self, endpoint, params=None): + """GET an HTTP resource and return JSON.""" + url = self.base_url + endpoint + + try: + response = self.session.get(url, params=params) + except requests.RequestException as e: + logging.warning(f'Failed to execute GET request: {str(e)}') + return None + + self.__parse_headers(response.headers) + return response.json() + + def __parse_headers(self, headers): + """Parse headers to update rate limits.""" + pass + + def get_events(self, page=None): + """Fetch GitHub events.""" + endpoint = '/events' + params = None + + if page: + params = {'page': page} + + events = self.__get(endpoint, params) + + return events diff --git a/main.py b/main.py new file mode 100644 index 0000000..bffe2ec --- /dev/null +++ b/main.py @@ -0,0 +1,16 @@ +"""GitMon""" +from gitmon.api import GitHubApi + + +def main(): + """Main entry point.""" + + api = GitHubApi() + + events = api.get_events() + for event in events: + print(event['type']) + + +if __name__ == '__main__': + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f229360 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +requests