Unit test for federated shared items

main
Bob Mottram 2021-08-05 12:24:24 +01:00
parent ccc0d09ece
commit 0f71fae658
5 changed files with 209 additions and 86 deletions

View File

@ -4893,9 +4893,10 @@ class PubServer(BaseHTTPRequestHandler):
self.server.sharedItemFederationTokens self.server.sharedItemFederationTokens
self.server.sharedItemsFederatedDomains = \ self.server.sharedItemsFederatedDomains = \
siDomains siDomains
domainFull = self.server.domainFull
self.server.sharedItemFederationTokens = \ self.server.sharedItemFederationTokens = \
mergeSharedItemTokens(self.server.baseDir, mergeSharedItemTokens(self.server.baseDir,
self.server.domain, domainFull,
siDomains, siDomains,
siTokens) siTokens)
@ -10820,13 +10821,15 @@ class PubServer(BaseHTTPRequestHandler):
print('Catalog access is not authorized. Checking' + print('Catalog access is not authorized. Checking' +
'Authorization header') 'Authorization header')
# basic auth access to shared items catalog # basic auth access to shared items catalog
if self.headers.get('Authorization'): if self.headers.get('Origin') and \
self.headers.get('Authorization'):
permittedDomains = \ permittedDomains = \
self.server.sharedItemsFederatedDomains self.server.sharedItemsFederatedDomains
sharedItemTokens = self.server.sharedItemFederationTokens sharedItemTokens = self.server.sharedItemFederationTokens
originDomain = self.headers.get('Origin')
if authorizeSharedItems(permittedDomains, if authorizeSharedItems(permittedDomains,
self.server.baseDir, self.server.baseDir,
callingDomain, originDomain,
self.headers['Authorization'], self.headers['Authorization'],
self.server.debug, self.server.debug,
sharedItemTokens): sharedItemTokens):
@ -10835,8 +10838,12 @@ class PubServer(BaseHTTPRequestHandler):
print('Authorization token refused for ' + print('Authorization token refused for ' +
'shared items federation') 'shared items federation')
elif self.server.debug: elif self.server.debug:
print('No authorization header is available for ' + if not self.headers.get('Origin'):
'shared items federation') print('No Origin header is available for ' +
'shared items federation')
else:
print('No Authorization header is available for ' +
'shared items federation')
# show shared items catalog for federation # show shared items catalog for federation
if self._hasAccept(callingDomain) and catalogAuthorized: if self._hasAccept(callingDomain) and catalogAuthorized:
catalogType = 'json' catalogType = 'json'
@ -14625,6 +14632,49 @@ class PubServer(BaseHTTPRequestHandler):
self.server.defaultTimeline) self.server.defaultTimeline)
return return
# update the shared item federation token for the calling domain
# if it is within the permitted federation
if self.headers.get('Origin') and \
self.headers.get('SharesCatalog'):
if self.server.debug:
print('SharesCatalog header: ' + self.headers['SharesCatalog'])
if not self.server.sharedItemsFederatedDomains:
siDomainsStr = getConfigParam(self.server.baseDir,
'sharedItemsFederatedDomains')
if siDomainsStr:
if self.server.debug:
print('Loading shared items federated domains list')
siDomainsList = siDomainsStr.split(',')
domainsList = self.server.sharedItemsFederatedDomains
for siDomain in siDomainsList:
domainsList.append(siDomain.strip())
originDomain = self.headers.get('Origin')
if originDomain != self.server.domainFull and \
originDomain != self.server.onionDomain and \
originDomain != self.server.i2pDomain and \
originDomain in self.server.sharedItemsFederatedDomains:
if self.server.debug:
print('DEBUG: ' +
'POST updating shared item federation ' +
'token for ' + originDomain + ' to ' +
self.server.domainFull)
sharedItemTokens = self.server.sharedItemFederationTokens
sharesToken = self.headers['SharesCatalog']
self.server.sharedItemFederationTokens = \
updateSharedItemFederationToken(self.server.baseDir,
originDomain,
sharesToken,
self.server.debug,
sharedItemTokens)
elif self.server.debug:
if originDomain not in self.server.sharedItemsFederatedDomains:
print('originDomain is not in federated domains list ' +
originDomain)
else:
print('originDomain is not a different instance. ' +
originDomain + ' ' + self.server.domainFull + ' ' +
str(self.server.sharedItemsFederatedDomains))
self._benchmarkPOSTtimings(POSTstartTime, POSTtimings, 14) self._benchmarkPOSTtimings(POSTstartTime, POSTtimings, 14)
# receive different types of post created by htmlNewPost # receive different types of post created by htmlNewPost
@ -14906,23 +14956,6 @@ class PubServer(BaseHTTPRequestHandler):
self._benchmarkPOSTtimings(POSTstartTime, POSTtimings, 23) self._benchmarkPOSTtimings(POSTstartTime, POSTtimings, 23)
# update the shared item federation token for the calling domain
# if it is within the permitted federation
if self.headers.get('SharesCatalog') and \
callingDomain != self.server.domain and \
callingDomain != self.server.domainFull and \
callingDomain in self.server.sharedItemsFederatedDomains:
if self.server.debug:
print('DEBUG: ' +
'POST updating shared item federation token for ' +
callingDomain)
sharedItemTokens = self.server.sharedItemFederationTokens
self.server.sharedItemFederationTokens = \
updateSharedItemFederationToken(self.server.baseDir,
callingDomain,
self.headers['SharesCatalog'],
sharedItemTokens)
if self.server.debug: if self.server.debug:
print('DEBUG: POST saving to inbox queue') print('DEBUG: POST saving to inbox queue')
if usersInPath: if usersInPath:
@ -15469,7 +15502,7 @@ def runDaemon(maxLikeCount: int,
generateSharedItemFederationTokens(httpd.sharedItemsFederatedDomains, generateSharedItemFederationTokens(httpd.sharedItemsFederatedDomains,
baseDir) baseDir)
httpd.sharedItemFederationTokens = \ httpd.sharedItemFederationTokens = \
createSharedItemFederationToken(baseDir, domain, createSharedItemFederationToken(baseDir, httpd.domainFull,
httpd.sharedItemFederationTokens) httpd.sharedItemFederationTokens)
# load peertube instances from file into a list # load peertube instances from file into a list
@ -15518,7 +15551,7 @@ def runDaemon(maxLikeCount: int,
httpd.thrFederatedSharesDaemon = \ httpd.thrFederatedSharesDaemon = \
threadWithTrace(target=runFederatedSharesDaemon, threadWithTrace(target=runFederatedSharesDaemon,
args=(baseDir, httpd, args=(baseDir, httpd,
httpPrefix, domain, httpPrefix, httpd.domainFull,
proxyType, debug, proxyType, debug,
httpd.systemLanguage), daemon=True) httpd.systemLanguage), daemon=True)

View File

@ -614,7 +614,6 @@ if args.tests:
if args.testsnetwork: if args.testsnetwork:
print('Network Tests') print('Network Tests')
testSharedItemsFederation() testSharedItemsFederation()
sys.exit()
testGroupFollow() testGroupFollow()
testPostMessageBetweenServers() testPostMessageBetweenServers()
testFollowBetweenServers() testFollowBetweenServers()

View File

@ -2009,9 +2009,11 @@ def sendPost(projectVersion: str,
federationList: [], sendThreads: [], postLog: [], federationList: [], sendThreads: [], postLog: [],
cachedWebfingers: {}, personCache: {}, cachedWebfingers: {}, personCache: {},
isArticle: bool, systemLanguage: str, isArticle: bool, systemLanguage: str,
sharedItemsFederatedDomains: [],
sharedItemFederationTokens: {},
debug: bool = False, inReplyTo: str = None, debug: bool = False, inReplyTo: str = None,
inReplyToAtomUri: str = None, subject: str = None) -> int: inReplyToAtomUri: str = None, subject: str = None) -> int:
"""Post to another inbox """Post to another inbox. Used by unit tests.
""" """
withDigest = True withDigest = True
@ -2099,6 +2101,26 @@ def sendPost(projectVersion: str,
toDomain, toPort, toDomain, toPort,
postPath, httpPrefix, withDigest, postJsonStr) postPath, httpPrefix, withDigest, postJsonStr)
# if the "to" domain is within the shared items
# federation list then send the token for this domain
# so that it can request a catalog
if toDomain in sharedItemsFederatedDomains:
domainFull = getFullDomain(domain, port)
if sharedItemFederationTokens.get(domainFull):
signatureHeaderJson['Origin'] = domainFull
signatureHeaderJson['SharesCatalog'] = \
sharedItemFederationTokens[domainFull]
if debug:
print('SharesCatalog added to header')
elif debug:
print(domainFull + ' not in sharedItemFederationTokens')
elif debug:
print(toDomain + ' not in sharedItemsFederatedDomains ' +
str(sharedItemsFederatedDomains))
if debug:
print('signatureHeaderJson: ' + str(signatureHeaderJson))
# Keep the number of threads being used small # Keep the number of threads being used small
while len(sendThreads) > 1000: while len(sendThreads) > 1000:
print('WARN: Maximum threads reached - killing send thread') print('WARN: Maximum threads reached - killing send thread')
@ -2139,14 +2161,14 @@ def sendPostViaServer(projectVersion: str,
print('WARN: No session for sendPostViaServer') print('WARN: No session for sendPostViaServer')
return 6 return 6
fromDomain = getFullDomain(fromDomain, fromPort) fromDomainFull = getFullDomain(fromDomain, fromPort)
handle = httpPrefix + '://' + fromDomain + '/@' + fromNickname handle = httpPrefix + '://' + fromDomainFull + '/@' + fromNickname
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, cachedWebfingers, webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
fromDomain, projectVersion, debug, False) fromDomainFull, projectVersion, debug, False)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: post webfinger failed for ' + handle) print('DEBUG: post webfinger failed for ' + handle)
@ -2167,7 +2189,7 @@ def sendPostViaServer(projectVersion: str,
personCache, personCache,
projectVersion, httpPrefix, projectVersion, httpPrefix,
fromNickname, fromNickname,
fromDomain, postToBox, fromDomainFull, postToBox,
82796) 82796)
if not inboxUrl: if not inboxUrl:
if debug: if debug:
@ -2185,7 +2207,6 @@ def sendPostViaServer(projectVersion: str,
clientToServer = True clientToServer = True
if toDomain.lower().endswith('public'): if toDomain.lower().endswith('public'):
toPersonId = 'https://www.w3.org/ns/activitystreams#Public' toPersonId = 'https://www.w3.org/ns/activitystreams#Public'
fromDomainFull = getFullDomain(fromDomain, fromPort)
cc = httpPrefix + '://' + fromDomainFull + '/users/' + \ cc = httpPrefix + '://' + fromDomainFull + '/users/' + \
fromNickname + '/followers' fromNickname + '/followers'
else: else:
@ -2217,7 +2238,7 @@ def sendPostViaServer(projectVersion: str,
if attachImageFilename: if attachImageFilename:
headers = { headers = {
'host': fromDomain, 'host': fromDomainFull,
'Authorization': authHeader 'Authorization': authHeader
} }
postResult = \ postResult = \
@ -2229,7 +2250,7 @@ def sendPostViaServer(projectVersion: str,
# return 9 # return 9
headers = { headers = {
'host': fromDomain, 'host': fromDomainFull,
'Content-type': 'application/json', 'Content-type': 'application/json',
'Authorization': authHeader 'Authorization': authHeader
} }
@ -2434,7 +2455,10 @@ def sendSignedJson(postJsonObject: {}, session, baseDir: str,
# optionally add a token so that the receiving instance may access # optionally add a token so that the receiving instance may access
# your shared items catalog # your shared items catalog
if sharedItemsToken: if sharedItemsToken:
signatureHeaderJson['Origin'] = getFullDomain(domain, port)
signatureHeaderJson['SharesCatalog'] = sharedItemsToken signatureHeaderJson['SharesCatalog'] = sharedItemsToken
elif debug:
print('Not sending shared items federation token')
# Keep the number of threads being used small # Keep the number of threads being used small
while len(sendThreads) > 1000: while len(sendThreads) > 1000:

View File

@ -1080,9 +1080,9 @@ def generateSharedItemFederationTokens(sharedItemsFederatedDomains: [],
tokensJson = {} tokensJson = {}
tokensAdded = False tokensAdded = False
for domain in sharedItemsFederatedDomains: for domainFull in sharedItemsFederatedDomains:
if not tokensJson.get(domain): if not tokensJson.get(domainFull):
tokensJson[domain] = '' tokensJson[domainFull] = ''
tokensAdded = True tokensAdded = True
if not tokensAdded: if not tokensAdded:
@ -1093,33 +1093,38 @@ def generateSharedItemFederationTokens(sharedItemsFederatedDomains: [],
def updateSharedItemFederationToken(baseDir: str, def updateSharedItemFederationToken(baseDir: str,
tokenDomain: str, newToken: str, tokenDomainFull: str, newToken: str,
debug: bool,
tokensJson: {} = None) -> {}: tokensJson: {} = None) -> {}:
"""Updates an individual token for shared item federation """Updates an individual token for shared item federation
""" """
if debug:
print('Updating shared items token for ' + tokenDomainFull)
if not tokensJson: if not tokensJson:
tokensJson = {} tokensJson = {}
if baseDir: if baseDir:
tokensFilename = \ tokensFilename = \
baseDir + '/accounts/sharedItemsFederationTokens.json' baseDir + '/accounts/sharedItemsFederationTokens.json'
if os.path.isfile(tokensFilename): if os.path.isfile(tokensFilename):
if debug:
print('Update loading tokens for ' + tokenDomainFull)
tokensJson = loadJson(tokensFilename, 1, 2) tokensJson = loadJson(tokensFilename, 1, 2)
if tokensJson is None: if tokensJson is None:
tokensJson = {} tokensJson = {}
updateRequired = False updateRequired = False
if tokensJson.get(tokenDomain): if tokensJson.get(tokenDomainFull):
if tokensJson[tokenDomain] != newToken: if tokensJson[tokenDomainFull] != newToken:
updateRequired = True updateRequired = True
else: else:
updateRequired = True updateRequired = True
if updateRequired: if updateRequired:
tokensJson[tokenDomain] = newToken tokensJson[tokenDomainFull] = newToken
if baseDir: if baseDir:
saveJson(tokensJson, tokensFilename) saveJson(tokensJson, tokensFilename)
return tokensJson return tokensJson
def mergeSharedItemTokens(baseDir: str, domain: str, def mergeSharedItemTokens(baseDir: str, domainFull: str,
newSharedItemsFederatedDomains: [], newSharedItemsFederatedDomains: [],
tokensJson: {}) -> {}: tokensJson: {}) -> {}:
"""When the shared item federation domains list has changed, update """When the shared item federation domains list has changed, update
@ -1127,20 +1132,20 @@ def mergeSharedItemTokens(baseDir: str, domain: str,
""" """
removals = [] removals = []
changed = False changed = False
for tokenDomain, tok in tokensJson.items(): for tokenDomainFull, tok in tokensJson.items():
if domain: if domainFull:
if tokenDomain.startswith(domain): if tokenDomainFull.startswith(domainFull):
continue continue
if tokenDomain not in newSharedItemsFederatedDomains: if tokenDomainFull not in newSharedItemsFederatedDomains:
removals.append(tokenDomain) removals.append(tokenDomainFull)
# remove domains no longer in the federation list # remove domains no longer in the federation list
for tokenDomain in removals: for tokenDomainFull in removals:
del tokensJson[tokenDomain] del tokensJson[tokenDomainFull]
changed = True changed = True
# add new domains from the federation list # add new domains from the federation list
for tokenDomain in newSharedItemsFederatedDomains: for tokenDomainFull in newSharedItemsFederatedDomains:
if tokenDomain not in tokensJson: if tokenDomainFull not in tokensJson:
tokensJson[tokenDomain] = '' tokensJson[tokenDomainFull] = ''
changed = True changed = True
if baseDir and changed: if baseDir and changed:
tokensFilename = \ tokensFilename = \
@ -1150,7 +1155,7 @@ def mergeSharedItemTokens(baseDir: str, domain: str,
def createSharedItemFederationToken(baseDir: str, def createSharedItemFederationToken(baseDir: str,
tokenDomain: str, tokenDomainFull: str,
tokensJson: {} = None) -> {}: tokensJson: {} = None) -> {}:
"""Updates an individual token for shared item federation """Updates an individual token for shared item federation
""" """
@ -1163,8 +1168,8 @@ def createSharedItemFederationToken(baseDir: str,
tokensJson = loadJson(tokensFilename, 1, 2) tokensJson = loadJson(tokensFilename, 1, 2)
if tokensJson is None: if tokensJson is None:
tokensJson = {} tokensJson = {}
if not tokensJson.get(tokenDomain): if not tokensJson.get(tokenDomainFull):
tokensJson[tokenDomain] = secrets.token_urlsafe(64) tokensJson[tokenDomainFull] = secrets.token_urlsafe(64)
if baseDir: if baseDir:
saveJson(tokensJson, tokensFilename) saveJson(tokensJson, tokensFilename)
return tokensJson return tokensJson
@ -1172,7 +1177,7 @@ def createSharedItemFederationToken(baseDir: str,
def authorizeSharedItems(sharedItemsFederatedDomains: [], def authorizeSharedItems(sharedItemsFederatedDomains: [],
baseDir: str, baseDir: str,
callingDomain: str, originDomainFull: str,
authHeader: str, authHeader: str,
debug: bool, debug: bool,
tokensJson: {} = None) -> bool: tokensJson: {} = None) -> bool:
@ -1181,9 +1186,9 @@ def authorizeSharedItems(sharedItemsFederatedDomains: [],
if not sharedItemsFederatedDomains: if not sharedItemsFederatedDomains:
# no shared item federation # no shared item federation
return False return False
if callingDomain not in sharedItemsFederatedDomains: if originDomainFull not in sharedItemsFederatedDomains:
if debug: if debug:
print(callingDomain + print(originDomainFull +
' is not in the shared items federation list') ' is not in the shared items federation list')
return False return False
if 'Basic ' in authHeader: if 'Basic ' in authHeader:
@ -1211,21 +1216,22 @@ def authorizeSharedItems(sharedItemsFederatedDomains: [],
tokensJson = loadJson(tokensFilename, 1, 2) tokensJson = loadJson(tokensFilename, 1, 2)
if not tokensJson: if not tokensJson:
return False return False
if not tokensJson.get(callingDomain): if not tokensJson.get(originDomainFull):
if debug: if debug:
print('DEBUG: shared item federation token ' + print('DEBUG: shared item federation token ' +
'check failed for ' + callingDomain) 'check failed for ' + originDomainFull)
return False return False
if not constantTimeStringCheck(tokensJson[callingDomain], providedToken): if not constantTimeStringCheck(tokensJson[originDomainFull],
providedToken):
if debug: if debug:
print('DEBUG: shared item federation token ' + print('DEBUG: shared item federation token ' +
'mismatch for ' + callingDomain) 'mismatch for ' + originDomainFull)
return False return False
return True return True
def _updateFederatedSharesCache(session, sharedItemsFederatedDomains: [], def _updateFederatedSharesCache(session, sharedItemsFederatedDomains: [],
baseDir: str, domain: str, baseDir: str, domainFull: str,
httpPrefix: str, httpPrefix: str,
tokensJson: {}, debug: bool, tokensJson: {}, debug: bool,
systemLanguage: str) -> None: systemLanguage: str) -> None:
@ -1242,37 +1248,38 @@ def _updateFederatedSharesCache(session, sharedItemsFederatedDomains: [],
os.mkdir(catalogsDir) os.mkdir(catalogsDir)
asHeader = { asHeader = {
'Accept': 'application/ld+json' "Accept": "application/ld+json",
"Origin": domainFull
} }
for federatedDomain in sharedItemsFederatedDomains: for federatedDomainFull in sharedItemsFederatedDomains:
# NOTE: federatedDomain does not have a port extension, # NOTE: federatedDomain does not have a port extension,
# so may not work in some situations # so may not work in some situations
if federatedDomain.startswith(domain): if federatedDomainFull.startswith(domainFull):
# only download from instances other than this one # only download from instances other than this one
continue continue
if not tokensJson.get(federatedDomain): if not tokensJson.get(federatedDomainFull):
# token has been obtained for the other domain # token has been obtained for the other domain
continue continue
if not siteIsActive(httpPrefix + '://' + federatedDomain): if not siteIsActive(httpPrefix + '://' + federatedDomainFull):
continue continue
url = httpPrefix + '://' + federatedDomain + '/catalog' url = httpPrefix + '://' + federatedDomainFull + '/catalog'
asHeader['Authorization'] = tokensJson[federatedDomain] asHeader['Authorization'] = tokensJson[federatedDomainFull]
catalogJson = getJson(session, url, asHeader, None, catalogJson = getJson(session, url, asHeader, None,
debug, __version__, httpPrefix, None) debug, __version__, httpPrefix, None)
if not catalogJson: if not catalogJson:
print('WARN: failed to download shared items catalog for ' + print('WARN: failed to download shared items catalog for ' +
federatedDomain) federatedDomainFull)
continue continue
catalogFilename = catalogsDir + '/' + federatedDomain + '.json' catalogFilename = catalogsDir + '/' + federatedDomainFull + '.json'
if saveJson(catalogJson, catalogFilename): if saveJson(catalogJson, catalogFilename):
print('Downloaded shared items catalog for ' + federatedDomain) print('Downloaded shared items catalog for ' + federatedDomainFull)
sharesJson = _dfcToSharesFormat(catalogJson, sharesJson = _dfcToSharesFormat(catalogJson,
baseDir, systemLanguage) baseDir, systemLanguage)
if sharesJson: if sharesJson:
sharesFilename = \ sharesFilename = \
catalogsDir + '/' + federatedDomain + '.shares.json' catalogsDir + '/' + federatedDomainFull + '.shares.json'
saveJson(sharesJson, sharesFilename) saveJson(sharesJson, sharesFilename)
print('Converted shares catalog for ' + federatedDomain) print('Converted shares catalog for ' + federatedDomainFull)
else: else:
time.sleep(2) time.sleep(2)
@ -1297,7 +1304,7 @@ def runFederatedSharesWatchdog(projectVersion: str, httpd) -> None:
def runFederatedSharesDaemon(baseDir: str, httpd, httpPrefix: str, def runFederatedSharesDaemon(baseDir: str, httpd, httpPrefix: str,
domain: str, proxyType: str, debug: bool, domainFull: str, proxyType: str, debug: bool,
systemLanguage: str) -> None: systemLanguage: str) -> None:
"""Runs the daemon used to update federated shared items """Runs the daemon used to update federated shared items
""" """
@ -1334,8 +1341,8 @@ def runFederatedSharesDaemon(baseDir: str, httpd, httpPrefix: str,
session = createSession(proxyType) session = createSession(proxyType)
_updateFederatedSharesCache(session, sharedItemsFederatedDomains, _updateFederatedSharesCache(session, sharedItemsFederatedDomains,
baseDir, domain, httpPrefix, tokensJson, baseDir, domainFull, httpPrefix,
debug, systemLanguage) tokensJson, debug, systemLanguage)
time.sleep(secondsPerHour * 6) time.sleep(secondsPerHour * 6)

View File

@ -42,6 +42,7 @@ from follow import clearFollowers
from follow import sendFollowRequestViaServer from follow import sendFollowRequestViaServer
from follow import sendUnfollowRequestViaServer from follow import sendUnfollowRequestViaServer
from siteactive import siteIsActive from siteactive import siteIsActive
from utils import setConfigParam
from utils import isGroupActor from utils import isGroupActor
from utils import dateStringToSeconds from utils import dateStringToSeconds
from utils import dateSecondsToString from utils import dateSecondsToString
@ -942,6 +943,8 @@ def testPostMessageBetweenServers():
ccUrl = None ccUrl = None
alicePersonCache = {} alicePersonCache = {}
aliceCachedWebfingers = {} aliceCachedWebfingers = {}
aliceSharedItemsFederatedDomains = []
aliceSharedItemFederationTokens = {}
attachedImageFilename = baseDir + '/img/logo.png' attachedImageFilename = baseDir + '/img/logo.png'
testImageWidth, testImageHeight = \ testImageWidth, testImageHeight = \
getImageDimensions(attachedImageFilename) getImageDimensions(attachedImageFilename)
@ -967,8 +970,10 @@ def testPostMessageBetweenServers():
attachedImageFilename, mediaType, attachedImageFilename, mediaType,
attachedImageDescription, city, federationList, attachedImageDescription, city, federationList,
aliceSendThreads, alicePostLog, aliceCachedWebfingers, aliceSendThreads, alicePostLog, aliceCachedWebfingers,
alicePersonCache, isArticle, systemLanguage, inReplyTo, alicePersonCache, isArticle, systemLanguage,
inReplyToAtomUri, subject) aliceSharedItemsFederatedDomains,
aliceSharedItemFederationTokens,
inReplyTo, inReplyToAtomUri, subject)
print('sendResult: ' + str(sendResult)) print('sendResult: ' + str(sendResult))
queuePath = bobDir + '/accounts/bob@' + bobDomain + '/queue' queuePath = bobDir + '/accounts/bob@' + bobDomain + '/queue'
@ -1284,6 +1289,8 @@ def testFollowBetweenServers():
alicePostLog = [] alicePostLog = []
alicePersonCache = {} alicePersonCache = {}
aliceCachedWebfingers = {} aliceCachedWebfingers = {}
aliceSharedItemsFederatedDomains = []
aliceSharedItemFederationTokens = {}
alicePostLog = [] alicePostLog = []
isArticle = False isArticle = False
city = 'London, England' city = 'London, England'
@ -1295,8 +1302,10 @@ def testFollowBetweenServers():
clientToServer, True, clientToServer, True,
None, None, None, city, federationList, None, None, None, city, federationList,
aliceSendThreads, alicePostLog, aliceCachedWebfingers, aliceSendThreads, alicePostLog, aliceCachedWebfingers,
alicePersonCache, isArticle, systemLanguage, inReplyTo, alicePersonCache, isArticle, systemLanguage,
inReplyToAtomUri, subject) aliceSharedItemsFederatedDomains,
aliceSharedItemFederationTokens,
inReplyTo, inReplyToAtomUri, subject)
print('sendResult: ' + str(sendResult)) print('sendResult: ' + str(sendResult))
queuePath = bobDir + '/accounts/bob@' + bobDomain + '/queue' queuePath = bobDir + '/accounts/bob@' + bobDomain + '/queue'
@ -1413,6 +1422,13 @@ def testSharedItemsFederation():
# In the beginning all was calm and there were no follows # In the beginning all was calm and there were no follows
print('\n\n*********************************************************')
print("Alice and Bob agree to share items catalogs")
assert os.path.isdir(aliceDir)
assert os.path.isdir(bobDir)
setConfigParam(aliceDir, 'sharedItemsFederatedDomains', bobAddress)
setConfigParam(bobDir, 'sharedItemsFederatedDomains', aliceAddress)
print('*********************************************************') print('*********************************************************')
print('Alice sends a follow request to Bob') print('Alice sends a follow request to Bob')
os.chdir(aliceDir) os.chdir(aliceDir)
@ -1572,9 +1588,20 @@ def testSharedItemsFederation():
print('\n\n*********************************************************') print('\n\n*********************************************************')
print('Alice sends a message to Bob') print('Alice sends a message to Bob')
aliceTokensFilename = \
aliceDir + '/accounts/sharedItemsFederationTokens.json'
assert os.path.isfile(aliceTokensFilename)
aliceSharedItemFederationTokens = loadJson(aliceTokensFilename)
assert aliceSharedItemFederationTokens
print('Alice shared item federation tokens:')
pprint(aliceSharedItemFederationTokens)
assert len(aliceSharedItemFederationTokens.items()) > 0
for hostStr, token in aliceSharedItemFederationTokens.items():
assert ':' in hostStr
alicePostLog = [] alicePostLog = []
alicePersonCache = {} alicePersonCache = {}
aliceCachedWebfingers = {} aliceCachedWebfingers = {}
aliceSharedItemsFederatedDomains = [bobAddress]
alicePostLog = [] alicePostLog = []
isArticle = False isArticle = False
city = 'London, England' city = 'London, England'
@ -1586,8 +1613,10 @@ def testSharedItemsFederation():
clientToServer, True, clientToServer, True,
None, None, None, city, federationList, None, None, None, city, federationList,
aliceSendThreads, alicePostLog, aliceCachedWebfingers, aliceSendThreads, alicePostLog, aliceCachedWebfingers,
alicePersonCache, isArticle, systemLanguage, inReplyTo, alicePersonCache, isArticle, systemLanguage,
inReplyToAtomUri, subject) aliceSharedItemsFederatedDomains,
aliceSharedItemFederationTokens, True,
inReplyTo, inReplyToAtomUri, subject)
print('sendResult: ' + str(sendResult)) print('sendResult: ' + str(sendResult))
queuePath = bobDir + '/accounts/bob@' + bobDomain + '/queue' queuePath = bobDir + '/accounts/bob@' + bobDomain + '/queue'
@ -1605,6 +1634,32 @@ def testSharedItemsFederation():
assert aliceMessageArrived is True assert aliceMessageArrived is True
print('Message from Alice to Bob succeeded') print('Message from Alice to Bob succeeded')
print('\n\n*********************************************************')
print('Check that Alice received the shared items authorization')
print('token from Bob')
aliceTokensFilename = \
aliceDir + '/accounts/sharedItemsFederationTokens.json'
bobTokensFilename = \
bobDir + '/accounts/sharedItemsFederationTokens.json'
assert os.path.isfile(aliceTokensFilename)
assert os.path.isfile(bobTokensFilename)
aliceTokens = loadJson(aliceTokensFilename)
assert aliceTokens
for hostStr, token in aliceTokens.items():
assert ':' in hostStr
assert aliceTokens.get(aliceAddress)
print('Alice tokens')
pprint(aliceTokens)
bobTokens = loadJson(bobTokensFilename)
assert bobTokens
for hostStr, token in bobTokens.items():
assert ':' in hostStr
assert bobTokens.get(bobAddress)
print("Check that Bob now has Alice's token")
assert bobTokens.get(aliceAddress)
print('Bob tokens')
pprint(bobTokens)
# stop the servers # stop the servers
thrAlice.kill() thrAlice.kill()
thrAlice.join() thrAlice.join()
@ -1919,6 +1974,8 @@ def testGroupFollow():
alicePostLog = [] alicePostLog = []
alicePersonCache = {} alicePersonCache = {}
aliceCachedWebfingers = {} aliceCachedWebfingers = {}
aliceSharedItemsFederatedDomains = []
aliceSharedItemFederationTokens = {}
alicePostLog = [] alicePostLog = []
isArticle = False isArticle = False
city = 'London, England' city = 'London, England'
@ -1930,8 +1987,10 @@ def testGroupFollow():
saveToFile, clientToServer, True, saveToFile, clientToServer, True,
None, None, None, city, federationList, None, None, None, city, federationList,
aliceSendThreads, alicePostLog, aliceCachedWebfingers, aliceSendThreads, alicePostLog, aliceCachedWebfingers,
alicePersonCache, isArticle, systemLanguage, inReplyTo, alicePersonCache, isArticle, systemLanguage,
inReplyToAtomUri, subject) aliceSharedItemsFederatedDomains,
aliceSharedItemFederationTokens,
inReplyTo, inReplyToAtomUri, subject)
print('sendResult: ' + str(sendResult)) print('sendResult: ' + str(sendResult))
queuePath = \ queuePath = \
@ -5047,7 +5106,8 @@ def _testAuthorizeSharedItems():
False, tokensJson) False, tokensJson)
tokensJson = \ tokensJson = \
updateSharedItemFederationToken(None, updateSharedItemFederationToken(None,
'dog.domain', 'testToken', tokensJson) 'dog.domain', 'testToken',
True, tokensJson)
assert tokensJson['dog.domain'] == 'testToken' assert tokensJson['dog.domain'] == 'testToken'
# the shared item federation list changes # the shared item federation list changes