Test for announce via c2s

master
Bob Mottram 2019-07-16 20:07:45 +01:00
parent 53d68cd10d
commit a819c4ae57
5 changed files with 149 additions and 22 deletions

View File

@ -14,6 +14,10 @@ from utils import urlPermitted
from utils import getNicknameFromActor from utils import getNicknameFromActor
from utils import getDomainFromActor from utils import getDomainFromActor
from posts import sendSignedJson from posts import sendSignedJson
from posts import getPersonBox
from session import postJson
from webfinger import webfingerHandle
from auth import createBasicAuthHeader
def createAnnounce(session,baseDir: str,federationList: [], \ def createAnnounce(session,baseDir: str,federationList: [], \
nickname: str, domain: str, port: int, \ nickname: str, domain: str, port: int, \
@ -229,3 +233,78 @@ def undoRepeatPost(session,baseDir: str,federationList: [], \
sendThreads,postLog, \ sendThreads,postLog, \
personCache,cachedWebfingers, \ personCache,cachedWebfingers, \
debug) debug)
def sendAnnounceViaServer(session,fromNickname: str,password: str,
fromDomain: str,fromPort: int, \
httpPrefix: str,repeatObjectUrl: str, \
cachedWebfingers: {},personCache: {}, \
debug: bool) -> {}:
"""Creates an announce message via c2s
"""
if not session:
print('WARN: No session for sendAnnounceViaServer')
return 6
withDigest=True
fromDomainFull=fromDomain
if fromPort!=80 and fromPort!=443:
fromDomainFull=fromDomain+':'+str(fromPort)
toUrl = 'https://www.w3.org/ns/activitystreams#Public'
ccUrl = httpPrefix + '://'+fromDomainFull+'/users/'+fromNickname+'/followers'
statusNumber,published = getStatusNumber()
newAnnounceId= \
httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname+'/statuses/'+statusNumber
newAnnounceJson = {
'actor': httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname,
'atomUri': newAnnounceId,
'cc': [ccUrl],
'id': newAnnounceId+'/activity',
'object': repeatObjectUrl,
'published': published,
'to': [toUrl],
'type': 'Announce'
}
handle=httpPrefix+'://'+fromDomainFull+'/@'+fromNickname
# lookup the inbox for the To handle
wfRequest = webfingerHandle(session,handle,httpPrefix,cachedWebfingers)
if not wfRequest:
if debug:
print('DEBUG: announce webfinger failed for '+handle)
return 1
postToBox='outbox'
# get the actor inbox for the To handle
inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition = \
getPersonBox(session,wfRequest,personCache,postToBox)
if not inboxUrl:
if debug:
print('DEBUG: No '+postToBox+' was found for '+handle)
return 3
if not fromPersonId:
if debug:
print('DEBUG: No actor was found for '+handle)
return 4
authHeader=createBasicAuthHeader(fromNickname,password)
headers = {'host': fromDomain, \
'Content-type': 'application/json', \
'Authorization': authHeader}
postResult = \
postJson(session,newAnnounceJson,[],inboxUrl,headers,"inbox:write")
#if not postResult:
# if debug:
# print('DEBUG: POST announce failed for c2s to '+inboxUrl)
# return 5
if debug:
print('DEBUG: c2s POST announce success')
return newAnnounceJson

View File

@ -703,15 +703,9 @@ class PubServer(BaseHTTPRequestHandler):
# https://www.w3.org/TR/activitypub/#object-without-create # https://www.w3.org/TR/activitypub/#object-without-create
if self.outboxAuthenticated: if self.outboxAuthenticated:
if self._postToOutbox(messageJson): if self._postToOutbox(messageJson):
if messageJson.get('object'): if messageJson.get('id'):
#self.send_header('Location', \
self.headers['Location']= \ self.headers['Location']= \
messageJson['object']['id'].replace('/activity','') messageJson['id'].replace('/activity','')
else:
if messageJson.get('id'):
#self.send_header('Location', \
self.headers['Location']= \
messageJson['id'].replace('/activity','')
self.send_response(201) self.send_response(201)
self.end_headers() self.end_headers()
self.server.POSTbusy=False self.server.POSTbusy=False

View File

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

View File

@ -305,8 +305,9 @@ def savePostToBox(baseDir: str,httpPrefix: str,postId: str, \
'/statuses/'+statusNumber '/statuses/'+statusNumber
postJsonObject['id']=postId+'/activity' postJsonObject['id']=postId+'/activity'
if postJsonObject.get('object'): if postJsonObject.get('object'):
postJsonObject['object']['id']=postId if isinstance(postJsonObject['object'], dict):
postJsonObject['object']['atomUri']=postId postJsonObject['object']['id']=postId
postJsonObject['object']['atomUri']=postId
boxDir = createPersonDir(nickname,domain,baseDir,boxname) boxDir = createPersonDir(nickname,domain,baseDir,boxname)
filename=boxDir+'/'+postId.replace('/','#')+'.json' filename=boxDir+'/'+postId.replace('/','#')+'.json'
@ -493,19 +494,29 @@ def postIsAddressedToFollowers(baseDir: str,
if not postJsonObject.get('object'): if not postJsonObject.get('object'):
return False return False
if not postJsonObject['object'].get('to'): toList=[]
return False ccList=[]
if isinstance(postJsonObject['object'], dict):
if not postJsonObject['object'].get('to'):
return False
toList=postJsonObject['object']['to']
if postJsonObject['object'].get('cc'):
ccList=postJsonObject['object']['cc']
else:
if not postJsonObject.get('to'):
return False
toList=postJsonObject['to']
if postJsonObject.get('cc'):
ccList=postJsonObject['cc']
followersUrl=httpPrefix+'://'+domain+'/users/'+nickname+'/followers' followersUrl=httpPrefix+'://'+domain+'/users/'+nickname+'/followers'
# does the followers url exist in 'to' or 'cc' lists? # does the followers url exist in 'to' or 'cc' lists?
addressedToFollowers=False addressedToFollowers=False
if followersUrl in postJsonObject['object']['to']: if followersUrl in toList:
addressedToFollowers=True addressedToFollowers=True
if not addressedToFollowers: if not addressedToFollowers:
if not postJsonObject['object'].get('cc'): if followersUrl in ccList:
return False
if followersUrl in postJsonObject['object']['cc']:
addressedToFollowers=True addressedToFollowers=True
return addressedToFollowers return addressedToFollowers
@ -872,13 +883,22 @@ def sendToNamedAddresses(session,baseDir: str, \
return return
if not postJsonObject.get('object'): if not postJsonObject.get('object'):
return return
if not postJsonObject['object'].get('to'): toList=[]
return if isinstance(postJsonObject['object'], dict):
if not postJsonObject['object'].get('to'):
return
toList=postJsonObject['object']['to']
recipientsObject=postJsonObject['object']
else:
if not postJsonObject.get('to'):
return
toList=postJsonObject['to']
recipientsObject=postJsonObject
recipients=[] recipients=[]
recipientType=['to','cc'] recipientType=['to','cc']
for rType in recipientType: for rType in recipientType:
for address in postJsonObject['object'][rType]: for address in recipientsObject[rType]:
if address.endswith('#Public'): if address.endswith('#Public'):
continue continue
if address.endswith('/followers'): if address.endswith('/followers'):

View File

@ -48,6 +48,7 @@ from auth import authorizeBasic
from auth import storeBasicCredentials from auth import storeBasicCredentials
from like import likePost from like import likePost
from announce import announcePublic from announce import announcePublic
from announce import sendAnnounceViaServer
from media import getMediaPath from media import getMediaPath
testServerAliceRunning = False testServerAliceRunning = False
@ -1043,7 +1044,7 @@ def testClientToServer():
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==1 assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==1
print(">>> c2s post arrived in Alice's outbox") print(">>> c2s post arrived in Alice's outbox")
for i in range(30): for i in range(30):
if os.path.isdir(inboxPath): if os.path.isdir(inboxPath):
if len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==1: if len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==1:
@ -1054,6 +1055,39 @@ def testClientToServer():
print(">>> s2s post arrived in Bob's inbox") print(">>> s2s post arrived in Bob's inbox")
print("c2s send success") print("c2s send success")
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)
print('\n\nBob repeats the post')
sessionBob = createSession(bobDomain,bobPort,useTor)
password='bobpass'
outboxPath=bobDir+'/accounts/bob@'+bobDomain+'/outbox'
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==0
sendAnnounceViaServer(sessionBob,'bob',password,
bobDomain,bobPort, \
httpPrefix,outboxPostId, \
cachedWebfingers,personCache, \
True)
for i in range(10):
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)
assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==1
print('Post repeated')
# stop the servers # stop the servers
thrAlice.kill() thrAlice.kill()
thrAlice.join() thrAlice.join()