Fixing --posts option

main
Bob Mottram 2021-08-01 14:25:11 +01:00
parent faa747fc30
commit cfea4f0c90
7 changed files with 166 additions and 20 deletions

View File

@ -162,9 +162,10 @@ def _acceptFollow(baseDir: str, domain: str, messageJson: {},
return return
# does the url path indicate that this is a group actor # does the url path indicate that this is a group actor
groupAccount = hasGroupType(baseDir, followedActor, None) groupAccount = hasGroupType(baseDir, followedActor, None, debug)
if debug: if debug:
print('Accepted follow is a group: ' + str(groupAccount)) print('Accepted follow is a group: ' + str(groupAccount) +
' ' + followedActor + ' ' + baseDir)
if followPerson(baseDir, if followPerson(baseDir,
nickname, acceptedDomainFull, nickname, acceptedDomainFull,

View File

@ -609,7 +609,7 @@ if args.tests:
sys.exit() sys.exit()
if args.testsnetwork: if args.testsnetwork:
print('Network Tests') print('Network Tests')
testGroupFollow() # testGroupFollow()
testPostMessageBetweenServers() testPostMessageBetweenServers()
testFollowBetweenServers() testFollowBetweenServers()
testClientToServer() testClientToServer()

View File

@ -787,8 +787,11 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
if os.path.isfile(followersFilename): if os.path.isfile(followersFilename):
if approveHandle not in open(followersFilename).read(): if approveHandle not in open(followersFilename).read():
groupAccount = \ groupAccount = \
hasGroupType(baseDir, messageJson['object'], hasGroupType(baseDir, messageJson['actor'],
personCache) personCache)
if debug:
print(approveHandle + ' / ' + messageJson['actor'] +
' is Group: ' + str(groupAccount))
try: try:
with open(followersFilename, 'r+') as followersFile: with open(followersFilename, 'r+') as followersFile:
content = followersFile.read() content = followersFile.read()

View File

@ -217,19 +217,22 @@ def validInboxFilenames(baseDir: str, nickname: str, domain: str,
domain = removeDomainPort(domain) domain = removeDomainPort(domain)
inboxDir = acctDir(baseDir, nickname, domain) + '/inbox' inboxDir = acctDir(baseDir, nickname, domain) + '/inbox'
if not os.path.isdir(inboxDir): if not os.path.isdir(inboxDir):
print('Not an inbox directory: ' + inboxDir)
return True return True
expectedStr = expectedDomain + ':' + str(expectedPort) expectedStr = expectedDomain + ':' + str(expectedPort)
expectedFound = False
for subdir, dirs, files in os.walk(inboxDir): for subdir, dirs, files in os.walk(inboxDir):
for f in files: for f in files:
filename = os.path.join(subdir, f) filename = os.path.join(subdir, f)
if not os.path.isfile(filename): if not os.path.isfile(filename):
print('filename: ' + filename) print('filename: ' + filename)
return False return False
if expectedStr not in filename: if expectedStr in filename:
print('Expected: ' + expectedStr) expectedFound = True
print('Invalid filename: ' + filename)
return False
break break
if not expectedFound:
print('Expected file was not found: ' + expectedStr)
return False
return True return True
@ -1890,6 +1893,9 @@ def _sendToGroupMembers(session, baseDir: str, handle: str, port: int,
systemLanguage: str) -> None: systemLanguage: str) -> None:
"""When a post arrives for a group send it out to the group members """When a post arrives for a group send it out to the group members
""" """
if debug:
print('\n\n=========================================================')
print(handle + ' sending to group members')
followersFile = baseDir + '/accounts/' + handle + '/followers.txt' followersFile = baseDir + '/accounts/' + handle + '/followers.txt'
if not os.path.isfile(followersFile): if not os.path.isfile(followersFile):
return return

View File

@ -428,8 +428,7 @@ def _getPosts(session, outboxUrl: str, maxPosts: int,
if tagItem['icon'].get('url'): if tagItem['icon'].get('url'):
# No emoji from non-permitted domains # No emoji from non-permitted domains
if urlPermitted(tagItem['icon']['url'], if urlPermitted(tagItem['icon']['url'],
federationList, federationList):
"objects:read"):
emojiName = tagItem['name'] emojiName = tagItem['name']
emojiIcon = tagItem['icon']['url'] emojiIcon = tagItem['icon']['url']
emoji[emojiName] = emojiIcon emoji[emojiName] = emojiIcon
@ -461,8 +460,7 @@ def _getPosts(session, outboxUrl: str, maxPosts: int,
if isinstance(item['object']['inReplyTo'], str): if isinstance(item['object']['inReplyTo'], str):
# No replies to non-permitted domains # No replies to non-permitted domains
if not urlPermitted(item['object']['inReplyTo'], if not urlPermitted(item['object']['inReplyTo'],
federationList, federationList):
"objects:read"):
if debug: if debug:
print('url not permitted ' + print('url not permitted ' +
item['object']['inReplyTo']) item['object']['inReplyTo'])
@ -474,7 +472,7 @@ def _getPosts(session, outboxUrl: str, maxPosts: int,
if item['object']['conversation']: if item['object']['conversation']:
# no conversations originated in non-permitted domains # no conversations originated in non-permitted domains
if urlPermitted(item['object']['conversation'], if urlPermitted(item['object']['conversation'],
federationList, "objects:read"): federationList):
conversation = item['object']['conversation'] conversation = item['object']['conversation']
attachment = [] attachment = []
@ -484,8 +482,7 @@ def _getPosts(session, outboxUrl: str, maxPosts: int,
if attach.get('name') and attach.get('url'): if attach.get('name') and attach.get('url'):
# no attachments from non-permitted domains # no attachments from non-permitted domains
if urlPermitted(attach['url'], if urlPermitted(attach['url'],
federationList, federationList):
"objects:read"):
attachment.append([attach['name'], attachment.append([attach['name'],
attach['url']]) attach['url']])
else: else:

131
tests.py
View File

@ -614,7 +614,7 @@ def createServerBob(path: str, domain: str, port: int,
False, password) False, password)
deleteAllPosts(path, nickname, domain, 'inbox') deleteAllPosts(path, nickname, domain, 'inbox')
deleteAllPosts(path, nickname, domain, 'outbox') deleteAllPosts(path, nickname, domain, 'outbox')
if hasFollows: if hasFollows and aliceAddress:
followPerson(path, nickname, domain, followPerson(path, nickname, domain,
'alice', aliceAddress, federationList, False, False) 'alice', aliceAddress, federationList, False, False)
followerOfPerson(path, nickname, domain, followerOfPerson(path, nickname, domain,
@ -1321,9 +1321,11 @@ def testGroupFollow():
print('Testing following of a group') print('Testing following of a group')
global testServerAliceRunning global testServerAliceRunning
global testServerBobRunning
global testServerGroupRunning global testServerGroupRunning
systemLanguage = 'en' systemLanguage = 'en'
testServerAliceRunning = False testServerAliceRunning = False
testServerBobRunning = False
testServerGroupRunning = False testServerGroupRunning = False
# systemLanguage = 'en' # systemLanguage = 'en'
@ -1343,6 +1345,12 @@ def testGroupFollow():
aliceSendThreads = [] aliceSendThreads = []
# aliceAddress = aliceDomain + ':' + str(alicePort) # aliceAddress = aliceDomain + ':' + str(alicePort)
bobDir = baseDir + '/.tests/bob'
bobDomain = '127.0.0.59'
bobPort = 61814
bobSendThreads = []
# bobAddress = bobDomain + ':' + str(bobPort)
testgroupDir = baseDir + '/.tests/testgroup' testgroupDir = baseDir + '/.tests/testgroup'
testgroupDomain = '127.0.0.63' testgroupDomain = '127.0.0.63'
testgroupPort = 61925 testgroupPort = 61925
@ -1364,6 +1372,20 @@ def testGroupFollow():
aliceSendThreads), aliceSendThreads),
daemon=True) daemon=True)
global thrBob
if thrBob:
while thrBob.is_alive():
thrBob.stop()
time.sleep(1)
thrBob.kill()
thrBob = \
threadWithTrace(target=createServerBob,
args=(bobDir, bobDomain, bobPort, None,
federationList, False, False,
bobSendThreads),
daemon=True)
global thrGroup global thrGroup
if thrGroup: if thrGroup:
while thrGroup.is_alive(): while thrGroup.is_alive():
@ -1379,18 +1401,23 @@ def testGroupFollow():
daemon=True) daemon=True)
thrAlice.start() thrAlice.start()
thrBob.start()
thrGroup.start() thrGroup.start()
assert thrAlice.is_alive() is True assert thrAlice.is_alive() is True
assert thrBob.is_alive() is True
assert thrGroup.is_alive() is True assert thrGroup.is_alive() is True
# wait for all servers to be running # wait for all servers to be running
ctr = 0 ctr = 0
while not (testServerAliceRunning and testServerGroupRunning): while not (testServerAliceRunning and
testServerBobRunning and
testServerGroupRunning):
time.sleep(1) time.sleep(1)
ctr += 1 ctr += 1
if ctr > 60: if ctr > 60:
break break
print('Alice online: ' + str(testServerAliceRunning)) print('Alice online: ' + str(testServerAliceRunning))
print('Bob online: ' + str(testServerBobRunning))
print('Test Group online: ' + str(testServerGroupRunning)) print('Test Group online: ' + str(testServerGroupRunning))
assert ctr <= 60 assert ctr <= 60
time.sleep(1) time.sleep(1)
@ -1448,6 +1475,7 @@ def testGroupFollow():
assert validInboxFilenames(testgroupDir, 'testgroup', testgroupDomain, assert validInboxFilenames(testgroupDir, 'testgroup', testgroupDomain,
aliceDomain, alicePort) aliceDomain, alicePort)
assert 'alice@' + aliceDomain in open(testgroupFollowersFilename).read() assert 'alice@' + aliceDomain in open(testgroupFollowersFilename).read()
assert '!alice@' + aliceDomain not in open(testgroupFollowersFilename).read()
testgroupWebfingerFilename = \ testgroupWebfingerFilename = \
testgroupDir + '/wfendpoints/testgroup@' + \ testgroupDir + '/wfendpoints/testgroup@' + \
@ -1468,10 +1496,88 @@ def testGroupFollow():
assert '!testgroup' in followingStr assert '!testgroup' in followingStr
assert testgroupHandle in open(aliceFollowingFilename).read() assert testgroupHandle in open(aliceFollowingFilename).read()
assert testgroupHandle in open(aliceFollowingCalendarFilename).read() assert testgroupHandle in open(aliceFollowingCalendarFilename).read()
print('\n\n*********************************************************')
print('Alice follows the test group') print('Alice follows the test group')
print('*********************************************************')
print('Bob sends a follow request to the test group')
os.chdir(bobDir)
sessionBob = createSession(proxyType)
inReplyTo = None
inReplyToAtomUri = None
subject = None
bobPostLog = []
followersOnly = False
saveToFile = True
clientToServer = False
ccUrl = None
bobPersonCache = {}
bobCachedWebfingers = {}
bobPostLog = []
# bobActor = httpPrefix + '://' + bobAddress + '/users/bob'
testgroupActor = httpPrefix + '://' + testgroupAddress + '/users/testgroup'
sendResult = \
sendFollowRequest(sessionBob, bobDir,
'bob', bobDomain, bobPort, httpPrefix,
'testgroup', testgroupDomain, testgroupActor,
testgroupPort, httpPrefix,
clientToServer, federationList,
bobSendThreads, bobPostLog,
bobCachedWebfingers, bobPersonCache,
True, __version__)
print('sendResult: ' + str(sendResult))
bobFollowingFilename = \
bobDir + '/accounts/bob@' + bobDomain + '/following.txt'
bobFollowingCalendarFilename = \
bobDir + '/accounts/bob@' + bobDomain + \
'/followingCalendar.txt'
testgroupFollowersFilename = \
testgroupDir + '/accounts/testgroup@' + testgroupDomain + \
'/followers.txt'
for t in range(16):
if os.path.isfile(testgroupFollowersFilename):
if os.path.isfile(bobFollowingFilename):
if os.path.isfile(bobFollowingCalendarFilename):
break
time.sleep(1)
assert validInbox(testgroupDir, 'testgroup', testgroupDomain)
assert validInboxFilenames(testgroupDir, 'testgroup', testgroupDomain,
bobDomain, bobPort)
assert 'bob@' + bobDomain in open(testgroupFollowersFilename).read()
assert '!bob@' + bobDomain not in open(testgroupFollowersFilename).read()
testgroupWebfingerFilename = \
testgroupDir + '/wfendpoints/testgroup@' + \
testgroupDomain + ':' + str(testgroupPort) + '.json'
assert os.path.isfile(testgroupWebfingerFilename)
assert 'group:testgroup@' in open(testgroupWebfingerFilename).read()
print('group: exists within the webfinger endpoint for testgroup')
testgroupHandle = 'testgroup@' + testgroupDomain
followingStr = ''
with open(bobFollowingFilename, 'r') as fp:
followingStr = fp.read()
print('Bob following.txt:\n\n' + followingStr)
if '!testgroup' not in followingStr:
print('Bob following.txt does not contain !testgroup@' +
testgroupDomain + ':' + str(testgroupPort))
assert isGroupActor(bobDir, testgroupActor, bobPersonCache)
assert '!testgroup' in followingStr
assert testgroupHandle in open(bobFollowingFilename).read()
assert testgroupHandle in open(bobFollowingCalendarFilename).read()
print('Bob follows the test group')
print('\n\n*********************************************************') print('\n\n*********************************************************')
print('Alice posts to the test group') print('Alice posts to the test group')
inboxPathBob = \
bobDir + '/accounts/bob@' + bobDomain + '/inbox'
startPostsBob = \
len([name for name in os.listdir(inboxPathBob)
if os.path.isfile(os.path.join(inboxPathBob, name))])
assert startPostsBob == 0
alicePostLog = [] alicePostLog = []
alicePersonCache = {} alicePersonCache = {}
aliceCachedWebfingers = {} aliceCachedWebfingers = {}
@ -1509,13 +1615,34 @@ def testGroupFollow():
break break
assert aliceMessageArrived is True assert aliceMessageArrived is True
print('\n\n*********************************************************')
print('Post from Alice to test group succeeded') print('Post from Alice to test group succeeded')
print('\n\n*********************************************************')
print('Check that post was relayed from test group to bob')
bobMessageArrived = False
for i in range(20):
time.sleep(1)
if os.path.isdir(inboxPathBob):
currPostsBob = \
len([name for name in os.listdir(inboxPathBob)
if os.path.isfile(os.path.join(inboxPathBob, name))])
if currPostsBob > startPostsBob:
bobMessageArrived = True
print('Bob received relayed group post!')
break
assert bobMessageArrived is True
# stop the servers # stop the servers
thrAlice.kill() thrAlice.kill()
thrAlice.join() thrAlice.join()
assert thrAlice.is_alive() is False assert thrAlice.is_alive() is False
thrBob.kill()
thrBob.join()
assert thrBob.is_alive() is False
thrGroup.kill() thrGroup.kill()
thrGroup.join() thrGroup.join()
assert thrGroup.is_alive() is False assert thrGroup.is_alive() is False

View File

@ -2687,7 +2687,8 @@ def dateSecondsToString(dateSec: int) -> str:
return thisDate.strftime("%Y-%m-%dT%H:%M:%SZ") return thisDate.strftime("%Y-%m-%dT%H:%M:%SZ")
def hasGroupType(baseDir: str, actor: str, personCache: {}) -> bool: def hasGroupType(baseDir: str, actor: str, personCache: {},
debug: bool = False) -> bool:
"""Does the given actor url have a group type? """Does the given actor url have a group type?
""" """
# does the actor path clearly indicate that this is a group? # does the actor path clearly indicate that this is a group?
@ -2695,12 +2696,15 @@ def hasGroupType(baseDir: str, actor: str, personCache: {}) -> bool:
groupPaths = getGroupPaths() groupPaths = getGroupPaths()
for grpPath in groupPaths: for grpPath in groupPaths:
if grpPath in actor: if grpPath in actor:
if debug:
print('grpPath ' + grpPath + ' in ' + actor)
return True return True
# is there a cached actor which can be examined for Group type? # is there a cached actor which can be examined for Group type?
return isGroupActor(baseDir, actor, personCache) return isGroupActor(baseDir, actor, personCache, debug)
def isGroupActor(baseDir: str, actor: str, personCache: {}) -> bool: def isGroupActor(baseDir: str, actor: str, personCache: {},
debug: bool = False) -> bool:
"""Is the given actor a group? """Is the given actor a group?
""" """
if personCache: if personCache:
@ -2708,12 +2712,20 @@ def isGroupActor(baseDir: str, actor: str, personCache: {}) -> bool:
if personCache[actor].get('actor'): if personCache[actor].get('actor'):
if personCache[actor]['actor'].get('type'): if personCache[actor]['actor'].get('type'):
if personCache[actor]['actor']['type'] == 'Group': if personCache[actor]['actor']['type'] == 'Group':
if debug:
print('Cached actor ' + actor + ' has Group type')
return True return True
return False return False
if debug:
print('Actor ' + actor + ' not in cache')
cachedActorFilename = \ cachedActorFilename = \
baseDir + '/cache/actors/' + (actor.replace('/', '#')) + '.json' baseDir + '/cache/actors/' + (actor.replace('/', '#')) + '.json'
if not os.path.isfile(cachedActorFilename): if not os.path.isfile(cachedActorFilename):
if debug:
print('Cached actor file not found ' + cachedActorFilename)
return False return False
if '"type": "Group"' in open(cachedActorFilename).read(): if '"type": "Group"' in open(cachedActorFilename).read():
if debug:
print('Group type found in ' + cachedActorFilename)
return True return True
return False return False