Skip to content

Commit a9fc715

Browse files
Merge pull request #33 from FireTail-io/hotfix/rate-limit-2
Various hotfixes
2 parents 122b0ad + b6fb588 commit a9fc715

File tree

9 files changed

+61
-73
lines changed

9 files changed

+61
-73
lines changed

src/lambda_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ def handler(event, context):
2020
"message": "Scan complete",
2121
"repositories_scanned": list(repositories_scanned),
2222
"openapi_specs_discovered": openapi_specs_discovered,
23-
"scan_duration": scan_duration
23+
"scan_duration": scan_duration,
2424
}

src/local_handler.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ def handler():
88
repositories_scanned, openapi_specs_discovered = scan()
99
scan_duration = time.time() - start_time
1010

11+
if len(repositories_scanned) == 0:
12+
logger.warning(
13+
f"Scanned 0 repositories. Check your config.yml & access token permissions. "
14+
f"Scan took {round(scan_duration, ndigits=3)} second(s)"
15+
)
16+
return
17+
1118
logger.info(
1219
f"Scanned {len(repositories_scanned)} repositories: {', '.join(repositories_scanned)}. "
1320
f"{openapi_specs_discovered} OpenAPI spec(s) discovered. "

src/openapi/validation.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import prance # type: ignore
55
import yaml
66
from prance.util.resolver import RESOLVE_INTERNAL # type: ignore
7-
from prance.util.url import ResolutionError
87

98

109
def resolve_and_validate_openapi_spec(file_contents: str) -> dict | None:
@@ -16,7 +15,7 @@ def resolve_and_validate_openapi_spec(file_contents: str) -> dict | None:
1615
)
1716
try:
1817
parser.parse()
19-
except (prance.ValidationError, ResolutionError, AssertionError):
18+
except: # noqa: E722
2019
# In the future, maybe we can provide some proper details here.
2120
return None
2221
return parser.specification
@@ -38,6 +37,6 @@ def parse_resolve_and_validate_openapi_spec(file_path: str, get_file_contents: C
3837

3938
else:
4039
return None
41-
40+
4241
# If it was a valid JSON/YAML file, we can give it to Prance to load
4342
return resolve_and_validate_openapi_spec(get_file_contents())

src/scanning.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def scan_repository_contents_recursive(
101101
def scan_repository_contents(
102102
github_client: GithubClient, repository: GithubRepository
103103
) -> tuple[set[str], dict[str, dict]]:
104-
repository_languages = list(respect_rate_limit(repository.get_languages, github_client).keys())
104+
repository_languages = list(respect_rate_limit(lambda: repository.get_languages(), github_client).keys())
105105
logger.info(f"{repository.full_name}: Language(s) detected: {', '.join(repository_languages)}")
106106

107107
language_analysers = get_language_analysers(repository_languages)
@@ -204,8 +204,8 @@ def scan_repositories(
204204
def get_organisations_of_user(github_client: GithubClient) -> set[GithubOrganisation]:
205205
organisations_to_scan = set()
206206

207-
for repo in github_client.get_user().get_repos():
208-
organisations_to_scan.add(repo)
207+
for org in github_client.get_user().get_orgs():
208+
organisations_to_scan.add(org)
209209

210210
return organisations_to_scan
211211

@@ -250,13 +250,17 @@ def scan_with_config(
250250

251251
# Get all of the repos belonging to users in the config
252252
for user, user_config in config.users.items():
253-
repositories_to_scan.update(respect_rate_limit(get_repositories_of_user(github_client, user, user_config)))
253+
repositories_to_scan.update(respect_rate_limit(
254+
lambda: get_repositories_of_user(github_client, user, user_config),
255+
github_client
256+
))
254257

255258
# Get all of the repos beloning to orgs in the config
256259
for organisation, organisation_config in config.organisations.items():
257-
repositories_to_scan.update(respect_rate_limit(get_repositories_of_organisation(
258-
github_client, organisation, organisation_config
259-
)))
260+
repositories_to_scan.update(respect_rate_limit(
261+
lambda: get_repositories_of_organisation(github_client, organisation, organisation_config),
262+
github_client
263+
))
260264

261265
# Filter out any repos which have been explicitly excluded
262266
repositories_to_scan = set(filter(lambda repo: not config.skip_repo(repo), repositories_to_scan))
@@ -287,7 +291,7 @@ def scan_with_config(
287291
return 0, 0
288292

289293
return (
290-
repositories_to_scan,
294+
{respect_rate_limit(lambda: repository.full_name, github_client) for repository in repositories_to_scan},
291295
scan_repositories(github_client, firetail_app_token, firetail_api_url, repositories_to_scan)
292296
)
293297

@@ -297,17 +301,21 @@ def scan_without_config(
297301
) -> tuple[set[GithubRepository], int]:
298302
github_client = github.Github(github_token)
299303

300-
organisations_to_scan: set[GithubOrganisation] = respect_rate_limit(get_organisations_of_user(github_client))
304+
organisations_to_scan: set[GithubOrganisation] = respect_rate_limit(
305+
lambda: get_organisations_of_user(github_client),
306+
github_client
307+
)
301308

302309
repositories_to_scan = set()
303310
for organisation in organisations_to_scan:
304311
logger.info(f"{organisation.login}: Getting repositories...")
305-
repositories_to_scan.update(respect_rate_limit(get_repositories_of_organisation(
306-
github_client, organisation.login, OrgConfig()
307-
)))
312+
repositories_to_scan.update(respect_rate_limit(
313+
lambda: get_repositories_of_organisation(github_client, organisation.login, OrgConfig()),
314+
github_client
315+
))
308316

309317
return (
310-
repositories_to_scan,
318+
{respect_rate_limit(lambda: repository.full_name, github_client) for repository in repositories_to_scan},
311319
scan_repositories(github_client, firetail_app_token, firetail_api_url, repositories_to_scan)
312320
)
313321

@@ -321,7 +329,7 @@ def scan() -> tuple[set[str], int]:
321329
for env_var_name, env_var_value in required_env_vars.items():
322330
if env_var_value in {None, ""}:
323331
logger.critical(f"{env_var_name} not set in environment. Cannot scan.")
324-
return 0, 0
332+
return set(), 0
325333

326334
config_dict = None
327335
try:
@@ -342,4 +350,4 @@ def scan() -> tuple[set[str], int]:
342350
GITHUB_TOKEN, FIRETAIL_APP_TOKEN, FIRETAIL_API_URL
343351
)
344352

345-
return {repository.full_name for repository in repositories_scanned}, openapi_specs_discovered
353+
return repositories_scanned, openapi_specs_discovered

src/static_analysis/python/analyse_flask.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,12 @@ def analyse_flask(module: ast.Module) -> dict | None:
121121
# definition under each of the methods, but it's good enough for now.
122122
return {
123123
"openapi": "3.0.0",
124-
"info": {
125-
"title": "Static Analysis - Flask",
126-
"version": get_datestamp()
127-
},
124+
"info": {"title": "Static Analysis - Flask", "version": get_datestamp()},
128125
"paths": {
129126
path: {
130-
method: {
131-
"responses": {"default": {"description": "Discovered via static analysis"}}
132-
} for method in methods
133-
} for path, methods in paths.items()
127+
method: {"responses": {"default": {"description": "Discovered via static analysis"}}}
128+
for method in methods
129+
}
130+
for path, methods in paths.items()
134131
},
135132
}

tests/golang/test_analyse_golang.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ def test_analyse_net_http_hello_world():
1313
"openapi": "3.0.0",
1414
"info": {"title": "Static Analysis - Golang net/http"},
1515
"paths": {
16-
"/hello": {
17-
"responses": {"default": {"description": "Discovered via static analysis"}}
18-
},
16+
"/hello": {"responses": {"default": {"description": "Discovered via static analysis"}}},
1917
},
2018
}
2119
}

tests/javascript/test_analyse_express.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
import yaml
44

55
from static_analysis.javascript.analyse_express import (
6-
analyse_express, get_app_identifiers, get_express_identifiers,
7-
get_paths_and_methods, get_router_identifiers)
6+
analyse_express,
7+
get_app_identifiers,
8+
get_express_identifiers,
9+
get_paths_and_methods,
10+
get_router_identifiers,
11+
)
812
from static_analysis.javascript.analyse_javascript import JS_PARSER
913

1014

@@ -13,7 +17,8 @@ def patch_datetime_now(monkeypatch):
1317
class PatchedDatetime(datetime.datetime):
1418
def utcnow():
1519
return datetime.datetime(2000, 1, 1)
16-
monkeypatch.setattr(datetime, 'datetime', PatchedDatetime)
20+
21+
monkeypatch.setattr(datetime, "datetime", PatchedDatetime)
1722

1823

1924
@pytest.mark.parametrize(

tests/javascript/test_analyse_javascript.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22
import pytest
33
import yaml
44

5-
from static_analysis.javascript.analyse_javascript import (JS_PARSER,
6-
analyse_javascript,
7-
get_imports)
5+
from static_analysis.javascript.analyse_javascript import JS_PARSER, analyse_javascript, get_imports
86

97

108
@pytest.fixture(autouse=True)
119
def patch_datetime_now(monkeypatch):
1210
class PatchedDatetime(datetime.datetime):
1311
def utcnow():
1412
return datetime.datetime(2000, 1, 1)
15-
monkeypatch.setattr(datetime, 'datetime', PatchedDatetime)
13+
14+
monkeypatch.setattr(datetime, "datetime", PatchedDatetime)
1615

1716

1817
@pytest.mark.parametrize(

tests/python/test_analyse_python.py

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ def patch_datetime_now(monkeypatch):
99
class PatchedDatetime(datetime.datetime):
1010
def utcnow():
1111
return datetime.datetime(2000, 1, 1)
12-
monkeypatch.setattr(datetime, 'datetime', PatchedDatetime)
12+
13+
monkeypatch.setattr(datetime, "datetime", PatchedDatetime)
1314

1415

1516
@pytest.mark.parametrize(
@@ -58,17 +59,8 @@ def test_analyse_flask_hello_world(test_file_contents):
5859
assert appspecs == {
5960
"static-analysis:flask:tests/python/example_apps/flask_hello_world.py": {
6061
"openapi": "3.0.0",
61-
"info": {
62-
"title": "Static Analysis - Flask",
63-
"version": "2000-01-01 00:00:00"
64-
},
65-
"paths": {
66-
"/": {
67-
"get": {
68-
"responses": {"default": {"description": "Discovered via static analysis"}}
69-
}
70-
}
71-
},
62+
"info": {"title": "Static Analysis - Flask", "version": "2000-01-01 00:00:00"},
63+
"paths": {"/": {"get": {"responses": {"default": {"description": "Discovered via static analysis"}}}}},
7264
}
7365
}
7466

@@ -83,36 +75,19 @@ def test_analyse_flask_notes_app():
8375
assert appspecs == {
8476
"static-analysis:flask:tests/python/example_apps/flask_notes_app.py": {
8577
"openapi": "3.0.0",
86-
"info": {
87-
"title": "Static Analysis - Flask",
88-
"version": "2000-01-01 00:00:00"
89-
},
78+
"info": {"title": "Static Analysis - Flask", "version": "2000-01-01 00:00:00"},
9079
"paths": {
91-
"/": {
92-
"get": {
93-
"responses": {"default": {"description": "Discovered via static analysis"}}
94-
}
95-
},
80+
"/": {"get": {"responses": {"default": {"description": "Discovered via static analysis"}}}},
9681
"/new": {
97-
"get": {
98-
"responses": {"default": {"description": "Discovered via static analysis"}}
99-
},
100-
"post": {
101-
"responses": {"default": {"description": "Discovered via static analysis"}}
102-
}
82+
"get": {"responses": {"default": {"description": "Discovered via static analysis"}}},
83+
"post": {"responses": {"default": {"description": "Discovered via static analysis"}}},
10384
},
10485
"/edit/<int:note_id>": {
105-
"get": {
106-
"responses": {"default": {"description": "Discovered via static analysis"}}
107-
},
108-
"post": {
109-
"responses": {"default": {"description": "Discovered via static analysis"}}
110-
}
86+
"get": {"responses": {"default": {"description": "Discovered via static analysis"}}},
87+
"post": {"responses": {"default": {"description": "Discovered via static analysis"}}},
11188
},
11289
"/delete/<int:note_id>": {
113-
"post": {
114-
"responses": {"default": {"description": "Discovered via static analysis"}}
115-
}
90+
"post": {"responses": {"default": {"description": "Discovered via static analysis"}}}
11691
},
11792
},
11893
}

0 commit comments

Comments
 (0)