forked from indymedia/epicyon
Test for announce via c2s
parent
53d68cd10d
commit
a819c4ae57
79
announce.py
79
announce.py
|
@ -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
|
||||||
|
|
10
daemon.py
10
daemon.py
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
42
posts.py
42
posts.py
|
@ -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'):
|
||||||
|
|
36
tests.py
36
tests.py
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue