aboutsummaryrefslogtreecommitdiff
path: root/tools/global_domains.py
diff options
context:
space:
mode:
authorJeremy Lin <[email protected]>2020-08-04 00:45:16 -0700
committerJeremy Lin <[email protected]>2020-08-06 12:12:32 -0700
commit9621278fca31311aa7720b95d5805eeb6e8d4141 (patch)
tree6c7aa98d3b3944dcea1d32b01af8f6f3647768e1 /tools/global_domains.py
parentad48e9ed0f91a1a7b38a032b2a538d4c9725f31c (diff)
downloadvaultwarden-9621278fca31311aa7720b95d5805eeb6e8d4141.tar.gz
vaultwarden-9621278fca31311aa7720b95d5805eeb6e8d4141.zip
Add a script to auto-generate the global equivalent domains JSON file
The script works by reading the relevant files from the upstream Bitwarden source repo and generating a matching JSON file. It could potentially be integrated into the build/release process, but for now it can be run manually as needed.
Diffstat (limited to 'tools/global_domains.py')
-rwxr-xr-xtools/global_domains.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/tools/global_domains.py b/tools/global_domains.py
new file mode 100755
index 00000000..8a3b5a8f
--- /dev/null
+++ b/tools/global_domains.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+#
+# This script generates a global equivalent domains JSON file from
+# the upstream Bitwarden source repo.
+#
+import json
+import re
+import sys
+import urllib.request
+
+from collections import OrderedDict
+
+if len(sys.argv) != 2:
+ print("usage: %s <OUTPUT-FILE>" % sys.argv[0])
+ print()
+ print("This script generates a global equivalent domains JSON file from")
+ print("the upstream Bitwarden source repo.")
+ sys.exit(1)
+
+OUTPUT_FILE = sys.argv[1]
+
+BASE_URL = 'https://github.com/bitwarden/server/raw/master'
+ENUMS_URL = '%s/src/Core/Enums/GlobalEquivalentDomainsType.cs' % BASE_URL
+DOMAIN_LISTS_URL = '%s/src/Core/Utilities/StaticStore.cs' % BASE_URL
+
+# Enum lines look like:
+#
+# EnumName0 = 0,
+# EnumName1 = 1,
+#
+ENUM_RE = re.compile(
+ r'\s*' # Leading whitespace (optional).
+ r'([_0-9a-zA-Z]+)' # Enum name (capture group 1).
+ r'\s*=\s*' # '=' with optional surrounding whitespace.
+ r'([0-9]+)' # Enum value (capture group 2).
+)
+
+# Global domains lines look like:
+#
+# GlobalDomains.Add(GlobalEquivalentDomainsType.EnumName, new List<string> { "x.com", "y.com" });
+#
+DOMAIN_LIST_RE = re.compile(
+ r'\s*' # Leading whitespace (optional).
+ r'GlobalDomains\.Add\(GlobalEquivalentDomainsType\.'
+ r'([_0-9a-zA-Z]+)' # Enum name (capture group 1).
+ r'\s*,\s*new List<string>\s*{'
+ r'([^}]+)' # Domain list (capture group 2).
+ r'}\);'
+)
+
+enums = dict()
+domain_lists = OrderedDict()
+
+# Read in the enum names and values.
+with urllib.request.urlopen(ENUMS_URL) as response:
+ for ln in response.read().decode('utf-8').split('\n'):
+ m = ENUM_RE.match(ln)
+ if m:
+ enums[m.group(1)] = int(m.group(2))
+
+# Read in the domain lists.
+with urllib.request.urlopen(DOMAIN_LISTS_URL) as response:
+ for ln in response.read().decode('utf-8').split('\n'):
+ m = DOMAIN_LIST_RE.match(ln)
+ if m:
+ # Strip double quotes and extraneous spaces in each domain.
+ domain_lists[m.group(1)] = [d.strip(' "') for d in m.group(2).split(",")]
+
+# Build the global domains data structure.
+global_domains = []
+for name, domain_list in domain_lists.items():
+ entry = OrderedDict()
+ entry["Type"] = enums[name]
+ entry["Domains"] = domain_list
+ entry["Excluded"] = False
+ global_domains.append(entry)
+
+# Write out the global domains JSON file.
+with open(OUTPUT_FILE, 'w') as f:
+ json.dump(global_domains, f, indent=2)