diff --git a/acceptreject.py b/acceptreject.py index fcf496d1..840a8e59 100644 --- a/acceptreject.py +++ b/acceptreject.py @@ -11,6 +11,9 @@ import commentjson from utils import getStatusNumber from utils import createOutboxDir from utils import urlPermitted +from utils import getDomainFromActor +from utils import getNicknameFromActor +from utils import domainPermitted 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) @@ -41,3 +44,35 @@ def createAccept(baseDir: str,federationList: [],capsList: [],nickname: str,doma def createReject(baseDir: str,federationList: [],capsList: [],nickname: str,domain: str,port: int,toUrl: str,ccUrl: str,httpPrefix: str,objectUrl: str) -> {}: return createAcceptReject(baseDir,federationList,capsList,nickname,domain,port,toUrl,ccUrl,httpPrefix,objectUrl,'Reject') + +def receiveAcceptReject(session,baseDir: str,httpPrefix: str,port: int,sendThreads: [],postLog: [],cachedWebfingers: {},personCache: {},messageJson: {},federationList: [],capsList: [],debug : bool) -> bool: + """Receives an Accept or Reject within the POST section of HTTPServer + """ + if messageJson['type']!='Accept' and messageJson['type']!='Reject': + return False + if not messageJson.get('actor'): + if debug: + print('DEBUG: '+messageJson['type']+' has no actor') + 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 '/users/' not in messageJson['object']: + if debug: + print('DEBUG: "users" not found within object of '+messageJson['type']) + return False + if debug: + print('DEBUG: Uh, '+messageJson['type']+', I guess') + return True diff --git a/follow.py b/follow.py index c6f543ce..05602c59 100644 --- a/follow.py +++ b/follow.py @@ -12,6 +12,8 @@ import os import sys from person import validNickname from utils import domainPermitted +from utils import getDomainFromActor +from utils import getNicknameFromActor from posts import sendSignedJson from capabilities import isCapable from acceptreject import createAccept @@ -244,29 +246,34 @@ def receiveFollowRequest(session,baseDir: str,httpPrefix: str,port: int,sendThre if debug: print('DEBUG: "users" missing from actor') return False - domain=messageJson['actor'].split('/users/')[0].replace('https://','').replace('http://','').replace('dat://','') - if ':' in domain: - domain=domain.split(':')[0] + domain,tempPort=getDomainFromActor(messageJson['actor']) + fromPort=port + if tempPort: + fromPort=tempPort if not domainPermitted(domain,federationList): if debug: print('DEBUG: follower from domain not permitted - '+domain) return False - nickname=messageJson['actor'].split('/users/')[1].replace('@','') + nickname=getNicknameFromActor(messageJson['actor']) + if not nickname: + if debug: + print('DEBUG: follow request does not contain a nickname') + return False handle=nickname.lower()+'@'+domain.lower() if '/users/' not in messageJson['object']: if debug: print('DEBUG: "users" not found within object') return False - domainToFollow=messageJson['object'].split('/users/')[0].replace('https://','').replace('http://','').replace('dat://','') - toPort=port - if ':' in domainToFollow: - toPort=domainToFollow.split(':')[1] - domainToFollow=domainToFollow.split(':')[0] + domainToFollow,tempPort=getDomainFromActor(messageJson['object']) if not domainPermitted(domainToFollow,federationList): if debug: print('DEBUG: follow domain not permitted '+domainToFollow) return False - nicknameToFollow=messageJson['object'].split('/users/')[1].replace('@','') + nicknameToFollow=getNicknameFromActor(messageJson['object']) + if not nicknameToFollow: + if debug: + print('DEBUG: follow request does not contain a nickname for the account followed') + return False handleToFollow=nicknameToFollow.lower()+'@'+domainToFollow.lower() if domainToFollow==domain: if not os.path.isdir(baseDir+'/accounts/'+handleToFollow): @@ -283,12 +290,15 @@ def receiveFollowRequest(session,baseDir: str,httpPrefix: str,port: int,sendThre personUrl=messageJson['actor'] acceptJson=createAccept(baseDir,federationList,capsList,nickname,domain,port, \ personUrl,'',httpPrefix,messageJson['object']) + if debug: + pprint(acceptJson) + print('DEBUG: sending follow Accept from '+nicknameToFollow+'@'+domainToFollow+' port '+str(port)+' to '+nickname+'@'+domain+' port '+ str(fromPort)) clientToServer=False - sendSignedJson(acceptJson,session,baseDir,nickname,domain,port, \ - nicknameToFollow,domainToFollow,port, '', \ - httpPrefix,True,clientToServer, \ - federationList, capsList, \ - sendThreads,postLog,cachedWebfingers,personCache,debug) + return sendSignedJson(acceptJson,session,baseDir,nicknameToFollow,domainToFollow,port, \ + nickname,domain,fromPort, '', \ + httpPrefix,True,clientToServer, \ + federationList, capsList, \ + sendThreads,postLog,cachedWebfingers,personCache,debug) def sendFollowRequest(session,baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \ followNickname: str,followDomain: str,followPort: bool,followHttpPrefix: str, \ diff --git a/inbox.py b/inbox.py index 48626695..5351249d 100644 --- a/inbox.py +++ b/inbox.py @@ -23,6 +23,7 @@ from follow import receiveFollowRequest from pprint import pprint from cache import getPersonFromCache from cache import storePersonInCache +from acceptreject import receiveAcceptReject def getPersonPubKey(session,personUrl: str,personCache: {},debug: bool) -> str: if not personUrl: @@ -238,7 +239,21 @@ def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [],cache os.remove(queueFilename) queue.pop(0) continue - + + if receiveAcceptReject(session, \ + baseDir,httpPrefix,port, \ + sendThreads,postLog, \ + cachedWebfingers, + personCache, + queueJson['post'], \ + federationList,capsList, \ + debug): + if debug: + print('DEBUG: Accept/Reject received from '+keyId) + os.remove(queueFilename) + queue.pop(0) + continue + if debug: print('DEBUG: Queue post accepted') diff --git a/utils.py b/utils.py index 9688344a..be2f7061 100644 --- a/utils.py +++ b/utils.py @@ -59,3 +59,25 @@ def urlPermitted(url: str, federationList: [],capsList: [],capability: str): if domain in url: return True return False + +def getNicknameFromActor(actor: str) -> str: + """Returns the nickname from an actor url + """ + if '/users/' not in actor: + return None + return actor.split('/users/')[1].replace('@','') + +def getDomainFromActor(actor: str) -> (str,int): + """Returns the domain name from an actor url + """ + port=None + if '/users/' not in actor: + domain = actor.replace('https://','').replace('http://','').replace('dat://','') + else: + domain = actor.split('/users/')[0].replace('https://','').replace('http://','').replace('dat://','') + if ':' in domain: + port=int(domain.split(':')[1]) + domain=domain.split(':')[0] + return domain,port + +