mirror of https://gitlab.com/bashrc2/epicyon
Updating of capabilities
parent
1b10d7ef4b
commit
76e8167ce7
|
@ -18,7 +18,7 @@ from utils import getNicknameFromActor
|
||||||
from utils import domainPermitted
|
from utils import domainPermitted
|
||||||
from utils import followPerson
|
from utils import followPerson
|
||||||
|
|
||||||
def createAcceptReject(baseDir: str,federationList: [],ocapGranted: {}, \
|
def createAcceptReject(baseDir: str,federationList: [], \
|
||||||
nickname: str,domain: str,port: int, \
|
nickname: str,domain: str,port: int, \
|
||||||
toUrl: str,ccUrl: str,httpPrefix: str, \
|
toUrl: str,ccUrl: str,httpPrefix: str, \
|
||||||
objectJson: {},ocapJson,acceptType: str) -> {}:
|
objectJson: {},ocapJson,acceptType: str) -> {}:
|
||||||
|
@ -31,7 +31,7 @@ def createAcceptReject(baseDir: str,federationList: [],ocapGranted: {}, \
|
||||||
if not objectJson.get('actor'):
|
if not objectJson.get('actor'):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not urlPermitted(objectJson['actor'],federationList,ocapGranted,"inbox:write"):
|
if not urlPermitted(objectJson['actor'],federationList,"inbox:write"):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if port!=80 and port!=443:
|
if port!=80 and port!=443:
|
||||||
|
@ -52,28 +52,28 @@ def createAcceptReject(baseDir: str,federationList: [],ocapGranted: {}, \
|
||||||
newAccept['capabilities']=ocapJson
|
newAccept['capabilities']=ocapJson
|
||||||
return newAccept
|
return newAccept
|
||||||
|
|
||||||
def createAccept(baseDir: str,federationList: [],ocapGranted: {}, \
|
def createAccept(baseDir: str,federationList: [], \
|
||||||
nickname: str,domain: str,port: int, \
|
nickname: str,domain: str,port: int, \
|
||||||
toUrl: str,ccUrl: str,httpPrefix: str, \
|
toUrl: str,ccUrl: str,httpPrefix: str, \
|
||||||
objectJson: {}) -> {}:
|
objectJson: {}) -> {}:
|
||||||
# create capabilities accept
|
# create capabilities accept
|
||||||
ocapNew=capabilitiesAccept(baseDir,httpPrefix,nickname,domain,port,toUrl,True)
|
ocapNew=capabilitiesAccept(baseDir,httpPrefix,nickname,domain,port,toUrl,True)
|
||||||
return createAcceptReject(baseDir,federationList,ocapGranted, \
|
return createAcceptReject(baseDir,federationList, \
|
||||||
nickname,domain,port, \
|
nickname,domain,port, \
|
||||||
toUrl,ccUrl,httpPrefix, \
|
toUrl,ccUrl,httpPrefix, \
|
||||||
objectJson,ocapNew,'Accept')
|
objectJson,ocapNew,'Accept')
|
||||||
|
|
||||||
def createReject(baseDir: str,federationList: [],ocapGranted: {}, \
|
def createReject(baseDir: str,federationList: [], \
|
||||||
nickname: str,domain: str,port: int, \
|
nickname: str,domain: str,port: int, \
|
||||||
toUrl: str,ccUrl: str,httpPrefix: str, \
|
toUrl: str,ccUrl: str,httpPrefix: str, \
|
||||||
objectJson: {}) -> {}:
|
objectJson: {}) -> {}:
|
||||||
return createAcceptReject(baseDir,federationList,ocapGranted, \
|
return createAcceptReject(baseDir,federationList, \
|
||||||
nickname,domain,port, \
|
nickname,domain,port, \
|
||||||
toUrl,ccUrl, \
|
toUrl,ccUrl, \
|
||||||
httpPrefix,objectJson,None,'Reject')
|
httpPrefix,objectJson,None,'Reject')
|
||||||
|
|
||||||
def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
|
def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
|
||||||
federationList: [],ocapGranted: {},debug : bool) -> None:
|
federationList: [],debug : bool) -> None:
|
||||||
if not messageJson.get('object'):
|
if not messageJson.get('object'):
|
||||||
return
|
return
|
||||||
if not messageJson['object'].get('type'):
|
if not messageJson['object'].get('type'):
|
||||||
|
@ -161,7 +161,7 @@ def receiveAcceptReject(session,baseDir: str, \
|
||||||
httpPrefix: str,domain :str,port: int, \
|
httpPrefix: str,domain :str,port: int, \
|
||||||
sendThreads: [],postLog: [],cachedWebfingers: {}, \
|
sendThreads: [],postLog: [],cachedWebfingers: {}, \
|
||||||
personCache: {},messageJson: {},federationList: [], \
|
personCache: {},messageJson: {},federationList: [], \
|
||||||
ocapGranted: {},debug : bool) -> bool:
|
debug : bool) -> bool:
|
||||||
"""Receives an Accept or Reject within the POST section of HTTPServer
|
"""Receives an Accept or Reject within the POST section of HTTPServer
|
||||||
"""
|
"""
|
||||||
if messageJson['type']!='Accept' and messageJson['type']!='Reject':
|
if messageJson['type']!='Accept' and messageJson['type']!='Reject':
|
||||||
|
@ -185,7 +185,7 @@ def receiveAcceptReject(session,baseDir: str, \
|
||||||
print('DEBUG: '+messageJson['type']+' does not contain a nickname')
|
print('DEBUG: '+messageJson['type']+' does not contain a nickname')
|
||||||
return False
|
return False
|
||||||
handle=nickname.lower()+'@'+domain.lower()
|
handle=nickname.lower()+'@'+domain.lower()
|
||||||
acceptFollow(baseDir,domain,messageJson,federationList,ocapGranted,debug)
|
acceptFollow(baseDir,domain,messageJson,federationList,debug)
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: Uh, '+messageJson['type']+', I guess')
|
print('DEBUG: Uh, '+messageJson['type']+', I guess')
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -12,7 +12,7 @@ from utils import getStatusNumber
|
||||||
from utils import createOutboxDir
|
from utils import createOutboxDir
|
||||||
from utils import urlPermitted
|
from utils import urlPermitted
|
||||||
|
|
||||||
def createAnnounce(baseDir: str,federationList: [], ocapGranted: {}, \
|
def createAnnounce(baseDir: str,federationList: [], \
|
||||||
nickname: str, domain: str, port: int, \
|
nickname: str, domain: str, port: int, \
|
||||||
toUrl: str, ccUrl: str, httpPrefix: str, \
|
toUrl: str, ccUrl: str, httpPrefix: str, \
|
||||||
objectUrl: str, saveToFile: bool) -> {}:
|
objectUrl: str, saveToFile: bool) -> {}:
|
||||||
|
@ -22,7 +22,7 @@ def createAnnounce(baseDir: str,federationList: [], ocapGranted: {}, \
|
||||||
followers url objectUrl is typically the url of the message,
|
followers url objectUrl is typically the url of the message,
|
||||||
corresponding to url or atomUri in createPostBase
|
corresponding to url or atomUri in createPostBase
|
||||||
"""
|
"""
|
||||||
if not urlPermitted(objectUrl,federationList,ocapGranted,"inbox:write"):
|
if not urlPermitted(objectUrl,federationList,"inbox:write"):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if port!=80 and port!=443:
|
if port!=80 and port!=443:
|
||||||
|
|
|
@ -16,6 +16,9 @@ from utils import getNicknameFromActor
|
||||||
from utils import getDomainFromActor
|
from utils import getDomainFromActor
|
||||||
|
|
||||||
def getOcapFilename(baseDir :str,nickname: str,domain: str,actor :str,subdir: str) -> str:
|
def getOcapFilename(baseDir :str,nickname: str,domain: str,actor :str,subdir: str) -> str:
|
||||||
|
"""Returns the filename for a particular capability accepted or granted
|
||||||
|
Also creates directories as needed
|
||||||
|
"""
|
||||||
if ':' in domain:
|
if ':' in domain:
|
||||||
domain=domain.split(':')[0]
|
domain=domain.split(':')[0]
|
||||||
|
|
||||||
|
@ -151,3 +154,84 @@ def capabilitiesGrantedSave(baseDir :str,nickname :str,domain :str,ocap: {}) ->
|
||||||
with open(ocapFilename, 'w') as fp:
|
with open(ocapFilename, 'w') as fp:
|
||||||
commentjson.dump(ocap, fp, indent=4, sort_keys=False)
|
commentjson.dump(ocap, fp, indent=4, sort_keys=False)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def capabilitiesUpdate(baseDir: str,httpPrefix: str, \
|
||||||
|
nickname: str,domain: str, port: int, \
|
||||||
|
updateActor: str, \
|
||||||
|
updateCaps: []) -> {}:
|
||||||
|
"""Used to sends an update for a change of object capabilities
|
||||||
|
Note that the capability id gets changed with a new random token
|
||||||
|
so that the old capabilities can't continue to be used
|
||||||
|
"""
|
||||||
|
|
||||||
|
# reject excessively long actors
|
||||||
|
if len(updateActor)>256:
|
||||||
|
return None
|
||||||
|
|
||||||
|
fullDomain=domain
|
||||||
|
if port!=80 and port !=443:
|
||||||
|
fullDomain=domain+':'+str(port)
|
||||||
|
|
||||||
|
# Get the filename of the capability
|
||||||
|
ocapFilename=getOcapFilename(baseDir,nickname,fullDomain,updateActor,'accept')
|
||||||
|
|
||||||
|
# The capability should already exist for it to be updated
|
||||||
|
if not os.path.isfile(ocapFilename):
|
||||||
|
return None
|
||||||
|
|
||||||
|
# create an update activity
|
||||||
|
ocapUpdate = {
|
||||||
|
'type': 'Update',
|
||||||
|
'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname,
|
||||||
|
'to': [updateActor],
|
||||||
|
'cc': [],
|
||||||
|
'object': {}
|
||||||
|
}
|
||||||
|
|
||||||
|
# read the existing capability
|
||||||
|
with open(ocapFilename, 'r') as fp:
|
||||||
|
ocapJson=commentjson.load(fp)
|
||||||
|
|
||||||
|
# set the new capabilities list. eg. ["inbox:write","objects:read"]
|
||||||
|
ocapJson['capability']=updateCaps
|
||||||
|
|
||||||
|
# change the id, so that the old capabilities can't continue to be used
|
||||||
|
updateActorNickname=getNicknameFromActor(updateActor)
|
||||||
|
updateActorDomain,updateActorPort=getDomainFromActor(updateActor)
|
||||||
|
if updateActorPort:
|
||||||
|
ocapId=updateActorNickname+'@'+updateActorDomain+':'+str(updateActorPort)+'#'+createPassword(32)
|
||||||
|
else:
|
||||||
|
ocapId=updateActorNickname+'@'+updateActorDomain+'#'+createPassword(32)
|
||||||
|
ocapJson['id']=httpPrefix+"://"+fullDomain+"/caps/"+ocapId
|
||||||
|
ocapUpdate['object']=ocapJson
|
||||||
|
|
||||||
|
# save it again
|
||||||
|
with open(ocapFilename, 'w') as fp:
|
||||||
|
commentjson.dump(ocapJson, fp, indent=4, sort_keys=False)
|
||||||
|
|
||||||
|
return ocapUpdate
|
||||||
|
|
||||||
|
def capabilitiesReceiveUpdate(baseDir :str, \
|
||||||
|
nickname :str,domain :str,port :int, \
|
||||||
|
actor :str, \
|
||||||
|
newCapabilitiesId :str, \
|
||||||
|
capabilityList :[], debug :bool) -> bool:
|
||||||
|
"""An update for a capability or the given actor has arrived
|
||||||
|
"""
|
||||||
|
ocapFilename= \
|
||||||
|
getOcapFilename(baseDir,nickname,domain,actor,'granted')
|
||||||
|
if not os.path.isfile(ocapFilename):
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: capabilities file not found during update')
|
||||||
|
print(ocapFilename)
|
||||||
|
return False
|
||||||
|
|
||||||
|
with open(ocapFilename, 'r') as fp:
|
||||||
|
ocapJson=commentjson.load(fp)
|
||||||
|
ocapJson['id']=newCapabilitiesId
|
||||||
|
ocapJson['capability']=capabilityList
|
||||||
|
|
||||||
|
with open(ocapFilename, 'w') as fp:
|
||||||
|
commentjson.dump(ocapJson, fp, indent=4, sort_keys=False)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
|
@ -450,8 +450,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
if not inboxPermittedMessage(self.server.domain, \
|
if not inboxPermittedMessage(self.server.domain, \
|
||||||
messageJson, \
|
messageJson, \
|
||||||
self.server.federationList, \
|
self.server.federationList):
|
||||||
self.server.ocapGranted):
|
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
# https://www.youtube.com/watch?v=K3PrSj9XEu4
|
# https://www.youtube.com/watch?v=K3PrSj9XEu4
|
||||||
print('DEBUG: Ah Ah Ah')
|
print('DEBUG: Ah Ah Ah')
|
||||||
|
@ -498,7 +497,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.POSTbusy=False
|
self.server.POSTbusy=False
|
||||||
|
|
||||||
def runDaemon(baseDir: str,domain: str,port=80,httpPrefix='https', \
|
def runDaemon(baseDir: str,domain: str,port=80,httpPrefix='https', \
|
||||||
fedList=[],ocapAlways=False,ocapGranted={}, \
|
fedList=[],ocapAlways=False, \
|
||||||
useTor=False,debug=False) -> None:
|
useTor=False,debug=False) -> None:
|
||||||
if len(domain)==0:
|
if len(domain)==0:
|
||||||
domain='localhost'
|
domain='localhost'
|
||||||
|
@ -514,7 +513,6 @@ def runDaemon(baseDir: str,domain: str,port=80,httpPrefix='https', \
|
||||||
httpd.httpPrefix=httpPrefix
|
httpd.httpPrefix=httpPrefix
|
||||||
httpd.debug=debug
|
httpd.debug=debug
|
||||||
httpd.federationList=fedList.copy()
|
httpd.federationList=fedList.copy()
|
||||||
httpd.ocapGranted=ocapGranted.copy()
|
|
||||||
httpd.baseDir=baseDir
|
httpd.baseDir=baseDir
|
||||||
httpd.personCache={}
|
httpd.personCache={}
|
||||||
httpd.cachedWebfingers={}
|
httpd.cachedWebfingers={}
|
||||||
|
@ -538,6 +536,6 @@ def runDaemon(baseDir: str,domain: str,port=80,httpPrefix='https', \
|
||||||
httpd.personCache,httpd.inboxQueue, \
|
httpd.personCache,httpd.inboxQueue, \
|
||||||
domain,port,useTor,httpd.federationList, \
|
domain,port,useTor,httpd.federationList, \
|
||||||
httpd.ocapAlways, \
|
httpd.ocapAlways, \
|
||||||
httpd.ocapGranted,debug),daemon=True)
|
debug),daemon=True)
|
||||||
httpd.thrInboxQueue.start()
|
httpd.thrInboxQueue.start()
|
||||||
httpd.serve_forever()
|
httpd.serve_forever()
|
||||||
|
|
20
epicyon.py
20
epicyon.py
|
@ -320,8 +320,6 @@ else:
|
||||||
if configFederationList:
|
if configFederationList:
|
||||||
federationList=configFederationList
|
federationList=configFederationList
|
||||||
|
|
||||||
ocapGranted={}
|
|
||||||
|
|
||||||
if federationList:
|
if federationList:
|
||||||
print('Federating with: '+str(federationList))
|
print('Federating with: '+str(federationList))
|
||||||
|
|
||||||
|
@ -348,13 +346,13 @@ if args.testdata:
|
||||||
deleteAllPosts(baseDir,nickname,domain,'outbox')
|
deleteAllPosts(baseDir,nickname,domain,'outbox')
|
||||||
followPerson(baseDir,nickname,domain,'admin',domain,federationList,True)
|
followPerson(baseDir,nickname,domain,'admin',domain,federationList,True)
|
||||||
followerOfPerson(baseDir,nickname,domain,'admin',domain,federationList,True)
|
followerOfPerson(baseDir,nickname,domain,'admin',domain,federationList,True)
|
||||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"like, this is totally just a test, man",False,True,False,ocapGranted)
|
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"like, this is totally just a test, man",False,True,False)
|
||||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Zoiks!!!",False,True,False,ocapGranted)
|
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Zoiks!!!",False,True,False)
|
||||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Hey scoob we need like a hundred more milkshakes",False,True,False,ocapGranted)
|
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Hey scoob we need like a hundred more milkshakes",False,True,False)
|
||||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Getting kinda spooky around here",False,True,False,ocapGranted)
|
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"Getting kinda spooky around here",False,True,False)
|
||||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"And they would have gotten away with it too if it wasn't for those pesky hackers",False,True,False,ocapGranted)
|
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"And they would have gotten away with it too if it wasn't for those pesky hackers",False,True,False)
|
||||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"man, these centralized sites are, like, the worst!",False,True,False,ocapGranted)
|
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"man, these centralized sites are, like, the worst!",False,True,False)
|
||||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"another mystery solved hey",False,True,False,ocapGranted)
|
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"another mystery solved hey",False,True,False)
|
||||||
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"let's go bowling",False,True,False,ocapGranted)
|
createPublicPost(baseDir,nickname,domain,port,httpPrefix,"let's go bowling",False,True,False)
|
||||||
|
|
||||||
runDaemon(baseDir,domain,port,httpPrefix,federationList,ocapAlways,ocapGranted,useTor,debug)
|
runDaemon(baseDir,domain,port,httpPrefix,federationList,ocapAlways,useTor,debug)
|
||||||
|
|
10
follow.py
10
follow.py
|
@ -221,7 +221,7 @@ def receiveFollowRequest(session,baseDir: str,httpPrefix: str, \
|
||||||
port: int,sendThreads: [],postLog: [], \
|
port: int,sendThreads: [],postLog: [], \
|
||||||
cachedWebfingers: {},personCache: {}, \
|
cachedWebfingers: {},personCache: {}, \
|
||||||
messageJson: {},federationList: [], \
|
messageJson: {},federationList: [], \
|
||||||
ocapGranted: {},debug : bool) -> bool:
|
debug : bool) -> bool:
|
||||||
"""Receives a follow request within the POST section of HTTPServer
|
"""Receives a follow request within the POST section of HTTPServer
|
||||||
"""
|
"""
|
||||||
if not messageJson['type'].startswith('Follow'):
|
if not messageJson['type'].startswith('Follow'):
|
||||||
|
@ -281,7 +281,7 @@ def receiveFollowRequest(session,baseDir: str,httpPrefix: str, \
|
||||||
print('DEBUG: sending Accept for follow request which arrived at '+ \
|
print('DEBUG: sending Accept for follow request which arrived at '+ \
|
||||||
nicknameToFollow+'@'+domainToFollow+' back to '+nickname+'@'+domain)
|
nicknameToFollow+'@'+domainToFollow+' back to '+nickname+'@'+domain)
|
||||||
personUrl=messageJson['actor']
|
personUrl=messageJson['actor']
|
||||||
acceptJson=createAccept(baseDir,federationList,ocapGranted, \
|
acceptJson=createAccept(baseDir,federationList, \
|
||||||
nicknameToFollow,domainToFollow,port, \
|
nicknameToFollow,domainToFollow,port, \
|
||||||
personUrl,'',httpPrefix,messageJson)
|
personUrl,'',httpPrefix,messageJson)
|
||||||
if debug:
|
if debug:
|
||||||
|
@ -295,7 +295,7 @@ def receiveFollowRequest(session,baseDir: str,httpPrefix: str, \
|
||||||
nicknameToFollow,domainToFollow,port, \
|
nicknameToFollow,domainToFollow,port, \
|
||||||
nickname,domain,fromPort, '', \
|
nickname,domain,fromPort, '', \
|
||||||
httpPrefix,True,clientToServer, \
|
httpPrefix,True,clientToServer, \
|
||||||
federationList, ocapGranted, \
|
federationList, \
|
||||||
sendThreads,postLog,cachedWebfingers, \
|
sendThreads,postLog,cachedWebfingers, \
|
||||||
personCache,debug)
|
personCache,debug)
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ def sendFollowRequest(session,baseDir: str, \
|
||||||
nickname: str,domain: str,port: int,httpPrefix: str, \
|
nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||||
followNickname: str,followDomain: str, \
|
followNickname: str,followDomain: str, \
|
||||||
followPort: bool,followHttpPrefix: str, \
|
followPort: bool,followHttpPrefix: str, \
|
||||||
clientToServer: bool,federationList: [],ocapGranted: {}, \
|
clientToServer: bool,federationList: [], \
|
||||||
sendThreads: [],postLog: [],cachedWebfingers: {}, \
|
sendThreads: [],postLog: [],cachedWebfingers: {}, \
|
||||||
personCache: {},debug : bool) -> {}:
|
personCache: {},debug : bool) -> {}:
|
||||||
"""Gets the json object for sending a follow request
|
"""Gets the json object for sending a follow request
|
||||||
|
@ -339,7 +339,7 @@ def sendFollowRequest(session,baseDir: str, \
|
||||||
followNickname,followDomain,followPort, \
|
followNickname,followDomain,followPort, \
|
||||||
'https://www.w3.org/ns/activitystreams#Public', \
|
'https://www.w3.org/ns/activitystreams#Public', \
|
||||||
httpPrefix,True,clientToServer, \
|
httpPrefix,True,clientToServer, \
|
||||||
federationList, ocapGranted, \
|
federationList, \
|
||||||
sendThreads,postLog,cachedWebfingers,personCache, debug)
|
sendThreads,postLog,cachedWebfingers,personCache, debug)
|
||||||
|
|
||||||
return newFollowJson
|
return newFollowJson
|
||||||
|
|
86
inbox.py
86
inbox.py
|
@ -16,6 +16,9 @@ from shutil import copyfile
|
||||||
from utils import urlPermitted
|
from utils import urlPermitted
|
||||||
from utils import createInboxQueueDir
|
from utils import createInboxQueueDir
|
||||||
from utils import getStatusNumber
|
from utils import getStatusNumber
|
||||||
|
from utils import getDomainFromActor
|
||||||
|
from utils import getNicknameFromActor
|
||||||
|
from utils import domainPermitted
|
||||||
from httpsig import verifyPostHeaders
|
from httpsig import verifyPostHeaders
|
||||||
from session import createSession
|
from session import createSession
|
||||||
from session import getJson
|
from session import getJson
|
||||||
|
@ -27,6 +30,7 @@ from cache import storePersonInCache
|
||||||
from acceptreject import receiveAcceptReject
|
from acceptreject import receiveAcceptReject
|
||||||
from capabilities import getOcapFilename
|
from capabilities import getOcapFilename
|
||||||
from capabilities import CapablePost
|
from capabilities import CapablePost
|
||||||
|
from capabilities import capabilitiesReceiveUpdate
|
||||||
|
|
||||||
def getPersonPubKey(session,personUrl: str,personCache: {},debug: bool) -> str:
|
def getPersonPubKey(session,personUrl: str,personCache: {},debug: bool) -> str:
|
||||||
if not personUrl:
|
if not personUrl:
|
||||||
|
@ -68,7 +72,7 @@ def inboxMessageHasParams(messageJson: {}) -> bool:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def inboxPermittedMessage(domain: str,messageJson: {},federationList: [],ocapGranted: {}) -> bool:
|
def inboxPermittedMessage(domain: str,messageJson: {},federationList: []) -> bool:
|
||||||
""" check that we are receiving from a permitted domain
|
""" check that we are receiving from a permitted domain
|
||||||
"""
|
"""
|
||||||
testParam='actor'
|
testParam='actor'
|
||||||
|
@ -79,14 +83,14 @@ def inboxPermittedMessage(domain: str,messageJson: {},federationList: [],ocapGra
|
||||||
if domain in actor:
|
if domain in actor:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not urlPermitted(actor,federationList,ocapGranted,"inbox:write"):
|
if not urlPermitted(actor,federationList,"inbox:write"):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if messageJson['type']!='Follow':
|
if messageJson['type']!='Follow':
|
||||||
if messageJson.get('object'):
|
if messageJson.get('object'):
|
||||||
if messageJson['object'].get('inReplyTo'):
|
if messageJson['object'].get('inReplyTo'):
|
||||||
inReplyTo=messageJson['object']['inReplyTo']
|
inReplyTo=messageJson['object']['inReplyTo']
|
||||||
if not urlPermitted(inReplyTo,federationList,ocapGranted):
|
if not urlPermitted(inReplyTo,federationList):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -299,7 +303,62 @@ def inboxPostRecipients(baseDir :str,postJsonObject :{},httpPrefix :str,domain :
|
||||||
|
|
||||||
return 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:
|
def receiveUpdate(session,baseDir: str, \
|
||||||
|
httpPrefix: str,domain :str,port: int, \
|
||||||
|
sendThreads: [],postLog: [],cachedWebfingers: {}, \
|
||||||
|
personCache: {},messageJson: {},federationList: [], \
|
||||||
|
debug : bool) -> bool:
|
||||||
|
"""Receives an Update activity within the POST section of HTTPServer
|
||||||
|
"""
|
||||||
|
if messageJson['type']!='Update':
|
||||||
|
return False
|
||||||
|
if not messageJson.get('actor'):
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: '+messageJson['type']+' has no actor')
|
||||||
|
return False
|
||||||
|
if not messageJson.get('object'):
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: '+messageJson['type']+' has no object')
|
||||||
|
return False
|
||||||
|
if not isinstance(messageJson['object'], dict):
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: '+messageJson['type']+' object is not a dict')
|
||||||
|
return False
|
||||||
|
if not messageJson['object'].get('type'):
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: '+messageJson['type']+' object has no type')
|
||||||
|
return False
|
||||||
|
if '/users/' not in messageJson['actor']:
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: "users" missing from actor in '+messageJson['type'])
|
||||||
|
return False
|
||||||
|
domain,tempPort=getDomainFromActor(messageJson['actor'])
|
||||||
|
if not domainPermitted(domain,federationList):
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: '+messageJson['type']+' from domain not permitted - '+domain)
|
||||||
|
return False
|
||||||
|
nickname=getNicknameFromActor(messageJson['actor'])
|
||||||
|
if not nickname:
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: '+messageJson['type']+' does not contain a nickname')
|
||||||
|
return False
|
||||||
|
handle=nickname.lower()+'@'+domain.lower()
|
||||||
|
if messageJson['object'].get('capability') and messageJson['object'].get('scope'):
|
||||||
|
domain,tempPort=getDomainFromActor(messageJson['object']['scope'])
|
||||||
|
nickname=getNicknameFromActor(messageJson['object']['scope'])
|
||||||
|
|
||||||
|
if messageJson['object']['type']=='Capability':
|
||||||
|
if capabilitiesReceiveUpdate(baseDir,nickname,domain,port,
|
||||||
|
messageJson['actor'], \
|
||||||
|
messageJson['object']['id'], \
|
||||||
|
messageJson['object']['capability'], \
|
||||||
|
debug):
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: An update was received')
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [],cachedWebfingers: {},personCache: {},queue: [],domain: str,port: int,useTor: bool,federationList: [],ocapAlways: bool,debug: bool) -> None:
|
||||||
"""Processes received items and moves them to
|
"""Processes received items and moves them to
|
||||||
the appropriate directories
|
the appropriate directories
|
||||||
"""
|
"""
|
||||||
|
@ -389,7 +448,7 @@ def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [],cache
|
||||||
cachedWebfingers,
|
cachedWebfingers,
|
||||||
personCache,
|
personCache,
|
||||||
queueJson['post'], \
|
queueJson['post'], \
|
||||||
federationList,ocapGranted, \
|
federationList, \
|
||||||
debug):
|
debug):
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: Follow accepted from '+keyId)
|
print('DEBUG: Follow accepted from '+keyId)
|
||||||
|
@ -403,7 +462,7 @@ def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [],cache
|
||||||
cachedWebfingers,
|
cachedWebfingers,
|
||||||
personCache,
|
personCache,
|
||||||
queueJson['post'], \
|
queueJson['post'], \
|
||||||
federationList,ocapGranted, \
|
federationList, \
|
||||||
debug):
|
debug):
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: Accept/Reject received from '+keyId)
|
print('DEBUG: Accept/Reject received from '+keyId)
|
||||||
|
@ -411,6 +470,21 @@ def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [],cache
|
||||||
queue.pop(0)
|
queue.pop(0)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if receiveUpdate(session, \
|
||||||
|
baseDir,httpPrefix, \
|
||||||
|
domain,port, \
|
||||||
|
sendThreads,postLog, \
|
||||||
|
cachedWebfingers,
|
||||||
|
personCache,
|
||||||
|
queueJson['post'], \
|
||||||
|
federationList, \
|
||||||
|
debug):
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: Update accepted from '+keyId)
|
||||||
|
os.remove(queueFilename)
|
||||||
|
queue.pop(0)
|
||||||
|
continue
|
||||||
|
|
||||||
# get recipients list
|
# get recipients list
|
||||||
recipientsDict=inboxPostRecipients(baseDir,queueJson['post'],httpPrefix,domain,port)
|
recipientsDict=inboxPostRecipients(baseDir,queueJson['post'],httpPrefix,domain,port)
|
||||||
|
|
||||||
|
|
2
like.py
2
like.py
|
@ -17,7 +17,7 @@ def like(baseDir: str,federationList: [],nickname: str,domain: str,port: int, \
|
||||||
and ccUrl might be a specific person whose post was liked
|
and ccUrl might be a specific person whose post was liked
|
||||||
objectUrl is typically the url of the message, corresponding to url or atomUri in createPostBase
|
objectUrl is typically the url of the message, corresponding to url or atomUri in createPostBase
|
||||||
"""
|
"""
|
||||||
if not urlPermitted(objectUrl,federationList,ocapGranted,"inbox:write"):
|
if not urlPermitted(objectUrl,federationList,"inbox:write"):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if port!=80 and port!=443:
|
if port!=80 and port!=443:
|
||||||
|
|
68
posts.py
68
posts.py
|
@ -30,7 +30,10 @@ from httpsig import createSignedHeader
|
||||||
from utils import getStatusNumber
|
from utils import getStatusNumber
|
||||||
from utils import createPersonDir
|
from utils import createPersonDir
|
||||||
from utils import urlPermitted
|
from utils import urlPermitted
|
||||||
|
from utils import getNicknameFromActor
|
||||||
|
from utils import getDomainFromActor
|
||||||
from capabilities import getOcapFilename
|
from capabilities import getOcapFilename
|
||||||
|
from capabilities import capabilitiesUpdate
|
||||||
try:
|
try:
|
||||||
from BeautifulSoup import BeautifulSoup
|
from BeautifulSoup import BeautifulSoup
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -153,7 +156,7 @@ def getPersonBox(session,wfRequest: {},personCache: {}, \
|
||||||
|
|
||||||
def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
|
def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
|
||||||
maxEmoji: int,maxAttachments: int, \
|
maxEmoji: int,maxAttachments: int, \
|
||||||
federationList: [], ocapGranted: {},\
|
federationList: [],\
|
||||||
personCache: {},raw: bool,simple: bool) -> {}:
|
personCache: {},raw: bool,simple: bool) -> {}:
|
||||||
personPosts={}
|
personPosts={}
|
||||||
if not outboxUrl:
|
if not outboxUrl:
|
||||||
|
@ -193,7 +196,7 @@ def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
|
||||||
if tagItem['icon'].get('url'):
|
if tagItem['icon'].get('url'):
|
||||||
# No emoji from non-permitted domains
|
# No emoji from non-permitted domains
|
||||||
if urlPermitted(tagItem['icon']['url'], \
|
if urlPermitted(tagItem['icon']['url'], \
|
||||||
federationList,ocapGranted, \
|
federationList, \
|
||||||
"objects:read"):
|
"objects:read"):
|
||||||
emojiName=tagItem['name']
|
emojiName=tagItem['name']
|
||||||
emojiIcon=tagItem['icon']['url']
|
emojiIcon=tagItem['icon']['url']
|
||||||
|
@ -217,7 +220,7 @@ def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
|
||||||
if item['object']['inReplyTo']:
|
if item['object']['inReplyTo']:
|
||||||
# No replies to non-permitted domains
|
# No replies to non-permitted domains
|
||||||
if not urlPermitted(item['object']['inReplyTo'], \
|
if not urlPermitted(item['object']['inReplyTo'], \
|
||||||
federationList,ocapGranted, \
|
federationList, \
|
||||||
"objects:read"):
|
"objects:read"):
|
||||||
continue
|
continue
|
||||||
inReplyTo = item['object']['inReplyTo']
|
inReplyTo = item['object']['inReplyTo']
|
||||||
|
@ -227,7 +230,7 @@ def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
|
||||||
if item['object']['conversation']:
|
if item['object']['conversation']:
|
||||||
# no conversations originated in non-permitted domains
|
# no conversations originated in non-permitted domains
|
||||||
if urlPermitted(item['object']['conversation'], \
|
if urlPermitted(item['object']['conversation'], \
|
||||||
federationList,ocapGranted,"objects:read"):
|
federationList,"objects:read"):
|
||||||
conversation = item['object']['conversation']
|
conversation = item['object']['conversation']
|
||||||
|
|
||||||
attachment = []
|
attachment = []
|
||||||
|
@ -237,7 +240,7 @@ def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
|
||||||
if attach.get('name') and attach.get('url'):
|
if attach.get('name') and attach.get('url'):
|
||||||
# no attachments from non-permitted domains
|
# no attachments from non-permitted domains
|
||||||
if urlPermitted(attach['url'], \
|
if urlPermitted(attach['url'], \
|
||||||
federationList,ocapGranted, \
|
federationList, \
|
||||||
"objects:read"):
|
"objects:read"):
|
||||||
attachment.append([attach['name'],attach['url']])
|
attachment.append([attach['name'],attach['url']])
|
||||||
|
|
||||||
|
@ -319,7 +322,6 @@ def savePostToBox(baseDir: str,httpPrefix: str,postId: str, \
|
||||||
def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
|
def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
|
||||||
toUrl: str, ccUrl: str, httpPrefix: str, content: str, \
|
toUrl: str, ccUrl: str, httpPrefix: str, content: str, \
|
||||||
followersOnly: bool, saveToFile: bool, clientToServer: bool, \
|
followersOnly: bool, saveToFile: bool, clientToServer: bool, \
|
||||||
ocapGranted: {}, \
|
|
||||||
inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}:
|
inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}:
|
||||||
"""Creates a message
|
"""Creates a message
|
||||||
"""
|
"""
|
||||||
|
@ -487,7 +489,7 @@ def postIsAddressedToFollowers(baseDir: str,
|
||||||
def createPublicPost(baseDir: str,
|
def createPublicPost(baseDir: str,
|
||||||
nickname: str, domain: str, port: int,httpPrefix: str, \
|
nickname: str, domain: str, port: int,httpPrefix: str, \
|
||||||
content: str, followersOnly: bool, saveToFile: bool,
|
content: str, followersOnly: bool, saveToFile: bool,
|
||||||
clientToServer: bool, ocapGranted: {},\
|
clientToServer: bool,\
|
||||||
inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}:
|
inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}:
|
||||||
"""Public post to the outbox
|
"""Public post to the outbox
|
||||||
"""
|
"""
|
||||||
|
@ -495,10 +497,10 @@ def createPublicPost(baseDir: str,
|
||||||
'https://www.w3.org/ns/activitystreams#Public', \
|
'https://www.w3.org/ns/activitystreams#Public', \
|
||||||
httpPrefix+'://'+domain+'/users/'+nickname+'/followers', \
|
httpPrefix+'://'+domain+'/users/'+nickname+'/followers', \
|
||||||
httpPrefix, content, followersOnly, saveToFile, \
|
httpPrefix, content, followersOnly, saveToFile, \
|
||||||
clientToServer, ocapGranted, \
|
clientToServer, \
|
||||||
inReplyTo, inReplyToAtomUri, subject)
|
inReplyTo, inReplyToAtomUri, subject)
|
||||||
|
|
||||||
def threadSendPost(session,postJsonObject: {},federationList: [],ocapGranted: {},\
|
def threadSendPost(session,postJsonObject: {},federationList: [],\
|
||||||
inboxUrl: str, baseDir: str,signatureHeaderJson: {},postLog: [],
|
inboxUrl: str, baseDir: str,signatureHeaderJson: {},postLog: [],
|
||||||
debug :bool) -> None:
|
debug :bool) -> None:
|
||||||
"""Sends a post with exponential backoff
|
"""Sends a post with exponential backoff
|
||||||
|
@ -507,7 +509,7 @@ def threadSendPost(session,postJsonObject: {},federationList: [],ocapGranted: {}
|
||||||
backoffTime=60
|
backoffTime=60
|
||||||
for attempt in range(20):
|
for attempt in range(20):
|
||||||
postResult = postJson(session,postJsonObject,federationList, \
|
postResult = postJson(session,postJsonObject,federationList, \
|
||||||
ocapGranted,inboxUrl,signatureHeaderJson, \
|
inboxUrl,signatureHeaderJson, \
|
||||||
"inbox:write")
|
"inbox:write")
|
||||||
if postResult:
|
if postResult:
|
||||||
if debug:
|
if debug:
|
||||||
|
@ -534,7 +536,7 @@ def sendPost(session,baseDir: str,nickname: str, domain: str, port: int, \
|
||||||
toNickname: str, toDomain: str, toPort: int, cc: str, \
|
toNickname: str, toDomain: str, toPort: int, cc: str, \
|
||||||
httpPrefix: str, content: str, followersOnly: bool, \
|
httpPrefix: str, content: str, followersOnly: bool, \
|
||||||
saveToFile: bool, clientToServer: bool, \
|
saveToFile: bool, clientToServer: bool, \
|
||||||
federationList: [], ocapGranted: {},\
|
federationList: [],\
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {},personCache: {}, \
|
sendThreads: [], postLog: [], cachedWebfingers: {},personCache: {}, \
|
||||||
debug=False,inReplyTo=None,inReplyToAtomUri=None,subject=None) -> int:
|
debug=False,inReplyTo=None,inReplyToAtomUri=None,subject=None) -> int:
|
||||||
"""Post to another inbox
|
"""Post to another inbox
|
||||||
|
@ -583,7 +585,6 @@ def sendPost(session,baseDir: str,nickname: str, domain: str, port: int, \
|
||||||
createPostBase(baseDir,nickname,domain,port, \
|
createPostBase(baseDir,nickname,domain,port, \
|
||||||
toPersonId,cc,httpPrefix,content, \
|
toPersonId,cc,httpPrefix,content, \
|
||||||
followersOnly,saveToFile,clientToServer, \
|
followersOnly,saveToFile,clientToServer, \
|
||||||
ocapGranted, \
|
|
||||||
inReplyTo,inReplyToAtomUri,subject)
|
inReplyTo,inReplyToAtomUri,subject)
|
||||||
|
|
||||||
# get the senders private key
|
# get the senders private key
|
||||||
|
@ -607,7 +608,6 @@ def sendPost(session,baseDir: str,nickname: str, domain: str, port: int, \
|
||||||
thr = threadWithTrace(target=threadSendPost,args=(session, \
|
thr = threadWithTrace(target=threadSendPost,args=(session, \
|
||||||
postJsonObject.copy(), \
|
postJsonObject.copy(), \
|
||||||
federationList, \
|
federationList, \
|
||||||
ocapGranted, \
|
|
||||||
inboxUrl,baseDir, \
|
inboxUrl,baseDir, \
|
||||||
signatureHeaderJson.copy(), \
|
signatureHeaderJson.copy(), \
|
||||||
postLog,
|
postLog,
|
||||||
|
@ -639,7 +639,7 @@ def sendSignedJson(postJsonObject: {},session,baseDir: str, \
|
||||||
nickname: str, domain: str, port: int, \
|
nickname: str, domain: str, port: int, \
|
||||||
toNickname: str, toDomain: str, toPort: int, cc: str, \
|
toNickname: str, toDomain: str, toPort: int, cc: str, \
|
||||||
httpPrefix: str, saveToFile: bool, clientToServer: bool, \
|
httpPrefix: str, saveToFile: bool, clientToServer: bool, \
|
||||||
federationList: [], ocapGranted: {}, \
|
federationList: [], \
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {}, \
|
sendThreads: [], postLog: [], cachedWebfingers: {}, \
|
||||||
personCache: {}, debug: bool) -> int:
|
personCache: {}, debug: bool) -> int:
|
||||||
"""Sends a signed json object to an inbox/outbox
|
"""Sends a signed json object to an inbox/outbox
|
||||||
|
@ -715,7 +715,6 @@ def sendSignedJson(postJsonObject: {},session,baseDir: str, \
|
||||||
args=(session, \
|
args=(session, \
|
||||||
postJsonObject.copy(), \
|
postJsonObject.copy(), \
|
||||||
federationList, \
|
federationList, \
|
||||||
ocapGranted, \
|
|
||||||
inboxUrl,baseDir, \
|
inboxUrl,baseDir, \
|
||||||
signatureHeaderJson.copy(), \
|
signatureHeaderJson.copy(), \
|
||||||
postLog,
|
postLog,
|
||||||
|
@ -754,7 +753,7 @@ def sendToFollowers(session,baseDir: str,
|
||||||
nickname,domain,port, \
|
nickname,domain,port, \
|
||||||
toNickname,toDomain,toPort, \
|
toNickname,toDomain,toPort, \
|
||||||
cc,httpPrefix,True,clientToServer, \
|
cc,httpPrefix,True,clientToServer, \
|
||||||
federationList,ocapGranted, \
|
federationList, \
|
||||||
sendThreads,postLog,cachedWebfingers, \
|
sendThreads,postLog,cachedWebfingers, \
|
||||||
personCache,debug)
|
personCache,debug)
|
||||||
|
|
||||||
|
@ -900,7 +899,6 @@ def getPublicPostsOfPerson(nickname: str,domain: str, \
|
||||||
personCache={}
|
personCache={}
|
||||||
cachedWebfingers={}
|
cachedWebfingers={}
|
||||||
federationList=[]
|
federationList=[]
|
||||||
ocapGranted={}
|
|
||||||
|
|
||||||
httpPrefix='https'
|
httpPrefix='https'
|
||||||
handle=httpPrefix+"://"+domain+"/@"+nickname
|
handle=httpPrefix+"://"+domain+"/@"+nickname
|
||||||
|
@ -917,6 +915,40 @@ def getPublicPostsOfPerson(nickname: str,domain: str, \
|
||||||
maxEmoji=10
|
maxEmoji=10
|
||||||
maxAttachments=5
|
maxAttachments=5
|
||||||
userPosts = getPosts(session,personUrl,30,maxMentions,maxEmoji, \
|
userPosts = getPosts(session,personUrl,30,maxMentions,maxEmoji, \
|
||||||
maxAttachments,federationList,ocapGranted, \
|
maxAttachments,federationList, \
|
||||||
personCache,raw,simple)
|
personCache,raw,simple)
|
||||||
#print(str(userPosts))
|
#print(str(userPosts))
|
||||||
|
|
||||||
|
def sendCapabilitiesUpdate(session,baseDir: str,httpPrefix: str, \
|
||||||
|
nickname: str,domain: str,port: int, \
|
||||||
|
followerUrl,updateCaps: [], \
|
||||||
|
sendThreads: [],postLog: [], \
|
||||||
|
cachedWebfingers: {},personCache: {}, \
|
||||||
|
federationList :[],debug :bool) -> int:
|
||||||
|
"""When the capabilities for a follower are changed this
|
||||||
|
sends out an update. followerUrl is the actor of the follower.
|
||||||
|
"""
|
||||||
|
updateJson=capabilitiesUpdate(baseDir,httpPrefix, \
|
||||||
|
nickname,domain,port, \
|
||||||
|
followerUrl, \
|
||||||
|
updateCaps)
|
||||||
|
|
||||||
|
if not updateJson:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
pprint(updateJson)
|
||||||
|
print('DEBUG: sending capabilities update from '+ \
|
||||||
|
nickname+'@'+domain+' port '+ str(port) + \
|
||||||
|
' to '+followerUrl)
|
||||||
|
|
||||||
|
clientToServer=False
|
||||||
|
followerNickname=getNicknameFromActor(followerUrl)
|
||||||
|
followerDomain,followerPort=getDomainFromActor(followerUrl)
|
||||||
|
return sendSignedJson(updateJson,session,baseDir, \
|
||||||
|
nickname,domain,port, \
|
||||||
|
followerNickname,followerDomain,followerPort, '', \
|
||||||
|
httpPrefix,True,clientToServer, \
|
||||||
|
federationList, \
|
||||||
|
sendThreads,postLog,cachedWebfingers, \
|
||||||
|
personCache,debug)
|
||||||
|
|
|
@ -39,7 +39,7 @@ def getJson(session,url: str,headers: {},params: {}) -> {}:
|
||||||
pass
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def postJson(session,postJsonObject: {},federationList: [],ocapGranted: {},inboxUrl: str,headers: {},capability: str) -> str:
|
def postJson(session,postJsonObject: {},federationList: [],inboxUrl: str,headers: {},capability: str) -> str:
|
||||||
"""Post a json message to the inbox of another person
|
"""Post a json message to the inbox of another person
|
||||||
Supplying a capability, such as "inbox:write"
|
Supplying a capability, such as "inbox:write"
|
||||||
"""
|
"""
|
||||||
|
@ -47,7 +47,7 @@ def postJson(session,postJsonObject: {},federationList: [],ocapGranted: {},inbox
|
||||||
# always allow capability requests
|
# always allow capability requests
|
||||||
if not capability.startswith('cap'):
|
if not capability.startswith('cap'):
|
||||||
# check that we are posting to a permitted domain
|
# check that we are posting to a permitted domain
|
||||||
if not urlPermitted(inboxUrl,federationList,ocapGranted,capability):
|
if not urlPermitted(inboxUrl,federationList,capability):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
postResult = session.post(url = inboxUrl, data = json.dumps(postJsonObject), headers=headers)
|
postResult = session.post(url = inboxUrl, data = json.dumps(postJsonObject), headers=headers)
|
||||||
|
|
126
tests.py
126
tests.py
|
@ -10,6 +10,8 @@ import base64
|
||||||
import time
|
import time
|
||||||
import os, os.path
|
import os, os.path
|
||||||
import shutil
|
import shutil
|
||||||
|
import commentjson
|
||||||
|
from pprint import pprint
|
||||||
from person import createPerson
|
from person import createPerson
|
||||||
from Crypto.Hash import SHA256
|
from Crypto.Hash import SHA256
|
||||||
from httpsig import signPostHeaders
|
from httpsig import signPostHeaders
|
||||||
|
@ -25,6 +27,7 @@ from posts import sendPost
|
||||||
from posts import archivePosts
|
from posts import archivePosts
|
||||||
from posts import noOfFollowersOnDomain
|
from posts import noOfFollowersOnDomain
|
||||||
from posts import groupFollowersByDomain
|
from posts import groupFollowersByDomain
|
||||||
|
from posts import sendCapabilitiesUpdate
|
||||||
from follow import clearFollows
|
from follow import clearFollows
|
||||||
from follow import clearFollowers
|
from follow import clearFollowers
|
||||||
from utils import followPerson
|
from utils import followPerson
|
||||||
|
@ -111,7 +114,7 @@ def testThreads():
|
||||||
thr.join()
|
thr.join()
|
||||||
assert thr.isAlive()==False
|
assert thr.isAlive()==False
|
||||||
|
|
||||||
def createServerAlice(path: str,domain: str,port: int,federationList: [],ocapGranted: {},hasFollows: bool,hasPosts :bool,ocapAlways: bool):
|
def createServerAlice(path: str,domain: str,port: int,federationList: [],hasFollows: bool,hasPosts :bool,ocapAlways: bool):
|
||||||
print('Creating test server: Alice on port '+str(port))
|
print('Creating test server: Alice on port '+str(port))
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
shutil.rmtree(path)
|
shutil.rmtree(path)
|
||||||
|
@ -129,15 +132,15 @@ def createServerAlice(path: str,domain: str,port: int,federationList: [],ocapGra
|
||||||
followPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList,True)
|
followPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList,True)
|
||||||
followerOfPerson(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:
|
if hasPosts:
|
||||||
createPublicPost(path,nickname, domain, port,httpPrefix, "No wise fish would go anywhere without a porpoise", False, True, clientToServer,ocapGranted)
|
createPublicPost(path,nickname, domain, port,httpPrefix, "No wise fish would go anywhere without a porpoise", False, True, clientToServer)
|
||||||
createPublicPost(path,nickname, domain, port,httpPrefix, "Curiouser and curiouser!", False, True, clientToServer,ocapGranted)
|
createPublicPost(path,nickname, domain, port,httpPrefix, "Curiouser and curiouser!", False, True, clientToServer)
|
||||||
createPublicPost(path,nickname, domain, port,httpPrefix, "In the gardens of memory, in the palace of dreams, that is where you and I shall meet", False, True, clientToServer,ocapGranted)
|
createPublicPost(path,nickname, domain, port,httpPrefix, "In the gardens of memory, in the palace of dreams, that is where you and I shall meet", False, True, clientToServer)
|
||||||
global testServerAliceRunning
|
global testServerAliceRunning
|
||||||
testServerAliceRunning = True
|
testServerAliceRunning = True
|
||||||
print('Server running: Alice')
|
print('Server running: Alice')
|
||||||
runDaemon(path,domain,port,httpPrefix,federationList,ocapAlways,ocapGranted,useTor,True)
|
runDaemon(path,domain,port,httpPrefix,federationList,ocapAlways,useTor,True)
|
||||||
|
|
||||||
def createServerBob(path: str,domain: str,port: int,federationList: [],ocapGranted: {},hasFollows: bool,hasPosts :bool,ocapAlways :bool):
|
def createServerBob(path: str,domain: str,port: int,federationList: [],hasFollows: bool,hasPosts :bool,ocapAlways :bool):
|
||||||
print('Creating test server: Bob on port '+str(port))
|
print('Creating test server: Bob on port '+str(port))
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
shutil.rmtree(path)
|
shutil.rmtree(path)
|
||||||
|
@ -155,15 +158,15 @@ def createServerBob(path: str,domain: str,port: int,federationList: [],ocapGrant
|
||||||
followPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList,True)
|
followPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList,True)
|
||||||
followerOfPerson(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:
|
if hasPosts:
|
||||||
createPublicPost(path,nickname, domain, port,httpPrefix, "It's your life, live it your way.", False, True, clientToServer,ocapGranted)
|
createPublicPost(path,nickname, domain, port,httpPrefix, "It's your life, live it your way.", False, True, clientToServer)
|
||||||
createPublicPost(path,nickname, domain, port,httpPrefix, "One of the things I've realised is that I am very simple", False, True, clientToServer,ocapGranted)
|
createPublicPost(path,nickname, domain, port,httpPrefix, "One of the things I've realised is that I am very simple", False, True, clientToServer)
|
||||||
createPublicPost(path,nickname, domain, port,httpPrefix, "Quantum physics is a bit of a passion of mine", False, True, clientToServer,ocapGranted)
|
createPublicPost(path,nickname, domain, port,httpPrefix, "Quantum physics is a bit of a passion of mine", False, True, clientToServer)
|
||||||
global testServerBobRunning
|
global testServerBobRunning
|
||||||
testServerBobRunning = True
|
testServerBobRunning = True
|
||||||
print('Server running: Bob')
|
print('Server running: Bob')
|
||||||
runDaemon(path,domain,port,httpPrefix,federationList,ocapAlways,ocapGranted,useTor,True)
|
runDaemon(path,domain,port,httpPrefix,federationList,ocapAlways,useTor,True)
|
||||||
|
|
||||||
def createServerEve(path: str,domain: str,port: int,federationList: [],ocapGranted: {},hasFollows: bool,hasPosts :bool,ocapAlways :bool):
|
def createServerEve(path: str,domain: str,port: int,federationList: [],hasFollows: bool,hasPosts :bool,ocapAlways :bool):
|
||||||
print('Creating test server: Eve on port '+str(port))
|
print('Creating test server: Eve on port '+str(port))
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
shutil.rmtree(path)
|
shutil.rmtree(path)
|
||||||
|
@ -180,7 +183,7 @@ def createServerEve(path: str,domain: str,port: int,federationList: [],ocapGrant
|
||||||
global testServerEveRunning
|
global testServerEveRunning
|
||||||
testServerEveRunning = True
|
testServerEveRunning = True
|
||||||
print('Server running: Eve')
|
print('Server running: Eve')
|
||||||
runDaemon(path,domain,port,httpPrefix,federationList,ocapAlways,ocapGranted,useTor,True)
|
runDaemon(path,domain,port,httpPrefix,federationList,ocapAlways,useTor,True)
|
||||||
|
|
||||||
def testPostMessageBetweenServers():
|
def testPostMessageBetweenServers():
|
||||||
print('Testing sending message from one server to the inbox of another')
|
print('Testing sending message from one server to the inbox of another')
|
||||||
|
@ -193,7 +196,6 @@ def testPostMessageBetweenServers():
|
||||||
httpPrefix='http'
|
httpPrefix='http'
|
||||||
useTor=False
|
useTor=False
|
||||||
federationList=['127.0.0.50','127.0.0.100']
|
federationList=['127.0.0.50','127.0.0.100']
|
||||||
ocapGranted={}
|
|
||||||
|
|
||||||
baseDir=os.getcwd()
|
baseDir=os.getcwd()
|
||||||
if os.path.isdir(baseDir+'/.tests'):
|
if os.path.isdir(baseDir+'/.tests'):
|
||||||
|
@ -206,12 +208,12 @@ def testPostMessageBetweenServers():
|
||||||
aliceDir=baseDir+'/.tests/alice'
|
aliceDir=baseDir+'/.tests/alice'
|
||||||
aliceDomain='127.0.0.50'
|
aliceDomain='127.0.0.50'
|
||||||
alicePort=61935
|
alicePort=61935
|
||||||
thrAlice = threadWithTrace(target=createServerAlice,args=(aliceDir,aliceDomain,alicePort,federationList,ocapGranted,True,True,ocapAlways),daemon=True)
|
thrAlice = threadWithTrace(target=createServerAlice,args=(aliceDir,aliceDomain,alicePort,federationList,True,True,ocapAlways),daemon=True)
|
||||||
|
|
||||||
bobDir=baseDir+'/.tests/bob'
|
bobDir=baseDir+'/.tests/bob'
|
||||||
bobDomain='127.0.0.100'
|
bobDomain='127.0.0.100'
|
||||||
bobPort=61936
|
bobPort=61936
|
||||||
thrBob = threadWithTrace(target=createServerBob,args=(bobDir,bobDomain,bobPort,federationList,ocapGranted,True,True,ocapAlways),daemon=True)
|
thrBob = threadWithTrace(target=createServerBob,args=(bobDir,bobDomain,bobPort,federationList,True,True,ocapAlways),daemon=True)
|
||||||
|
|
||||||
thrAlice.start()
|
thrAlice.start()
|
||||||
thrBob.start()
|
thrBob.start()
|
||||||
|
@ -238,7 +240,7 @@ def testPostMessageBetweenServers():
|
||||||
ccUrl=None
|
ccUrl=None
|
||||||
alicePersonCache={}
|
alicePersonCache={}
|
||||||
aliceCachedWebfingers={}
|
aliceCachedWebfingers={}
|
||||||
sendResult = sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Why is a mouse when it spins?', followersOnly, saveToFile, clientToServer, federationList, ocapGranted, aliceSendThreads, alicePostLog, aliceCachedWebfingers,alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
sendResult = sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Why is a mouse when it spins?', followersOnly, saveToFile, clientToServer, federationList, aliceSendThreads, alicePostLog, aliceCachedWebfingers,alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
||||||
print('sendResult: '+str(sendResult))
|
print('sendResult: '+str(sendResult))
|
||||||
|
|
||||||
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
|
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
|
||||||
|
@ -280,7 +282,6 @@ def testFollowBetweenServers():
|
||||||
httpPrefix='http'
|
httpPrefix='http'
|
||||||
useTor=False
|
useTor=False
|
||||||
federationList=[]
|
federationList=[]
|
||||||
ocapGranted={}
|
|
||||||
|
|
||||||
baseDir=os.getcwd()
|
baseDir=os.getcwd()
|
||||||
if os.path.isdir(baseDir+'/.tests'):
|
if os.path.isdir(baseDir+'/.tests'):
|
||||||
|
@ -293,17 +294,17 @@ def testFollowBetweenServers():
|
||||||
aliceDir=baseDir+'/.tests/alice'
|
aliceDir=baseDir+'/.tests/alice'
|
||||||
aliceDomain='127.0.0.42'
|
aliceDomain='127.0.0.42'
|
||||||
alicePort=61935
|
alicePort=61935
|
||||||
thrAlice = threadWithTrace(target=createServerAlice,args=(aliceDir,aliceDomain,alicePort,federationList,ocapGranted,False,False,ocapAlways),daemon=True)
|
thrAlice = threadWithTrace(target=createServerAlice,args=(aliceDir,aliceDomain,alicePort,federationList,False,False,ocapAlways),daemon=True)
|
||||||
|
|
||||||
bobDir=baseDir+'/.tests/bob'
|
bobDir=baseDir+'/.tests/bob'
|
||||||
bobDomain='127.0.0.64'
|
bobDomain='127.0.0.64'
|
||||||
bobPort=61936
|
bobPort=61936
|
||||||
thrBob = threadWithTrace(target=createServerBob,args=(bobDir,bobDomain,bobPort,federationList,ocapGranted,False,False,ocapAlways),daemon=True)
|
thrBob = threadWithTrace(target=createServerBob,args=(bobDir,bobDomain,bobPort,federationList,False,False,ocapAlways),daemon=True)
|
||||||
|
|
||||||
eveDir=baseDir+'/.tests/eve'
|
eveDir=baseDir+'/.tests/eve'
|
||||||
eveDomain='127.0.0.55'
|
eveDomain='127.0.0.55'
|
||||||
evePort=61937
|
evePort=61937
|
||||||
thrEve = threadWithTrace(target=createServerEve,args=(eveDir,eveDomain,evePort,federationList,ocapGranted,False,False,False),daemon=True)
|
thrEve = threadWithTrace(target=createServerEve,args=(eveDir,eveDomain,evePort,federationList,False,False,False),daemon=True)
|
||||||
|
|
||||||
thrAlice.start()
|
thrAlice.start()
|
||||||
thrBob.start()
|
thrBob.start()
|
||||||
|
@ -327,6 +328,7 @@ def testFollowBetweenServers():
|
||||||
|
|
||||||
# In the beginning all was calm and there were no follows
|
# In the beginning all was calm and there were no follows
|
||||||
|
|
||||||
|
print('*********************************************************')
|
||||||
print('Alice sends a follow request to Bob')
|
print('Alice sends a follow request to Bob')
|
||||||
print('Both are strictly enforcing object capabilities')
|
print('Both are strictly enforcing object capabilities')
|
||||||
os.chdir(aliceDir)
|
os.chdir(aliceDir)
|
||||||
|
@ -348,20 +350,31 @@ def testFollowBetweenServers():
|
||||||
sendFollowRequest(sessionAlice,aliceDir, \
|
sendFollowRequest(sessionAlice,aliceDir, \
|
||||||
'alice',aliceDomain,alicePort,httpPrefix, \
|
'alice',aliceDomain,alicePort,httpPrefix, \
|
||||||
'bob',bobDomain,bobPort,httpPrefix, \
|
'bob',bobDomain,bobPort,httpPrefix, \
|
||||||
clientToServer,federationList,ocapGranted,
|
clientToServer,federationList,
|
||||||
aliceSendThreads,alicePostLog, \
|
aliceSendThreads,alicePostLog, \
|
||||||
aliceCachedWebfingers,alicePersonCache,True)
|
aliceCachedWebfingers,alicePersonCache,True)
|
||||||
print('sendResult: '+str(sendResult))
|
print('sendResult: '+str(sendResult))
|
||||||
|
|
||||||
|
bobCapsFilename=bobDir+'/accounts/bob@'+bobDomain+'/ocap/accept/'+httpPrefix+':##'+aliceDomain+':'+str(alicePort)+'#users#alice.json'
|
||||||
|
aliceCapsFilename=aliceDir+'/accounts/alice@'+aliceDomain+'/ocap/granted/'+httpPrefix+':##'+bobDomain+':'+str(bobPort)+'#users#bob.json'
|
||||||
|
|
||||||
for t in range(10):
|
for t in range(10):
|
||||||
if os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt'):
|
if os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/followers.txt'):
|
||||||
if os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt'):
|
if os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/following.txt'):
|
||||||
if os.path.isfile(bobDir+'/accounts/bob@'+bobDomain+'/ocap/accept/'+httpPrefix+':##'+aliceDomain+':'+str(alicePort)+'#users#alice.json'):
|
if os.path.isfile(bobCapsFilename):
|
||||||
if os.path.isfile(aliceDir+'/accounts/alice@'+aliceDomain+'/ocap/granted/'+httpPrefix+':##'+bobDomain+':'+str(bobPort)+'#users#bob.json'):
|
if os.path.isfile(aliceCapsFilename):
|
||||||
break
|
break
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
print('\n\nEve tries to send to Bob')
|
with open(bobCapsFilename, 'r') as fp:
|
||||||
|
bobCapsJson=commentjson.load(fp)
|
||||||
|
if not bobCapsJson.get('capability'):
|
||||||
|
print("Unexpected format for Bob's capabilities")
|
||||||
|
pprint(bobCapsJson)
|
||||||
|
assert False
|
||||||
|
|
||||||
|
print('\n\n*********************************************************')
|
||||||
|
print('Eve tries to send to Bob')
|
||||||
sessionEve = createSession(eveDomain,evePort,useTor)
|
sessionEve = createSession(eveDomain,evePort,useTor)
|
||||||
eveSendThreads = []
|
eveSendThreads = []
|
||||||
evePostLog = []
|
evePostLog = []
|
||||||
|
@ -369,7 +382,7 @@ def testFollowBetweenServers():
|
||||||
eveCachedWebfingers={}
|
eveCachedWebfingers={}
|
||||||
eveSendThreads=[]
|
eveSendThreads=[]
|
||||||
evePostLog=[]
|
evePostLog=[]
|
||||||
sendResult = sendPost(sessionEve,eveDir,'eve', eveDomain, evePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Eve message', followersOnly, saveToFile, clientToServer, federationList, ocapGranted, eveSendThreads, evePostLog, eveCachedWebfingers,evePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
sendResult = sendPost(sessionEve,eveDir,'eve', eveDomain, evePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Eve message', followersOnly, saveToFile, clientToServer, federationList, eveSendThreads, evePostLog, eveCachedWebfingers,evePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
||||||
print('sendResult: '+str(sendResult))
|
print('sendResult: '+str(sendResult))
|
||||||
|
|
||||||
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
|
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
|
||||||
|
@ -387,14 +400,15 @@ def testFollowBetweenServers():
|
||||||
assert eveMessageArrived==False
|
assert eveMessageArrived==False
|
||||||
print('Message from Eve to Bob was correctly rejected by object capabilities')
|
print('Message from Eve to Bob was correctly rejected by object capabilities')
|
||||||
|
|
||||||
|
print('\n\n*********************************************************')
|
||||||
|
print('Alice sends a message to Bob')
|
||||||
aliceSendThreads = []
|
aliceSendThreads = []
|
||||||
alicePostLog = []
|
alicePostLog = []
|
||||||
alicePersonCache={}
|
alicePersonCache={}
|
||||||
aliceCachedWebfingers={}
|
aliceCachedWebfingers={}
|
||||||
aliceSendThreads=[]
|
aliceSendThreads=[]
|
||||||
alicePostLog=[]
|
alicePostLog=[]
|
||||||
sendResult = sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Alice message', followersOnly, saveToFile, clientToServer, federationList, ocapGranted, aliceSendThreads, alicePostLog, aliceCachedWebfingers,alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
sendResult = sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, 'bob', bobDomain, bobPort, ccUrl, httpPrefix, 'Alice message', followersOnly, saveToFile, clientToServer, federationList, aliceSendThreads, alicePostLog, aliceCachedWebfingers,alicePersonCache,inReplyTo, inReplyToAtomUri, subject)
|
||||||
print('sendResult: '+str(sendResult))
|
print('sendResult: '+str(sendResult))
|
||||||
|
|
||||||
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
|
queuePath=bobDir+'/accounts/bob@'+bobDomain+'/queue'
|
||||||
|
@ -411,6 +425,64 @@ def testFollowBetweenServers():
|
||||||
assert aliceMessageArrived==True
|
assert aliceMessageArrived==True
|
||||||
print('Message from Alice to Bob succeeded, since it was granted capabilities')
|
print('Message from Alice to Bob succeeded, since it was granted capabilities')
|
||||||
|
|
||||||
|
print('\n\n*********************************************************')
|
||||||
|
print("\nBob changes Alice's capabilities so that she can't reply on his posts")
|
||||||
|
sessionBob = createSession(bobDomain,bobPort,useTor)
|
||||||
|
bobSendThreads = []
|
||||||
|
bobPostLog = []
|
||||||
|
bobPersonCache={}
|
||||||
|
bobCachedWebfingers={}
|
||||||
|
print("Bob's capabilities for Alice:")
|
||||||
|
with open(bobCapsFilename, 'r') as fp:
|
||||||
|
bobCapsJson=commentjson.load(fp)
|
||||||
|
pprint(bobCapsJson)
|
||||||
|
assert "inbox:noreply" not in bobCapsJson['capability']
|
||||||
|
print("Alice's capabilities granted by Bob")
|
||||||
|
with open(aliceCapsFilename, 'r') as fp:
|
||||||
|
aliceCapsJson=commentjson.load(fp)
|
||||||
|
pprint(aliceCapsJson)
|
||||||
|
assert "inbox:noreply" not in aliceCapsJson['capability']
|
||||||
|
newCapabilities=["inbox:write","objects:read","inbox:noreply"]
|
||||||
|
sendCapabilitiesUpdate(sessionBob,bobDir,httpPrefix, \
|
||||||
|
'bob',bobDomain,bobPort, \
|
||||||
|
httpPrefix+'://'+aliceDomain+':'+str(alicePort)+'/users/alice',
|
||||||
|
newCapabilities, \
|
||||||
|
bobSendThreads, bobPostLog, \
|
||||||
|
bobCachedWebfingers,bobPersonCache, \
|
||||||
|
federationList,True)
|
||||||
|
|
||||||
|
bobChanged=False
|
||||||
|
bobNewCapsJson=None
|
||||||
|
for i in range(20):
|
||||||
|
time.sleep(1)
|
||||||
|
with open(bobCapsFilename, 'r') as fp:
|
||||||
|
bobNewCapsJson=commentjson.load(fp)
|
||||||
|
if "inbox:noreply" in bobNewCapsJson['capability']:
|
||||||
|
print("Bob's capabilities were changed")
|
||||||
|
pprint(bobNewCapsJson)
|
||||||
|
bobChanged=True
|
||||||
|
break
|
||||||
|
|
||||||
|
assert bobChanged
|
||||||
|
|
||||||
|
aliceChanged=False
|
||||||
|
aliceNewCapsJson=None
|
||||||
|
for i in range(20):
|
||||||
|
time.sleep(1)
|
||||||
|
with open(aliceCapsFilename, 'r') as fp:
|
||||||
|
aliceNewCapsJson=commentjson.load(fp)
|
||||||
|
if "inbox:noreply" in aliceNewCapsJson['capability']:
|
||||||
|
print("Alice's granted capabilities were changed")
|
||||||
|
pprint(aliceNewCapsJson)
|
||||||
|
aliceChanged=True
|
||||||
|
break
|
||||||
|
|
||||||
|
assert aliceChanged
|
||||||
|
|
||||||
|
# check that the capabilities id has changed
|
||||||
|
assert bobNewCapsJson['id']!=bobCapsJson['id']
|
||||||
|
assert aliceNewCapsJson['id']!=aliceCapsJson['id']
|
||||||
|
|
||||||
# stop the servers
|
# stop the servers
|
||||||
thrAlice.kill()
|
thrAlice.kill()
|
||||||
thrAlice.join()
|
thrAlice.join()
|
||||||
|
|
2
utils.py
2
utils.py
|
@ -48,7 +48,7 @@ def domainPermitted(domain: str, federationList: []):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def urlPermitted(url: str, federationList: [],ocapGranted: {},capability: str):
|
def urlPermitted(url: str, federationList: [],capability: str):
|
||||||
if len(federationList)==0:
|
if len(federationList)==0:
|
||||||
return True
|
return True
|
||||||
for domain in federationList:
|
for domain in federationList:
|
||||||
|
|
Loading…
Reference in New Issue