Just deleted about 400 bot accounts and a bunch of spam. To mitigate this in the future, we've enabled reCaptcha on signup. Let me know if someone got caught in the crossfire.

Commit 23b9e48c authored by Rob Nelson's avatar Rob Nelson
Browse files

Better injector status detection, fixed some issues.

parent 1bf315b0
import os, stat, re, json
import os, stat, re, json, pathlib
from typing import Dict
from buildtools import os_utils, log
from discordjail.addons.framework import Addon, Addons
......@@ -22,6 +22,20 @@ class BBDPlugin(object):
self.name: str = _id
self.url: str = url
@classmethod
def CreateFromFile(cls, filename: str) -> 'BDDPlugin':
with open(filename, 'r') as f:
for line in f:
line=line.strip()
if line.startswith('//META{'):
meta = json.loads(line[6:line.find('}')])
if 'name' in meta and 'source' in meta:
plug = cls()
plug.id = plug.name = meta['name']
plug.url = meta['source']
return plug
return None
def deserialize(self, key: str, data: dict) -> None:
self.id = key
self.name = data.get('name', key)
......@@ -31,6 +45,20 @@ class BBDPlugin(object):
download_file_to(self.url, os.path.join(bbd.plugins_dir, f'{self.id}.plugin.js'))
class BBDTheme(BBDPlugin):
@classmethod
def CreateFromFile(cls, filename: str) -> 'BBDTheme':
with open(filename, 'r') as f:
for line in f:
line=line.strip()
if line.startswith('//META{'):
meta = json.loads(line[6:line.find('}')])
if 'name' in meta and 'source' in meta:
plug = cls()
plug.id = plug.name = meta['name']
plug.url = meta['source']
return plug
return None
def install(self, bbd: 'BandagedBetterDiscordAddon') -> None:
download_file_to(self.url, os.path.join(bbd.themes_dir, f'{self.id}.theme.css'))
......@@ -76,15 +104,48 @@ class BandagedBetterDiscordAddon(Addon):
self.themes_dir = os.path.join(self.discord.homedir, '.config', 'BetterDiscord', 'themes')
os_utils.ensureDirExists(os.path.dirname(self.bbdctl_path), noisy=True)
download_file_to(BDDCTL_URL, self.bbdctl_path)
#download_file_to(BDDCTL_URL, self.bbdctl_path)
with log.info(f'Setting {self.bbdctl_path} +x (+S_IEXEC)...'):
st = os.stat(self.bbdctl_path)
os.chmod(self.bbdctl_path, st.st_mode|stat.S_IEXEC)
opts = ['-d', self.discord_dir]
opts += ['-m', self.modules_dir]
if os.path.isdir(os.path.join(self.modules_dir, 'discord_desktop_core', 'injector')):
with log.info('Injector not found, installing...'):
os_utils.cmd([self.bbdctl_path, 'install']+opts, show_output=True, echo=True, critical=False)
injpath = os.path.join(self.modules_dir, 'discord_desktop_core', 'injector')
# injpath = /home/nexis/discordjail/jails/N3X15/home/.config/discord/0.0.9/modules/discord_desktop_core/injector
# Core: /home/nexis/discordjail/jails/N3X15/home/.config/discord/0.0.9/modules/discord_desktop_core
idxpath = os.path.join(self.modules_dir, 'discord_desktop_core', 'index.js')
injhealth = 'OK'
injbad = False
idxhealth = 'OK'
bddctl_op = []
if not os.path.isdir(injpath):
injhealth = 'MISSING'
injbad = True
bddctl_op = ['install']
else:
realinjpath = pathlib.Path(injpath).resolve()
if not os.path.isdir(realinjpath):
injhealth = "BROKEN"
bddctl_op = ['uninstall', 'install']
injhealth += f' ({realinjpath})'
if not os.path.isfile(idxpath):
idxhealth = 'MISSING'
injbad = True
bddctl_op = ['uninstall', 'install']
else:
with open(idxpath, 'r') as f:
if 'injector' not in f.read():
idxhealth = 'UNPATCHED'
injbad = True
bddctl_op = ['uninstall', 'install']
with log.info('BDD Status:'):
log.info('Modules path: %s', self.modules_dir)
log.info('Injector: %s - %s', injpath, injhealth)
log.info('index.js: %s - %s', idxpath, idxhealth)
if len(bddctl_op)>0:
with log.info('Injector broken, attempting repair...'):
for op in bddctl_op:
os_utils.cmd([self.bbdctl_path, op]+opts, show_output=True, echo=True, critical=False)
if not os_utils.cmd([self.bbdctl_path, 'update']+opts, show_output=True, echo=True, critical=False):
with log.info('Update failed, attempting reinstall...'):
os_utils.cmd([self.bbdctl_path, 'install']+opts, show_output=True, echo=True, critical=False)
......@@ -99,13 +160,6 @@ class BandagedBetterDiscordAddon(Addon):
log.info(f'Creating {self.themes_dir}...')
os.makedirs(self.themes_dir)
for plugin in self.plugins.values():
plugin.install(self)
for theme in self.themes.values():
theme.install(self)
bdstorage = {
'settings': {
'stable': {
......@@ -114,10 +168,12 @@ class BandagedBetterDiscordAddon(Addon):
}
}
}
bdstorage_filename = os.path.join(self.discord.homedir, '.config', 'BetterDiscord', 'bdstorage.json')
if os.path.isfile(bdstorage_filename):
with open(bdstorage_filename, 'r') as f:
bdstorage = json.load(f)
for plid in ENABLE_BY_DEFAULT:
curbase = bdstorage
for key in ['settings', 'stable', 'plugins', plid]:
......@@ -125,6 +181,13 @@ class BandagedBetterDiscordAddon(Addon):
curbase[key] = {}
curbase=curbase[key]
bdstorage['settings']['stable']['plugins'][plid] = True
for plugin in self.plugins.values():
plugin.install(self)
for theme in self.themes.values():
theme.install(self)
with open(bdstorage_filename, 'w') as f:
json.dump(bdstorage, f)
......
......@@ -2,14 +2,17 @@ import os, shutil, hashlib, requests
from buildtools import os_utils, log, http
from urllib.parse import urlparse
from discordjail.consts import CACHE_DIR
def download_file_to(url, path):
def download_file_to(url, path, cache=True):
etag=''
urlchunks = urlparse(url)
etagdir = os.path.join(CACHE_DIR, urlchunks.hostname)
fileid = hashlib.md5(urlchunks.path.encode('utf-8')).hexdigest()
etagdir = os.path.join(CACHE_DIR, urlchunks.hostname, fileid[0:2], fileid[2:4])
old_uri_id = hashlib.sha256(urlchunks.path.encode('utf-8')).hexdigest()+'.etags'
uri_id = hashlib.md5(urlchunks.path.encode('utf-8')).hexdigest()+'.etags'
uri_id = fileid[4:]+'.etags'
cached_dl = os.path.join(etagdir, fileid[4:]+'.dat')
if os.path.isfile(os.path.join(etagdir, old_uri_id)):
shutil.move(os.path.join(etagdir, old_uri_id),os.path.join(etagdir, uri_id))
......@@ -25,15 +28,18 @@ def download_file_to(url, path):
res = requests.head(url, allow_redirects=True, headers={'If-None-Match':etag})
if res.status_code==304:
log.info('304 - Not Modified')
return None
if not cache:
return None
else:
res.raise_for_status()
with log.info('Response headers:'):
for k,v in res.headers.items():
log.info('%s: %s',k,v)
filename = path or os.path.join(CACHE_DIR, res.history[0].headers.get('Location').split('/')[-1])
http.DownloadFile(url, filename, log_after=True, print_status=True, log_before=True)
with open(etagfile,'w') as f:
f.write(res.headers.get('ETag'))
return filename
http.DownloadFile(url, cached_dl, log_after=True, print_status=True, log_before=True)
filename = path or os.path.join(CACHE_DIR, res.history[0].headers.get('Location').split('/')[-1])
shutil.copy2(cached_dl, filename)
if not cache:
os.remove(cached_dl)
return filename
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment