epicyon/tests.py

950 lines
36 KiB
Python
Raw Normal View History

2019-06-30 20:14:03 +00:00
__filename__ = "tests.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "0.0.1"
__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
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 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-01 11:09:09 +00:00
from follow import clearFollows
from follow import clearFollowers
2019-07-06 19:24:52 +00:00
from utils import followPerson
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 setPreferredNickname
from person import setBio
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
2019-07-11 17:55:10 +00:00
from announce import announcePublic
2019-07-12 19:26:54 +00:00
from media import getMediaPath
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-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-06-30 22:56:37 +00:00
baseDir=os.getcwd()
2019-07-04 19:09:48 +00:00
password='SuperSecretPassword'
2019-07-13 09:37:17 +00:00
privateKeyPem,publicKeyPem,person,wfEndpoint= \
createPerson(baseDir,nickname,domain,port,httpPrefix,False,password)
2019-07-01 09:31:02 +00:00
messageBodyJsonStr = '{"a key": "a value", "another key": "A string"}'
headersDomain=domain
if port!=80 and port !=443:
headersDomain=domain+':'+str(port)
2019-06-30 20:14:03 +00:00
if not withDigest:
2019-07-01 09:31:02 +00:00
headers = {'host': headersDomain}
2019-06-30 20:14:03 +00:00
else:
2019-07-13 09:37:17 +00:00
bodyDigest = \
base64.b64encode(SHA256.new(messageBodyJsonStr.encode()).digest())
2019-07-01 09:31:02 +00:00
headers = {'host': headersDomain, 'digest': f'SHA-256={bodyDigest}'}
2019-06-30 20:14:03 +00:00
path='/inbox'
2019-07-13 09:37:17 +00:00
signatureHeader = \
signPostHeaders(privateKeyPem, nickname, domain, port, path, httpPrefix, None)
2019-06-30 20:14:03 +00:00
headers['signature'] = signatureHeader
2019-07-13 09:37:17 +00:00
assert verifyPostHeaders(httpPrefix, publicKeyPem, headers, \
'/inbox' ,False, messageBodyJsonStr)
assert verifyPostHeaders(httpPrefix, publicKeyPem, headers, \
'/parambulator/inbox', False , messageBodyJsonStr) == False
assert verifyPostHeaders(httpPrefix, publicKeyPem, headers, \
'/inbox', True, messageBodyJsonStr) == False
2019-06-30 20:14:03 +00:00
if not withDigest:
# fake domain
headers = {'host': 'bogon.domain'}
else:
# correct domain but fake message
2019-07-01 09:31:02 +00:00
messageBodyJsonStr = '{"a key": "a value", "another key": "Fake GNUs"}'
bodyDigest = base64.b64encode(SHA256.new(messageBodyJsonStr.encode()).digest())
2019-06-30 20:14:03 +00:00
headers = {'host': domain, 'digest': f'SHA-256={bodyDigest}'}
headers['signature'] = signatureHeader
2019-07-13 09:37:17 +00:00
assert verifyPostHeaders(httpPrefix, publicKeyPem, headers, \
'/inbox', True, messageBodyJsonStr) == False
2019-06-30 20:14:03 +00:00
def testHttpsig():
testHttpsigBase(False)
testHttpsigBase(True)
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={}
storePersonInCache(personUrl,personJson,personCache)
result=getPersonFromCache(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-03 15:10:18 +00:00
clientToServer=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 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-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', \
federationList,True)
followerOfPerson(path,nickname,domain,'bob','127.0.0.100:61936', \
federationList,True)
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-07-13 09:37:17 +00:00
runDaemon(False,path,domain,port,httpPrefix,federationList, \
noreply,nolike,nopics,noannounce,cw,ocapAlways,useTor,True)
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 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-06 13:49:25 +00:00
if hasFollows:
2019-07-13 09:37:17 +00:00
followPerson(path,nickname,domain, \
'alice','127.0.0.50:61935',federationList,True)
followerOfPerson(path,nickname,domain, \
'alice','127.0.0.50:61935',federationList,True)
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-07-13 09:37:17 +00:00
runDaemon(False,path,domain,port,httpPrefix,federationList, \
noreply,nolike,nopics,noannounce,cw,ocapAlways,useTor,True)
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 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-07-13 09:37:17 +00:00
runDaemon(False,path,domain,port,httpPrefix,federationList, \
noreply,nolike,nopics,noannounce,cw,ocapAlways,useTor,True)
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'
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 = \
sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, \
'bob', bobDomain, bobPort, ccUrl, httpPrefix, \
'Why is a mouse when it spins?', followersOnly, \
saveToFile, clientToServer,attachedImageFilename, \
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-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', \
aliceDomain+':'+str(alicePort),federationList,True)
followPerson(aliceDir,'alice',aliceDomain,'bob', \
bobDomain+':'+str(bobPort),federationList,True)
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, \
bobPersonCache,bobCachedWebfingers,True)
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, \
True)
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-07-06 13:49:25 +00:00
def testFollowBetweenServers():
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, \
aliceCachedWebfingers,alicePersonCache,True)
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-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 = \
sendPost(sessionEve,eveDir,'eve', eveDomain, evePort, \
'bob', bobDomain, bobPort, ccUrl, \
httpPrefix, 'Eve message', followersOnly, \
saveToFile, clientToServer,None,None, \
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 = \
sendPost(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'
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, \
federationList,True)
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-06 19:24:52 +00:00
followPerson(baseDir,nickname,domain,'maxboardroom',domain,federationList,True)
followPerson(baseDir,'drokk',domain,'ultrapancake',domain,federationList,True)
# deliberate duplication
2019-07-06 19:24:52 +00:00
followPerson(baseDir,'drokk',domain,'ultrapancake',domain,federationList,True)
followPerson(baseDir,'sausagedog',domain,'ultrapancake',domain,federationList,True)
followPerson(baseDir,nickname,domain,'ultrapancake',domain,federationList,True)
followPerson(baseDir,nickname,domain,'someother','randodomain.net',federationList,True)
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-06 19:24:52 +00:00
followPerson(baseDir,'drokk',otherdomain,nickname,domain,federationList,True)
followPerson(baseDir,'sausagedog',otherdomain,nickname,domain,federationList,True)
followPerson(baseDir,'maxboardroom',otherdomain,nickname,domain,federationList,True)
2019-07-06 19:24:52 +00:00
followerOfPerson(baseDir,nickname,domain,'cucumber','sandwiches.party',federationList,True)
followerOfPerson(baseDir,nickname,domain,'captainsensible','damned.zone',federationList,True)
followerOfPerson(baseDir,nickname,domain,'pilchard','zombies.attack',federationList,True)
followerOfPerson(baseDir,nickname,domain,'drokk',otherdomain,federationList,True)
followerOfPerson(baseDir,nickname,domain,'sausagedog',otherdomain,federationList,True)
followerOfPerson(baseDir,nickname,domain,'maxboardroom',otherdomain,federationList,True)
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')
2019-07-03 10:04:23 +00:00
setPreferredNickname(baseDir,nickname,domain,'badger')
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-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-06-30 21:20:02 +00:00
def runAllTests():
print('Running tests...')
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-03 18:24:44 +00:00
print('Tests succeeded\n')