Ensure that groups can't follow groups, to prevent circular reference

merge-requests/30/head
Bob Mottram 2021-08-12 18:50:33 +01:00
parent 59fc02c0a7
commit e775ed4cdf
5 changed files with 30 additions and 13 deletions

View File

@ -29,6 +29,7 @@ from utils import isAccountDir
from utils import getUserPaths
from utils import acctDir
from utils import hasGroupType
from utils import isGroupAccount
from acceptreject import createAccept
from acceptreject import createReject
from webfinger import webfingerHandle
@ -750,6 +751,9 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
groupAccount = \
hasGroupType(baseDir, messageJson['actor'], personCache)
if groupAccount and isGroupAccount(baseDir, nickname, domain):
print('Group cannot follow a group')
return False
print('Storing follow request for approval')
return _storeFollowRequest(baseDir,
@ -791,6 +795,10 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
if debug:
print(approveHandle + ' / ' + messageJson['actor'] +
' is Group: ' + str(groupAccount))
if groupAccount and \
isGroupAccount(baseDir, nickname, domain):
print('Group cannot follow a group')
return False
try:
with open(followersFilename, 'r+') as followersFile:
content = followersFile.read()

View File

@ -1876,18 +1876,6 @@ def _groupHandle(baseDir: str, handle: str) -> bool:
return actorJson['type'] == 'Group'
def _getGroupName(baseDir: str, handle: str) -> str:
"""Returns the preferred name of a group
"""
actorFile = baseDir + '/accounts/' + handle + '.json'
if not os.path.isfile(actorFile):
return False
actorJson = loadJson(actorFile)
if not actorJson:
return 'Group'
return actorJson['name']
def _sendToGroupMembers(session, baseDir: str, handle: str, port: int,
postJsonObject: {},
httpPrefix: str, federationList: [],

View File

@ -1584,7 +1584,12 @@ def _generateNextSharesTokenUpdate(baseDir: str,
"""Creates a file containing the next date when the shared items token
for this instance will be updated
"""
tokenUpdateFilename = baseDir + '/accounts/.tokenUpdate'
tokenUpdateDir = baseDir + '/accounts'
if not os.path.isdir(baseDir):
os.mkdir(baseDir)
if not os.path.isdir(tokenUpdateDir):
os.mkdir(tokenUpdateDir)
tokenUpdateFilename = tokenUpdateDir + '/.tokenUpdate'
nextUpdateSec = None
if os.path.isfile(tokenUpdateFilename):
with open(tokenUpdateFilename, 'r') as fp:

View File

@ -42,6 +42,7 @@ from follow import clearFollowers
from follow import sendFollowRequestViaServer
from follow import sendUnfollowRequestViaServer
from siteactive import siteIsActive
from utils import isGroupAccount
from utils import getActorLanguagesList
from utils import getCategoryTypes
from utils import getSupportedLanguages
@ -1291,6 +1292,7 @@ def testFollowBetweenServers():
aliceDomain +
'/followingCalendar.txt').read()
assert not isGroupActor(aliceDir, bobActor, alicePersonCache)
assert not isGroupAccount(aliceDir, 'alice', aliceDomain)
print('\n\n*********************************************************')
print('Alice sends a message to Bob')
@ -1485,6 +1487,7 @@ def testSharedItemsFederation():
aliceDomain +
'/followingCalendar.txt').read()
assert not isGroupActor(aliceDir, bobActor, alicePersonCache)
assert not isGroupAccount(bobDir, 'bob', bobDomain)
print('\n\n*********************************************************')
print('Bob publishes some shared items')
@ -1914,6 +1917,8 @@ def testGroupFollow():
print('Alice following.txt does not contain !testgroup@' +
testgroupDomain + ':' + str(testgroupPort))
assert isGroupActor(aliceDir, testgroupActor, alicePersonCache)
assert not isGroupAccount(aliceDir, 'alice', aliceDomain)
assert isGroupAccount(testgroupDir, 'testgroup', testgroupDomain)
assert '!testgroup' in followingStr
assert testgroupHandle in open(aliceFollowingFilename).read()
assert testgroupHandle in open(aliceFollowingCalendarFilename).read()

View File

@ -2787,6 +2787,17 @@ def isGroupActor(baseDir: str, actor: str, personCache: {},
return False
def isGroupAccount(baseDir: str, nickname: str, domain: str) -> bool:
"""Returns true if the given account is a group
"""
accountFilename = acctDir(baseDir, nickname, domain) + '.json'
if not os.path.isfile(accountFilename):
return False
if '"type": "Group"' in open(accountFilename).read():
return True
return False
def getCurrencies() -> {}:
"""Returns a dictionary of currencies
"""