forked from indymedia/epicyon
Fixing tests
parent
0f01a5a11a
commit
f8cc1873d4
|
@ -93,11 +93,17 @@ def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
|
|||
if debug:
|
||||
print('DEBUG: No "to" parameter in follow Accept')
|
||||
return
|
||||
if len(messageJson['object']['to'])!=1:
|
||||
if debug:
|
||||
print('DEBUG: "to" does not contain a single recipient')
|
||||
print(str(messageJson['object']['to']))
|
||||
return
|
||||
#if len(messageJson['object']['to'])!=1:
|
||||
# if debug:
|
||||
# print('DEBUG: "to" does not contain a single recipient')
|
||||
# print(str(messageJson['object']['to']))
|
||||
# if messageJson['object'].get('object'):
|
||||
# if not isinstance(messageJson['object']['object'], str):
|
||||
# messageJson['object']['to']=messageJson['object']['object']
|
||||
# else:
|
||||
# return
|
||||
# else:
|
||||
# return
|
||||
if debug:
|
||||
print('DEBUG: follow Accept received')
|
||||
thisActor=messageJson['object']['actor']
|
||||
|
|
|
@ -42,6 +42,7 @@ from posts import createUnlistedPost
|
|||
from posts import createFollowersOnlyPost
|
||||
from posts import createDirectMessagePost
|
||||
from posts import populateRepliesJson
|
||||
from posts import addToField
|
||||
from inbox import inboxPermittedMessage
|
||||
from inbox import inboxMessageHasParams
|
||||
from inbox import runInboxQueue
|
||||
|
@ -406,6 +407,11 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
if self.headers.get('Content-type'):
|
||||
headersDict['Content-type']=self.headers['Content-type']
|
||||
|
||||
# For follow activities add a 'to' field, which is a copy of the object field
|
||||
messageJson,toFieldExists=addToField('Follow',messageJson,self.server.debug)
|
||||
|
||||
pprint(messageJson)
|
||||
|
||||
# save the json for later queue processing
|
||||
queueFilename = \
|
||||
savePostToInboxQueue(self.server.baseDir,
|
||||
|
@ -2460,7 +2466,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
if self.server.debug:
|
||||
print(followerNickname+' stops following '+followingActor)
|
||||
followActor=self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+followerNickname
|
||||
followId=followActor+'#follows/'+followingNickname
|
||||
statusNumber,published = getStatusNumber()
|
||||
followId=followActor+'/statuses/'+str(statusNumber)
|
||||
unfollowJson = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': followId+'/undo',
|
||||
|
|
|
@ -492,7 +492,7 @@ def sendFollowRequest(session,baseDir: str, \
|
|||
|
||||
newFollowJson = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': followActor+'#follows/'+followNickname,
|
||||
'id': followActor+'/statuses/'+str(statusNumber),
|
||||
'type': 'Follow',
|
||||
'actor': followActor,
|
||||
'object': followedId
|
||||
|
@ -538,7 +538,7 @@ def sendFollowRequestViaServer(session,fromNickname: str,password: str,
|
|||
statusNumber,published = getStatusNumber()
|
||||
newFollowJson = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': followActor+'#follows/'+followNickname,
|
||||
'id': followActor+'/statuses/'+str(statusNumber),
|
||||
'type': 'Follow',
|
||||
'actor': followActor,
|
||||
'object': followedId
|
||||
|
@ -612,14 +612,15 @@ def sendUnfollowRequestViaServer(session,fromNickname: str,password: str,
|
|||
|
||||
followActor=httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname
|
||||
followedId=httpPrefix+'://'+followDomainFull+'/users/'+followNickname
|
||||
statusNumber,published = getStatusNumber()
|
||||
|
||||
unfollowJson = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': followActor+'#follows/'+followNickname+'/undo',
|
||||
'id': followActor+'/statuses/'+str(statusNumber)+'/undo',
|
||||
'type': 'Undo',
|
||||
'actor': followActor,
|
||||
'object': {
|
||||
'id': followActor+'#follows/'+followNickname,
|
||||
'id': followActor+'/statuses/'+str(statusNumber),
|
||||
'type': 'Follow',
|
||||
'actor': followActor,
|
||||
'object': followedId
|
||||
|
|
19
inbox.py
19
inbox.py
|
@ -166,7 +166,12 @@ def validPublishedDate(published) -> bool:
|
|||
return False
|
||||
return True
|
||||
|
||||
def savePostToInboxQueue(baseDir: str,httpPrefix: str,nickname: str, domain: str,postJsonObject: {},messageBytes: str,httpHeaders: {},postPath: str,debug: bool) -> str:
|
||||
def savePostToInboxQueue(baseDir: str,httpPrefix: str, \
|
||||
nickname: str, domain: str, \
|
||||
postJsonObject: {}, \
|
||||
messageBytes: str, \
|
||||
httpHeaders: {}, \
|
||||
postPath: str,debug: bool) -> str:
|
||||
"""Saves the give json to the inbox queue for the person
|
||||
keyId specifies the actor sending the post
|
||||
"""
|
||||
|
@ -184,6 +189,8 @@ def savePostToInboxQueue(baseDir: str,httpPrefix: str,nickname: str, domain: str
|
|||
postNickname=getNicknameFromActor(postJsonObject['actor'])
|
||||
postDomain,postPort=getDomainFromActor(postJsonObject['actor'])
|
||||
if isBlocked(baseDir,nickname,domain,postNickname,postDomain):
|
||||
if debug:
|
||||
print('DEBUG: post from '+postNickname+' blocked')
|
||||
return None
|
||||
if postPort:
|
||||
if postPort!=80 and postPort!=443:
|
||||
|
@ -195,6 +202,8 @@ def savePostToInboxQueue(baseDir: str,httpPrefix: str,nickname: str, domain: str
|
|||
if postJsonObject['object'].get('content'):
|
||||
if isinstance(postJsonObject['object']['content'], str):
|
||||
if isFiltered(baseDir,nickname,domain,postJsonObject['object']['content']):
|
||||
if debug:
|
||||
print('DEBUG: post was filtered out due to content')
|
||||
return None
|
||||
originalPostId=None
|
||||
if postJsonObject.get('id'):
|
||||
|
@ -222,6 +231,7 @@ def savePostToInboxQueue(baseDir: str,httpPrefix: str,nickname: str, domain: str
|
|||
destination=baseDir+'/accounts/'+handle+'/inbox/'+postId.replace('/','#')+'.json'
|
||||
if os.path.isfile(destination):
|
||||
if debug:
|
||||
print(destination)
|
||||
print('DEBUG: inbox item already exists')
|
||||
return None
|
||||
filename=inboxQueueDir+'/'+postId.replace('/','#')+'.json'
|
||||
|
@ -480,8 +490,6 @@ def receiveUndoFollow(session,baseDir: str,httpPrefix: str, \
|
|||
if debug:
|
||||
print('DEBUG: actors do not match')
|
||||
return False
|
||||
if not messageJson['object'].get('to'):
|
||||
messageJson['object']['to']=messageJson['object']['object']
|
||||
|
||||
nicknameFollower=getNicknameFromActor(messageJson['object']['actor'])
|
||||
domainFollower,portFollower=getDomainFromActor(messageJson['object']['actor'])
|
||||
|
@ -1342,7 +1350,7 @@ def runInboxQueue(projectVersion: str, \
|
|||
maxReplies,allowDeletion)
|
||||
else:
|
||||
if debug:
|
||||
print('DEBUG: object capabilities check failed')
|
||||
print('DEBUG: object capabilities check has failed')
|
||||
pprint(queueJson['post'])
|
||||
else:
|
||||
if not ocapAlways:
|
||||
|
@ -1358,6 +1366,9 @@ def runInboxQueue(projectVersion: str, \
|
|||
queueFilename,destination, \
|
||||
maxReplies,allowDeletion)
|
||||
if debug:
|
||||
pprint(queueJson['post'])
|
||||
print('No capability list within post')
|
||||
print('ocapAlways: '+str(ocapAlways))
|
||||
print('DEBUG: object capabilities check failed')
|
||||
|
||||
if debug:
|
||||
|
|
2
like.py
2
like.py
|
@ -104,7 +104,7 @@ def updateLikesCollection(postFilename: str,objectUrl: str, actor: str,debug: bo
|
|||
postJsonObject['object']['likes']=likesJson
|
||||
else:
|
||||
if postJsonObject['object']['likes'].get('items'):
|
||||
for likeItem in postJsonObject['likes']['items']:
|
||||
for likeItem in postJsonObject['object']['likes']['items']:
|
||||
if likeItem.get('actor'):
|
||||
if likeItem['actor']==actor:
|
||||
return
|
||||
|
|
55
posts.py
55
posts.py
|
@ -1245,6 +1245,46 @@ def sendSignedJson(postJsonObject: {},session,baseDir: str, \
|
|||
thr.start()
|
||||
return 0
|
||||
|
||||
def addToField(activityType: str,postJsonObject: {},debug: bool) -> ({},bool):
|
||||
"""The Follow activity doesn't have a 'to' field and so one
|
||||
needs to be added so that activity distribution happens in a consistent way
|
||||
Returns true if a 'to' field exists or was added
|
||||
"""
|
||||
if postJsonObject.get('to'):
|
||||
return postJsonObject,True
|
||||
|
||||
if debug:
|
||||
pprint(postJsonObject)
|
||||
print('DEBUG: no "to" field when sending to named addresses 2')
|
||||
|
||||
isSameType=False
|
||||
toFieldAdded=False
|
||||
if postJsonObject.get('object'):
|
||||
if isinstance(postJsonObject['object'], str):
|
||||
if postJsonObject.get('type'):
|
||||
if postJsonObject['type']==activityType:
|
||||
isSameType=True
|
||||
if debug:
|
||||
print('DEBUG: "to" field assigned to Follow')
|
||||
postJsonObject['to']=[postJsonObject['object']]
|
||||
toFieldAdded=True
|
||||
elif isinstance(postJsonObject['object'], dict):
|
||||
if postJsonObject['object'].get('type'):
|
||||
if postJsonObject['object']['type']==activityType:
|
||||
isSameType=True
|
||||
if isinstance(postJsonObject['object']['object'], str):
|
||||
if debug:
|
||||
print('DEBUG: "to" field assigned to Follow')
|
||||
postJsonObject['object']['to']=[postJsonObject['object']['object']]
|
||||
postJsonObject['to']=[postJsonObject['object']['object']]
|
||||
toFieldAdded=True
|
||||
|
||||
if not isSameType:
|
||||
return postJsonObject,True
|
||||
if toFieldAdded:
|
||||
return postJsonObject,True
|
||||
return postJsonObject,False
|
||||
|
||||
def sendToNamedAddresses(session,baseDir: str, \
|
||||
nickname: str, domain: str, port: int, \
|
||||
httpPrefix: str,federationList: [], \
|
||||
|
@ -1260,17 +1300,30 @@ def sendToNamedAddresses(session,baseDir: str, \
|
|||
if not postJsonObject.get('object'):
|
||||
return
|
||||
if isinstance(postJsonObject['object'], dict):
|
||||
if not postJsonObject['object'].get('to'):
|
||||
if debug:
|
||||
pprint(postJsonObject)
|
||||
print('DEBUG: no "to" field when sending to named addresses')
|
||||
if postJsonObject['object'].get('type'):
|
||||
if postJsonObject['object']['type']=='Follow':
|
||||
if isinstance(postJsonObject['object']['object'], str):
|
||||
if debug:
|
||||
print('DEBUG: "to" field assigned to Follow')
|
||||
postJsonObject['object']['to']=[postJsonObject['object']['object']]
|
||||
if not postJsonObject['object'].get('to'):
|
||||
return
|
||||
recipientsObject=postJsonObject['object']
|
||||
else:
|
||||
if not postJsonObject.get('to'):
|
||||
postJsonObject,fieldAdded=addToField('Follow',postJsonObject,debug)
|
||||
if not fieldAdded:
|
||||
return
|
||||
recipientsObject=postJsonObject
|
||||
|
||||
recipients=[]
|
||||
recipientType=['to','cc']
|
||||
for rType in recipientType:
|
||||
if not recipientsObject.get(rType):
|
||||
continue
|
||||
for address in recipientsObject[rType]:
|
||||
if address.endswith('#Public'):
|
||||
continue
|
||||
|
|
176
tests.py
176
tests.py
|
@ -484,7 +484,7 @@ def testPostMessageBetweenServers():
|
|||
shutil.rmtree(aliceDir)
|
||||
shutil.rmtree(bobDir)
|
||||
|
||||
def testFollowBetweenServers():
|
||||
def testFollowBetweenServersOld():
|
||||
print('Testing sending a follow request from one server to another')
|
||||
|
||||
global testServerAliceRunning
|
||||
|
@ -768,6 +768,180 @@ def testFollowBetweenServers():
|
|||
os.chdir(baseDir)
|
||||
shutil.rmtree(baseDir+'/.tests')
|
||||
|
||||
def testFollowBetweenServers():
|
||||
print('Testing sending a follow request from one server to another')
|
||||
|
||||
global testServerAliceRunning
|
||||
global testServerBobRunning
|
||||
global testServerEveRunning
|
||||
testServerAliceRunning = False
|
||||
testServerBobRunning = False
|
||||
testServerEveRunning = False
|
||||
|
||||
httpPrefix='http'
|
||||
useTor=False
|
||||
federationList=[]
|
||||
|
||||
baseDir=os.getcwd()
|
||||
if os.path.isdir(baseDir+'/.tests'):
|
||||
shutil.rmtree(baseDir+'/.tests')
|
||||
os.mkdir(baseDir+'/.tests')
|
||||
|
||||
ocapAlways=False
|
||||
|
||||
# create the servers
|
||||
aliceDir=baseDir+'/.tests/alice'
|
||||
aliceDomain='127.0.0.42'
|
||||
alicePort=61935
|
||||
thrAlice = \
|
||||
threadWithTrace(target=createServerAlice, \
|
||||
args=(aliceDir,aliceDomain,alicePort, \
|
||||
federationList,False,False, \
|
||||
ocapAlways),daemon=True)
|
||||
|
||||
bobDir=baseDir+'/.tests/bob'
|
||||
bobDomain='127.0.0.64'
|
||||
bobPort=61936
|
||||
thrBob = \
|
||||
threadWithTrace(target=createServerBob, \
|
||||
args=(bobDir,bobDomain,bobPort, \
|
||||
federationList,False,False, \
|
||||
ocapAlways),daemon=True)
|
||||
|
||||
eveDir=baseDir+'/.tests/eve'
|
||||
eveDomain='127.0.0.55'
|
||||
evePort=61937
|
||||
thrEve = \
|
||||
threadWithTrace(target=createServerEve, \
|
||||
args=(eveDir,eveDomain,evePort, \
|
||||
federationList,False,False, \
|
||||
False),daemon=True)
|
||||
|
||||
thrAlice.start()
|
||||
thrBob.start()
|
||||
thrEve.start()
|
||||
assert thrAlice.isAlive()==True
|
||||
assert thrBob.isAlive()==True
|
||||
assert thrEve.isAlive()==True
|
||||
|
||||
# wait for all servers to be running
|
||||
ctr=0
|
||||
while not (testServerAliceRunning and testServerBobRunning and testServerEveRunning):
|
||||
time.sleep(1)
|
||||
ctr+=1
|
||||
if ctr>60:
|
||||
break
|
||||
print('Alice online: '+str(testServerAliceRunning))
|
||||
print('Bob online: '+str(testServerBobRunning))
|
||||
print('Eve online: '+str(testServerEveRunning))
|
||||
assert ctr<=60
|
||||
time.sleep(1)
|
||||
|
||||
# In the beginning all was calm and there were no follows
|
||||
|
||||
print('*********************************************************')
|
||||
print('Alice sends a follow request to Bob')
|
||||
print('Both are strictly enforcing object capabilities')
|
||||
os.chdir(aliceDir)
|
||||
sessionAlice = createSession(aliceDomain,alicePort,useTor)
|
||||
inReplyTo=None
|
||||
inReplyToAtomUri=None
|
||||
subject=None
|
||||
aliceSendThreads = []
|
||||
alicePostLog = []
|
||||
followersOnly=False
|
||||
saveToFile=True
|
||||
clientToServer=False
|
||||
ccUrl=None
|
||||
alicePersonCache={}
|
||||
aliceCachedWebfingers={}
|
||||
aliceSendThreads=[]
|
||||
alicePostLog=[]
|
||||
sendResult = \
|
||||
sendFollowRequest(sessionAlice,aliceDir, \
|
||||
'alice',aliceDomain,alicePort,httpPrefix, \
|
||||
'bob',bobDomain,bobPort,httpPrefix, \
|
||||
clientToServer,federationList, \
|
||||
aliceSendThreads,alicePostLog, \
|
||||
aliceCachedWebfingers,alicePersonCache, \
|
||||
True,__version__)
|
||||
print('sendResult: '+str(sendResult))
|
||||
|
||||
bobCapsFilename=bobDir+'/accounts/bob@'+bobDomain+'/ocap/accept/'+httpPrefix+':##'+aliceDomain+':'+str(alicePort)+'#users#alice.json'
|
||||
aliceCapsFilename=aliceDir+'/accounts/alice@'+aliceDomain+'/ocap/granted/'+httpPrefix+':##'+bobDomain+':'+str(bobPort)+'#users#bob.json'
|
||||
|
||||
for t in range(10):
|
||||
if os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt'):
|
||||
if os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt'):
|
||||
if os.path.isfile(bobCapsFilename):
|
||||
if os.path.isfile(aliceCapsFilename):
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
with open(bobCapsFilename, 'r') as fp:
|
||||
bobCapsJson=commentjson.load(fp)
|
||||
if not bobCapsJson.get('capability'):
|
||||
print("Unexpected format for Bob's capabilities")
|
||||
pprint(bobCapsJson)
|
||||
assert False
|
||||
assert validInbox(bobDir,'bob',bobDomain)
|
||||
assert validInboxFilenames(bobDir,'bob',bobDomain,aliceDomain,alicePort)
|
||||
|
||||
print('\n\n*********************************************************')
|
||||
print('Alice sends a message to Bob')
|
||||
aliceSendThreads = []
|
||||
alicePostLog = []
|
||||
alicePersonCache={}
|
||||
aliceCachedWebfingers={}
|
||||
aliceSendThreads=[]
|
||||
alicePostLog=[]
|
||||
useBlurhash=False
|
||||
sendResult = \
|
||||
sendPost(__version__, \
|
||||
sessionAlice,aliceDir,'alice', aliceDomain, alicePort, \
|
||||
'bob', bobDomain, bobPort, ccUrl, \
|
||||
httpPrefix, 'Alice message', followersOnly, saveToFile, \
|
||||
clientToServer,None,None,useBlurhash, federationList, \
|
||||
aliceSendThreads, alicePostLog, aliceCachedWebfingers, \
|
||||
alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
||||
print('sendResult: '+str(sendResult))
|
||||
|
||||
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
|
||||
inboxPath=bobDir+'/accounts/bob@'+bobDomain+'/inbox'
|
||||
aliceMessageArrived=False
|
||||
for i in range(20):
|
||||
time.sleep(1)
|
||||
if os.path.isdir(inboxPath):
|
||||
if len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])>0:
|
||||
aliceMessageArrived=True
|
||||
print('Alice message sent to Bob!')
|
||||
break
|
||||
|
||||
assert aliceMessageArrived==True
|
||||
print('Message from Alice to Bob succeeded')
|
||||
|
||||
# stop the servers
|
||||
thrAlice.kill()
|
||||
thrAlice.join()
|
||||
assert thrAlice.isAlive()==False
|
||||
|
||||
thrBob.kill()
|
||||
thrBob.join()
|
||||
assert thrBob.isAlive()==False
|
||||
|
||||
thrEve.kill()
|
||||
thrEve.join()
|
||||
assert thrEve.isAlive()==False
|
||||
|
||||
assert 'alice@'+aliceDomain in open(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt').read()
|
||||
assert 'bob@'+bobDomain in open(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt').read()
|
||||
|
||||
# queue item removed
|
||||
assert len([name for name in os.listdir(queuePath) if os.path.isfile(os.path.join(queuePath, name))])==0
|
||||
|
||||
os.chdir(baseDir)
|
||||
shutil.rmtree(baseDir+'/.tests')
|
||||
|
||||
def testFollowersOfPerson():
|
||||
print('testFollowersOfPerson')
|
||||
currDir=os.getcwd()
|
||||
|
|
Loading…
Reference in New Issue