Resolving recipients

master
Bob Mottram 2019-07-08 23:12:24 +01:00
parent 7106ad84e6
commit 5d9f972a5d
3 changed files with 116 additions and 41 deletions

View File

@ -350,22 +350,21 @@ def sendFollowRequest(session,baseDir: str, \
return newFollowJson
def getFollowersOfActor(baseDir :str,actor :str) -> []:
def getFollowersOfActor(baseDir :str,actor :str,recipientsDict: {}) -> {}:
"""In a shared inbox if we receive a post we know who it's from
and if it's addressed to followers then we need to get a list of those.
This returns a list of account handles which follow the given actor
and also the corresponding capability id if it exists
"""
result=[]
if ':' not in actor:
return result
return recipientsDict
httpPrefix=actor.split(':')[0]
nickname=getNicknameFromActor(actor)
if not nickname:
return result
return recipientsDict
domain,port=getDomainFromActor(actor)
if not domain:
return result
return recipientsDict
actorHandle=nickname+'@'+domain
# for each of the accounts
for subdir, dirs, files in os.walk(baseDir+'/accounts'):
@ -375,14 +374,14 @@ def getFollowersOfActor(baseDir :str,actor :str) -> []:
if os.path.isfile(followingFilename):
# does this account follow the given actor?
if actorHandle in open(followingFilename).read():
ocapFilename=baseDir+'/accounts/'+account+'/ocap/granted/'+httpPrefix+':##'+domain+':'+str(port)+'#users#'+nickname+'.json'
ocapFilename=baseDir+'/accounts/'+account+'/ocap/accept/'+httpPrefix+':##'+domain+':'+str(port)+'#users#'+nickname+'.json'
if os.path.isfile(ocapFilename):
with open(ocapFilename, 'r') as fp:
ocapJson=commentjson.load(fp)
if ocapJson.get('id'):
result.append([account,ocapJson['id']])
recipientsDict[account]=ocapJson['id']
else:
result.append([account,None])
recipientsDict[account]=None
else:
result.append([account,None])
return result
recipientsDict[account]=None
return recipientsDict

130
inbox.py
View File

@ -149,29 +149,6 @@ def savePostToInboxQueue(baseDir: str,httpPrefix: str,nickname: str, domain: str
commentjson.dump(newQueueItem, fp, indent=4, sort_keys=False)
return filename
def postedToFollowers(postJsonObject: {}) -> bool:
"""Is the given post sent to followers
"""
if postJsonObject.get('object'):
if postJsonObject['object'].get('to'):
for recipient in postJsonObject['object']['to']:
if 'followers' in recipient:
return True
if postJsonObject['object'].get('cc'):
for recipient in postJsonObject['object']['cc']:
if 'followers' in recipient:
return True
if postJsonObject.get('to'):
for recipient in postJsonObject['to']:
if 'followers' in recipient:
return True
if postJsonObject.get('cc'):
for recipient in postJsonObject['cc']:
if 'followers' in recipient:
return True
return False
def inboxCheckCapabilities(baseDir :str,nickname :str,domain :str, \
actor: str,queue: [],queueJson: {}, \
capabilityId: str,debug : bool) -> bool:
@ -225,6 +202,103 @@ def inboxCheckCapabilities(baseDir :str,nickname :str,domain :str, \
print('DEBUG: object capabilities check success')
return True
def inboxPostRecipientsAdd(baseDir :str,httpPrefix :str,toList :[], \
recipientsDict :{}, \
domainMatch: str,domain :str, \
actor :str) -> bool:
"""Given a list of post recipients (toList) from 'to' or 'cc' parameters
populate a recipientsDict with the handle and capabilities id for each
"""
followerRecipients=False
for recipient in toList:
# is this a to a local account?
if domainMatch in recipient:
# get the handle for the local account
nickname=recipient.split(domainMatch)[1]
handle=nickname+'@'+domain
if os.path.isdir(baseDir+'/accounts/'+handle):
# are capabilities granted for this account to the
# sender (actor) of the post?
ocapFilename=baseDir+'/accounts/'+handle+'/ocap/accept/'+actor.replace('/','#')+'.json'
if os.path.isfile(ocapFilename):
# read the granted capabilities and obtain the id
with open(ocapFilename, 'r') as fp:
ocapJson=commentjson.load(fp)
if ocapJson.get('id'):
# append with the capabilities id
recipientsDict[handle]=ocapJson['id']
else:
recipientsDict[handle]=None
else:
recipientsDict[handle]=None
if recipient.endswith('followers'):
followerRecipients=True
return followerRecipients,recipientsDict
def inboxPostRecipients(baseDir :str,postJsonObject :{},httpPrefix :str,domain : str,port :int) -> []:
recipientsDict={}
if not postJsonObject.get('actor'):
return recipientsDict
if ':' in domain:
domain=domain.split(':')[0]
domainBase=domain
if port!=80 and port!=443:
domain=domain+':'+str(port)
domainMatch='/'+domain+'/users/'
actor = postJsonObject['actor']
# first get any specific people which the post is addressed to
followerRecipients=False
if postJsonObject.get('object'):
if isinstance(postJsonObject['object'], dict):
if postJsonObject['object'].get('to'):
includesFollowers,recipientsDict= \
inboxPostRecipientsAdd(baseDir,httpPrefix, \
postJsonObject['object']['to'], \
recipientsDict, \
domainMatch,domainBase,actor)
if includesFollowers:
followerRecipients=True
if postJsonObject['object'].get('cc'):
includesFollowers,recipientsDict= \
inboxPostRecipientsAdd(baseDir,httpPrefix, \
postJsonObject['object']['cc'], \
recipientsDict, \
domainMatch,domainBase,actor)
if includesFollowers:
followerRecipients=True
if postJsonObject.get('to'):
includesFollowers,recipientsDict= \
inboxPostRecipientsAdd(baseDir,httpPrefix, \
postJsonObject['to'], \
recipientsDict, \
domainMatch,domainBase,actor)
if includesFollowers:
followerRecipients=True
if postJsonObject.get('cc'):
includesFollowers,recipientsDict= \
inboxPostRecipientsAdd(baseDir,httpPrefix, \
postJsonObject['cc'], \
recipientsDict, \
domainMatch,domainBase,actor)
if includesFollowers:
followerRecipients=True
if not followerRecipients:
return recipientsDict
# now resolve the followers
recipientsDict= \
getFollowersOfActor(baseDir,actor,recipientsDict)
return recipientsDict
def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [],cachedWebfingers: {},personCache: {},queue: [],domain: str,port: int,useTor: bool,federationList: [],ocapAlways: bool,ocapGranted: {},debug: bool) -> None:
"""Processes received items and moves them to
the appropriate directories
@ -256,11 +330,19 @@ def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [],cache
with open(queueFilename, 'r') as fp:
queueJson=commentjson.load(fp)
# get recipients list
recipientsDict=inboxPostRecipients(baseDir,queueJson['post'],httpPrefix,domain,port)
print('*************************************')
print('Resolved recipients list:')
pprint(recipientsDict)
print('*************************************')
sentToSharedInbox=False
followerOcap=[]
if queueJson['post'].get('actor'):
# get the followers of this actor and their capabilities ids
followerOcap=getFollowersOfActor(baseDir,queueJson['post']['actor'])
#followerOcap=getFollowersOfActor(baseDir,queueJson['post']['actor'])
if queueJson['post']['actor'].endswith('/inbox'):
sentToSharedInbox=True

View File

@ -360,12 +360,6 @@ def testFollowBetweenServers():
if os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/ocap/granted/'+httpPrefix+':##'+bobDomain+':'+str(bobPort)+'#users#bob.json'):
break
time.sleep(1)
actorFollows=getFollowersOfActor(aliceDir,httpPrefix+'://'+bobDomain+':'+str(bobPort)+'/users/bob')
print(str(actorFollows))
assert len(actorFollows)==1
assert actorFollows[0][0]=='alice@'+aliceDomain
assert actorFollows[0][1].startswith(httpPrefix+'://'+bobDomain+':'+str(bobPort)+'/caps/')
print('\n\nEve tries to send to Bob')
sessionEve = createSession(eveDomain,evePort,useTor)
@ -437,7 +431,7 @@ def testFollowBetweenServers():
assert 'bob@'+bobDomain in open(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt').read()
os.chdir(baseDir)
shutil.rmtree(baseDir+'/.tests')
#shutil.rmtree(baseDir+'/.tests')
def testFollowersOfPerson():
print('testFollowersOfPerson')