Adding capabilities to posts

master
Bob Mottram 2019-07-06 11:33:57 +01:00
parent f3065516ae
commit c9d62e8361
12 changed files with 79 additions and 54 deletions

View File

@ -12,13 +12,13 @@ from utils import getStatusNumber
from utils import createOutboxDir from utils import createOutboxDir
from utils import urlPermitted from utils import urlPermitted
def createAcceptReject(baseDir: str,federationList: [],nickname: str,domain: str,port: int,toUrl: str,ccUrl: str,httpPrefix: str,objectUrl: str,acceptType: str) -> {}: def createAcceptReject(baseDir: str,federationList: [],capsList: [],nickname: str,domain: str,port: int,toUrl: str,ccUrl: str,httpPrefix: str,objectUrl: str,acceptType: str) -> {}:
"""Accepts or rejects something (eg. a follow request) """Accepts or rejects something (eg. a follow request)
Typically toUrl will be https://www.w3.org/ns/activitystreams#Public 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 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 objectUrl is typically the url of the message, corresponding to url or atomUri in createPostBase
""" """
if not urlPermitted(objectUrl,federationList): if not urlPermitted(objectUrl,federationList,capsList,"inbox:write"):
return None return None
if port!=80 and port!=443: if port!=80 and port!=443:

View File

@ -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: [], \ def createAnnounce(baseDir: str,federationList: [], capsList: [], \
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) -> {}:
@ -21,7 +21,7 @@ def createAnnounce(baseDir: str,federationList: [], \
and ccUrl might be a specific person favorited or repeated and the followers url 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 objectUrl is typically the url of the message, corresponding to url or atomUri in createPostBase
""" """
if not urlPermitted(objectUrl,federationList): if not urlPermitted(objectUrl,federationList,capsList,"inbox:write"):
return None return None
if port!=80 and port!=443: if port!=80 and port!=443:

View File

@ -16,10 +16,7 @@ def sendCapabilitiesRequest(baseDir: str,httpPrefix: str,domain: str,requestedAc
capRequest = { capRequest = {
"id": httpPrefix+"://"+requestedDomain+"/caps/request/"+capId, "id": httpPrefix+"://"+requestedDomain+"/caps/request/"+capId,
"type": "Request", "type": "Request",
"capability": { "capability": ["inbox:write","objects:read"],
"inbox": inbox,
"objects": objects
},
"actor": requestedActor "actor": requestedActor
} }
#TODO #TODO
@ -30,10 +27,7 @@ def sendCapabilitiesAccept(baseDir: str,httpPrefix: str,nickname: str,domain: st
capAccept = { capAccept = {
"id": httpPrefix+"://"+domain+"/caps/"+capId, "id": httpPrefix+"://"+domain+"/caps/"+capId,
"type": "Capability", "type": "Capability",
"capability": { "capability": ["inbox:write","objects:read"],
"inbox": inbox,
"objects": objects
},
"scope": acceptedActor, "scope": acceptedActor,
"actor": httpPrefix+"://"+domain "actor": httpPrefix+"://"+domain
} }
@ -41,9 +35,10 @@ def sendCapabilitiesAccept(baseDir: str,httpPrefix: str,nickname: str,domain: st
capAccept['actor']=httpPrefix+"://"+domain+'/users/'+nickname capAccept['actor']=httpPrefix+"://"+domain+'/users/'+nickname
#TODO #TODO
def isCapable(actor: str,capsJson: []) -> bool: def isCapable(actor: str,capsJson: [],capability: str) -> bool:
# is the given actor capable of using the current resource? # is the given actor capable of using the current resource?
for cap in capsJson: for cap in capsJson:
if cap['scope'] in actor: if cap['scope'] in actor:
return True if capability in cap['capability']:
return True
return False return False

View File

@ -375,7 +375,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.POSTbusy=False self.server.POSTbusy=False
return return
if not inboxPermittedMessage(self.server.domain,messageJson,self.server.federationList): if not inboxPermittedMessage(self.server.domain,messageJson,self.server.federationList,self.server.capsList):
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')
@ -421,7 +421,7 @@ class PubServer(BaseHTTPRequestHandler):
self.end_headers() self.end_headers()
self.server.POSTbusy=False self.server.POSTbusy=False
def runDaemon(baseDir: str,domain: str,port=80,httpPrefix='https',fedList=[],useTor=False,debug=False) -> None: def runDaemon(baseDir: str,domain: str,port=80,httpPrefix='https',fedList=[],capsList=[],useTor=False,debug=False) -> None:
if len(domain)==0: if len(domain)==0:
domain='localhost' domain='localhost'
if '.' not in domain: if '.' not in domain:
@ -436,6 +436,7 @@ def runDaemon(baseDir: str,domain: str,port=80,httpPrefix='https',fedList=[],use
httpd.httpPrefix=httpPrefix httpd.httpPrefix=httpPrefix
httpd.debug=debug httpd.debug=debug
httpd.federationList=fedList.copy() httpd.federationList=fedList.copy()
httpd.capsList=capsList.copy()
httpd.baseDir=baseDir httpd.baseDir=baseDir
httpd.personCache={} httpd.personCache={}
httpd.cachedWebfingers={} httpd.cachedWebfingers={}

View File

@ -286,7 +286,7 @@ if args.changepassword:
if not args.domain and not domain: if not args.domain and not domain:
print('Specify a domain with --domain [name]') print('Specify a domain with --domain [name]')
sys.exit() sys.exit()
federationList=[] federationList=[]
if args.federationList: if args.federationList:
if len(args.federationList)==1: if len(args.federationList)==1:
@ -304,6 +304,8 @@ else:
if configFederationList: if configFederationList:
federationList=configFederationList federationList=configFederationList
capsList=[]
if federationList: if federationList:
print('Federating with: '+str(federationList)) print('Federating with: '+str(federationList))
@ -322,4 +324,4 @@ if not os.path.isdir(baseDir+'/accounts/capabilities@'+domain):
print('Creating capabilities account which can sign requests') print('Creating capabilities account which can sign requests')
createCapabilitiesInbox(baseDir,'capabilities',domain,port,httpPrefix) createCapabilitiesInbox(baseDir,'capabilities',domain,port,httpPrefix)
runDaemon(baseDir,domain,port,httpPrefix,federationList,useTor,debug) runDaemon(baseDir,domain,port,httpPrefix,federationList,capsList,useTor,debug)

View File

@ -13,6 +13,7 @@ import sys
from person import validNickname from person import validNickname
from utils import domainPermitted from utils import domainPermitted
from posts import sendSignedJson from posts import sendSignedJson
from capabilities import isCapable
def getFollowersOfPerson(baseDir: str,nickname: str,domain: str,followFile='following.txt') -> []: def getFollowersOfPerson(baseDir: str,nickname: str,domain: str,followFile='following.txt') -> []:
"""Returns a list containing the followers of the given person """Returns a list containing the followers of the given person
@ -268,7 +269,7 @@ def receiveFollowRequest(session,baseDir: str,httpPrefix: str,port: int,sendThre
def sendFollowRequest(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \ def sendFollowRequest(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
followNickname: str,followDomain: str,followPort: bool,followHttpPrefix: str, \ followNickname: str,followDomain: str,followPort: bool,followHttpPrefix: str, \
federationList: []) -> {}: federationList: [],capsList: []) -> {}:
"""Gets the json object for sending a follow request """Gets the json object for sending a follow request
""" """
if not domainPermitted(followDomain,federationList): if not domainPermitted(followDomain,federationList):
@ -280,9 +281,16 @@ def sendFollowRequest(baseDir: str,nickname: str,domain: str,port: int,httpPrefi
if followPort!=80 and followPort!=443: if followPort!=80 and followPort!=443:
followDomain=followDomain+':'+str(followPort) followDomain=followDomain+':'+str(followPort)
followActor=httpPrefix+'://'+domain+'/users/'+nickname
# check that we are capable
if capsList:
if not isCapable(followActor,capsList,'inbox:write'):
return None
newFollowJson = { newFollowJson = {
'type': 'Follow', 'type': 'Follow',
'actor': httpPrefix+'://'+domain+'/users/'+nickname, 'actor': followActor,
'object': followHttpPrefix+'://'+followDomain+'/users/'+followNickname 'object': followHttpPrefix+'://'+followDomain+'/users/'+followNickname
} }

View File

@ -59,7 +59,7 @@ def inboxMessageHasParams(messageJson: {}) -> bool:
return False return False
return True return True
def inboxPermittedMessage(domain: str,messageJson: {},federationList: []) -> bool: def inboxPermittedMessage(domain: str,messageJson: {},federationList: [],capsList: []) -> bool:
""" check that we are receiving from a permitted domain """ check that we are receiving from a permitted domain
""" """
testParam='actor' testParam='actor'
@ -70,13 +70,13 @@ def inboxPermittedMessage(domain: str,messageJson: {},federationList: []) -> boo
if domain in actor: if domain in actor:
return True return True
if not urlPermitted(actor,federationList): if not urlPermitted(actor,federationList,capsList,"inbox:write"):
return False return False
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): if not urlPermitted(inReplyTo,federationList,capsList):
return False return False
return True return True

View File

@ -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): if not urlPermitted(objectUrl,federationList,capsList,"inbox:write"):
return None return None
if port!=80 and port!=443: if port!=80 and port!=443:

View File

@ -30,6 +30,7 @@ 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 capabilities import isCapable
try: try:
from BeautifulSoup import BeautifulSoup from BeautifulSoup import BeautifulSoup
except ImportError: except ImportError:
@ -153,7 +154,8 @@ def getPersonBox(session,wfRequest: {},personCache: {},boxName='inbox') -> (str,
return boxJson,pubKeyId,pubKey,personId,sharedInbox,capabilityAcquisition return boxJson,pubKeyId,pubKey,personId,sharedInbox,capabilityAcquisition
def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \ def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
maxEmoji: int,maxAttachments: int,federationList: [], \ maxEmoji: int,maxAttachments: int, \
federationList: [], capsList: [],\
personCache: {},raw: bool,simple: bool) -> {}: personCache: {},raw: bool,simple: bool) -> {}:
personPosts={} personPosts={}
if not outboxUrl: if not outboxUrl:
@ -192,7 +194,7 @@ def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
if tagItem.get('name') and tagItem.get('icon'): if tagItem.get('name') and tagItem.get('icon'):
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'],federationList): if urlPermitted(tagItem['icon']['url'],federationList,capsList,"objects:read"):
emojiName=tagItem['name'] emojiName=tagItem['name']
emojiIcon=tagItem['icon']['url'] emojiIcon=tagItem['icon']['url']
emoji[emojiName]=emojiIcon emoji[emojiName]=emojiIcon
@ -214,7 +216,7 @@ def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
if item['object'].get('inReplyTo'): if item['object'].get('inReplyTo'):
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'],federationList): if not urlPermitted(item['object']['inReplyTo'],federationList,capsList,"objects:read"):
continue continue
inReplyTo = item['object']['inReplyTo'] inReplyTo = item['object']['inReplyTo']
@ -222,7 +224,7 @@ def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
if item['object'].get('conversation'): if item['object'].get('conversation'):
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'],federationList): if urlPermitted(item['object']['conversation'],federationList,"objects:read"):
conversation = item['object']['conversation'] conversation = item['object']['conversation']
attachment = [] attachment = []
@ -231,7 +233,7 @@ def getPosts(session,outboxUrl: str,maxPosts: int,maxMentions: int, \
for attach in item['object']['attachment']: for attach in item['object']['attachment']:
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'],federationList): if urlPermitted(attach['url'],federationList,capsList,"objects:read"):
attachment.append([attach['name'],attach['url']]) attachment.append([attach['name'],attach['url']])
sensitive = False sensitive = False
@ -308,6 +310,7 @@ def savePostToBox(baseDir: str,httpPrefix: str,postId: str,nickname: str, domain
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, \
capsList: [], \
inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}: inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}:
"""Creates a message """Creates a message
""" """
@ -331,11 +334,16 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
summary=subject summary=subject
sensitive=True sensitive=True
if not clientToServer: if not clientToServer:
actorUrl=httpPrefix+'://'+domain+'/users/'+nickname
if capsList:
if not isCapable(actorUrl,capsList,'inbox:write'):
return None
newPost = { newPost = {
'id': newPostId+'/activity', 'id': newPostId+'/activity',
'capability': capabilityUrl, 'capability': capabilityUrl,
'type': 'Create', 'type': 'Create',
'actor': httpPrefix+'://'+domain+'/users/'+nickname, 'actor': actorUrl,
'published': published, 'published': published,
'to': [toUrl], 'to': [toUrl],
'cc': [], 'cc': [],
@ -433,7 +441,7 @@ def outboxMessageCreateWrap(httpPrefix: str,nickname: str,domain: str,messageJso
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, \ clientToServer: bool, capsList: [],\
inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}: inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}:
"""Public post to the outbox """Public post to the outbox
""" """
@ -441,17 +449,18 @@ 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, clientToServer, \ httpPrefix, content, followersOnly, saveToFile, clientToServer, \
capsList,
inReplyTo, inReplyToAtomUri, subject) inReplyTo, inReplyToAtomUri, subject)
def threadSendPost(session,postJsonObject: {},federationList: [],inboxUrl: str, \ def threadSendPost(session,postJsonObject: {},federationList: [],capsList: [],\
baseDir: str,signatureHeaderJson: {},postLog: []) -> None: inboxUrl: str, baseDir: str,signatureHeaderJson: {},postLog: []) -> None:
"""Sends a post with exponential backoff """Sends a post with exponential backoff
""" """
tries=0 tries=0
backoffTime=60 backoffTime=60
for attempt in range(20): for attempt in range(20):
postResult = postJson(session,postJsonObject,federationList, \ postResult = postJson(session,postJsonObject,federationList, \
inboxUrl,signatureHeaderJson) capsList,inboxUrl,signatureHeaderJson)
if postResult: if postResult:
postLog.append(postJsonObject['published']+' '+postResult+'\n') postLog.append(postJsonObject['published']+' '+postResult+'\n')
# keep the length of the log finite # keep the length of the log finite
@ -471,7 +480,8 @@ def threadSendPost(session,postJsonObject: {},federationList: [],inboxUrl: str,
def sendPost(session,baseDir: str,nickname: str, domain: str, port: int, \ 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, federationList: [], \ saveToFile: bool, clientToServer: bool, \
federationList: [], capsList: [],\
sendThreads: [], postLog: [], cachedWebfingers: {},personCache: {}, \ sendThreads: [], postLog: [], cachedWebfingers: {},personCache: {}, \
inReplyTo=None, inReplyToAtomUri=None, subject=None) -> int: inReplyTo=None, inReplyToAtomUri=None, subject=None) -> int:
"""Post to another inbox """Post to another inbox
@ -519,8 +529,8 @@ 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, \
inReplyTo,inReplyToAtomUri, \ capsList, \
subject) inReplyTo,inReplyToAtomUri,subject)
# get the senders private key # get the senders private key
privateKeyPem=getPersonKey(nickname,domain,baseDir,'private') privateKeyPem=getPersonKey(nickname,domain,baseDir,'private')
@ -543,6 +553,7 @@ 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, \
capsList, \
inboxUrl,baseDir, \ inboxUrl,baseDir, \
signatureHeaderJson.copy(), \ signatureHeaderJson.copy(), \
postLog),daemon=True) postLog),daemon=True)
@ -552,7 +563,8 @@ def sendPost(session,baseDir: str,nickname: str, domain: str, port: int, \
def sendSignedJson(postJsonObject: {},session,baseDir: str,nickname: str, domain: str, port: int, \ def sendSignedJson(postJsonObject: {},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, saveToFile: bool, clientToServer: bool, federationList: [], \ httpPrefix: str, saveToFile: bool, clientToServer: bool, \
federationList: [], capsList: [], \
sendThreads: [], postLog: [], cachedWebfingers: {},personCache: {}) -> int: sendThreads: [], postLog: [], cachedWebfingers: {},personCache: {}) -> int:
"""Sends a signed json object to an inbox/outbox """Sends a signed json object to an inbox/outbox
""" """
@ -616,6 +628,7 @@ def sendSignedJson(postJsonObject: {},session,baseDir: str,nickname: str, domain
thr = threadWithTrace(target=threadSendPost,args=(session, \ thr = threadWithTrace(target=threadSendPost,args=(session, \
postJsonObject.copy(), \ postJsonObject.copy(), \
federationList, \ federationList, \
capsList, \
inboxUrl,baseDir, \ inboxUrl,baseDir, \
signatureHeaderJson.copy(), \ signatureHeaderJson.copy(), \
postLog),daemon=True) postLog),daemon=True)

View File

@ -39,11 +39,12 @@ def getJson(session,url: str,headers: {},params: {}) -> {}:
pass pass
return None return None
def postJson(session,postJsonObject: {},federationList: [],inboxUrl: str,headers: {}) -> str: def postJson(session,postJsonObject: {},federationList: [],capsList: [],inboxUrl: str,headers: {}) -> str:
"""Post a json message to the inbox of another person """Post a json message to the inbox of another person
""" """
# check that we are posting to a permitted domain # check that we are posting to a permitted domain
if not urlPermitted(inboxUrl,federationList): if not urlPermitted(inboxUrl,federationList,capsList,"inbox:write"):
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)

View File

@ -107,7 +107,7 @@ def testThreads():
thr.join() thr.join()
assert thr.isAlive()==False assert thr.isAlive()==False
def createServerAlice(path: str,domain: str,port: int,federationList: []): def createServerAlice(path: str,domain: str,port: int,federationList: [],capsList: []):
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)
@ -123,15 +123,15 @@ def createServerAlice(path: str,domain: str,port: int,federationList: []):
deleteAllPosts(path,nickname,domain,'outbox') deleteAllPosts(path,nickname,domain,'outbox')
followPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList) followPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList)
followerOfPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList) followerOfPerson(path,nickname,domain,'bob','127.0.0.100:61936',federationList)
createPublicPost(path,nickname, domain, port,httpPrefix, "No wise fish would go anywhere without a porpoise", False, True, clientToServer) 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) createPublicPost(path,nickname, domain, port,httpPrefix, "Curiouser and curiouser!", False, True, clientToServer,capsList)
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) 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,capsList)
global testServerAliceRunning global testServerAliceRunning
testServerAliceRunning = True testServerAliceRunning = True
print('Server running: Alice') print('Server running: Alice')
runDaemon(path,domain,port,httpPrefix,federationList,useTor,True) runDaemon(path,domain,port,httpPrefix,federationList,capsList,useTor,True)
def createServerBob(path: str,domain: str,port: int,federationList: []): def createServerBob(path: str,domain: str,port: int,federationList: [],capsList: []):
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)
@ -147,13 +147,13 @@ def createServerBob(path: str,domain: str,port: int,federationList: []):
deleteAllPosts(path,nickname,domain,'outbox') deleteAllPosts(path,nickname,domain,'outbox')
followPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList) followPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList)
followerOfPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList) followerOfPerson(path,nickname,domain,'alice','127.0.0.50:61935',federationList)
createPublicPost(path,nickname, domain, port,httpPrefix, "It's your life, live it your way.", False, True, clientToServer) 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) createPublicPost(path,nickname, domain, port,httpPrefix, "One of the things I've realised is that I am very simple", False, True, clientToServer,capsList)
createPublicPost(path,nickname, domain, port,httpPrefix, "Quantum physics is a bit of a passion of mine", False, True, clientToServer) createPublicPost(path,nickname, domain, port,httpPrefix, "Quantum physics is a bit of a passion of mine", False, True, clientToServer,capsList)
global testServerBobRunning global testServerBobRunning
testServerBobRunning = True testServerBobRunning = True
print('Server running: Bob') print('Server running: Bob')
runDaemon(path,domain,port,httpPrefix,federationList,useTor,True) runDaemon(path,domain,port,httpPrefix,federationList,capsList,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')
@ -166,6 +166,7 @@ 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']
capsList=[]
baseDir=os.getcwd() baseDir=os.getcwd()
if not os.path.isdir(baseDir+'/.tests'): if not os.path.isdir(baseDir+'/.tests'):
@ -175,12 +176,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),daemon=True) thrAlice = threadWithTrace(target=createServerAlice,args=(aliceDir,aliceDomain,alicePort,federationList,capsList),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),daemon=True) thrBob = threadWithTrace(target=createServerBob,args=(bobDir,bobDomain,bobPort,federationList,capsList),daemon=True)
thrAlice.start() thrAlice.start()
thrBob.start() thrBob.start()
@ -207,7 +208,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, 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, capsList, 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'

View File

@ -8,6 +8,7 @@ __status__ = "Production"
import os import os
import datetime import datetime
from capabilities import isCapable
def getStatusNumber() -> (str,str): def getStatusNumber() -> (str,str):
"""Returns the status number and published date """Returns the status number and published date
@ -48,7 +49,10 @@ def domainPermitted(domain: str, federationList: []):
return True return True
return False return False
def urlPermitted(url: str, federationList: []): def urlPermitted(url: str, federationList: [],capsList: [],capability: str):
if capsList:
if not isCapable(url,capsList,capability):
return False
if len(federationList)==0: if len(federationList)==0:
return True return True
for domain in federationList: for domain in federationList: