Delete activity

master
Bob Mottram 2019-07-11 22:38:28 +01:00
parent dca558a0fa
commit ab475f05f6
2 changed files with 187 additions and 1 deletions

122
delete.py 100644
View File

@ -0,0 +1,122 @@
__filename__ = "delete.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "0.0.1"
__maintainer__ = "Bob Mottram"
__email__ = "bob@freedombone.net"
__status__ = "Production"
import os
import json
import commentjson
from utils import getStatusNumber
from utils import createOutboxDir
from utils import urlPermitted
from utils import getNicknameFromActor
from utils import getDomainFromActor
from posts import sendSignedJson
def createDelete(session,baseDir: str,federationList: [], \
nickname: str, domain: str, port: int, \
toUrl: str, ccUrl: str, httpPrefix: str, \
objectUrl: str,clientToServer: bool, \
sendThreads: [],postLog: [], \
personCache: {},cachedWebfingers: {}, \
debug: bool) -> {}:
"""Creates an delete message
Typically toUrl will be https://www.w3.org/ns/activitystreams#Public
and ccUrl might be a specific person whose post is to be deleted
objectUrl is typically the url of the message, corresponding to url
or atomUri in createPostBase
"""
if not urlPermitted(objectUrl,federationList,"inbox:write"):
return None
if ':' in domain:
domain=domain.split(':')[0]
fullDomain=domain
if port!=80 and port!=443:
fullDomain=domain+':'+str(port)
statusNumber,published = getStatusNumber()
newDeleteId= \
httpPrefix+'://'+fullDomain+'/users/'+nickname+'/statuses/'+statusNumber
newDelete = {
'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname,
'atomUri': httpPrefix+'://'+fullDomain+'/users/'+nickname+'/statuses/'+statusNumber,
'cc': [],
'id': newDeleteId+'/activity',
'object': objectUrl,
'published': published,
'to': [toUrl],
'type': 'Delete'
}
if ccUrl:
if len(ccUrl)>0:
newDelete['cc']=[ccUrl]
deleteNickname=None
deleteDomain=None
deletePort=None
if '/users/' in objectUrl:
deleteNickname=getNicknameFromActor(objectUrl)
deleteDomain,deletePort=getDomainFromActor(objectUrl)
if deleteNickname and deleteDomain:
sendSignedJson(newDelete,session,baseDir, \
nickname,domain,port, \
deleteNickname,deleteDomain,deletePort, \
'https://www.w3.org/ns/activitystreams#Public', \
httpPrefix,True,clientToServer,federationList, \
sendThreads,postLog,cachedWebfingers,personCache,debug)
return newDelete
def deletePublic(session,baseDir: str,federationList: [], \
nickname: str, domain: str, port: int, httpPrefix: str, \
objectUrl: str,clientToServer: bool, \
sendThreads: [],postLog: [], \
personCache: {},cachedWebfingers: {}, \
debug: bool) -> {}:
"""Makes a public delete activity
"""
fromDomain=domain
if port!=80 and port!=443:
if ':' not in domain:
fromDomain=domain+':'+str(port)
toUrl = 'https://www.w3.org/ns/activitystreams#Public'
ccUrl = httpPrefix + '://'+fromDomain+'/users/'+nickname+'/followers'
return createDelete(session,baseDir,federationList, \
nickname,domain,port, \
toUrl,ccUrl,httpPrefix, \
objectUrl,clientToServer, \
sendThreads,postLog, \
personCache,cachedWebfingers, \
debug)
def deletePost(session,baseDir: str,federationList: [], \
nickname: str, domain: str, port: int, httpPrefix: str, \
deleteNickname: str, deleteDomain: str, \
deletePort: int, deleteHttpsPrefix: str, \
deleteStatusNumber: int,clientToServer: bool, \
sendThreads: [],postLog: [], \
personCache: {},cachedWebfingers: {}, \
debug: bool) -> {}:
"""Deletes a given status post
"""
deletedDomain=deleteDomain
if deletePort!=80 and deletePort!=443:
if ':' not in deletedDomain:
deletedDomain=deletedDomain+':'+str(deletePort)
objectUrl = deleteHttpsPrefix + '://'+deletedDomain+'/users/'+ \
deleteNickname+'/statuses/'+str(deleteStatusNumber)
return deletePublic(session,baseDir,federationList, \
nickname,domain,port,httpPrefix, \
objectUrl,clientToServer, \
sendThreads,postLog, \
personCache,cachedWebfingers, \
debug)

View File

@ -90,6 +90,7 @@ def inboxPermittedMessage(domain: str,messageJson: {},federationList: []) -> boo
if messageJson['type']!='Follow' and \
messageJson['type']!='Like' and \
messageJson['type']!='Delete' and \
messageJson['type']!='Announce':
if messageJson.get('object'):
if messageJson['object'].get('inReplyTo'):
@ -438,6 +439,53 @@ def receiveLike(session,handle: str,baseDir: str, \
updateLikesCollection(postFilename,messageJson['object'],messageJson['actor'],debug)
return True
def receiveDelete(session,handle: str,baseDir: str, \
httpPrefix: str,domain :str,port: int, \
sendThreads: [],postLog: [],cachedWebfingers: {}, \
personCache: {},messageJson: {},federationList: [], \
debug : bool) -> bool:
"""Receives a Delete activity within the POST section of HTTPServer
"""
if messageJson['type']!='Delete':
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'], str):
if debug:
print('DEBUG: '+messageJson['type']+' object is not a string')
return False
if not messageJson.get('to'):
if debug:
print('DEBUG: '+messageJson['type']+' has no "to" list')
return False
if '/users/' not in messageJson['actor']:
if debug:
print('DEBUG: "users" missing from actor in '+messageJson['type'])
return False
if '/statuses/' not in messageJson['object']:
if debug:
print('DEBUG: "statuses" missing from object in '+messageJson['type'])
return False
if not os.path.isdir(baseDir+'/accounts/'+handle):
print('DEBUG: unknown recipient of like - '+handle)
# if this post in the outbox of the person?
postFilename=locatePost(baseDir,handle.split('@')[0],handle.split('@')[1],messageJson['object'])
if not postFilename:
if debug:
print('DEBUG: delete post not found in inbox or outbox')
print(messageJson['object'])
return True
os.remove(postFilename)
if debug:
print('DEBUG: post deleted - '+postFilename)
return True
def receiveAnnounce(session,handle: str,baseDir: str, \
httpPrefix: str,domain :str,port: int, \
sendThreads: [],postLog: [],cachedWebfingers: {}, \
@ -518,6 +566,18 @@ def inboxAfterCapabilities(session,keyId: str,handle: str,messageJson: {}, \
if debug:
print('DEBUG: Announce accepted from '+keyId)
if receiveDelete(session,handle, \
baseDir,httpPrefix, \
domain,port, \
sendThreads,postLog, \
cachedWebfingers, \
personCache, \
messageJson, \
federationList, \
debug):
if debug:
print('DEBUG: Announce accepted from '+keyId)
if debug:
print('DEBUG: object capabilities passed')
print('copy from '+queueFilename+' to '+destinationFilename)
@ -525,7 +585,11 @@ def inboxAfterCapabilities(session,keyId: str,handle: str,messageJson: {}, \
copyfile(queueFilename,destinationFilename)
return True
def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [],cachedWebfingers: {},personCache: {},queue: [],domain: str,port: int,useTor: bool,federationList: [],ocapAlways: bool,debug: bool,acceptedCaps=["inbox:write","objects:read"]) -> None:
def runInboxQueue(baseDir: str,httpPrefix: str,sendThreads: [],postLog: [], \
cachedWebfingers: {},personCache: {},queue: [], \
domain: str,port: int,useTor: bool,federationList: [], \
ocapAlways: bool,debug: bool, \
acceptedCaps=["inbox:write","objects:read"]) -> None:
"""Processes received items and moves them to
the appropriate directories
"""