Send accept message after follow

master
Bob Mottram 2019-07-05 19:57:19 +01:00
parent f805786f9a
commit d257b59c3a
4 changed files with 89 additions and 9 deletions

View File

@ -446,7 +446,9 @@ def runDaemon(baseDir: str,domain: str,port=80,httpPrefix='https',fedList=[],use
httpd.POSTbusy=False
httpd.receivedMessage=False
httpd.inboxQueue=[]
httpd.sendThreads=[]
httpd.postLog=[]
print('Running ActivityPub daemon on ' + domain + ' port ' + str(port))
httpd.thrInboxQueue=threadWithTrace(target=runInboxQueue,args=(baseDir,httpPrefix,httpd.personCache,httpd.inboxQueue,domain,port,useTor,httpd.federationList,debug),daemon=True)
httpd.thrInboxQueue=threadWithTrace(target=runInboxQueue,args=(baseDir,httpPrefix,httpd.sendThreads,httpd.postLog,httpd.cachedWebfingers,httpd.personCache,httpd.inboxQueue,domain,port,useTor,httpd.federationList,debug),daemon=True)
httpd.thrInboxQueue.start()
httpd.serve_forever()

View File

@ -12,6 +12,7 @@ import os
import sys
from person import validNickname
from utils import domainPermitted
from posts import sendSignedJson
def getFollowersOfPerson(baseDir: str,nickname: str,domain: str,followFile='following.txt') -> []:
"""Returns a list containing the followers of the given person
@ -228,9 +229,11 @@ def getFollowingFeed(baseDir: str,domain: str,port: int,path: str,httpPrefix: st
following['next']=httpPrefix+'://'+domain+'/users/'+nickname+'/'+followFile+'?page='+str(lastPage)
return following
def receiveFollowRequest(baseDir: str,messageJson: {},federationList: []) -> bool:
def receiveFollowRequest(session,baseDir: str,httpPrefix: str,port: int,sendThreads: [],postLog: [],cachedWebfingers: {},personCache: {},messageJson: {},federationList: []) -> bool:
"""Receives a follow request within the POST section of HTTPServer
"""
if not messageJson.get('actor'):
return False
if not messageJson['type'].startswith('Follow'):
return False
if '/users/' not in messageJson['actor']:
@ -252,7 +255,16 @@ def receiveFollowRequest(baseDir: str,messageJson: {},federationList: []) -> boo
if domainToFollow==domain:
if not os.path.isdir(baseDir+'/accounts/'+handleToFollow):
return False
return followerOfPerson(baseDir,nickname,domain,nicknameToFollow,domainToFollow,federationList)
if not followerOfPerson(baseDir,nickname,domain,nicknameToFollow,domainToFollow,federationList):
return False
# send accept back
personUrl=messageJson['actor']
acceptJson=createAccept(baseDir,federationList,nickname,domain,port, \
personUrl,'',httpPrefix,messageJson['object'])
sendSignedJson(acceptJson,session,baseDir,nickname,domain,port, \
nicknameToFollow,domainToFollow,toPort, '', \
httpPrefix,saveToFile,clientToServer,federationList, \
sendThreads,postLog,cachedWebfingers,personCache)
def sendFollowRequest(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
followNickname: str,followDomain: str,followPort: bool,followHttpPrefix: str, \

View File

@ -129,7 +129,7 @@ def savePostToInboxQueue(baseDir: str,httpPrefix: str,nickname: str, domain: str
commentjson.dump(newQueueItem, fp, indent=4, sort_keys=False)
return filename
def runInboxQueue(baseDir: str,httpPrefix: str,personCache: {},queue: [],domain: str,port: int,useTor: bool,federationList: [],debug: bool) -> None:
def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [],cachedWebfingers: {},personCache: {},queue: [],domain: str,port: int,useTor: bool,federationList: [],debug: bool) -> None:
"""Processes received items and moves them to
the appropriate directories
"""
@ -211,15 +211,18 @@ def runInboxQueue(baseDir: str,httpPrefix: str,personCache: {},queue: [],domain:
if debug:
print('DEBUG: Signature check success')
if receiveFollowRequest(baseDir, \
if receiveFollowRequest(session, \
baseDir,httpPrefix,port, \
sendThreads,postLog, \
cachedWebfingers,
personCache,
queueJson['post'], \
federationList):
if debug:
print('DEBUG: Follow accepted from '+keyId)
os.remove(queueFilename)
queue.pop(0)
continue
os.remove(queueFilename)
queue.pop(0)
continue
if debug:
print('DEBUG: Queue post accepted')

View File

@ -521,6 +521,69 @@ def sendPost(session,baseDir: str,nickname: str, domain: str, port: int, \
thr.start()
return 0
def sendSignedJson(postJsonObject: {},session,baseDir: str,nickname: str, domain: str, port: int, \
toNickname: str, toDomain: str, toPort: int, cc: str, \
httpPrefix: str, saveToFile: bool, clientToServer: bool, federationList: [], \
sendThreads: [], postLog: [], cachedWebfingers: {},personCache: {}) -> int:
"""Sends a signed json object to an inbox/outbox
"""
withDigest=True
if toPort!=80 and toPort!=443:
toDomain=toDomain+':'+str(toPort)
handle=httpPrefix+'://'+toDomain+'/@'+toNickname
# lookup the inbox for the To handle
wfRequest = webfingerHandle(session,handle,httpPrefix,cachedWebfingers)
if not wfRequest:
return 1
# get the actor inbox for the To handle
inboxUrl,pubKeyId,pubKey,toPersonId,sharedInbox = \
getPersonBox(session,wfRequest,personCache,'inbox')
# If there are more than one followers on the target domain
# then send to teh shared inbox indead of the individual inbox
if noOfFollowersOnDomain(baseDir,handle,toDomain)>1 and sharedInbox:
inboxUrl=sharedInbox
if not inboxUrl:
return 2
if not pubKey:
return 3
if not toPersonId:
return 4
# get the senders private key
privateKeyPem=getPersonKey(nickname,domain,baseDir,'private')
if len(privateKeyPem)==0:
return 5
if not clientToServer:
postPath='/inbox'
else:
postPath='/outbox'
# construct the http header
signatureHeaderJson = \
createSignedHeader(privateKeyPem, nickname, domain, port, \
postPath, httpPrefix, withDigest, postJsonObject)
# Keep the number of threads being used small
while len(sendThreads)>10:
sendThreads[0].kill()
sendThreads.pop(0)
thr = threadWithTrace(target=threadSendPost,args=(session, \
postJsonObject.copy(), \
federationList, \
inboxUrl,baseDir, \
signatureHeaderJson.copy(), \
postLog),daemon=True)
sendThreads.append(thr)
thr.start()
return 0
def createInbox(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
itemsPerPage: int,headerOnly: bool,pageNumber=None) -> {}:
return createBoxBase(baseDir,'inbox',nickname,domain,port,httpPrefix, \