forked from indymedia/epicyon
Follow request test passes
parent
755d28f3e1
commit
03ecaf9a8a
|
@ -14,18 +14,22 @@ from utils import urlPermitted
|
|||
from utils import getDomainFromActor
|
||||
from utils import getNicknameFromActor
|
||||
from utils import domainPermitted
|
||||
from utils import followPerson
|
||||
|
||||
def createAcceptReject(baseDir: str,federationList: [],capsList: [], \
|
||||
nickname: str,domain: str,port: int, \
|
||||
toUrl: str,ccUrl: str,httpPrefix: str, \
|
||||
objectUrl: str,acceptType: str) -> {}:
|
||||
objectJson: {},acceptType: str) -> {}:
|
||||
"""Accepts or rejects something (eg. a follow request or offer)
|
||||
Typically toUrl will be https://www.w3.org/ns/activitystreams#Public
|
||||
and ccUrl might be a specific person favorited or repeated and
|
||||
the followers url objectUrl is typically the url of the message,
|
||||
corresponding to url or atomUri in createPostBase
|
||||
"""
|
||||
if not urlPermitted(objectUrl,federationList,capsList,"inbox:write"):
|
||||
if not objectJson.get('actor'):
|
||||
return None
|
||||
|
||||
if not urlPermitted(objectJson['actor'],federationList,capsList,"inbox:write"):
|
||||
return None
|
||||
|
||||
if port!=80 and port!=443:
|
||||
|
@ -36,7 +40,7 @@ def createAcceptReject(baseDir: str,federationList: [],capsList: [], \
|
|||
'actor': httpPrefix+'://'+domain+'/users/'+nickname,
|
||||
'to': [toUrl],
|
||||
'cc': [],
|
||||
'object': objectUrl
|
||||
'object': objectJson
|
||||
}
|
||||
if ccUrl:
|
||||
if len(ccUrl)>0:
|
||||
|
@ -46,22 +50,82 @@ def createAcceptReject(baseDir: str,federationList: [],capsList: [], \
|
|||
def createAccept(baseDir: str,federationList: [],capsList: [], \
|
||||
nickname: str,domain: str,port: int, \
|
||||
toUrl: str,ccUrl: str,httpPrefix: str, \
|
||||
objectUrl: str) -> {}:
|
||||
objectJson: {}) -> {}:
|
||||
return createAcceptReject(baseDir,federationList,capsList, \
|
||||
nickname,domain,port, \
|
||||
toUrl,ccUrl,httpPrefix, \
|
||||
objectUrl,'Accept')
|
||||
objectJson,'Accept')
|
||||
|
||||
def createReject(baseDir: str,federationList: [],capsList: [], \
|
||||
nickname: str,domain: str,port: int, \
|
||||
toUrl: str,ccUrl: str,httpPrefix: str, \
|
||||
objectUrl: str) -> {}:
|
||||
objectJson: {}) -> {}:
|
||||
return createAcceptReject(baseDir,federationList,capsList, \
|
||||
nickname,domain,port, \
|
||||
toUrl,ccUrl, \
|
||||
httpPrefix,objectUrl,'Reject')
|
||||
httpPrefix,objectJson,'Reject')
|
||||
|
||||
def receiveAcceptReject(session,baseDir: str,httpPrefix: str,port: int, \
|
||||
def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
|
||||
federationList: [],capsList: [],debug : bool) -> None:
|
||||
if not messageJson.get('object'):
|
||||
return
|
||||
if not messageJson['object'].get('type'):
|
||||
return
|
||||
if not messageJson['object'].get('actor'):
|
||||
return
|
||||
# no, this isn't a mistake
|
||||
if not messageJson['object'].get('object'):
|
||||
return
|
||||
if not messageJson['object']['type']=='Follow':
|
||||
return
|
||||
if debug:
|
||||
print('DEBUG: follow Accept received')
|
||||
thisActor=messageJson['object']['actor']
|
||||
nickname=getNicknameFromActor(thisActor)
|
||||
acceptedDomain,acceptedPort=getDomainFromActor(thisActor)
|
||||
if not acceptedDomain:
|
||||
if debug:
|
||||
print('DEBUG: domain not found in '+thisActor)
|
||||
return
|
||||
if acceptedDomain != domain:
|
||||
if debug:
|
||||
print('DEBUG: domain mismatch '+acceptedDomain+' != '+domain)
|
||||
return
|
||||
if not nickname:
|
||||
if debug:
|
||||
print('DEBUG: nickname not found in '+thisActor)
|
||||
return
|
||||
if acceptedPort:
|
||||
if not '/'+domain+':'+str(acceptedPort)+'/users/'+nickname in thisActor:
|
||||
if debug:
|
||||
print('DEBUG: unrecognized actor '+thisActor)
|
||||
return
|
||||
else:
|
||||
if not '/'+domain+'/users/'+nickname in thisActor:
|
||||
if debug:
|
||||
print('DEBUG: unrecognized actor '+thisActor)
|
||||
return
|
||||
followedActor=messageJson['object']['object']
|
||||
followedDomain,port=getDomainFromActor(followedActor)
|
||||
if not followedDomain:
|
||||
return
|
||||
followedDomainFull=followedDomain
|
||||
if port:
|
||||
followedDomainFull=followedDomain+':'+str(port)
|
||||
followedNickname=getNicknameFromActor(followedActor)
|
||||
if not followedNickname:
|
||||
return
|
||||
if followPerson(baseDir,nickname,domain, \
|
||||
followedNickname,followedDomain, \
|
||||
federationList,debug):
|
||||
if debug:
|
||||
print('DEBUG: '+nickname+'@'+domain+' followed '+followedNickname+'@'+followedDomain)
|
||||
else:
|
||||
if debug:
|
||||
print('DEBUG: Unable to create follow - '+nickname+'@'+domain+' -> '+followedNickname+'@'+followedDomain)
|
||||
|
||||
def receiveAcceptReject(session,baseDir: str, \
|
||||
httpPrefix: str,domain :str,port: int, \
|
||||
sendThreads: [],postLog: [],cachedWebfingers: {}, \
|
||||
personCache: {},messageJson: {},federationList: [], \
|
||||
capsList: [],debug : bool) -> bool:
|
||||
|
@ -88,10 +152,7 @@ def receiveAcceptReject(session,baseDir: str,httpPrefix: str,port: int, \
|
|||
print('DEBUG: '+messageJson['type']+' does not contain a nickname')
|
||||
return False
|
||||
handle=nickname.lower()+'@'+domain.lower()
|
||||
if '/users/' not in messageJson['object']:
|
||||
if debug:
|
||||
print('DEBUG: "users" not found within object of '+messageJson['type'])
|
||||
return False
|
||||
acceptFollow(baseDir,domain,messageJson,federationList,capsList,debug)
|
||||
if debug:
|
||||
print('DEBUG: Uh, '+messageJson['type']+', I guess')
|
||||
return True
|
||||
|
|
|
@ -34,7 +34,7 @@ from daemon import runDaemon
|
|||
import socket
|
||||
from follow import clearFollows
|
||||
from follow import clearFollowers
|
||||
from follow import followPerson
|
||||
from utils import followPerson
|
||||
from follow import followerOfPerson
|
||||
from follow import unfollowPerson
|
||||
from follow import unfollowerOfPerson
|
||||
|
|
54
follow.py
54
follow.py
|
@ -14,6 +14,8 @@ from person import validNickname
|
|||
from utils import domainPermitted
|
||||
from utils import getDomainFromActor
|
||||
from utils import getNicknameFromActor
|
||||
from utils import getStatusNumber
|
||||
from utils import followPerson
|
||||
from posts import sendSignedJson
|
||||
from capabilities import isCapable
|
||||
from acceptreject import createAccept
|
||||
|
@ -43,39 +45,14 @@ def getFollowersOfPerson(baseDir: str, \
|
|||
break
|
||||
return followers
|
||||
|
||||
def followPerson(baseDir: str,nickname: str, domain: str, \
|
||||
followNickname: str, followDomain: str, \
|
||||
federationList: [], followFile='following.txt') -> bool:
|
||||
"""Adds a person to the follow list
|
||||
"""
|
||||
if not domainPermitted(followDomain.lower().replace('\n',''), \
|
||||
federationList):
|
||||
return False
|
||||
handle=nickname.lower()+'@'+domain.lower()
|
||||
handleToFollow=followNickname.lower()+'@'+followDomain.lower()
|
||||
if not os.path.isdir(baseDir+'/accounts'):
|
||||
os.mkdir(baseDir+'/accounts')
|
||||
if not os.path.isdir(baseDir+'/accounts/'+handle):
|
||||
os.mkdir(baseDir+'/accounts/'+handle)
|
||||
filename=baseDir+'/accounts/'+handle+'/'+followFile
|
||||
if os.path.isfile(filename):
|
||||
if handleToFollow in open(filename).read():
|
||||
return True
|
||||
with open(filename, "a") as followfile:
|
||||
followfile.write(handleToFollow+'\n')
|
||||
return True
|
||||
with open(filename, "w") as followfile:
|
||||
followfile.write(handleToFollow+'\n')
|
||||
return True
|
||||
|
||||
def followerOfPerson(baseDir: str,nickname: str, domain: str, \
|
||||
followerNickname: str, followerDomain: str, \
|
||||
federationList: []) -> bool:
|
||||
federationList: [],debug :bool) -> bool:
|
||||
"""Adds a follower of the given person
|
||||
"""
|
||||
return followPerson(baseDir,nickname, domain, \
|
||||
followerNickname, followerDomain, \
|
||||
federationList, 'followers.txt')
|
||||
return followPerson(baseDir,nickname,domain, \
|
||||
followerNickname,followerDomain, \
|
||||
federationList,debug,'followers.txt')
|
||||
|
||||
def unfollowPerson(baseDir: str,nickname: str, domain: str, \
|
||||
followNickname: str, followDomain: str, \
|
||||
|
@ -293,7 +270,7 @@ def receiveFollowRequest(session,baseDir: str,httpPrefix: str, \
|
|||
baseDir+'/accounts/'+handleToFollow)
|
||||
return False
|
||||
if not followerOfPerson(baseDir,nicknameToFollow,domainToFollow, \
|
||||
nickname,domain,federationList):
|
||||
nickname,domain,federationList,debug):
|
||||
if debug:
|
||||
print('DEBUG: '+nickname+'@'+domain+ \
|
||||
' is already a follower of '+ \
|
||||
|
@ -306,7 +283,7 @@ def receiveFollowRequest(session,baseDir: str,httpPrefix: str, \
|
|||
personUrl=messageJson['actor']
|
||||
acceptJson=createAccept(baseDir,federationList,capsList, \
|
||||
nickname,domain,port, \
|
||||
personUrl,'',httpPrefix,messageJson['object'])
|
||||
personUrl,'',httpPrefix,messageJson)
|
||||
if debug:
|
||||
pprint(acceptJson)
|
||||
print('DEBUG: sending follow Accept from '+ \
|
||||
|
@ -346,15 +323,24 @@ def sendFollowRequest(session,baseDir: str, \
|
|||
if capsList:
|
||||
if not isCapable(followActor,capsList,'inbox:write'):
|
||||
return None
|
||||
|
||||
|
||||
statusNumber,published = getStatusNumber()
|
||||
|
||||
followedId=followHttpPrefix+'://'+requestDomain+'/users/'+followNickname
|
||||
|
||||
newFollowJson = {
|
||||
'id': httpPrefix+'://'+domain+'/users/'+nickname+'/statuses/'+statusNumber,
|
||||
'type': 'Follow',
|
||||
'actor': followActor,
|
||||
'object': followHttpPrefix+'://'+requestDomain+'/users/'+followNickname
|
||||
'object': followedId,
|
||||
'to': [followedId],
|
||||
'cc': ['https://www.w3.org/ns/activitystreams#Public'],
|
||||
'published': published
|
||||
}
|
||||
|
||||
sendSignedJson(newFollowJson,session,baseDir,nickname,domain,port, \
|
||||
followNickname,followDomain,followPort, '', \
|
||||
followNickname,followDomain,followPort, \
|
||||
'https://www.w3.org/ns/activitystreams#Public', \
|
||||
httpPrefix,True,clientToServer, \
|
||||
federationList, capsList, \
|
||||
sendThreads,postLog,cachedWebfingers,personCache, debug)
|
||||
|
|
2
inbox.py
2
inbox.py
|
@ -241,7 +241,7 @@ def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [],cache
|
|||
continue
|
||||
|
||||
if receiveAcceptReject(session, \
|
||||
baseDir,httpPrefix,port, \
|
||||
baseDir,httpPrefix,domain,port, \
|
||||
sendThreads,postLog, \
|
||||
cachedWebfingers,
|
||||
personCache,
|
||||
|
|
63
tests.py
63
tests.py
|
@ -26,7 +26,7 @@ from posts import archivePosts
|
|||
from posts import noOfFollowersOnDomain
|
||||
from follow import clearFollows
|
||||
from follow import clearFollowers
|
||||
from follow import followPerson
|
||||
from utils import followPerson
|
||||
from follow import followerOfPerson
|
||||
from follow import unfollowPerson
|
||||
from follow import unfollowerOfPerson
|
||||
|
@ -123,8 +123,8 @@ def createServerAlice(path: str,domain: str,port: int,federationList: [],capsLis
|
|||
deleteAllPosts(path,nickname,domain,'inbox')
|
||||
deleteAllPosts(path,nickname,domain,'outbox')
|
||||
if hasFollows:
|
||||
followPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList)
|
||||
followerOfPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList)
|
||||
followPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList,True)
|
||||
followerOfPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList,True)
|
||||
if hasPosts:
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "No wise fish would go anywhere without a porpoise", False, True, clientToServer,capsList)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "Curiouser and curiouser!", False, True, clientToServer,capsList)
|
||||
|
@ -149,8 +149,8 @@ def createServerBob(path: str,domain: str,port: int,federationList: [],capsList:
|
|||
deleteAllPosts(path,nickname,domain,'inbox')
|
||||
deleteAllPosts(path,nickname,domain,'outbox')
|
||||
if hasFollows:
|
||||
followPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList)
|
||||
followerOfPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList)
|
||||
followPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList,True)
|
||||
followerOfPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList,True)
|
||||
if hasPosts:
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "It's your life, live it your way.", False, True, clientToServer,capsList)
|
||||
createPublicPost(path,nickname, domain, port,httpPrefix, "One of the things I've realised is that I am very simple", False, True, clientToServer,capsList)
|
||||
|
@ -312,7 +312,8 @@ def testFollowBetweenServers():
|
|||
|
||||
for t in range(10):
|
||||
if os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt'):
|
||||
break
|
||||
if os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt'):
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
# stop the servers
|
||||
|
@ -351,13 +352,13 @@ def testFollowersOfPerson():
|
|||
createPerson(baseDir,'sausagedog',domain,port,httpPrefix,True,password)
|
||||
|
||||
clearFollows(baseDir,nickname,domain)
|
||||
followPerson(baseDir,nickname,domain,'maxboardroom',domain,federationList)
|
||||
followPerson(baseDir,'drokk',domain,'ultrapancake',domain,federationList)
|
||||
followPerson(baseDir,nickname,domain,'maxboardroom',domain,federationList,True)
|
||||
followPerson(baseDir,'drokk',domain,'ultrapancake',domain,federationList,True)
|
||||
# deliberate duplication
|
||||
followPerson(baseDir,'drokk',domain,'ultrapancake',domain,federationList)
|
||||
followPerson(baseDir,'sausagedog',domain,'ultrapancake',domain,federationList)
|
||||
followPerson(baseDir,nickname,domain,'ultrapancake',domain,federationList)
|
||||
followPerson(baseDir,nickname,domain,'someother','randodomain.net',federationList)
|
||||
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
|
||||
|
@ -388,16 +389,16 @@ def testNoOfFollowersOnDomain():
|
|||
createPerson(baseDir,'drokk',otherdomain,port,httpPrefix,True,password)
|
||||
createPerson(baseDir,'sausagedog',otherdomain,port,httpPrefix,True,password)
|
||||
|
||||
followPerson(baseDir,'drokk',otherdomain,nickname,domain,federationList)
|
||||
followPerson(baseDir,'sausagedog',otherdomain,nickname,domain,federationList)
|
||||
followPerson(baseDir,'maxboardroom',otherdomain,nickname,domain,federationList)
|
||||
followPerson(baseDir,'drokk',otherdomain,nickname,domain,federationList,True)
|
||||
followPerson(baseDir,'sausagedog',otherdomain,nickname,domain,federationList,True)
|
||||
followPerson(baseDir,'maxboardroom',otherdomain,nickname,domain,federationList,True)
|
||||
|
||||
followerOfPerson(baseDir,nickname,domain,'cucumber','sandwiches.party',federationList)
|
||||
followerOfPerson(baseDir,nickname,domain,'captainsensible','damned.zone',federationList)
|
||||
followerOfPerson(baseDir,nickname,domain,'pilchard','zombies.attack',federationList)
|
||||
followerOfPerson(baseDir,nickname,domain,'drokk',otherdomain,federationList)
|
||||
followerOfPerson(baseDir,nickname,domain,'sausagedog',otherdomain,federationList)
|
||||
followerOfPerson(baseDir,nickname,domain,'maxboardroom',otherdomain,federationList)
|
||||
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
|
||||
|
@ -426,11 +427,11 @@ def testFollows():
|
|||
createPerson(baseDir,nickname,domain,port,httpPrefix,True,password)
|
||||
|
||||
clearFollows(baseDir,nickname,domain)
|
||||
followPerson(baseDir,nickname,domain,'badger','wild.com',federationList)
|
||||
followPerson(baseDir,nickname,domain,'squirrel','secret.com',federationList)
|
||||
followPerson(baseDir,nickname,domain,'rodent','drainpipe.com',federationList)
|
||||
followPerson(baseDir,nickname,domain,'batman','mesh.com',federationList)
|
||||
followPerson(baseDir,nickname,domain,'giraffe','trees.com',federationList)
|
||||
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)
|
||||
|
||||
f = open(baseDir+'/accounts/'+nickname+'@'+domain+'/following.txt', "r")
|
||||
domainFound=False
|
||||
|
@ -453,11 +454,11 @@ def testFollows():
|
|||
assert(domainFound==False)
|
||||
|
||||
clearFollowers(baseDir,nickname,domain)
|
||||
followerOfPerson(baseDir,nickname,domain,'badger','wild.com',federationList)
|
||||
followerOfPerson(baseDir,nickname,domain,'squirrel','secret.com',federationList)
|
||||
followerOfPerson(baseDir,nickname,domain,'rodent','drainpipe.com',federationList)
|
||||
followerOfPerson(baseDir,nickname,domain,'batman','mesh.com',federationList)
|
||||
followerOfPerson(baseDir,nickname,domain,'giraffe','trees.com',federationList)
|
||||
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)
|
||||
|
||||
f = open(baseDir+'/accounts/'+nickname+'@'+domain+'/followers.txt', "r")
|
||||
for followerDomain in f:
|
||||
|
|
28
utils.py
28
utils.py
|
@ -80,4 +80,30 @@ def getDomainFromActor(actor: str) -> (str,int):
|
|||
domain=domain.split(':')[0]
|
||||
return domain,port
|
||||
|
||||
|
||||
def followPerson(baseDir: str,nickname: str, domain: str, \
|
||||
followNickname: str, followDomain: str, \
|
||||
federationList: [],debug: bool, \
|
||||
followFile='following.txt') -> bool:
|
||||
"""Adds a person to the follow list
|
||||
"""
|
||||
if not domainPermitted(followDomain.lower().replace('\n',''), \
|
||||
federationList):
|
||||
if debug:
|
||||
print('DEBUG: follow of domain '+followDomain+' not permitted')
|
||||
return False
|
||||
handle=nickname.lower()+'@'+domain.lower()
|
||||
handleToFollow=followNickname.lower()+'@'+followDomain.lower()
|
||||
if not os.path.isdir(baseDir+'/accounts'):
|
||||
os.mkdir(baseDir+'/accounts')
|
||||
if not os.path.isdir(baseDir+'/accounts/'+handle):
|
||||
os.mkdir(baseDir+'/accounts/'+handle)
|
||||
filename=baseDir+'/accounts/'+handle+'/'+followFile
|
||||
if os.path.isfile(filename):
|
||||
if handleToFollow in open(filename).read():
|
||||
return True
|
||||
with open(filename, "a") as followfile:
|
||||
followfile.write(handleToFollow+'\n')
|
||||
return True
|
||||
with open(filename, "w") as followfile:
|
||||
followfile.write(handleToFollow+'\n')
|
||||
return True
|
||||
|
|
Loading…
Reference in New Issue