-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLeakFinder.py
More file actions
97 lines (85 loc) · 4.93 KB
/
LeakFinder.py
File metadata and controls
97 lines (85 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import requests
from datetime import datetime
def a(num): return f"\033[{num}m"
def run_analysis(repo_path, prev_authors):
response = requests.get(f"https://api.github.com/repos/{repo_path}/commits?per_page=100")
return_headers, history_json = response.headers, response.json()
print_notes = len(prev_authors) == 0
if isinstance(history_json, list):
num_commits = "100+" if len(history_json) == 100 else len(history_json)
if print_notes:
print(f"{a(0)}\nResults for{a(96)} https://github.com/{repo_path} {a(0)}({num_commits} commits):\n")
for entry in history_json:
login = entry["author"]["login"] if entry["author"] else ""
name = entry["commit"]["author"]["name"]
email = entry["commit"]["author"]["email"]
tz_key, timezone = "", ""
if entry["commit"]["verification"]["verified"]:
signature = entry["commit"]["verification"]["payload"].split()
for j, v in enumerate(signature):
if v == "committer" and tz_key == "":
timezone, timestamp = signature[j-1], int(signature[j-2])
day = datetime.fromtimestamp(timestamp).strftime("%Y/%m/%d").replace("/0", "/")
tz_key = timezone
timezone = f"UTC{timezone[0]}{str(int(timezone[1:3]))}:{timezone[3:5]} ({day})"
author_string = " ".join([login, name, email, tz_key])
if not author_string in prev_authors:
if login != "": print(f"{a(0)}GH Username: {a(94)}{login}")
print(f"{a(0)}Name: {a(91)}{name}\n{a(0)}Email: {a(92)}{email}{a(0)}")
print("" if timezone == "" else f"{a(0)}Timezone: {a(95)}{timezone}{a(0)}\n")
prev_authors.append(author_string)
if len(history_json) == 100 and print_notes:
print(f"{a(93)}Note: only scanned most recent 100 commits{a(0)}")
if int(return_headers.get("X-RateLimit-Remaining")) < 20:
reset = datetime.fromtimestamp(int(return_headers.get('X-RateLimit-Reset')))
print(
f"{a(36)}Ratelimit warning: {a(33)}{return_headers.get('X-RateLimit-Remaining')}"
f"{a(36)}/{a(32)}{return_headers.get('X-RateLimit-Limit')}{a(36)} "
f"requests remaining (reset at {a(37)}{reset:%H:%M:%S}{a(36)}){a(0)}"
)
else:
if "rate limit" in history_json["message"]:
print(f"{a(33)}Github rate limit exceeded!{a(0)}\n")
return None
else:
print(f"{a(33)}Github returned error: {history_json['message'].lower()}{a(0)}\n")
return prev_authors
def main(repo_url):
while repo_url != "" and repo_url != "q":
if repo_url.startswith("https://github.com/") and repo_url.count("/") >= 4:
repo_url = repo_url.split("/")
repo_url = repo_url[3] + "/" + repo_url[4]
run_analysis(repo_url, [])
elif repo_url.count("/") == 1:
run_analysis(repo_url, [])
elif repo_url.startswith("@"):
user_repos = requests.get(f"https://api.github.com/users/{repo_url[1:]}/repos?per_page=100").json()
if isinstance(user_repos, list):
sorted_repos = sorted(user_repos, key=lambda r: r["created_at"])
for i, repo in enumerate(sorted_repos):
color = 93 if repo["fork"] else 95
date = repo["created_at"].split("T")[0].replace("-", "/")
print(f"{a(0)}{i+1}. {a(color)}{repo['name']}{a(0)} ({date})")
if len(user_repos) > 0:
index = input(f"{a(0)}Choose index to search: {a(96)}")
if index == "scan":
print(f"{a(92)}Doing full scan of {a(96)}@{repo_url[1:]}{a(0)} ({len(user_repos)} repos):")
all_authors = [""]
for i, repo in enumerate(sorted_repos):
if not all_authors is None and not user_repos[i]["fork"]:
all_authors = run_analysis(user_repos[i]["full_name"], all_authors)
else:
while index.isdigit() and int(index) <= len(user_repos):
run_analysis(sorted_repos[int(index) - 1]["full_name"], [])
index = input(f"Choose another index: {a(96)}")
else:
print(f"{a(33)}User {repo_url[1:]} has no repos!{a(0)}")
else:
print(f"{a(33)}Github returned error: {user_repos['message'].lower()}{a(0)}")
else:
print(f"{a(33)}Not a github repo or @user!{a(0)}")
repo_url = input(f"{a(0)}Search github repo or @user: {a(96)}")
if __name__ == "__main__":
print(f"\n{a(4)}{a(31)}Github LeakFinder CLI super haxx0r Xtreme edition pro max\n{a(0)}")
try: main(input(f"Search github repo or @user: {a(96)}"))
except KeyboardInterrupt: print()