baseDir as parameter

master
Bob Mottram 2019-06-30 23:56:37 +01:00
parent bee4f185a2
commit eeb74f6e16
7 changed files with 86 additions and 64 deletions

View File

@ -69,7 +69,7 @@ class PubServer(BaseHTTPRequestHandler):
self.wfile.write(wfResult.encode('utf-8')) self.wfile.write(wfResult.encode('utf-8'))
return return
wfResult=webfingerLookup(self.path) wfResult=webfingerLookup(self.path,self.server.baseDir)
if wfResult: if wfResult:
self._set_headers('application/json') self._set_headers('application/json')
self.wfile.write(json.dumps(wfResult).encode('utf-8')) self.wfile.write(json.dumps(wfResult).encode('utf-8'))
@ -103,7 +103,7 @@ class PubServer(BaseHTTPRequestHandler):
self.GETbusy=False self.GETbusy=False
return return
# get outbox feed for a person # get outbox feed for a person
outboxFeed=personOutboxJson(self.server.domain,self.server.port,self.path,self.server.https,maxPostsInFeed) outboxFeed=personOutboxJson(self.server.baseDir,self.server.domain,self.server.port,self.path,self.server.https,maxPostsInFeed)
if outboxFeed: if outboxFeed:
self._set_headers('application/json') self._set_headers('application/json')
self.wfile.write(json.dumps(outboxFeed).encode('utf-8')) self.wfile.write(json.dumps(outboxFeed).encode('utf-8'))
@ -122,13 +122,13 @@ class PubServer(BaseHTTPRequestHandler):
self.GETbusy=False self.GETbusy=False
return return
# look up a person # look up a person
getPerson = personLookup(self.server.domain,self.path) getPerson = personLookup(self.server.domain,self.path,self.server.baseDir)
if getPerson: if getPerson:
self._set_headers('application/json') self._set_headers('application/json')
self.wfile.write(json.dumps(getPerson).encode('utf-8')) self.wfile.write(json.dumps(getPerson).encode('utf-8'))
self.GETbusy=False self.GETbusy=False
return return
personKey = personKeyLookup(self.server.domain,self.path) personKey = personKeyLookup(self.server.domain,self.path,self.server.baseDir)
if personKey: if personKey:
self._set_headers('text/html; charset=utf-8') self._set_headers('text/html; charset=utf-8')
self.wfile.write(personKey.encode('utf-8')) self.wfile.write(personKey.encode('utf-8'))
@ -140,8 +140,7 @@ class PubServer(BaseHTTPRequestHandler):
self.GETbusy=False self.GETbusy=False
return return
# check that the file exists # check that the file exists
baseDir=os.getcwd() filename=self.server.baseDir+self.path
filename=baseDir+self.path
if os.path.isfile(filename): if os.path.isfile(filename):
self._set_headers('application/json') self._set_headers('application/json')
with open(filename, 'r', encoding='utf8') as File: with open(filename, 'r', encoding='utf8') as File:
@ -208,5 +207,6 @@ def runDaemon(domain: str,port=80,https=True,fedList=[],useTor=False) -> None:
httpd.port=port httpd.port=port
httpd.https=https httpd.https=https
httpd.federationList=fedList.copy() httpd.federationList=fedList.copy()
httpd.baseDir=os.getcwd()
print('Running ActivityPub daemon on ' + domain + ' port ' + str(port)) print('Running ActivityPub daemon on ' + domain + ' port ' + str(port))
httpd.serve_forever() httpd.serve_forever()

View File

@ -19,6 +19,7 @@ from posts import sendPost
from session import createSession from session import createSession
from session import getJson from session import getJson
import json import json
import os
import sys import sys
import requests import requests
from pprint import pprint from pprint import pprint
@ -43,8 +44,10 @@ domain='127.0.0.1'
port=6227 port=6227
https=False https=False
useTor=False useTor=False
baseDir=os.getcwd()
session = createSession(useTor) session = createSession(useTor)
clearFollows(username,domain) clearFollows(username,domain)
followPerson(username,domain,'badger','wild.com',federationList) followPerson(username,domain,'badger','wild.com',federationList)
followPerson(username,domain,'squirrel','secret.com',federationList) followPerson(username,domain,'squirrel','secret.com',federationList)
@ -70,17 +73,17 @@ followerOfPerson(username,domain,'giraffe','trees.com',federationList)
#sys.exit() #sys.exit()
privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(username,domain,port,https,True) privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(baseDir,username,domain,port,https,True)
#deleteAllPosts(username,domain) #deleteAllPosts(username,domain)
setPreferredUsername(username,domain,'badger') setPreferredUsername(username,domain,'badger')
setBio(username,domain,'Some personal info') setBio(username,domain,'Some personal info')
#createPublicPost(username, domain, https, "G'day world!", False, True, None, None, 'Not suitable for Vogons') #createPublicPost(username, domain, https, "G'day world!", False, True, None, None, 'Not suitable for Vogons')
#archivePosts(username,domain,4) #archivePosts(username,domain,baseDir,4)
#outboxJson=createOutbox(username,domain,port,https,2,True,None) #outboxJson=createOutbox(baseDir,username,domain,port,https,2,True,None)
#pprint(outboxJson) #pprint(outboxJson)
testPostMessageBetweenServers() #testPostMessageBetweenServers()
#runDaemon(domain,port,https,federationList,useTor) runDaemon(domain,port,https,federationList,useTor)
#testHttpsig() #testHttpsig()
sys.exit() sys.exit()

View File

@ -53,7 +53,7 @@ def validPublishedDate(published):
return False return False
return True return True
def receiveMessage(message): def receiveMessage(message,baseDir: str):
if not message.get('type'): if not message.get('type'):
return return
if message['type']!='Create': if message['type']!='Create':
@ -76,7 +76,6 @@ def receiveMessage(message):
domain='' domain=''
messageId=message['id'].replace('/','_') messageId=message['id'].replace('/','_')
handle=username.lower()+'@'+domain.lower() handle=username.lower()+'@'+domain.lower()
baseDir=os.getcwd()
if not os.path.isdir(baseDir+'/accounts/'+handle): if not os.path.isdir(baseDir+'/accounts/'+handle):
os.mkdir(baseDir+'/accounts/'+handle) os.mkdir(baseDir+'/accounts/'+handle)
if not os.path.isdir(baseDir+'/accounts/'+handle+'/inbox'): if not os.path.isdir(baseDir+'/accounts/'+handle+'/inbox'):

View File

@ -21,7 +21,7 @@ def generateRSAKey() -> (str,str):
publicKeyPem = key.publickey().exportKey("PEM").decode("utf-8") publicKeyPem = key.publickey().exportKey("PEM").decode("utf-8")
return privateKeyPem,publicKeyPem return privateKeyPem,publicKeyPem
def createPerson(username: str,domain: str,port: int,https: bool, saveToFile: bool) -> (str,str,{},{}): def createPerson(baseDir: str,username: str,domain: str,port: int,https: bool, saveToFile: bool) -> (str,str,{},{}):
"""Returns the private key, public key, actor and webfinger endpoint """Returns the private key, public key, actor and webfinger endpoint
""" """
prefix='https' prefix='https'
@ -31,7 +31,7 @@ def createPerson(username: str,domain: str,port: int,https: bool, saveToFile: bo
privateKeyPem,publicKeyPem=generateRSAKey() privateKeyPem,publicKeyPem=generateRSAKey()
webfingerEndpoint=createWebfingerEndpoint(username,domain,port,https,publicKeyPem) webfingerEndpoint=createWebfingerEndpoint(username,domain,port,https,publicKeyPem)
if saveToFile: if saveToFile:
storeWebfingerEndpoint(username,domain,webfingerEndpoint) storeWebfingerEndpoint(username,domain,baseDir,webfingerEndpoint)
handle=username.lower()+'@'+domain.lower() handle=username.lower()+'@'+domain.lower()
if port!=80 and port!=443: if port!=80 and port!=443:
@ -79,7 +79,6 @@ def createPerson(username: str,domain: str,port: int,https: bool, saveToFile: bo
if saveToFile: if saveToFile:
# save person to file # save person to file
baseDir=os.getcwd()
peopleSubdir='/accounts' peopleSubdir='/accounts'
if not os.path.isdir(baseDir+peopleSubdir): if not os.path.isdir(baseDir+peopleSubdir):
os.mkdir(baseDir+peopleSubdir) os.mkdir(baseDir+peopleSubdir)
@ -114,7 +113,7 @@ def validUsername(username):
return False return False
return True return True
def personKeyLookup(domain: str,path: str) -> str: def personKeyLookup(domain: str,path: str,baseDir: str) -> str:
"""Lookup the public key of the person with a given username """Lookup the public key of the person with a given username
""" """
if not path.endswith('/main-key'): if not path.endswith('/main-key'):
@ -125,7 +124,6 @@ def personKeyLookup(domain: str,path: str) -> str:
if not validUsername(username): if not validUsername(username):
return None return None
handle=username.lower()+'@'+domain.lower() handle=username.lower()+'@'+domain.lower()
baseDir=os.getcwd()
filename=baseDir+'/accounts/'+handle.lower()+'.json' filename=baseDir+'/accounts/'+handle.lower()+'.json'
if not os.path.isfile(filename): if not os.path.isfile(filename):
return None return None
@ -137,7 +135,7 @@ def personKeyLookup(domain: str,path: str) -> str:
return personJson['publicKey']['publicKeyPem'] return personJson['publicKey']['publicKeyPem']
return None return None
def personLookup(domain: str,path: str) -> {}: def personLookup(domain: str,path: str,baseDir: str) -> {}:
"""Lookup the person for an given username """Lookup the person for an given username
""" """
notPersonLookup=['/inbox','/outbox','/outboxarchive','/followers','/following','/featured','.png','.jpg','.gif','.mpv','#main-key','/main-key'] notPersonLookup=['/inbox','/outbox','/outboxarchive','/followers','/following','/featured','.png','.jpg','.gif','.mpv','#main-key','/main-key']
@ -154,7 +152,6 @@ def personLookup(domain: str,path: str) -> {}:
if not validUsername(username): if not validUsername(username):
return None return None
handle=username.lower()+'@'+domain.lower() handle=username.lower()+'@'+domain.lower()
baseDir=os.getcwd()
filename=baseDir+'/accounts/'+handle.lower()+'.json' filename=baseDir+'/accounts/'+handle.lower()+'.json'
if not os.path.isfile(filename): if not os.path.isfile(filename):
return None return None
@ -163,7 +160,7 @@ def personLookup(domain: str,path: str) -> {}:
personJson=commentjson.load(fp) personJson=commentjson.load(fp)
return personJson return personJson
def personOutboxJson(domain: str,port: int,path: str,https: bool,noOfItems: int) -> []: def personOutboxJson(baseDir: str,domain: str,port: int,path: str,https: bool,noOfItems: int) -> []:
"""Obtain the outbox feed for the given person """Obtain the outbox feed for the given person
""" """
if not '/outbox' in path: if not '/outbox' in path:
@ -197,7 +194,7 @@ def personOutboxJson(domain: str,port: int,path: str,https: bool,noOfItems: int)
return None return None
if not validUsername(username): if not validUsername(username):
return None return None
return createOutbox(username,domain,port,https,noOfItems,headerOnly,pageNumber) return createOutbox(baseDir,username,domain,port,https,noOfItems,headerOnly,pageNumber)
def setPreferredUsername(username: str, domain: str, preferredName: str) -> bool: def setPreferredUsername(username: str, domain: str, preferredName: str) -> bool:
if len(preferredName)>32: if len(preferredName)>32:

View File

@ -23,22 +23,16 @@ from pprint import pprint
from random import randint from random import randint
from session import getJson from session import getJson
from session import postJson from session import postJson
from webfinger import webfingerHandle
try: try:
from BeautifulSoup import BeautifulSoup from BeautifulSoup import BeautifulSoup
except ImportError: except ImportError:
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
# Contains threads for posts being sent def getPersonKey(username: str,domain: str,baseDir: str,keyType='public'):
sendThreads = []
# stores the results from recent post sending attempts
postLog = []
def getPersonKey(username: str,domain: str,keyType='public'):
"""Returns the public or private key of a person """Returns the public or private key of a person
""" """
handle=username+'@'+domain handle=username+'@'+domain
baseDir=os.getcwd()
keyFilename=baseDir+'/keys/'+keyType+'/'+handle.lower()+'.key' keyFilename=baseDir+'/keys/'+keyType+'/'+handle.lower()+'.key'
if not os.path.isfile(keyFilename): if not os.path.isfile(keyFilename):
return '' return ''
@ -200,11 +194,10 @@ def getUserPosts(session,wfRequest,maxPosts,maxMentions,maxEmoji,maxAttachments,
break break
return userPosts return userPosts
def createOutboxDir(username: str,domain: str) -> str: def createOutboxDir(username: str,domain: str,baseDir: str) -> str:
"""Create an outbox for a person and returns the feed filename and directory """Create an outbox for a person and returns the feed filename and directory
""" """
handle=username.lower()+'@'+domain.lower() handle=username.lower()+'@'+domain.lower()
baseDir=os.getcwd()
if not os.path.isdir(baseDir+'/accounts/'+handle): if not os.path.isdir(baseDir+'/accounts/'+handle):
os.mkdir(baseDir+'/accounts/'+handle) os.mkdir(baseDir+'/accounts/'+handle)
outboxDir=baseDir+'/accounts/'+handle+'/outbox' outboxDir=baseDir+'/accounts/'+handle+'/outbox'
@ -212,11 +205,10 @@ def createOutboxDir(username: str,domain: str) -> str:
os.mkdir(outboxDir) os.mkdir(outboxDir)
return outboxDir return outboxDir
def createOutboxArchive(username: str,domain: str) -> str: def createOutboxArchive(username: str,domain: str,baseDir: str) -> str:
"""Creates an archive directory for outbox posts """Creates an archive directory for outbox posts
""" """
handle=username.lower()+'@'+domain.lower() handle=username.lower()+'@'+domain.lower()
baseDir=os.getcwd()
if not os.path.isdir(baseDir+'/accounts/'+handle): if not os.path.isdir(baseDir+'/accounts/'+handle):
os.mkdir(baseDir+'/accounts/'+handle) os.mkdir(baseDir+'/accounts/'+handle)
outboxArchiveDir=baseDir+'/accounts/'+handle+'/outboxarchive' outboxArchiveDir=baseDir+'/accounts/'+handle+'/outboxarchive'
@ -224,10 +216,10 @@ def createOutboxArchive(username: str,domain: str) -> str:
os.mkdir(outboxArchiveDir) os.mkdir(outboxArchiveDir)
return outboxArchiveDir return outboxArchiveDir
def deleteAllPosts(username: str, domain: str) -> None: def deleteAllPosts(username: str, domain: str,baseDir: str) -> None:
"""Deletes all posts for a person """Deletes all posts for a person
""" """
outboxDir = createOutboxDir(username,domain) outboxDir = createOutboxDir(username,domain,baseDir)
for deleteFilename in os.listdir(outboxDir): for deleteFilename in os.listdir(outboxDir):
filePath = os.path.join(outboxDir, deleteFilename) filePath = os.path.join(outboxDir, deleteFilename)
try: try:
@ -248,7 +240,7 @@ def getStatusNumber() -> (str,str):
conversationDate=currTime.strftime("%Y-%m-%d") conversationDate=currTime.strftime("%Y-%m-%d")
return statusNumber,published return statusNumber,published
def createPostBase(username: str, domain: str, toUrl: str, ccUrl: str, https: bool, content: str, followersOnly: bool, saveToFile: bool, inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}: def createPostBase(baseDir: str,username: str, domain: str, toUrl: str, ccUrl: str, https: bool, content: str, followersOnly: bool, saveToFile: bool, inReplyTo=None, inReplyToAtomUri=None, subject=None) -> {}:
"""Creates a public post """Creates a public post
""" """
prefix='https' prefix='https'
@ -306,7 +298,7 @@ def createPostBase(username: str, domain: str, toUrl: str, ccUrl: str, https: bo
} }
} }
if saveToFile: if saveToFile:
outboxDir = createOutboxDir(username,domain) outboxDir = createOutboxDir(username,domain,baseDir)
filename=outboxDir+'/'+newPostId.replace('/','#')+'.json' filename=outboxDir+'/'+newPostId.replace('/','#')+'.json'
with open(filename, 'w') as fp: with open(filename, 'w') as fp:
commentjson.dump(newPost, fp, indent=4, sort_keys=False) commentjson.dump(newPost, fp, indent=4, sort_keys=False)
@ -320,7 +312,7 @@ def createPublicPost(username: str, domain: str, https: bool, content: str, foll
prefix='http' prefix='http'
return createPostBase(username, domain, 'https://www.w3.org/ns/activitystreams#Public', prefix+'://'+domain+'/users/'+username+'/followers', https, content, followersOnly, saveToFile, inReplyTo, inReplyToAtomUri, subject) return createPostBase(username, domain, 'https://www.w3.org/ns/activitystreams#Public', prefix+'://'+domain+'/users/'+username+'/followers', https, content, followersOnly, saveToFile, inReplyTo, inReplyToAtomUri, subject)
def threadSendPost(session,postJsonObject,federationList,inboxUrl: str,signatureHeader) -> None: def threadSendPost(session,postJsonObject,federationList,inboxUrl: str,baseDir: str,signatureHeader,postLog) -> None:
"""Sends a post with exponential backoff """Sends a post with exponential backoff
""" """
tries=0 tries=0
@ -334,7 +326,6 @@ def threadSendPost(session,postJsonObject,federationList,inboxUrl: str,signature
while len(postLog)>64: while len(postLog)>64:
postlog.pop(0) postlog.pop(0)
# save the log file # save the log file
baseDir=os.getcwd()
filename=baseDir+'/post.log' filename=baseDir+'/post.log'
with open(filename, "w") as logFile: with open(filename, "w") as logFile:
for line in postLog: for line in postLog:
@ -344,19 +335,24 @@ def threadSendPost(session,postJsonObject,federationList,inboxUrl: str,signature
time.sleep(backoffTime) time.sleep(backoffTime)
backoffTime *= 2 backoffTime *= 2
def sendPost(session,username: str, domain: str, toUsername: str, toDomain: str, cc: str, https: bool, content: str, followersOnly: bool, saveToFile: bool, federationList, inReplyTo=None, inReplyToAtomUri=None, subject=None) -> int: def sendPost(session,baseDir,username: str, domain: str, port: int, toUsername: str, toDomain: str, toPort: int, cc: str, https: bool, content: str, followersOnly: bool, saveToFile: bool, federationList, sendThreads, postLog, inReplyTo=None, inReplyToAtomUri=None, subject=None) -> int:
"""Post to another inbox """Post to another inbox
""" """
prefix='https' prefix='https'
if not https: if not https:
prefix='http' prefix='http'
# lookup the inbox if toPort!=80 and toPort!=443:
handle=prefix+'://'+domain+'/@'+username toDomain=toDomain+':'+str(toPort)
wfRequest = webfingerHandle(session,handle,True)
handle=prefix+'://'+toDomain+'/@'+toUsername
# lookup the inbox for the To handle
wfRequest = webfingerHandle(session,handle,https)
if not wfRequest: if not wfRequest:
return 1 return 1
# get the actor inbox for the To handle
inboxUrl,pubKey,toPersonId = getPersonBox(session,wfRequest,'inbox') inboxUrl,pubKey,toPersonId = getPersonBox(session,wfRequest,'inbox')
if not inboxUrl: if not inboxUrl:
return 2 return 2
@ -367,7 +363,8 @@ def sendPost(session,username: str, domain: str, toUsername: str, toDomain: str,
postJsonObject=createPostBase(username, domain, toPersonId, cc, https, content, followersOnly, saveToFile, inReplyTo, inReplyToAtomUri, subject) postJsonObject=createPostBase(username, domain, toPersonId, cc, https, content, followersOnly, saveToFile, inReplyTo, inReplyToAtomUri, subject)
privateKeyPem=getPersonKey(username,domain,'private') # get the senders private key
privateKeyPem=getPersonKey(username,domain,baseDir,'private')
if len(privateKeyPem)==0: if len(privateKeyPem)==0:
return 5 return 5
@ -379,19 +376,19 @@ def sendPost(session,username: str, domain: str, toUsername: str, toDomain: str,
while len(sendThreads)>10: while len(sendThreads)>10:
sendThreads[0].kill() sendThreads[0].kill()
sendThreads.pop(0) sendThreads.pop(0)
thr = threadWithTrace(target=threadSendPost,args=(session,postJsonObject.copy(),federationList,inboxUrl,signatureHeader.copy()),daemon=True) thr = threadWithTrace(target=threadSendPost,args=(session,postJsonObject.copy(),federationList,inboxUrl,baseDir,signatureHeader.copy(),postLog),daemon=True)
sendThreads.append(thr) sendThreads.append(thr)
thr.start() thr.start()
return 0 return 0
def createOutbox(username: str,domain: str,port: int,https: bool,itemsPerPage: int,headerOnly: bool,pageNumber=None) -> {}: def createOutbox(baseDir: str,username: str,domain: str,port: int,https: bool,itemsPerPage: int,headerOnly: bool,pageNumber=None) -> {}:
"""Constructs the outbox feed """Constructs the outbox feed
""" """
prefix='https' prefix='https'
if not https: if not https:
prefix='http' prefix='http'
outboxDir = createOutboxDir(username,domain) outboxDir = createOutboxDir(username,domain,baseDir)
if port!=80 and port!=443: if port!=80 and port!=443:
domain = domain+':'+str(port) domain = domain+':'+str(port)
@ -482,12 +479,12 @@ def createOutbox(username: str,domain: str,port: int,https: bool,itemsPerPage: i
return outboxHeader return outboxHeader
return outboxItems return outboxItems
def archivePosts(username: str,domain: str,maxPostsInOutbox=256) -> None: def archivePosts(username: str,domain: str,baseDir: str,maxPostsInOutbox=256) -> None:
"""Retain a maximum number of posts within the outbox """Retain a maximum number of posts within the outbox
Move any others to an archive directory Move any others to an archive directory
""" """
outboxDir = createOutboxDir(username,domain) outboxDir = createOutboxDir(username,domain,baseDir)
archiveDir = createOutboxArchive(username,domain) archiveDir = createOutboxArchive(username,domain,baseDir)
postsInOutbox=sorted(os.listdir(outboxDir), reverse=False) postsInOutbox=sorted(os.listdir(outboxDir), reverse=False)
noOfPosts=len(postsInOutbox) noOfPosts=len(postsInOutbox)
if noOfPosts<=maxPostsInOutbox: if noOfPosts<=maxPostsInOutbox:

View File

@ -22,6 +22,7 @@ from session import createSession
from person import createPerson from person import createPerson
from posts import deleteAllPosts from posts import deleteAllPosts
from posts import createPublicPost from posts import createPublicPost
from posts import sendPost
from follow import followPerson from follow import followPerson
from follow import followerOfPerson from follow import followerOfPerson
@ -34,7 +35,8 @@ def testHttpsigBase(withDigest):
domain='argumentative.social' domain='argumentative.social'
https=True https=True
port=80 port=80
privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(username,domain,port,https,False) baseDir=os.getcwd()
privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(baseDir,username,domain,port,https,False)
messageBodyJson = '{"a key": "a value", "another key": "A string"}' messageBodyJson = '{"a key": "a value", "another key": "A string"}'
if not withDigest: if not withDigest:
headers = {'host': domain} headers = {'host': domain}
@ -96,9 +98,8 @@ def createServerAlice(path: str,port: int):
domain='127.0.0.1' domain='127.0.0.1'
https=False https=False
useTor=False useTor=False
session = createSession(useTor) privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(path,username,domain,port,https,True)
privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(username,domain,port,https,True) deleteAllPosts(username,domain,path)
deleteAllPosts(username,domain)
followPerson(username,domain,'bob','127.0.0.1:61936',federationList) followPerson(username,domain,'bob','127.0.0.1:61936',federationList)
followerOfPerson(username,domain,'bob','127.0.0.1:61936',federationList) followerOfPerson(username,domain,'bob','127.0.0.1:61936',federationList)
createPublicPost(username, domain, https, "No wise fish would go anywhere without a porpoise", False, True) createPublicPost(username, domain, https, "No wise fish would go anywhere without a porpoise", False, True)
@ -120,9 +121,8 @@ def createServerBob(path: str,port: int):
domain='127.0.0.1' domain='127.0.0.1'
https=False https=False
useTor=False useTor=False
session = createSession(useTor) privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(path,username,domain,port,https,True)
privateKeyPem,publicKeyPem,person,wfEndpoint=createPerson(username,domain,port,https,True) deleteAllPosts(username,domain,path)
deleteAllPosts(username,domain)
followPerson(username,domain,'alice','127.0.0.1:61935',federationList) followPerson(username,domain,'alice','127.0.0.1:61935',federationList)
followerOfPerson(username,domain,'alice','127.0.0.1:61935',federationList) followerOfPerson(username,domain,'alice','127.0.0.1:61935',federationList)
createPublicPost(username, domain, https, "It's your life, live it your way.", False, True) createPublicPost(username, domain, https, "It's your life, live it your way.", False, True)
@ -141,16 +141,24 @@ def testPostMessageBetweenServers():
testServerAliceRunning = False testServerAliceRunning = False
testServerBobRunning = False testServerBobRunning = False
https=False
useTor=False
federationList=['127.0.0.1']
baseDir=os.getcwd() baseDir=os.getcwd()
if not os.path.isdir(baseDir+'/.tests'): if not os.path.isdir(baseDir+'/.tests'):
os.mkdir(baseDir+'/.tests') os.mkdir(baseDir+'/.tests')
# create the servers # create the servers
thrAlice = threadWithTrace(target=createServerAlice,args=(baseDir+'/.tests/alice',61935),daemon=True) aliceDir=baseDir+'/.tests/alice'
alicePort=61935
thrAlice = threadWithTrace(target=createServerAlice,args=(aliceDir,alicePort),daemon=True)
thrAlice.start() thrAlice.start()
assert thrAlice.isAlive()==True assert thrAlice.isAlive()==True
thrBob = threadWithTrace(target=createServerBob,args=(baseDir+'/.tests/bob',61936),daemon=True) bobDir=baseDir+'/.tests/bob'
bobPort=61936
thrBob = threadWithTrace(target=createServerBob,args=(bobDir,bobPort),daemon=True)
thrBob.start() thrBob.start()
assert thrBob.isAlive()==True assert thrBob.isAlive()==True
@ -160,6 +168,19 @@ def testPostMessageBetweenServers():
time.sleep(3) time.sleep(3)
print('Alice sends to Bob')
os.chdir(aliceDir)
sessionAlice = createSession(useTor)
inReplyTo=None
inReplyToAtomUri=None
subject=None
aliceSendThreads = []
alicePostLog = []
sendResult = sendPost(sessionAlice,aliceDir,'alice', '127.0.0.1', alicePort, 'bob', '127.0.0.1', bobPort, '', https, 'Why is a mouse when it spins?', False, True, federationList, aliceSendThreads, alicePostLog, inReplyTo, inReplyToAtomUri, subject)
print('sendResult: '+str(sendResult))
time.sleep(3)
# stop the servers # stop the servers
thrAlice.kill() thrAlice.kill()
thrAlice.join() thrAlice.join()

View File

@ -45,9 +45,13 @@ def webfingerHandle(session,handle: str,https: bool):
if not https: if not https:
prefix='http' prefix='http'
url = '{}://{}/.well-known/webfinger'.format(prefix,domain) url = '{}://{}/.well-known/webfinger'.format(prefix,domain)
if ':' in domain:
domain=domain.split(':')[0]
par = {'resource': 'acct:{}'.format(username+'@'+domain)} par = {'resource': 'acct:{}'.format(username+'@'+domain)}
hdr = {'Accept': 'application/jrd+json'} hdr = {'Accept': 'application/jrd+json'}
#try: #try:
print("webfinger url = "+url)
print("webfinger par = "+str(par))
result = getJson(session, url, hdr, par) result = getJson(session, url, hdr, par)
#except: #except:
# print("Unable to webfinger " + url) # print("Unable to webfinger " + url)
@ -64,11 +68,10 @@ def generateMagicKey(publicKeyPem):
pubexp = base64.urlsafe_b64encode(number.long_to_bytes(privkey.e)).decode("utf-8") pubexp = base64.urlsafe_b64encode(number.long_to_bytes(privkey.e)).decode("utf-8")
return f"data:application/magic-public-key,RSA.{mod}.{pubexp}" return f"data:application/magic-public-key,RSA.{mod}.{pubexp}"
def storeWebfingerEndpoint(username: str,domain: str,wfJson) -> bool: def storeWebfingerEndpoint(username: str,domain: str,baseDir: str,wfJson) -> bool:
"""Stores webfinger endpoint for a user to a file """Stores webfinger endpoint for a user to a file
""" """
handle=username+'@'+domain handle=username+'@'+domain
baseDir=os.getcwd()
wfSubdir='/wfendpoints' wfSubdir='/wfendpoints'
if not os.path.isdir(baseDir+wfSubdir): if not os.path.isdir(baseDir+wfSubdir):
os.mkdir(baseDir+wfSubdir) os.mkdir(baseDir+wfSubdir)
@ -140,25 +143,27 @@ def webfingerMeta() -> str:
" </Link>" \ " </Link>" \
"</XRD>" "</XRD>"
def webfingerLookup(path: str): def webfingerLookup(path: str,baseDir: str):
"""Lookup the webfinger endpoint for an account """Lookup the webfinger endpoint for an account
""" """
if not path.startswith('/.well-known/webfinger?'): if not path.startswith('/.well-known/webfinger?'):
return None return None
handle=None handle=None
print('************** '+path)
if 'resource=acct:' in path: if 'resource=acct:' in path:
handle=path.split('resource=acct:')[1].strip() handle=path.split('resource=acct:')[1].strip()
else: else:
if 'resource=acct%3A' in path: if 'resource=acct%3A' in path:
handle=path.split('resource=acct%3A')[1].replace('%40','@').strip() handle=path.split('resource=acct%3A')[1].replace('%40','@').strip()
print('************** handle: '+handle)
if not handle: if not handle:
return None return None
if '&' in handle: if '&' in handle:
handle=handle.split('&')[0].strip() handle=handle.split('&')[0].strip()
if '@' not in handle: if '@' not in handle:
return None return None
baseDir=os.getcwd()
filename=baseDir+'/wfendpoints/'+handle.lower()+'.json' filename=baseDir+'/wfendpoints/'+handle.lower()+'.json'
print('************** filename: '+filename)
if not os.path.isfile(filename): if not os.path.isfile(filename):
return None return None
wfJson={"user": "unknown"} wfJson={"user": "unknown"}