epicyon/tests.py

1385 lines
55 KiB
Python
Raw Normal View History

2019-06-30 20:14:03 +00:00
__filename__ = "tests.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
2019-08-29 13:35:29 +00:00
__version__ = "1.0.0"
2019-06-30 20:14:03 +00:00
__maintainer__ = "Bob Mottram"
__email__ = "bob@freedombone.net"
__status__ = "Production"
import base64
import time
2019-07-04 20:36:12 +00:00
import os, os.path
2019-06-30 21:20:02 +00:00
import shutil
2019-07-09 14:20:23 +00:00
import commentjson
2019-08-16 10:36:41 +00:00
import json
2019-08-15 18:21:43 +00:00
from time import gmtime, strftime
2019-07-09 14:20:23 +00:00
from pprint import pprint
2019-06-30 20:14:03 +00:00
from person import createPerson
from Crypto.Hash import SHA256
from httpsig import signPostHeaders
from httpsig import verifyPostHeaders
from httpsig import messageContentDigest
2019-06-30 20:14:03 +00:00
from cache import storePersonInCache
from cache import getPersonFromCache
from threads import threadWithTrace
2019-06-30 21:20:02 +00:00
from daemon import runDaemon
from session import createSession
from posts import deleteAllPosts
from posts import createPublicPost
2019-06-30 22:56:37 +00:00
from posts import sendPost
2019-07-03 10:09:24 +00:00
from posts import archivePosts
2019-07-05 14:39:24 +00:00
from posts import noOfFollowersOnDomain
from posts import groupFollowersByDomain
2019-07-09 14:20:23 +00:00
from posts import sendCapabilitiesUpdate
2019-07-12 22:29:10 +00:00
from posts import archivePostsForPerson
2019-07-16 10:19:04 +00:00
from posts import sendPostViaServer
2019-07-01 11:09:09 +00:00
from follow import clearFollows
from follow import clearFollowers
2019-07-16 21:38:06 +00:00
from follow import sendFollowRequestViaServer
2019-07-17 11:54:13 +00:00
from follow import sendUnfollowRequestViaServer
2019-07-06 19:24:52 +00:00
from utils import followPerson
2019-08-21 16:35:46 +00:00
from utils import getNicknameFromActor
from utils import getDomainFromActor
2019-06-30 21:20:02 +00:00
from follow import followerOfPerson
2019-07-01 11:09:09 +00:00
from follow import unfollowPerson
from follow import unfollowerOfPerson
from follow import getFollowersOfPerson
2019-07-06 13:49:25 +00:00
from follow import sendFollowRequest
2019-07-03 10:04:23 +00:00
from person import createPerson
from person import setDisplayNickname
2019-07-03 10:04:23 +00:00
from person import setBio
2019-07-19 10:01:24 +00:00
from skills import setSkillLevel
2019-07-18 15:09:23 +00:00
from roles import setRole
2019-07-18 16:21:26 +00:00
from roles import getRoles
from roles import outboxDelegate
2019-07-03 18:24:44 +00:00
from auth import createBasicAuthHeader
from auth import authorizeBasic
from auth import storeBasicCredentials
2019-07-11 12:29:31 +00:00
from like import likePost
from like import sendLikeViaServer
2019-07-11 17:55:10 +00:00
from announce import announcePublic
2019-07-16 19:07:45 +00:00
from announce import sendAnnounceViaServer
2019-07-12 19:26:54 +00:00
from media import getMediaPath
2019-08-30 15:50:20 +00:00
from media import getAttachmentMediaType
2019-07-17 17:16:48 +00:00
from delete import sendDeleteViaServer
from inbox import validInbox
2019-07-18 11:35:48 +00:00
from inbox import validInboxFilenames
2019-06-30 20:14:03 +00:00
2019-06-30 21:27:25 +00:00
testServerAliceRunning = False
testServerBobRunning = False
testServerEveRunning = False
2019-06-30 21:27:25 +00:00
2019-06-30 20:14:03 +00:00
def testHttpsigBase(withDigest):
print('testHttpsig(' + str(withDigest) + ')')
2019-08-09 09:46:33 +00:00
baseDir=os.getcwd()
path=baseDir+'/.testHttpsigBase'
if os.path.isdir(path):
shutil.rmtree(path)
os.mkdir(path)
os.chdir(path)
2019-08-16 10:36:41 +00:00
contentType='application/activity+json'
2019-07-03 09:40:27 +00:00
nickname='socrates'
2019-06-30 20:14:03 +00:00
domain='argumentative.social'
2019-07-03 19:00:03 +00:00
httpPrefix='https'
2019-07-01 09:31:02 +00:00
port=5576
2019-07-04 19:09:48 +00:00
password='SuperSecretPassword'
2019-07-13 09:37:17 +00:00
privateKeyPem,publicKeyPem,person,wfEndpoint= \
2019-08-09 09:46:33 +00:00
createPerson(path,nickname,domain,port,httpPrefix,False,password)
assert privateKeyPem
2019-08-16 10:36:41 +00:00
messageBodyJson = {"a key": "a value", "another key": "A string","yet another key": "Another string"}
messageBodyJsonStr=json.dumps(messageBodyJson)
2019-07-01 09:31:02 +00:00
headersDomain=domain
if port:
if port!=80 and port !=443:
if ':' not in domain:
headersDomain=domain+':'+str(port)
2019-07-01 09:31:02 +00:00
2019-08-15 18:21:43 +00:00
dateStr=strftime("%a, %d %b %Y %H:%M:%S %Z", gmtime())
2019-08-16 10:36:41 +00:00
boxpath='/inbox'
2019-06-30 20:14:03 +00:00
if not withDigest:
2019-08-15 21:34:25 +00:00
headers = {'host': headersDomain,'date': dateStr,'content-type': 'application/json'}
2019-08-16 10:36:41 +00:00
signatureHeader = \
2019-08-16 13:47:01 +00:00
signPostHeaders(dateStr,privateKeyPem, nickname, \
domain, port, \
domain, port, \
boxpath, httpPrefix, None)
2019-06-30 20:14:03 +00:00
else:
bodyDigest = messageContentDigest(messageBodyJsonStr)
2019-08-16 10:36:41 +00:00
headers = {'host': headersDomain,'date': dateStr,'digest': f'SHA-256={bodyDigest}','content-type': contentType}
signatureHeader = \
2019-08-16 13:47:01 +00:00
signPostHeaders(dateStr,privateKeyPem, nickname, \
domain, port, \
domain, port, \
boxpath, httpPrefix, messageBodyJsonStr)
2019-07-01 09:31:02 +00:00
2019-06-30 20:14:03 +00:00
headers['signature'] = signatureHeader
assert verifyPostHeaders(httpPrefix,publicKeyPem,headers, \
boxpath,False,None, \
2019-08-15 21:34:25 +00:00
messageBodyJsonStr)
assert verifyPostHeaders(httpPrefix,publicKeyPem,headers, \
'/parambulator'+boxpath,False,None, \
2019-08-15 21:34:25 +00:00
messageBodyJsonStr) == False
assert verifyPostHeaders(httpPrefix,publicKeyPem,headers, \
boxpath,True,None, \
2019-08-15 21:34:25 +00:00
messageBodyJsonStr) == False
2019-06-30 20:14:03 +00:00
if not withDigest:
# fake domain
2019-08-15 21:34:25 +00:00
headers = {'host': 'bogon.domain','date': dateStr,'content-type': 'application/json'}
2019-06-30 20:14:03 +00:00
else:
# correct domain but fake message
2019-08-15 21:34:25 +00:00
messageBodyJsonStr = '{"a key": "a value", "another key": "Fake GNUs", "yet another key": "More Fake GNUs"}'
bodyDigest = messageContentDigest(messageBodyJsonStr)
2019-08-16 10:36:41 +00:00
headers = {'host': domain,'date': dateStr,'digest': f'SHA-256={bodyDigest}','content-type': contentType}
2019-06-30 20:14:03 +00:00
headers['signature'] = signatureHeader
2019-08-15 21:34:25 +00:00
assert verifyPostHeaders(httpPrefix,publicKeyPem,headers, \
boxpath,True,None, \
2019-08-15 21:34:25 +00:00
messageBodyJsonStr) == False
2019-08-09 09:46:33 +00:00
os.chdir(baseDir)
shutil.rmtree(path)
2019-06-30 20:14:03 +00:00
def testHttpsig():
testHttpsigBase(True)
2019-08-15 21:34:25 +00:00
testHttpsigBase(False)
2019-06-30 20:14:03 +00:00
def testCache():
print('testCache')
personUrl="cat@cardboard.box"
personJson={ "id": 123456, "test": "This is a test" }
2019-07-01 14:30:48 +00:00
personCache={}
2019-08-20 09:16:03 +00:00
storePersonInCache(None,personUrl,personJson,personCache)
2019-08-20 09:37:09 +00:00
result=getPersonFromCache(None,personUrl,personCache)
2019-06-30 20:14:03 +00:00
assert result['id']==123456
assert result['test']=='This is a test'
def testThreadsFunction(param: str):
for i in range(10000):
time.sleep(2)
def testThreads():
print('testThreads')
thr = threadWithTrace(target=testThreadsFunction,args=('test',),daemon=True)
thr.start()
assert thr.isAlive()==True
time.sleep(1)
thr.kill()
thr.join()
assert thr.isAlive()==False
2019-06-30 21:20:02 +00:00
2019-07-13 09:37:17 +00:00
def createServerAlice(path: str,domain: str,port: int,federationList: [], \
hasFollows: bool,hasPosts :bool,ocapAlways: bool):
2019-06-30 21:20:02 +00:00
print('Creating test server: Alice on port '+str(port))
if os.path.isdir(path):
shutil.rmtree(path)
os.mkdir(path)
os.chdir(path)
2019-07-03 09:40:27 +00:00
nickname='alice'
2019-07-04 14:36:29 +00:00
httpPrefix='http'
2019-06-30 21:20:02 +00:00
useTor=False
2019-07-04 19:09:48 +00:00
password='alicepass'
2019-07-09 17:54:08 +00:00
noreply=False
nolike=False
2019-07-09 18:11:23 +00:00
nopics=False
noannounce=False
cw=False
2019-07-12 19:08:46 +00:00
useBlurhash=True
2019-07-13 21:00:12 +00:00
maxReplies=64
2019-07-15 10:22:19 +00:00
domainMaxPostsPerDay=1000
accountMaxPostsPerDay=1000
allowDeletion=True
2019-07-13 09:37:17 +00:00
privateKeyPem,publicKeyPem,person,wfEndpoint= \
createPerson(path,nickname,domain,port,httpPrefix,True,password)
2019-07-04 16:24:23 +00:00
deleteAllPosts(path,nickname,domain,'inbox')
deleteAllPosts(path,nickname,domain,'outbox')
2019-07-14 12:08:18 +00:00
assert setSkillLevel(path,nickname,domain,'hacking',90)
2019-07-14 12:25:16 +00:00
assert setRole(path,nickname,domain,'someproject','guru')
2019-07-06 13:49:25 +00:00
if hasFollows:
2019-07-13 09:37:17 +00:00
followPerson(path,nickname,domain,'bob','127.0.0.100:61936', \
2019-07-14 17:19:00 +00:00
federationList,False)
2019-07-13 09:37:17 +00:00
followerOfPerson(path,nickname,domain,'bob','127.0.0.100:61936', \
2019-07-14 17:19:00 +00:00
federationList,False)
2019-07-06 13:49:25 +00:00
if hasPosts:
2019-07-13 09:37:17 +00:00
createPublicPost(path,nickname, domain, port,httpPrefix, \
"No wise fish would go anywhere without a porpoise", \
False, True, clientToServer,None,None,useBlurhash)
createPublicPost(path,nickname, domain, port,httpPrefix, \
"Curiouser and curiouser!", False, True, \
clientToServer,None,None,useBlurhash)
createPublicPost(path,nickname, domain, port,httpPrefix, \
"In the gardens of memory, in the palace of dreams, that is where you and I shall meet", \
False, True, clientToServer,None,None,useBlurhash)
2019-06-30 21:27:25 +00:00
global testServerAliceRunning
testServerAliceRunning = True
2019-06-30 21:20:02 +00:00
print('Server running: Alice')
2019-08-14 20:12:27 +00:00
runDaemon(__version__,"instanceId",False,path,domain,port,port, \
2019-08-14 13:52:19 +00:00
httpPrefix,federationList, \
2019-07-13 21:00:12 +00:00
noreply,nolike,nopics,noannounce,cw,ocapAlways, \
2019-07-15 10:22:19 +00:00
useTor,maxReplies, \
domainMaxPostsPerDay,accountMaxPostsPerDay, \
allowDeletion,True,True,False)
2019-06-30 21:20:02 +00:00
2019-07-13 09:37:17 +00:00
def createServerBob(path: str,domain: str,port: int,federationList: [], \
hasFollows: bool,hasPosts :bool,ocapAlways :bool):
2019-06-30 21:20:02 +00:00
print('Creating test server: Bob on port '+str(port))
if os.path.isdir(path):
shutil.rmtree(path)
os.mkdir(path)
os.chdir(path)
2019-07-03 09:40:27 +00:00
nickname='bob'
2019-07-03 19:00:03 +00:00
httpPrefix='http'
2019-06-30 21:20:02 +00:00
useTor=False
2019-07-03 15:10:18 +00:00
clientToServer=False
2019-07-04 19:09:48 +00:00
password='bobpass'
2019-07-09 17:54:08 +00:00
noreply=False
nolike=False
2019-07-09 18:11:23 +00:00
nopics=False
noannounce=False
cw=False
2019-07-12 19:08:46 +00:00
useBlurhash=False
2019-07-13 21:00:12 +00:00
maxReplies=64
2019-07-15 10:22:19 +00:00
domainMaxPostsPerDay=1000
accountMaxPostsPerDay=1000
2019-07-17 19:31:52 +00:00
allowDeletion=True
2019-07-13 09:37:17 +00:00
privateKeyPem,publicKeyPem,person,wfEndpoint= \
createPerson(path,nickname,domain,port,httpPrefix,True,password)
2019-07-04 16:24:23 +00:00
deleteAllPosts(path,nickname,domain,'inbox')
deleteAllPosts(path,nickname,domain,'outbox')
2019-07-14 12:25:16 +00:00
assert setRole(path,nickname,domain,'bandname','bass player')
assert setRole(path,nickname,domain,'bandname','publicist')
2019-07-06 13:49:25 +00:00
if hasFollows:
2019-07-13 09:37:17 +00:00
followPerson(path,nickname,domain, \
2019-07-14 17:19:00 +00:00
'alice','127.0.0.50:61935',federationList,False)
2019-07-13 09:37:17 +00:00
followerOfPerson(path,nickname,domain, \
2019-07-14 17:19:00 +00:00
'alice','127.0.0.50:61935',federationList,False)
2019-07-06 13:49:25 +00:00
if hasPosts:
2019-07-13 09:37:17 +00:00
createPublicPost(path,nickname, domain, port,httpPrefix, \
"It's your life, live it your way.", \
False, True, clientToServer,None,None,useBlurhash)
createPublicPost(path,nickname, domain, port,httpPrefix, \
"One of the things I've realised is that I am very simple", \
False, True, clientToServer,None,None,useBlurhash)
createPublicPost(path,nickname, domain, port,httpPrefix, \
"Quantum physics is a bit of a passion of mine", \
False, True, clientToServer,None,None,useBlurhash)
2019-06-30 21:27:25 +00:00
global testServerBobRunning
testServerBobRunning = True
2019-06-30 21:20:02 +00:00
print('Server running: Bob')
2019-08-14 20:12:27 +00:00
runDaemon(__version__,"instanceId",False,path,domain,port,port, \
2019-08-14 13:52:19 +00:00
httpPrefix,federationList, \
2019-07-13 21:00:12 +00:00
noreply,nolike,nopics,noannounce,cw,ocapAlways, \
2019-07-15 10:22:19 +00:00
useTor,maxReplies, \
domainMaxPostsPerDay,accountMaxPostsPerDay, \
allowDeletion,True,True,False)
2019-06-30 21:20:02 +00:00
2019-07-13 09:37:17 +00:00
def createServerEve(path: str,domain: str,port: int,federationList: [], \
hasFollows: bool,hasPosts :bool,ocapAlways :bool):
print('Creating test server: Eve on port '+str(port))
if os.path.isdir(path):
shutil.rmtree(path)
os.mkdir(path)
os.chdir(path)
nickname='eve'
httpPrefix='http'
useTor=False
clientToServer=False
password='evepass'
2019-07-09 17:54:08 +00:00
noreply=False
nolike=False
2019-07-09 18:11:23 +00:00
nopics=False
noannounce=False
cw=False
2019-07-13 21:00:12 +00:00
maxReplies=64
allowDeletion=True
2019-07-13 09:37:17 +00:00
privateKeyPem,publicKeyPem,person,wfEndpoint= \
createPerson(path,nickname,domain,port,httpPrefix,True,password)
deleteAllPosts(path,nickname,domain,'inbox')
deleteAllPosts(path,nickname,domain,'outbox')
global testServerEveRunning
testServerEveRunning = True
print('Server running: Eve')
2019-08-14 20:12:27 +00:00
runDaemon(__version__,"instanceId",False,path,domain,port,port, \
2019-08-14 13:52:19 +00:00
httpPrefix,federationList, \
2019-07-13 21:00:12 +00:00
noreply,nolike,nopics,noannounce,cw,ocapAlways, \
useTor,maxReplies,allowDeletion,True,True,False)
2019-06-30 21:20:02 +00:00
def testPostMessageBetweenServers():
print('Testing sending message from one server to the inbox of another')
2019-06-30 21:27:25 +00:00
global testServerAliceRunning
global testServerBobRunning
testServerAliceRunning = False
testServerBobRunning = False
2019-07-03 19:00:03 +00:00
httpPrefix='http'
2019-06-30 22:56:37 +00:00
useTor=False
2019-06-30 21:20:02 +00:00
baseDir=os.getcwd()
2019-07-06 13:49:25 +00:00
if os.path.isdir(baseDir+'/.tests'):
shutil.rmtree(baseDir+'/.tests')
os.mkdir(baseDir+'/.tests')
2019-06-30 21:20:02 +00:00
ocapAlways=False
2019-06-30 21:20:02 +00:00
# create the servers
2019-06-30 22:56:37 +00:00
aliceDir=baseDir+'/.tests/alice'
2019-07-02 09:25:29 +00:00
aliceDomain='127.0.0.50'
2019-06-30 22:56:37 +00:00
alicePort=61935
bobDir=baseDir+'/.tests/bob'
2019-07-02 09:25:29 +00:00
bobDomain='127.0.0.100'
2019-06-30 22:56:37 +00:00
bobPort=61936
2019-07-11 12:29:31 +00:00
federationList=[bobDomain,aliceDomain]
2019-07-13 09:37:17 +00:00
thrAlice = \
threadWithTrace(target=createServerAlice, \
args=(aliceDir,aliceDomain,alicePort, \
federationList,False,False, \
ocapAlways),daemon=True)
thrBob = \
threadWithTrace(target=createServerBob, \
args=(bobDir,bobDomain,bobPort, \
federationList,False,False, \
ocapAlways),daemon=True)
2019-07-01 21:01:43 +00:00
thrAlice.start()
2019-06-30 21:20:02 +00:00
thrBob.start()
2019-07-01 21:01:43 +00:00
assert thrAlice.isAlive()==True
2019-06-30 21:20:02 +00:00
assert thrBob.isAlive()==True
2019-06-30 21:27:25 +00:00
# wait for both servers to be running
while not (testServerAliceRunning and testServerBobRunning):
time.sleep(1)
2019-07-04 20:25:19 +00:00
time.sleep(1)
2019-06-30 21:20:02 +00:00
2019-07-11 12:29:31 +00:00
print('\n\n*******************************************************')
2019-06-30 22:56:37 +00:00
print('Alice sends to Bob')
os.chdir(aliceDir)
2019-07-02 09:25:29 +00:00
sessionAlice = createSession(aliceDomain,alicePort,useTor)
2019-06-30 22:56:37 +00:00
inReplyTo=None
inReplyToAtomUri=None
subject=None
aliceSendThreads = []
alicePostLog = []
2019-07-01 12:51:55 +00:00
followersOnly=False
saveToFile=True
2019-07-03 15:10:18 +00:00
clientToServer=False
2019-07-01 12:51:55 +00:00
ccUrl=None
2019-07-01 14:30:48 +00:00
alicePersonCache={}
aliceCachedWebfingers={}
2019-07-12 19:26:54 +00:00
attachedImageFilename=baseDir+'/img/logo.png'
2019-08-30 15:50:20 +00:00
mediaType=getAttachmentMediaType(attachedImageFilename)
2019-07-12 19:26:54 +00:00
attachedImageDescription='Logo'
useBlurhash=True
2019-07-11 12:29:31 +00:00
# nothing in Alice's outbox
outboxPath=aliceDir+'/accounts/alice@'+aliceDomain+'/outbox'
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==0
2019-07-13 09:37:17 +00:00
sendResult = \
2019-08-14 20:12:27 +00:00
sendPost(__version__, \
sessionAlice,aliceDir,'alice', aliceDomain, alicePort, \
2019-07-13 09:37:17 +00:00
'bob', bobDomain, bobPort, ccUrl, httpPrefix, \
2019-08-09 11:12:08 +00:00
'Why is a mouse when it spins? #sillyquestion', followersOnly, \
2019-08-30 15:50:20 +00:00
saveToFile, clientToServer,attachedImageFilename,mediaType, \
2019-07-13 09:37:17 +00:00
attachedImageDescription,useBlurhash, federationList, \
aliceSendThreads, alicePostLog, aliceCachedWebfingers, \
alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
2019-06-30 22:56:37 +00:00
print('sendResult: '+str(sendResult))
2019-07-04 20:36:12 +00:00
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
inboxPath=bobDir+'/accounts/bob@'+bobDomain+'/inbox'
2019-07-12 19:26:54 +00:00
mPath=getMediaPath()
mediaPath=aliceDir+'/'+mPath
2019-07-07 22:25:22 +00:00
for i in range(30):
2019-07-04 20:36:12 +00:00
if os.path.isdir(inboxPath):
if len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])>0:
2019-07-11 12:29:31 +00:00
if len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==1:
2019-07-12 19:26:54 +00:00
if len([name for name in os.listdir(mediaPath) if os.path.isfile(os.path.join(mediaPath, name))])>0:
break
2019-07-01 21:01:43 +00:00
time.sleep(1)
2019-07-09 08:52:53 +00:00
2019-07-12 19:26:54 +00:00
# Image attachment created
assert len([name for name in os.listdir(mediaPath) if os.path.isfile(os.path.join(mediaPath, name))])>0
2019-07-11 12:29:31 +00:00
# inbox item created
assert len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==1
# queue item removed
assert len([name for name in os.listdir(queuePath) if os.path.isfile(os.path.join(queuePath, name))])==0
2019-07-18 09:31:29 +00:00
assert validInbox(bobDir,'bob',bobDomain)
2019-07-18 11:35:48 +00:00
assert validInboxFilenames(bobDir,'bob',bobDomain,aliceDomain,alicePort)
2019-07-11 12:29:31 +00:00
2019-07-11 12:59:00 +00:00
print('\n\n*******************************************************')
print("Bob likes Alice's post")
2019-07-13 09:37:17 +00:00
followerOfPerson(bobDir,'bob',bobDomain,'alice', \
2019-07-14 17:19:00 +00:00
aliceDomain+':'+str(alicePort),federationList,False)
2019-07-13 09:37:17 +00:00
followPerson(aliceDir,'alice',aliceDomain,'bob', \
2019-07-14 17:19:00 +00:00
bobDomain+':'+str(bobPort),federationList,False)
2019-07-11 12:59:00 +00:00
sessionBob = createSession(bobDomain,bobPort,useTor)
bobSendThreads = []
bobPostLog = []
bobPersonCache={}
bobCachedWebfingers={}
statusNumber=None
outboxPostFilename=None
outboxPath=aliceDir+'/accounts/alice@'+aliceDomain+'/outbox'
for name in os.listdir(outboxPath):
if '#statuses#' in name:
statusNumber=int(name.split('#statuses#')[1].replace('.json',''))
outboxPostFilename=outboxPath+'/'+name
2019-07-11 17:55:10 +00:00
assert statusNumber>0
2019-07-11 12:59:00 +00:00
assert outboxPostFilename
assert likePost(sessionBob,bobDir,federationList, \
'bob',bobDomain,bobPort,httpPrefix, \
'alice',aliceDomain,alicePort,[], \
statusNumber,False,bobSendThreads,bobPostLog, \
2019-08-14 20:12:27 +00:00
bobPersonCache,bobCachedWebfingers, \
True,__version__)
2019-07-11 12:59:00 +00:00
for i in range(20):
if 'likes' in open(outboxPostFilename).read():
break
time.sleep(1)
with open(outboxPostFilename, 'r') as fp:
alicePostJson=commentjson.load(fp)
pprint(alicePostJson)
assert 'likes' in open(outboxPostFilename).read()
2019-07-11 17:55:10 +00:00
print('\n\n*******************************************************')
print("Bob repeats Alice's post")
objectUrl=httpPrefix+'://'+aliceDomain+':'+str(alicePort)+'/users/alice/statuses/'+str(statusNumber)
2019-07-11 19:31:02 +00:00
inboxPath=aliceDir+'/accounts/alice@'+aliceDomain+'/inbox'
2019-07-11 19:34:00 +00:00
outboxPath=bobDir+'/accounts/bob@'+bobDomain+'/outbox'
outboxBeforeAnnounceCount=len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])
2019-07-11 19:31:02 +00:00
beforeAnnounceCount=len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])
assert beforeAnnounceCount==0
print('inbox items before announce: '+str(beforeAnnounceCount))
2019-07-11 17:55:10 +00:00
announcePublic(sessionBob,bobDir,federationList, \
'bob',bobDomain,bobPort,httpPrefix, \
objectUrl, \
False,bobSendThreads,bobPostLog, \
bobPersonCache,bobCachedWebfingers, \
2019-08-14 20:12:27 +00:00
True,__version__)
2019-07-11 19:31:02 +00:00
announceMessageArrived=False
for i in range(10):
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:
announceMessageArrived=True
print('Announce message sent to Alice!')
break
afterAnnounceCount=len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])
2019-07-11 19:34:00 +00:00
outboxAfterAnnounceCount=len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])
2019-07-11 19:31:02 +00:00
print('inbox items after announce: '+str(afterAnnounceCount))
assert afterAnnounceCount==beforeAnnounceCount+1
2019-07-11 19:34:00 +00:00
assert outboxAfterAnnounceCount==outboxBeforeAnnounceCount+1
2019-06-30 21:20:02 +00:00
# stop the servers
thrAlice.kill()
thrAlice.join()
assert thrAlice.isAlive()==False
thrBob.kill()
thrBob.join()
assert thrBob.isAlive()==False
os.chdir(baseDir)
shutil.rmtree(aliceDir)
shutil.rmtree(bobDir)
2019-08-18 09:45:04 +00:00
def testFollowBetweenServers():
2019-07-06 13:49:25 +00:00
print('Testing sending a follow request from one server to another')
global testServerAliceRunning
global testServerBobRunning
global testServerEveRunning
2019-07-06 13:49:25 +00:00
testServerAliceRunning = False
testServerBobRunning = False
testServerEveRunning = False
2019-07-06 13:49:25 +00:00
httpPrefix='http'
useTor=False
federationList=[]
2019-07-06 13:49:25 +00:00
baseDir=os.getcwd()
if os.path.isdir(baseDir+'/.tests'):
shutil.rmtree(baseDir+'/.tests')
os.mkdir(baseDir+'/.tests')
ocapAlways=True
2019-07-06 13:49:25 +00:00
# create the servers
aliceDir=baseDir+'/.tests/alice'
aliceDomain='127.0.0.42'
alicePort=61935
2019-07-13 09:37:17 +00:00
thrAlice = \
threadWithTrace(target=createServerAlice, \
args=(aliceDir,aliceDomain,alicePort, \
federationList,False,False, \
ocapAlways),daemon=True)
2019-07-06 13:49:25 +00:00
bobDir=baseDir+'/.tests/bob'
bobDomain='127.0.0.64'
bobPort=61936
2019-07-13 09:37:17 +00:00
thrBob = \
threadWithTrace(target=createServerBob, \
args=(bobDir,bobDomain,bobPort, \
federationList,False,False, \
ocapAlways),daemon=True)
2019-07-06 13:49:25 +00:00
eveDir=baseDir+'/.tests/eve'
eveDomain='127.0.0.55'
evePort=61937
2019-07-13 09:37:17 +00:00
thrEve = \
threadWithTrace(target=createServerEve, \
args=(eveDir,eveDomain,evePort, \
federationList,False,False, \
False),daemon=True)
2019-07-06 13:49:25 +00:00
thrAlice.start()
thrBob.start()
thrEve.start()
2019-07-06 13:49:25 +00:00
assert thrAlice.isAlive()==True
assert thrBob.isAlive()==True
assert thrEve.isAlive()==True
2019-07-06 13:49:25 +00:00
2019-07-07 22:38:35 +00:00
# wait for all servers to be running
ctr=0
while not (testServerAliceRunning and testServerBobRunning and testServerEveRunning):
2019-07-06 13:49:25 +00:00
time.sleep(1)
ctr+=1
2019-07-07 22:29:47 +00:00
if ctr>60:
break
print('Alice online: '+str(testServerAliceRunning))
print('Bob online: '+str(testServerBobRunning))
print('Eve online: '+str(testServerEveRunning))
2019-07-07 22:29:47 +00:00
assert ctr<=60
2019-07-06 13:49:25 +00:00
time.sleep(1)
# In the beginning all was calm and there were no follows
2019-07-09 14:20:23 +00:00
print('*********************************************************')
2019-07-06 13:49:25 +00:00
print('Alice sends a follow request to Bob')
print('Both are strictly enforcing object capabilities')
2019-07-06 13:49:25 +00:00
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, \
2019-07-09 15:51:31 +00:00
clientToServer,federationList, \
2019-07-06 13:49:25 +00:00
aliceSendThreads,alicePostLog, \
2019-08-14 20:12:27 +00:00
aliceCachedWebfingers,alicePersonCache, \
True,__version__)
2019-07-06 13:49:25 +00:00
print('sendResult: '+str(sendResult))
2019-07-09 14:20:23 +00:00
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'
2019-07-06 17:15:03 +00:00
for t in range(10):
if os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt'):
2019-07-06 19:24:52 +00:00
if os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt'):
2019-07-09 14:20:23 +00:00
if os.path.isfile(bobCapsFilename):
if os.path.isfile(aliceCapsFilename):
2019-07-07 16:06:38 +00:00
break
2019-07-06 17:15:03 +00:00
time.sleep(1)
2019-07-09 14:20:23 +00:00
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
2019-07-18 09:31:29 +00:00
assert validInbox(bobDir,'bob',bobDomain)
2019-07-18 11:35:48 +00:00
assert validInboxFilenames(bobDir,'bob',bobDomain,aliceDomain,alicePort)
2019-07-09 14:20:23 +00:00
print('\n\n*********************************************************')
print('Eve tries to send to Bob')
sessionEve = createSession(eveDomain,evePort,useTor)
eveSendThreads = []
evePostLog = []
evePersonCache={}
eveCachedWebfingers={}
eveSendThreads=[]
evePostLog=[]
2019-07-12 19:08:46 +00:00
useBlurhash=False
2019-07-13 09:37:17 +00:00
sendResult = \
2019-08-14 20:12:27 +00:00
sendPost(__version__, \
sessionEve,eveDir,'eve', eveDomain, evePort, \
2019-07-13 09:37:17 +00:00
'bob', bobDomain, bobPort, ccUrl, \
httpPrefix, 'Eve message', followersOnly, \
2019-08-30 15:50:20 +00:00
saveToFile, clientToServer,None,None,None, \
2019-07-13 09:37:17 +00:00
useBlurhash, federationList, eveSendThreads, \
evePostLog, eveCachedWebfingers, \
evePersonCache,inReplyTo, inReplyToAtomUri, subject)
print('sendResult: '+str(sendResult))
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
inboxPath=bobDir+'/accounts/bob@'+bobDomain+'/inbox'
eveMessageArrived=False
2019-07-07 22:58:12 +00:00
for i in range(10):
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))])>1:
eveMessageArrived=True
print('Eve message sent to Bob!')
break
# capabilities should have prevented delivery
assert eveMessageArrived==False
print('Message from Eve to Bob was correctly rejected by object capabilities')
2019-07-09 14:20:23 +00:00
print('\n\n*********************************************************')
print('Alice sends a message to Bob')
aliceSendThreads = []
alicePostLog = []
alicePersonCache={}
aliceCachedWebfingers={}
aliceSendThreads=[]
alicePostLog=[]
2019-07-12 19:08:46 +00:00
useBlurhash=False
2019-07-13 09:37:17 +00:00
sendResult = \
2019-08-14 20:12:27 +00:00
sendPost(__version__, \
sessionAlice,aliceDir,'alice', aliceDomain, alicePort, \
2019-07-13 09:37:17 +00:00
'bob', bobDomain, bobPort, ccUrl, \
httpPrefix, 'Alice message', followersOnly, saveToFile, \
2019-08-30 15:50:20 +00:00
clientToServer,None,None,None,useBlurhash, federationList, \
2019-07-13 09:37:17 +00:00
aliceSendThreads, alicePostLog, aliceCachedWebfingers, \
alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
print('sendResult: '+str(sendResult))
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
inboxPath=bobDir+'/accounts/bob@'+bobDomain+'/inbox'
2019-07-08 23:05:48 +00:00
aliceMessageArrived=False
2019-07-07 22:26:15 +00:00
for i in range(20):
time.sleep(1)
if os.path.isdir(inboxPath):
2019-07-08 23:05:48 +00:00
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, since it was granted capabilities')
2019-07-13 09:37:17 +00:00
2019-07-09 14:20:23 +00:00
print('\n\n*********************************************************')
print("\nBob changes Alice's capabilities so that she can't reply on his posts")
2019-07-13 09:37:17 +00:00
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'
2019-07-09 14:20:23 +00:00
sessionBob = createSession(bobDomain,bobPort,useTor)
bobSendThreads = []
bobPostLog = []
bobPersonCache={}
bobCachedWebfingers={}
print("Bob's capabilities for Alice:")
with open(bobCapsFilename, 'r') as fp:
bobCapsJson=commentjson.load(fp)
pprint(bobCapsJson)
assert "inbox:noreply" not in bobCapsJson['capability']
print("Alice's capabilities granted by Bob")
with open(aliceCapsFilename, 'r') as fp:
aliceCapsJson=commentjson.load(fp)
pprint(aliceCapsJson)
assert "inbox:noreply" not in aliceCapsJson['capability']
newCapabilities=["inbox:write","objects:read","inbox:noreply"]
sendCapabilitiesUpdate(sessionBob,bobDir,httpPrefix, \
'bob',bobDomain,bobPort, \
2019-07-13 09:37:17 +00:00
httpPrefix+'://'+aliceDomain+':'+\
str(alicePort)+'/users/alice',
2019-07-09 14:20:23 +00:00
newCapabilities, \
bobSendThreads, bobPostLog, \
bobCachedWebfingers,bobPersonCache, \
2019-08-14 20:12:27 +00:00
federationList,True,__version__)
2019-07-09 14:20:23 +00:00
bobChanged=False
bobNewCapsJson=None
for i in range(20):
time.sleep(1)
with open(bobCapsFilename, 'r') as fp:
bobNewCapsJson=commentjson.load(fp)
if "inbox:noreply" in bobNewCapsJson['capability']:
print("Bob's capabilities were changed")
pprint(bobNewCapsJson)
bobChanged=True
break
assert bobChanged
aliceChanged=False
aliceNewCapsJson=None
for i in range(20):
time.sleep(1)
with open(aliceCapsFilename, 'r') as fp:
aliceNewCapsJson=commentjson.load(fp)
if "inbox:noreply" in aliceNewCapsJson['capability']:
print("Alice's granted capabilities were changed")
pprint(aliceNewCapsJson)
aliceChanged=True
break
assert aliceChanged
# check that the capabilities id has changed
assert bobNewCapsJson['id']!=bobCapsJson['id']
assert aliceNewCapsJson['id']!=aliceCapsJson['id']
2019-07-06 13:49:25 +00:00
# stop the servers
thrAlice.kill()
thrAlice.join()
assert thrAlice.isAlive()==False
thrBob.kill()
thrBob.join()
assert thrBob.isAlive()==False
2019-07-07 22:38:35 +00:00
thrEve.kill()
thrEve.join()
assert thrEve.isAlive()==False
2019-07-13 09:37:17 +00:00
assert os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+ \
'/ocap/accept/'+httpPrefix+':##'+ \
aliceDomain+':'+str(alicePort)+ \
'#users#alice.json')
assert os.path.isfile(aliceDir+'/accounts/alice@'+ \
aliceDomain+'/ocap/granted/'+ \
httpPrefix+':##'+bobDomain+':'+ \
str(bobPort)+'#users#bob.json')
2019-07-07 16:33:59 +00:00
2019-07-06 17:15:03 +00:00
assert 'alice@'+aliceDomain in open(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt').read()
assert 'bob@'+bobDomain in open(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt').read()
2019-07-09 08:52:53 +00:00
# queue item removed
assert len([name for name in os.listdir(queuePath) if os.path.isfile(os.path.join(queuePath, name))])==0
2019-07-06 17:15:03 +00:00
2019-07-06 13:49:25 +00:00
os.chdir(baseDir)
2019-07-08 23:05:48 +00:00
shutil.rmtree(baseDir+'/.tests')
2019-07-06 13:49:25 +00:00
def testFollowersOfPerson():
print('testFollowersOfPerson')
currDir=os.getcwd()
nickname='mxpop'
domain='diva.domain'
password='birb'
port=80
httpPrefix='https'
federationList=[]
baseDir=currDir+'/.tests_followersofperson'
if os.path.isdir(baseDir):
shutil.rmtree(baseDir)
os.mkdir(baseDir)
os.chdir(baseDir)
createPerson(baseDir,nickname,domain,port,httpPrefix,True,password)
createPerson(baseDir,'maxboardroom',domain,port,httpPrefix,True,password)
createPerson(baseDir,'ultrapancake',domain,port,httpPrefix,True,password)
createPerson(baseDir,'drokk',domain,port,httpPrefix,True,password)
createPerson(baseDir,'sausagedog',domain,port,httpPrefix,True,password)
clearFollows(baseDir,nickname,domain)
2019-07-14 17:19:00 +00:00
followPerson(baseDir,nickname,domain,'maxboardroom',domain,federationList,False)
followPerson(baseDir,'drokk',domain,'ultrapancake',domain,federationList,False)
# deliberate duplication
2019-07-14 17:19:00 +00:00
followPerson(baseDir,'drokk',domain,'ultrapancake',domain,federationList,False)
followPerson(baseDir,'sausagedog',domain,'ultrapancake',domain,federationList,False)
followPerson(baseDir,nickname,domain,'ultrapancake',domain,federationList,False)
followPerson(baseDir,nickname,domain,'someother','randodomain.net',federationList,False)
followList=getFollowersOfPerson(baseDir,'ultrapancake',domain)
assert len(followList)==3
assert 'mxpop@'+domain in followList
assert 'drokk@'+domain in followList
assert 'sausagedog@'+domain in followList
os.chdir(currDir)
shutil.rmtree(baseDir)
def testNoOfFollowersOnDomain():
print('testNoOfFollowersOnDomain')
currDir=os.getcwd()
nickname='mxpop'
domain='diva.domain'
otherdomain='soup.dragon'
password='birb'
port=80
httpPrefix='https'
federationList=[]
baseDir=currDir+'/.tests_nooffollowersOndomain'
if os.path.isdir(baseDir):
shutil.rmtree(baseDir)
os.mkdir(baseDir)
os.chdir(baseDir)
createPerson(baseDir,nickname,domain,port,httpPrefix,True,password)
createPerson(baseDir,'maxboardroom',otherdomain,port,httpPrefix,True,password)
createPerson(baseDir,'ultrapancake',otherdomain,port,httpPrefix,True,password)
createPerson(baseDir,'drokk',otherdomain,port,httpPrefix,True,password)
createPerson(baseDir,'sausagedog',otherdomain,port,httpPrefix,True,password)
2019-07-14 17:19:00 +00:00
followPerson(baseDir,'drokk',otherdomain,nickname,domain,federationList,False)
followPerson(baseDir,'sausagedog',otherdomain,nickname,domain,federationList,False)
followPerson(baseDir,'maxboardroom',otherdomain,nickname,domain,federationList,False)
2019-07-14 17:19:00 +00:00
followerOfPerson(baseDir,nickname,domain,'cucumber','sandwiches.party',federationList,False)
followerOfPerson(baseDir,nickname,domain,'captainsensible','damned.zone',federationList,False)
followerOfPerson(baseDir,nickname,domain,'pilchard','zombies.attack',federationList,False)
followerOfPerson(baseDir,nickname,domain,'drokk',otherdomain,federationList,False)
followerOfPerson(baseDir,nickname,domain,'sausagedog',otherdomain,federationList,False)
followerOfPerson(baseDir,nickname,domain,'maxboardroom',otherdomain,federationList,False)
followersOnOtherDomain=noOfFollowersOnDomain(baseDir,nickname+'@'+domain, otherdomain)
assert followersOnOtherDomain==3
unfollowerOfPerson(baseDir,nickname,domain,'sausagedog',otherdomain)
followersOnOtherDomain=noOfFollowersOnDomain(baseDir,nickname+'@'+domain, otherdomain)
assert followersOnOtherDomain==2
os.chdir(currDir)
shutil.rmtree(baseDir)
def testGroupFollowers():
print('testGroupFollowers')
currDir=os.getcwd()
nickname='test735'
domain='mydomain.com'
password='somepass'
port=80
httpPrefix='https'
federationList=[]
baseDir=currDir+'/.tests_testgroupfollowers'
if os.path.isdir(baseDir):
shutil.rmtree(baseDir)
os.mkdir(baseDir)
os.chdir(baseDir)
createPerson(baseDir,nickname,domain,port,httpPrefix,True,password)
clearFollowers(baseDir,nickname,domain)
followerOfPerson(baseDir,nickname,domain,'badger','wild.domain',federationList,False)
followerOfPerson(baseDir,nickname,domain,'squirrel','wild.domain',federationList,False)
followerOfPerson(baseDir,nickname,domain,'rodent','wild.domain',federationList,False)
followerOfPerson(baseDir,nickname,domain,'utterly','clutterly.domain',federationList,False)
followerOfPerson(baseDir,nickname,domain,'zonked','zzz.domain',federationList,False)
followerOfPerson(baseDir,nickname,domain,'nap','zzz.domain',federationList,False)
grouped=groupFollowersByDomain(baseDir,nickname,domain)
assert len(grouped.items())==3
assert grouped.get('zzz.domain')
assert grouped.get('clutterly.domain')
assert grouped.get('wild.domain')
assert len(grouped['zzz.domain'])==2
assert len(grouped['wild.domain'])==3
assert len(grouped['clutterly.domain'])==1
os.chdir(currDir)
shutil.rmtree(baseDir)
2019-07-03 09:24:55 +00:00
def testFollows():
2019-07-03 10:04:23 +00:00
print('testFollows')
2019-07-03 09:24:55 +00:00
currDir=os.getcwd()
2019-07-03 09:40:27 +00:00
nickname='test529'
2019-07-03 09:24:55 +00:00
domain='testdomain.com'
2019-07-04 19:09:48 +00:00
password='mypass'
2019-07-03 09:24:55 +00:00
port=80
2019-07-03 19:00:03 +00:00
httpPrefix='https'
2019-07-03 09:24:55 +00:00
federationList=['wild.com','mesh.com']
baseDir=currDir+'/.tests_testfollows'
if os.path.isdir(baseDir):
shutil.rmtree(baseDir)
os.mkdir(baseDir)
2019-07-04 19:09:48 +00:00
os.chdir(baseDir)
createPerson(baseDir,nickname,domain,port,httpPrefix,True,password)
2019-07-03 09:24:55 +00:00
2019-07-03 09:40:27 +00:00
clearFollows(baseDir,nickname,domain)
2019-07-06 19:24:52 +00:00
followPerson(baseDir,nickname,domain,'badger','wild.com',federationList,False)
followPerson(baseDir,nickname,domain,'squirrel','secret.com',federationList,False)
followPerson(baseDir,nickname,domain,'rodent','drainpipe.com',federationList,False)
followPerson(baseDir,nickname,domain,'batman','mesh.com',federationList,False)
followPerson(baseDir,nickname,domain,'giraffe','trees.com',federationList,False)
2019-07-03 09:24:55 +00:00
2019-07-03 09:40:27 +00:00
f = open(baseDir+'/accounts/'+nickname+'@'+domain+'/following.txt', "r")
2019-07-03 09:33:28 +00:00
domainFound=False
2019-07-03 09:24:55 +00:00
for followingDomain in f:
testDomain=followingDomain.split('@')[1].replace('\n','')
2019-07-03 09:33:28 +00:00
if testDomain=='mesh.com':
domainFound=True
2019-07-03 09:24:55 +00:00
if testDomain not in federationList:
print(testDomain)
assert(False)
2019-07-03 09:33:28 +00:00
assert(domainFound)
2019-07-03 09:40:27 +00:00
unfollowPerson(baseDir,nickname,domain,'batman','mesh.com')
2019-07-03 09:33:28 +00:00
domainFound=False
for followingDomain in f:
testDomain=followingDomain.split('@')[1].replace('\n','')
if testDomain=='mesh.com':
domainFound=True
assert(domainFound==False)
2019-07-03 09:40:27 +00:00
clearFollowers(baseDir,nickname,domain)
2019-07-06 19:24:52 +00:00
followerOfPerson(baseDir,nickname,domain,'badger','wild.com',federationList,False)
followerOfPerson(baseDir,nickname,domain,'squirrel','secret.com',federationList,False)
followerOfPerson(baseDir,nickname,domain,'rodent','drainpipe.com',federationList,False)
followerOfPerson(baseDir,nickname,domain,'batman','mesh.com',federationList,False)
followerOfPerson(baseDir,nickname,domain,'giraffe','trees.com',federationList,False)
2019-07-03 09:24:55 +00:00
2019-07-03 09:40:27 +00:00
f = open(baseDir+'/accounts/'+nickname+'@'+domain+'/followers.txt', "r")
2019-07-03 09:24:55 +00:00
for followerDomain in f:
testDomain=followerDomain.split('@')[1].replace('\n','')
if testDomain not in federationList:
print(testDomain)
assert(False)
os.chdir(currDir)
shutil.rmtree(baseDir)
2019-07-03 10:04:23 +00:00
def testCreatePerson():
print('testCreatePerson')
currDir=os.getcwd()
nickname='test382'
domain='badgerdomain.com'
2019-07-04 19:09:48 +00:00
password='mypass'
2019-07-03 10:04:23 +00:00
port=80
2019-07-03 19:00:03 +00:00
httpPrefix='https'
2019-07-03 15:10:18 +00:00
clientToServer=False
2019-07-12 19:08:46 +00:00
useBlurhash=False
2019-07-03 10:04:23 +00:00
baseDir=currDir+'/.tests_createperson'
if os.path.isdir(baseDir):
shutil.rmtree(baseDir)
os.mkdir(baseDir)
os.chdir(baseDir)
2019-07-03 09:24:55 +00:00
2019-07-04 19:09:48 +00:00
privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(baseDir,nickname,domain,port,httpPrefix,True,password)
assert os.path.isfile(baseDir+'/accounts/passwords')
2019-07-04 16:24:23 +00:00
deleteAllPosts(baseDir,nickname,domain,'inbox')
deleteAllPosts(baseDir,nickname,domain,'outbox')
setDisplayNickname(baseDir,nickname,domain,'badger')
2019-07-03 10:04:23 +00:00
setBio(baseDir,nickname,domain,'Randomly roaming in your backyard')
2019-07-12 20:43:55 +00:00
archivePostsForPerson(nickname,domain,baseDir,'inbox',None,4)
archivePostsForPerson(nickname,domain,baseDir,'outbox',None,4)
2019-07-12 19:08:46 +00:00
createPublicPost(baseDir,nickname, domain, port,httpPrefix, "G'day world!", False, True, clientToServer,None,None,useBlurhash, None, None, 'Not suitable for Vogons')
2019-07-03 10:04:23 +00:00
os.chdir(currDir)
shutil.rmtree(baseDir)
2019-07-18 16:21:26 +00:00
def testDelegateRoles():
print('testDelegateRoles')
currDir=os.getcwd()
nickname='test382'
nicknameDelegated='test383'
domain='badgerdomain.com'
password='mypass'
port=80
httpPrefix='https'
clientToServer=False
useBlurhash=False
baseDir=currDir+'/.tests_delegaterole'
if os.path.isdir(baseDir):
shutil.rmtree(baseDir)
os.mkdir(baseDir)
os.chdir(baseDir)
privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(baseDir,nickname,domain,port,httpPrefix,True,password)
privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(baseDir,nicknameDelegated,domain,port,httpPrefix,True,'insecure')
httpPrefix='http'
project='artechoke'
role='delegator'
newRoleJson = {
'type': 'Delegate',
'actor': httpPrefix+'://'+domain+'/users/'+nickname,
'object': {
'type': 'Role',
'actor': httpPrefix+'://'+domain+'/users/'+nicknameDelegated,
'object': project+';'+role,
'to': [],
'cc': []
},
'to': [],
'cc': []
}
2019-07-19 10:01:24 +00:00
assert outboxDelegate(baseDir,nickname,newRoleJson,False)
2019-07-18 16:21:26 +00:00
# second time delegation has already happened so should return false
2019-07-19 10:01:24 +00:00
assert outboxDelegate(baseDir,nickname,newRoleJson,False)==False
2019-07-18 16:21:26 +00:00
assert '"delegator"' in open(baseDir+'/accounts/'+nickname+'@'+domain+'.json').read()
assert '"delegator"' in open(baseDir+'/accounts/'+nicknameDelegated+'@'+domain+'.json').read()
newRoleJson = {
'type': 'Delegate',
'actor': httpPrefix+'://'+domain+'/users/'+nicknameDelegated,
'object': {
'type': 'Role',
'actor': httpPrefix+'://'+domain+'/users/'+nickname,
'object': 'otherproject;otherrole',
'to': [],
'cc': []
},
'to': [],
'cc': []
}
# non-delegators cannot assign roles
2019-07-19 10:01:24 +00:00
assert outboxDelegate(baseDir,nicknameDelegated,newRoleJson,False)==False
2019-07-18 16:21:26 +00:00
assert '"otherrole"' not in open(baseDir+'/accounts/'+nickname+'@'+domain+'.json').read()
os.chdir(currDir)
shutil.rmtree(baseDir)
2019-07-03 18:24:44 +00:00
def testAuthentication():
print('testAuthentication')
currDir=os.getcwd()
nickname='test8743'
password='SuperSecretPassword12345'
baseDir=currDir+'/.tests_authentication'
if os.path.isdir(baseDir):
shutil.rmtree(baseDir)
os.mkdir(baseDir)
os.chdir(baseDir)
assert storeBasicCredentials(baseDir,'othernick','otherpass')
assert storeBasicCredentials(baseDir,'bad:nick','otherpass')==False
assert storeBasicCredentials(baseDir,'badnick','otherpa:ss')==False
assert storeBasicCredentials(baseDir,nickname,password)
authHeader=createBasicAuthHeader(nickname,password)
2019-07-04 08:56:15 +00:00
assert authorizeBasic(baseDir,'/users/'+nickname+'/inbox',authHeader,False)
assert authorizeBasic(baseDir,'/users/'+nickname,authHeader,False)==False
assert authorizeBasic(baseDir,'/users/othernick/inbox',authHeader,False)==False
2019-07-03 18:24:44 +00:00
authHeader=createBasicAuthHeader(nickname,password+'1')
2019-07-04 08:56:15 +00:00
assert authorizeBasic(baseDir,'/users/'+nickname+'/inbox',authHeader,False)==False
2019-07-03 18:24:44 +00:00
2019-07-03 19:13:23 +00:00
password='someOtherPassword'
assert storeBasicCredentials(baseDir,nickname,password)
authHeader=createBasicAuthHeader(nickname,password)
2019-07-04 08:56:15 +00:00
assert authorizeBasic(baseDir,'/users/'+nickname+'/inbox',authHeader,False)
2019-07-03 19:13:23 +00:00
2019-07-03 18:24:44 +00:00
os.chdir(currDir)
shutil.rmtree(baseDir)
2019-07-16 10:19:04 +00:00
def testClientToServer():
print('Testing sending a post via c2s')
global testServerAliceRunning
global testServerBobRunning
testServerAliceRunning = False
testServerBobRunning = 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)
thrAlice.start()
thrBob.start()
assert thrAlice.isAlive()==True
assert thrBob.isAlive()==True
# wait for both servers to be running
ctr=0
while not (testServerAliceRunning and testServerBobRunning):
time.sleep(1)
ctr+=1
if ctr>60:
break
print('Alice online: '+str(testServerAliceRunning))
print('Bob online: '+str(testServerBobRunning))
time.sleep(1)
print('\n\n*******************************************************')
print('Alice sends to Bob via c2s')
sessionAlice = createSession(aliceDomain,alicePort,useTor)
followersOnly=False
2019-07-16 14:23:06 +00:00
attachedImageFilename=baseDir+'/img/logo.png'
2019-08-30 15:50:20 +00:00
mediaType=getAttachmentMediaType(attachedImageFilename)
2019-07-16 14:23:06 +00:00
attachedImageDescription='Logo'
2019-07-16 10:19:04 +00:00
useBlurhash=False
cachedWebfingers={}
personCache={}
password='alicepass'
outboxPath=aliceDir+'/accounts/alice@'+aliceDomain+'/outbox'
2019-07-16 11:33:40 +00:00
inboxPath=bobDir+'/accounts/bob@'+bobDomain+'/inbox'
2019-07-16 10:19:04 +00:00
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==0
2019-07-16 11:33:40 +00:00
assert len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==0
2019-07-16 10:19:04 +00:00
sendResult= \
2019-08-14 20:12:27 +00:00
sendPostViaServer(__version__, \
aliceDir,sessionAlice,'alice',password, \
2019-07-16 10:19:04 +00:00
aliceDomain,alicePort, \
'bob',bobDomain,bobPort,None, \
httpPrefix,'Sent from my ActivityPub client',followersOnly, \
2019-08-30 15:50:20 +00:00
attachedImageFilename,mediaType, \
attachedImageDescription,useBlurhash, \
2019-07-16 10:19:04 +00:00
cachedWebfingers,personCache, \
True,None,None,None)
print('sendResult: '+str(sendResult))
for i in range(30):
if os.path.isdir(outboxPath):
if len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==1:
break
time.sleep(1)
2019-07-16 11:33:40 +00:00
2019-07-16 10:19:04 +00:00
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==1
2019-07-16 11:33:40 +00:00
print(">>> c2s post arrived in Alice's outbox")
2019-07-16 19:07:45 +00:00
2019-07-16 11:33:40 +00:00
for i in range(30):
if os.path.isdir(inboxPath):
if len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==1:
break
time.sleep(1)
assert len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==1
print(">>> s2s post arrived in Bob's inbox")
print("c2s send success")
2019-07-16 19:07:45 +00:00
print('\n\nGetting message id for the post')
statusNumber=0
outboxPostFilename=None
outboxPostId=None
for name in os.listdir(outboxPath):
if '#statuses#' in name:
statusNumber=int(name.split('#statuses#')[1].replace('.json','').replace('#activity',''))
outboxPostFilename=outboxPath+'/'+name
with open(outboxPostFilename, 'r') as fp:
postJsonObject=commentjson.load(fp)
outboxPostId=postJsonObject['id'].replace('/activity','')
assert outboxPostId
print('message id obtained: '+outboxPostId)
assert validInbox(bobDir,'bob',bobDomain)
2019-07-18 11:35:48 +00:00
assert validInboxFilenames(bobDir,'bob',bobDomain,aliceDomain,alicePort)
2019-07-16 21:38:06 +00:00
print('\n\nAlice follows Bob')
2019-08-20 09:16:03 +00:00
sendFollowRequestViaServer(aliceDir,sessionAlice, \
'alice',password, \
2019-07-16 21:38:06 +00:00
aliceDomain,alicePort, \
'bob',bobDomain,bobPort, \
httpPrefix, \
cachedWebfingers,personCache, \
2019-08-14 20:12:27 +00:00
True,__version__)
2019-07-16 21:38:06 +00:00
for t in range(10):
if os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt'):
2019-07-17 11:28:19 +00:00
if 'alice@'+aliceDomain+':'+str(alicePort) in open(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt').read():
2019-07-17 11:24:11 +00:00
if os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt'):
2019-07-17 11:28:19 +00:00
if 'bob@'+bobDomain+':'+str(bobPort) in open(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt').read():
2019-07-17 11:24:11 +00:00
break
2019-07-16 21:38:06 +00:00
time.sleep(1)
assert os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt')
assert os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt')
2019-07-17 11:30:26 +00:00
assert 'alice@'+aliceDomain+':'+str(alicePort) in open(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt').read()
assert 'bob@'+bobDomain+':'+str(bobPort) in open(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt').read()
assert validInbox(bobDir,'bob',bobDomain)
2019-07-18 11:35:48 +00:00
assert validInboxFilenames(bobDir,'bob',bobDomain,aliceDomain,alicePort)
2019-07-17 17:16:48 +00:00
print('\n\nBob follows Alice')
2019-08-20 09:16:03 +00:00
sendFollowRequestViaServer(aliceDir,sessionAlice, \
'bob','bobpass', \
2019-07-17 17:16:48 +00:00
bobDomain,bobPort, \
'alice',aliceDomain,alicePort, \
httpPrefix, \
cachedWebfingers,personCache, \
2019-08-14 20:12:27 +00:00
True,__version__)
2019-07-17 17:16:48 +00:00
for t in range(10):
if os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/followers.txt'):
if 'bob@'+bobDomain+':'+str(bobPort) in open(aliceDir+'/accounts/alice@'+aliceDomain+'/followers.txt').read():
if os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/following.txt'):
if 'alice@'+aliceDomain+':'+str(alicePort) in open(bobDir+'/accounts/bob@'+bobDomain+'/following.txt').read():
break
time.sleep(1)
assert os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/followers.txt')
assert os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/following.txt')
assert 'bob@'+bobDomain+':'+str(bobPort) in open(aliceDir+'/accounts/alice@'+aliceDomain+'/followers.txt').read()
assert 'alice@'+aliceDomain+':'+str(alicePort) in open(bobDir+'/accounts/bob@'+bobDomain+'/following.txt').read()
print('\n\nBob likes the post')
2019-07-16 19:07:45 +00:00
sessionBob = createSession(bobDomain,bobPort,useTor)
password='bobpass'
outboxPath=bobDir+'/accounts/bob@'+bobDomain+'/outbox'
2019-07-16 22:57:45 +00:00
inboxPath=aliceDir+'/accounts/alice@'+aliceDomain+'/inbox'
2019-07-17 17:16:48 +00:00
print(str(len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])))
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==1
print(str(len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])))
assert len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==1
2019-08-20 09:16:03 +00:00
sendLikeViaServer(bobDir,sessionBob, \
'bob','bobpass', \
bobDomain,bobPort, \
httpPrefix,outboxPostId, \
cachedWebfingers,personCache, \
2019-08-14 20:12:27 +00:00
True,__version__)
for i in range(20):
if os.path.isdir(outboxPath) and os.path.isdir(inboxPath):
if len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==2:
if len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==1:
break
time.sleep(1)
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==2
assert len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==1
print('Post liked')
print('\n\nBob repeats the post')
print(str(len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])))
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==2
print(str(len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])))
assert len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==1
2019-08-20 09:16:03 +00:00
sendAnnounceViaServer(bobDir,sessionBob,'bob',password, \
2019-07-16 19:07:45 +00:00
bobDomain,bobPort, \
httpPrefix,outboxPostId, \
2019-07-16 21:38:06 +00:00
cachedWebfingers, \
2019-08-14 20:12:27 +00:00
personCache,True,__version__)
2019-07-16 22:57:45 +00:00
for i in range(20):
if os.path.isdir(outboxPath) and os.path.isdir(inboxPath):
if len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==3:
2019-07-17 17:16:48 +00:00
if len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==2:
2019-07-16 22:57:45 +00:00
break
2019-07-16 19:07:45 +00:00
time.sleep(1)
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==3
2019-07-17 17:16:48 +00:00
assert len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==2
2019-07-16 19:07:45 +00:00
print('Post repeated')
2019-07-17 11:54:13 +00:00
2019-07-17 17:16:48 +00:00
inboxPath=bobDir+'/accounts/bob@'+bobDomain+'/inbox'
outboxPath=aliceDir+'/accounts/alice@'+aliceDomain+'/outbox'
postsBefore = len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])
print('\n\nAlice deletes her post: '+outboxPostId+' '+str(postsBefore))
password='alicepass'
2019-08-20 09:16:03 +00:00
sendDeleteViaServer(aliceDir,sessionAlice,'alice',password,
2019-07-17 17:16:48 +00:00
aliceDomain,alicePort, \
httpPrefix,outboxPostId, \
cachedWebfingers,personCache, \
2019-08-14 20:12:27 +00:00
True,__version__)
2019-07-17 17:16:48 +00:00
for i in range(30):
if os.path.isdir(inboxPath):
if len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==postsBefore-1:
break
time.sleep(1)
assert len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==postsBefore-1
print(">>> post deleted from Alice's outbox and Bob's inbox")
assert validInbox(bobDir,'bob',bobDomain)
2019-07-18 11:35:48 +00:00
assert validInboxFilenames(bobDir,'bob',bobDomain,aliceDomain,alicePort)
2019-07-17 17:16:48 +00:00
2019-07-17 11:54:13 +00:00
print('\n\nAlice unfollows Bob')
password='alicepass'
2019-08-20 09:16:03 +00:00
sendUnfollowRequestViaServer(baseDir,sessionAlice, \
'alice',password, \
2019-07-17 11:54:13 +00:00
aliceDomain,alicePort, \
'bob',bobDomain,bobPort, \
httpPrefix, \
cachedWebfingers,personCache, \
2019-08-14 20:12:27 +00:00
True,__version__)
2019-07-17 11:54:13 +00:00
for t in range(10):
if 'alice@'+aliceDomain+':'+str(alicePort) not in open(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt').read():
if 'bob@'+bobDomain+':'+str(bobPort) not in open(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt').read():
break
time.sleep(1)
assert os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt')
assert os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt')
assert 'alice@'+aliceDomain+':'+str(alicePort) not in open(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt').read()
assert 'bob@'+bobDomain+':'+str(bobPort) not in open(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt').read()
assert validInbox(bobDir,'bob',bobDomain)
2019-07-18 11:35:48 +00:00
assert validInboxFilenames(bobDir,'bob',bobDomain,aliceDomain,alicePort)
2019-07-18 11:38:52 +00:00
assert validInbox(aliceDir,'alice',aliceDomain)
assert validInboxFilenames(aliceDir,'alice',aliceDomain,bobDomain,bobPort)
2019-07-17 11:54:13 +00:00
2019-07-16 11:33:40 +00:00
# stop the servers
thrAlice.kill()
thrAlice.join()
assert thrAlice.isAlive()==False
thrBob.kill()
thrBob.join()
assert thrBob.isAlive()==False
os.chdir(baseDir)
2019-07-16 21:38:06 +00:00
#shutil.rmtree(aliceDir)
#shutil.rmtree(bobDir)
2019-07-16 10:19:04 +00:00
2019-08-21 16:35:46 +00:00
def testActorParsing():
print('testActorParsing')
actor='https://mydomain:72/users/mynick'
domain,port=getDomainFromActor(actor)
assert domain=='mydomain'
assert port==72
nickname=getNicknameFromActor(actor)
assert nickname=='mynick'
actor='https://randomain/users/rando'
domain,port=getDomainFromActor(actor)
assert domain=='randomain'
nickname=getNicknameFromActor(actor)
assert nickname=='rando'
actor='https://otherdomain:49/@othernick'
domain,port=getDomainFromActor(actor)
assert domain=='otherdomain'
assert port==49
nickname=getNicknameFromActor(actor)
assert nickname=='othernick'
2019-06-30 21:20:02 +00:00
def runAllTests():
print('Running tests...')
2019-08-21 16:35:46 +00:00
testActorParsing()
2019-06-30 21:20:02 +00:00
testHttpsig()
testCache()
testThreads()
2019-07-03 10:04:23 +00:00
testCreatePerson()
2019-07-03 18:24:44 +00:00
testAuthentication()
testFollowersOfPerson()
testNoOfFollowersOnDomain()
testFollows()
testGroupFollowers()
2019-07-18 16:21:26 +00:00
testDelegateRoles()
2019-07-03 18:24:44 +00:00
print('Tests succeeded\n')