diff --git a/epicyon.py b/epicyon.py index edb04cbf..3a1d5278 100644 --- a/epicyon.py +++ b/epicyon.py @@ -15,6 +15,7 @@ from person import deactivateAccount from skills import setSkillLevel from roles import setRole from webfinger import webfingerHandle +from posts import checkDomains from posts import getPublicPostDomains from posts import getPublicPostDomainsBlocked from posts import sendBlockViaServer @@ -162,6 +163,10 @@ parser.add_argument('--postDomainsBlocked', dest='postDomainsBlocked', type=str, default=None, help='Show blocked domains referenced in public ' 'posts for the given handle') +parser.add_argument('--checkDomains', dest='checkDomains', type=str, + default=None, + help='Check domains of non-mutual followers for ' + 'domains which are globally blocked by this instance') parser.add_argument('--socnet', dest='socnet', type=str, default=None, help='Show dot diagram for social network ' @@ -520,6 +525,44 @@ if args.postDomainsBlocked: print(postDomain) sys.exit() +if args.checkDomains: + # Domains which were referenced in public posts by a + # given handle but which are globally blocked on this instance + if '@' not in args.checkDomains: + if '/users/' in args.checkDomains: + postsNickname = getNicknameFromActor(args.posts) + postsDomain, postsPort = getDomainFromActor(args.posts) + args.checkDomains = postsNickname + '@' + postsDomain + if postsPort: + if postsPort != 80 and postsPort != 443: + args.checkDomains += ':' + str(postsPort) + else: + print('Syntax: --checkDomains nickname@domain') + sys.exit() + if not args.http: + args.port = 443 + nickname = args.checkDomains.split('@')[0] + domain = args.checkDomains.split('@')[1] + proxyType = None + if args.tor or domain.endswith('.onion'): + proxyType = 'tor' + if domain.endswith('.onion'): + args.port = 80 + elif args.i2p or domain.endswith('.i2p'): + proxyType = 'i2p' + if domain.endswith('.i2p'): + args.port = 80 + elif args.gnunet: + proxyType = 'gnunet' + maxBlockedDomains = 2 + checkDomains(None, + baseDir, nickname, domain, + proxyType, args.port, + httpPrefix, debug, + __version__, + maxBlockedDomains, False) + sys.exit() + if args.socnet: if ',' not in args.socnet: print('Syntax: ' diff --git a/posts.py b/posts.py index 8f735516..4218dbec 100644 --- a/posts.py +++ b/posts.py @@ -14,6 +14,7 @@ import shutil import sys import time import uuid +import random from socket import error as SocketError from time import gmtime, strftime from collections import OrderedDict @@ -59,6 +60,7 @@ from filters import isFiltered from git import convertPostToPatch from jsonldsig import jsonldSign from petnames import resolvePetnames +from follow import getNonMutualsOfPerson # try: # from BeautifulSoup import BeautifulSoup # except ImportError: @@ -3330,6 +3332,57 @@ def getPublicPostDomainsBlocked(session, baseDir: str, return blockedDomains +def checkDomains(session, baseDir: str, + nickname: str, domain: str, + proxyType: str, port: int, httpPrefix: str, + debug: bool, projectVersion: str, + maxBlockedDomains: int, singleCheck: bool): + """Checks follower accounts for references to globally blocked domains + """ + nonMutuals = getNonMutualsOfPerson(baseDir, nickname, domain) + if not nonMutuals: + return + followerWarningFilename = baseDir + '/accounts/followerWarnings.txt' + updateFollowerWarnings = False + followerWarningStr = '' + if os.path.isfile(followerWarningFilename): + with open(followerWarningFilename, 'r') as fp: + followerWarningStr = fp.read() + + if singleCheck: + # checks a single random non-mutual + index = random.randrange(0, len(nonMutuals)) + domainName = nonMutuals[index] + blockedDomains = \ + getPublicPostDomainsBlocked(session, baseDir, + nickname, domain, + proxyType, port, httpPrefix, + debug, projectVersion, []) + if blockedDomains: + if len(blockedDomains) > maxBlockedDomains: + followerWarningStr += domainName + '\n' + updateFollowerWarnings = True + else: + # checks all non-mutuals + for domainName in nonMutuals: + if domainName in followerWarningStr: + continue + blockedDomains = \ + getPublicPostDomainsBlocked(session, baseDir, + nickname, domain, + proxyType, port, httpPrefix, + debug, projectVersion, []) + if blockedDomains: + if len(blockedDomains) > maxBlockedDomains: + followerWarningStr += domainName + '\n' + updateFollowerWarnings = True + + if updateFollowerWarnings and followerWarningStr: + with open(followerWarningFilename, 'w+') as fp: + fp.write(followerWarningStr) + print(followerWarningStr) + + def sendCapabilitiesUpdate(session, baseDir: str, httpPrefix: str, nickname: str, domain: str, port: int, followerUrl, updateCaps: [],