mirror of https://gitlab.com/bashrc2/epicyon
				
				
				
			Test for announce via c2s
							parent
							
								
									53d68cd10d
								
							
						
					
					
						commit
						a819c4ae57
					
				
							
								
								
									
										79
									
								
								announce.py
								
								
								
								
							
							
						
						
									
										79
									
								
								announce.py
								
								
								
								
							| 
						 | 
				
			
			@ -14,6 +14,10 @@ from utils import urlPermitted
 | 
			
		|||
from utils import getNicknameFromActor
 | 
			
		||||
from utils import getDomainFromActor
 | 
			
		||||
from posts import sendSignedJson
 | 
			
		||||
from posts import getPersonBox
 | 
			
		||||
from session import postJson
 | 
			
		||||
from webfinger import webfingerHandle
 | 
			
		||||
from auth import createBasicAuthHeader
 | 
			
		||||
 | 
			
		||||
def createAnnounce(session,baseDir: str,federationList: [], \
 | 
			
		||||
                   nickname: str, domain: str, port: int, \
 | 
			
		||||
| 
						 | 
				
			
			@ -229,3 +233,78 @@ def undoRepeatPost(session,baseDir: str,federationList: [], \
 | 
			
		|||
                              sendThreads,postLog, \
 | 
			
		||||
                              personCache,cachedWebfingers, \
 | 
			
		||||
                              debug)
 | 
			
		||||
 | 
			
		||||
def sendAnnounceViaServer(session,fromNickname: str,password: str,
 | 
			
		||||
                          fromDomain: str,fromPort: int, \
 | 
			
		||||
                          httpPrefix: str,repeatObjectUrl: str, \
 | 
			
		||||
                          cachedWebfingers: {},personCache: {}, \
 | 
			
		||||
                          debug: bool) -> {}:
 | 
			
		||||
    """Creates an announce message via c2s
 | 
			
		||||
    """
 | 
			
		||||
    if not session:
 | 
			
		||||
        print('WARN: No session for sendAnnounceViaServer')
 | 
			
		||||
        return 6
 | 
			
		||||
 | 
			
		||||
    withDigest=True
 | 
			
		||||
 | 
			
		||||
    fromDomainFull=fromDomain
 | 
			
		||||
    if fromPort!=80 and fromPort!=443:
 | 
			
		||||
        fromDomainFull=fromDomain+':'+str(fromPort)
 | 
			
		||||
 | 
			
		||||
    toUrl = 'https://www.w3.org/ns/activitystreams#Public'
 | 
			
		||||
    ccUrl = httpPrefix + '://'+fromDomainFull+'/users/'+fromNickname+'/followers'
 | 
			
		||||
 | 
			
		||||
    statusNumber,published = getStatusNumber()
 | 
			
		||||
    newAnnounceId= \
 | 
			
		||||
        httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname+'/statuses/'+statusNumber
 | 
			
		||||
    newAnnounceJson = {
 | 
			
		||||
        'actor': httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname,
 | 
			
		||||
        'atomUri': newAnnounceId,
 | 
			
		||||
        'cc': [ccUrl],
 | 
			
		||||
        'id': newAnnounceId+'/activity',
 | 
			
		||||
        'object': repeatObjectUrl,
 | 
			
		||||
        'published': published,
 | 
			
		||||
        'to': [toUrl],
 | 
			
		||||
        'type': 'Announce'
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    handle=httpPrefix+'://'+fromDomainFull+'/@'+fromNickname
 | 
			
		||||
 | 
			
		||||
    # lookup the inbox for the To handle
 | 
			
		||||
    wfRequest = webfingerHandle(session,handle,httpPrefix,cachedWebfingers)
 | 
			
		||||
    if not wfRequest:
 | 
			
		||||
        if debug:
 | 
			
		||||
            print('DEBUG: announce webfinger failed for '+handle)
 | 
			
		||||
        return 1
 | 
			
		||||
 | 
			
		||||
    postToBox='outbox'
 | 
			
		||||
 | 
			
		||||
    # get the actor inbox for the To handle
 | 
			
		||||
    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition = \
 | 
			
		||||
        getPersonBox(session,wfRequest,personCache,postToBox)
 | 
			
		||||
                     
 | 
			
		||||
    if not inboxUrl:
 | 
			
		||||
        if debug:
 | 
			
		||||
            print('DEBUG: No '+postToBox+' was found for '+handle)
 | 
			
		||||
        return 3
 | 
			
		||||
    if not fromPersonId:
 | 
			
		||||
        if debug:
 | 
			
		||||
            print('DEBUG: No actor was found for '+handle)
 | 
			
		||||
        return 4
 | 
			
		||||
    
 | 
			
		||||
    authHeader=createBasicAuthHeader(fromNickname,password)
 | 
			
		||||
     
 | 
			
		||||
    headers = {'host': fromDomain, \
 | 
			
		||||
               'Content-type': 'application/json', \
 | 
			
		||||
               'Authorization': authHeader}
 | 
			
		||||
    postResult = \
 | 
			
		||||
        postJson(session,newAnnounceJson,[],inboxUrl,headers,"inbox:write")
 | 
			
		||||
    #if not postResult:
 | 
			
		||||
    #    if debug:
 | 
			
		||||
    #        print('DEBUG: POST announce failed for c2s to '+inboxUrl)
 | 
			
		||||
    #    return 5
 | 
			
		||||
 | 
			
		||||
    if debug:
 | 
			
		||||
        print('DEBUG: c2s POST announce success')
 | 
			
		||||
 | 
			
		||||
    return newAnnounceJson
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								daemon.py
								
								
								
								
							
							
						
						
									
										10
									
								
								daemon.py
								
								
								
								
							| 
						 | 
				
			
			@ -703,15 +703,9 @@ class PubServer(BaseHTTPRequestHandler):
 | 
			
		|||
        # https://www.w3.org/TR/activitypub/#object-without-create
 | 
			
		||||
        if self.outboxAuthenticated:
 | 
			
		||||
            if self._postToOutbox(messageJson):                
 | 
			
		||||
                if messageJson.get('object'):
 | 
			
		||||
                    #self.send_header('Location', \
 | 
			
		||||
                if messageJson.get('id'):
 | 
			
		||||
                    self.headers['Location']= \
 | 
			
		||||
                                     messageJson['object']['id'].replace('/activity','')
 | 
			
		||||
                else:
 | 
			
		||||
                    if messageJson.get('id'):
 | 
			
		||||
                        #self.send_header('Location', \
 | 
			
		||||
                        self.headers['Location']= \
 | 
			
		||||
                                         messageJson['id'].replace('/activity','')
 | 
			
		||||
                        messageJson['id'].replace('/activity','')
 | 
			
		||||
                self.send_response(201)
 | 
			
		||||
                self.end_headers()
 | 
			
		||||
                self.server.POSTbusy=False
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -214,8 +214,8 @@ if args.tests:
 | 
			
		|||
 | 
			
		||||
if args.testsnetwork:
 | 
			
		||||
    print('Network Tests')
 | 
			
		||||
    testPostMessageBetweenServers()
 | 
			
		||||
    testFollowBetweenServers()
 | 
			
		||||
    #testPostMessageBetweenServers()
 | 
			
		||||
    #testFollowBetweenServers()
 | 
			
		||||
    testClientToServer()
 | 
			
		||||
    sys.exit()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										42
									
								
								posts.py
								
								
								
								
							
							
						
						
									
										42
									
								
								posts.py
								
								
								
								
							| 
						 | 
				
			
			@ -305,8 +305,9 @@ def savePostToBox(baseDir: str,httpPrefix: str,postId: str, \
 | 
			
		|||
            '/statuses/'+statusNumber
 | 
			
		||||
        postJsonObject['id']=postId+'/activity'
 | 
			
		||||
    if postJsonObject.get('object'):
 | 
			
		||||
        postJsonObject['object']['id']=postId
 | 
			
		||||
        postJsonObject['object']['atomUri']=postId
 | 
			
		||||
        if isinstance(postJsonObject['object'], dict):
 | 
			
		||||
            postJsonObject['object']['id']=postId
 | 
			
		||||
            postJsonObject['object']['atomUri']=postId
 | 
			
		||||
         
 | 
			
		||||
    boxDir = createPersonDir(nickname,domain,baseDir,boxname)
 | 
			
		||||
    filename=boxDir+'/'+postId.replace('/','#')+'.json'
 | 
			
		||||
| 
						 | 
				
			
			@ -493,19 +494,29 @@ def postIsAddressedToFollowers(baseDir: str,
 | 
			
		|||
 | 
			
		||||
    if not postJsonObject.get('object'):
 | 
			
		||||
        return False
 | 
			
		||||
    if not postJsonObject['object'].get('to'):
 | 
			
		||||
        return False
 | 
			
		||||
    toList=[]
 | 
			
		||||
    ccList=[]
 | 
			
		||||
    if isinstance(postJsonObject['object'], dict):
 | 
			
		||||
        if not postJsonObject['object'].get('to'):
 | 
			
		||||
            return False
 | 
			
		||||
        toList=postJsonObject['object']['to']
 | 
			
		||||
        if postJsonObject['object'].get('cc'):
 | 
			
		||||
            ccList=postJsonObject['object']['cc']
 | 
			
		||||
    else:
 | 
			
		||||
        if not postJsonObject.get('to'):
 | 
			
		||||
            return False
 | 
			
		||||
        toList=postJsonObject['to']
 | 
			
		||||
        if postJsonObject.get('cc'):
 | 
			
		||||
            ccList=postJsonObject['cc']
 | 
			
		||||
        
 | 
			
		||||
    followersUrl=httpPrefix+'://'+domain+'/users/'+nickname+'/followers'
 | 
			
		||||
 | 
			
		||||
    # does the followers url exist in 'to' or 'cc' lists?
 | 
			
		||||
    addressedToFollowers=False
 | 
			
		||||
    if followersUrl in postJsonObject['object']['to']:
 | 
			
		||||
    if followersUrl in toList:
 | 
			
		||||
        addressedToFollowers=True
 | 
			
		||||
    if not addressedToFollowers:
 | 
			
		||||
        if not postJsonObject['object'].get('cc'):
 | 
			
		||||
            return False
 | 
			
		||||
        if followersUrl in postJsonObject['object']['cc']:
 | 
			
		||||
        if followersUrl in ccList:
 | 
			
		||||
            addressedToFollowers=True
 | 
			
		||||
    return addressedToFollowers
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -872,13 +883,22 @@ def sendToNamedAddresses(session,baseDir: str, \
 | 
			
		|||
        return
 | 
			
		||||
    if not postJsonObject.get('object'):
 | 
			
		||||
        return
 | 
			
		||||
    if not postJsonObject['object'].get('to'):
 | 
			
		||||
        return
 | 
			
		||||
    toList=[]
 | 
			
		||||
    if isinstance(postJsonObject['object'], dict): 
 | 
			
		||||
        if not postJsonObject['object'].get('to'):
 | 
			
		||||
            return
 | 
			
		||||
        toList=postJsonObject['object']['to']
 | 
			
		||||
        recipientsObject=postJsonObject['object']
 | 
			
		||||
    else: 
 | 
			
		||||
        if not postJsonObject.get('to'):
 | 
			
		||||
            return
 | 
			
		||||
        toList=postJsonObject['to']
 | 
			
		||||
        recipientsObject=postJsonObject
 | 
			
		||||
 | 
			
		||||
    recipients=[]
 | 
			
		||||
    recipientType=['to','cc']
 | 
			
		||||
    for rType in recipientType:
 | 
			
		||||
        for address in postJsonObject['object'][rType]:
 | 
			
		||||
        for address in recipientsObject[rType]:
 | 
			
		||||
            if address.endswith('#Public'):
 | 
			
		||||
                continue
 | 
			
		||||
            if address.endswith('/followers'):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										36
									
								
								tests.py
								
								
								
								
							
							
						
						
									
										36
									
								
								tests.py
								
								
								
								
							| 
						 | 
				
			
			@ -48,6 +48,7 @@ from auth import authorizeBasic
 | 
			
		|||
from auth import storeBasicCredentials
 | 
			
		||||
from like import likePost
 | 
			
		||||
from announce import announcePublic
 | 
			
		||||
from announce import sendAnnounceViaServer
 | 
			
		||||
from media import getMediaPath
 | 
			
		||||
 | 
			
		||||
testServerAliceRunning = False
 | 
			
		||||
| 
						 | 
				
			
			@ -1043,7 +1044,7 @@ def testClientToServer():
 | 
			
		|||
 | 
			
		||||
    assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==1
 | 
			
		||||
    print(">>> c2s post arrived in Alice's outbox")
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    for i in range(30):
 | 
			
		||||
        if os.path.isdir(inboxPath):
 | 
			
		||||
            if len([name for name in os.listdir(inboxPath) if os.path.isfile(os.path.join(inboxPath, name))])==1:
 | 
			
		||||
| 
						 | 
				
			
			@ -1054,6 +1055,39 @@ def testClientToServer():
 | 
			
		|||
    print(">>> s2s post arrived in Bob's inbox")
 | 
			
		||||
    print("c2s send success")
 | 
			
		||||
 | 
			
		||||
    print('\n\nGetting message id for the post')
 | 
			
		||||
    statusNumber=0
 | 
			
		||||
    outboxPostFilename=None
 | 
			
		||||
    outboxPostId=None
 | 
			
		||||
    for name in os.listdir(outboxPath):
 | 
			
		||||
        if '#statuses#' in name:
 | 
			
		||||
            statusNumber=int(name.split('#statuses#')[1].replace('.json','').replace('#activity',''))
 | 
			
		||||
            outboxPostFilename=outboxPath+'/'+name
 | 
			
		||||
            with open(outboxPostFilename, 'r') as fp:
 | 
			
		||||
                postJsonObject=commentjson.load(fp)
 | 
			
		||||
                outboxPostId=postJsonObject['id'].replace('/activity','')
 | 
			
		||||
    assert outboxPostId
 | 
			
		||||
    print('message id obtained: '+outboxPostId)
 | 
			
		||||
    
 | 
			
		||||
    print('\n\nBob repeats the post')
 | 
			
		||||
    sessionBob = createSession(bobDomain,bobPort,useTor)
 | 
			
		||||
    password='bobpass'
 | 
			
		||||
    outboxPath=bobDir+'/accounts/bob@'+bobDomain+'/outbox'
 | 
			
		||||
    assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==0
 | 
			
		||||
    sendAnnounceViaServer(sessionBob,'bob',password,
 | 
			
		||||
                          bobDomain,bobPort, \
 | 
			
		||||
                          httpPrefix,outboxPostId, \
 | 
			
		||||
                          cachedWebfingers,personCache, \
 | 
			
		||||
                          True)
 | 
			
		||||
    for i in range(10):
 | 
			
		||||
        if os.path.isdir(outboxPath):
 | 
			
		||||
            if len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==1:
 | 
			
		||||
                break
 | 
			
		||||
        time.sleep(1)
 | 
			
		||||
 | 
			
		||||
    assert len([name for name in os.listdir(outboxPath) if os.path.isfile(os.path.join(outboxPath, name))])==1
 | 
			
		||||
    print('Post repeated')
 | 
			
		||||
    
 | 
			
		||||
    # stop the servers
 | 
			
		||||
    thrAlice.kill()
 | 
			
		||||
    thrAlice.join()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue