77import socket
88import urllib3
99
10+ PROXY_REGEX = r"\s+set \$upstream_app (?P<name>\S+?);.*\n(\s+)set \$upstream_port (?P<port>\d+);.*\n(\s+)set \$upstream_proto (?P<proto>\w+);.*"
11+ AUTHELIA_REGEX = r"\n\s+include \/config\/nginx\/authelia-location\.conf;.*"
12+ AUTHENTIK_REGEX = r"\n\s+include \/config\/nginx\/authentik-location\.conf;.*"
13+ BASIC_AUTH_REGEX = r"\n\s+auth_basic.*"
14+ LDAP_REGEX = r"\n\s+include \/config\/nginx\/ldap-location\.conf;.*"
15+
1016
1117def find_apps ():
1218 apps = {}
19+ auths = collections .defaultdict (dict )
1320 file_paths = glob .glob ("/config/nginx/**/**" , recursive = True )
1421 auto_confs = glob .glob ("/etc/nginx/http.d/*" , recursive = True )
1522 file_paths .extend (auto_confs )
@@ -18,17 +25,36 @@ def find_apps():
1825 continue
1926 file = open (file_path , "r" )
2027 content = file .read ()
21- results = re .finditer (r"(\s+)set \$upstream_app (?P<name>\S+?);.*\n(\s+)set \$upstream_port (?P<port>\d+);.*\n(\s+)set \$upstream_proto (?P<proto>\w+);.*" , content )
22- for result in results :
23- params = result .groupdict ()
24- app = f"{ params ['proto' ]} ://{ params ['name' ]} :{ params ['port' ]} /"
25- if app not in apps :
26- apps [app ] = set ()
27- if file_path .startswith ("/config/nginx/site-confs/" ) or file_path .endswith (".conf" ):
28- file_path = "auto-proxy" if file_path .startswith ("/etc/nginx/http.d/" ) else file_path
29- apps [app ].add (file_path )
30- return apps
28+ match_proxy (content , file_path , apps )
29+ match_auth (apps , auths )
30+ return apps , auths
31+
32+ def match_proxy (content , file_path , apps ):
33+ results = re .finditer (PROXY_REGEX , content )
34+ for result in results :
35+ params = result .groupdict ()
36+ app = f"{ params ['proto' ]} ://{ params ['name' ]} :{ params ['port' ]} /"
37+ if app not in apps :
38+ apps [app ] = set ()
39+ if file_path .startswith ("/config/nginx/site-confs/" ) or file_path .endswith (".conf" ):
40+ file_path = "auto-proxy" if file_path .startswith ("/etc/nginx/http.d/" ) else file_path
41+ apps [app ].add (file_path )
3142
43+ def match_auth (apps , auths ):
44+ for app , file_paths in apps .items ():
45+ for file_path in file_paths :
46+ file = open (file_path , "r" )
47+ content = file .read ()
48+ if re .findall (AUTHELIA_REGEX , content ):
49+ auths [app ][file_path ] = "Authelia"
50+ elif re .findall (AUTHENTIK_REGEX , content ):
51+ auths [app ][file_path ] = "Authentik"
52+ elif re .findall (BASIC_AUTH_REGEX , content ):
53+ auths [app ][file_path ] = "Basic Auth"
54+ elif re .findall (LDAP_REGEX , content ):
55+ auths [app ][file_path ] = "LDAP"
56+ else :
57+ auths [app ][file_path ] = "No Auth"
3258
3359def is_available (url ):
3460 s = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
@@ -45,7 +71,7 @@ def is_available(url):
4571
4672
4773urllib3 .disable_warnings ()
48- apps = find_apps ()
74+ apps , auths = find_apps ()
4975discovered_apps = collections .defaultdict (dict )
5076with concurrent .futures .ThreadPoolExecutor (max_workers = 100 ) as executor :
5177 futures = {executor .submit (is_available , app ): app for app in apps .keys ()}
@@ -55,5 +81,7 @@ def is_available(url):
5581 continue
5682 discovered_apps [app ]["status" ] = future .result ()
5783 discovered_apps [app ]["locations" ] = list (apps [app ])
84+ discovered_apps [app ]["auths" ] = list (f"{ path } - { auth } " for path , auth in auths [app ].items ())
85+ discovered_apps [app ]["auth_status" ] = all (auth != "No Auth" for auth in auths [app ].values ())
5886
5987print (json .dumps (discovered_apps , sort_keys = True ))
0 commit comments