Skip to content

Commit f7e07a0

Browse files
authored
Merge pull request #541 from internetstandards/44
add subdomain suggestions
2 parents 0b4293b + 6892e6a commit f7e07a0

File tree

12 files changed

+515
-452
lines changed

12 files changed

+515
-452
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ vulture: ${app} ## Check for unused code
253253
${python} -m vulture ${pysrcdirs}
254254

255255
ruff: ${app} ## Faster than black, might autoformat some things
256-
${python} -m ruff ${pysrcdirs}
256+
${python} -m ruff check ${pysrcdirs}
257257

258258
bandit: ${app} ## Run basic security audit
259259
${python} -m bandit --configfile bandit.yaml -r ${pysrcdirs}

dashboard/internet_nl_dashboard/logic/domains.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import Any, Dict, List, Set, Tuple, Union
88

99
import pyexcel as p
10+
import requests
1011
import tldextract
1112
from actstream import action
1213
from celery import group
@@ -28,6 +29,25 @@
2829
log = logging.getLogger(__package__)
2930

3031

32+
def suggest_subdomains(domain: str, period: int = 370):
33+
extract = tldextract.extract(domain)
34+
35+
# ip address or garbage
36+
if not extract.domain or not extract.suffix:
37+
return []
38+
39+
# call SUBDOMAIN_SUGGESTION_SERVER_ADDRESS
40+
response = requests.get(config.SUBDOMAIN_SUGGESTION_SERVER_ADDRESS,
41+
params={'domain': extract.domain, 'suffix': extract.suffix, 'period': period},
42+
timeout=10)
43+
44+
if response.status_code != 200:
45+
log.error("Failed to retrieve subdomain suggestions from %s.", config.SUBDOMAIN_SUGGESTION_SERVER_ADDRESS)
46+
return []
47+
48+
return response.json()
49+
50+
3151
# todo: write test
3252
def alter_url_in_urllist(account, data) -> Dict[str, Any]:
3353
# data = {'list_id': list.id, 'url_id': url.id, 'new_url_string': url.url}

dashboard/internet_nl_dashboard/tests/test_domain_management.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77
import timeit
88

9+
import responses
910
from constance.test import override_config
1011
from websecmap.organizations.models import Url
1112

@@ -14,10 +15,24 @@
1415
get_urllist_content, get_urllists_from_account,
1516
keys_are_present_in_object, rename_list,
1617
retrieve_possible_urls_from_unfiltered_input,
17-
save_urllist_content_by_name)
18+
save_urllist_content_by_name, suggest_subdomains)
1819
from dashboard.internet_nl_dashboard.models import Account
1920

2021

22+
@responses.activate
23+
def test_suggest_subdomains(db, caplog):
24+
responses.add(responses.GET, 'http://localhost:8001/?domain=test&suffix=nl&period=370', json=["test"], status=200)
25+
responses.add(responses.GET, 'http://localhost:8001/?domain=broken&suffix=nl&period=370', json=[], status=404)
26+
27+
assert suggest_subdomains("test.nl", 370) == ["test"]
28+
assert suggest_subdomains("broken.nl") == []
29+
assert "Failed to retrieve" in caplog.text
30+
31+
# incomplete requests:
32+
assert suggest_subdomains("192.168.1.1") == []
33+
assert suggest_subdomains("a") == []
34+
35+
2136
@override_config(DASHBOARD_MAXIMUM_DOMAINS_PER_LIST=5000)
2237
def test_add_domains_from_raw_user_data(db, current_path, redis_server):
2338
"""

dashboard/internet_nl_dashboard/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def to_url(value):
5454
path('data/urllist/url/delete/', domains.delete_url_from_urllist_),
5555
path('data/urllist/download/', domains.download_list_),
5656
path('data/urllist/upload/<int:list_id>/', spreadsheet.upload_list_),
57+
path('data/urllist/suggest-subdomains/', domains.suggest_subdomains_),
5758

5859
path('data/urllist/tag/add/', tags.add_tag_),
5960
path('data/urllist/tag/remove/', tags.remove_tag_),

dashboard/internet_nl_dashboard/views/app.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ def config_content():
1212
"show": {
1313
"signup_form": configuration["SHOW_SIGNUP_FORM"],
1414
},
15+
"app": {
16+
"subdomain_suggestion": {
17+
"enabled": configuration["SUBDOMAIN_SUGGESTION_ENABLED"],
18+
"default_period": configuration["SUBDOMAIN_SUGGESTION_DEFAULT_TIME_PERIOD"],
19+
"default_extend_period": configuration["SUBDOMAIN_SUGGESTION_DEFAULT_EXTEND_TIME_PERIOD"],
20+
},
21+
# in the future we'll support this
22+
"signup": {
23+
"enabled": configuration["SHOW_SIGNUP_FORM"],
24+
}
25+
}
1526
}
1627

1728

dashboard/internet_nl_dashboard/views/domains.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,18 @@
1111
delete_url_from_urllist, download_as_spreadsheet,
1212
get_scan_status_of_list, get_urllist_content,
1313
get_urllists_from_account, save_urllist_content_by_name,
14-
scan_now, update_list_settings)
14+
scan_now, suggest_subdomains, update_list_settings)
1515
from dashboard.internet_nl_dashboard.views import LOGIN_URL, get_account, get_json_body
1616

1717

18+
@login_required(login_url=LOGIN_URL)
19+
def suggest_subdomains_(request) -> JsonResponse:
20+
request = get_json_body(request)
21+
domain = request.get("domain", "")
22+
period = request.get("period", 370)
23+
return JsonResponse(suggest_subdomains(domain, period), encoder=JSEncoder, safe=False)
24+
25+
1826
@login_required(login_url=LOGIN_URL)
1927
def get_lists(request) -> JsonResponse:
2028
return JsonResponse(get_urllists_from_account(account=get_account(request)), encoder=JSEncoder, safe=False)

0 commit comments

Comments
 (0)