forked from indymedia/epicyon
Create shared inbox on start of daemon
parent
810dad25da
commit
509ba6b840
5
auth.py
5
auth.py
|
@ -11,6 +11,7 @@ import hashlib
|
||||||
import binascii
|
import binascii
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import random
|
||||||
|
|
||||||
def hashPassword(password: str) -> str:
|
def hashPassword(password: str) -> str:
|
||||||
"""Hash a password for storing
|
"""Hash a password for storing
|
||||||
|
@ -135,3 +136,7 @@ def authorize(baseDir: str,path: str,authHeader: str,debug: bool) -> bool:
|
||||||
if authHeader.lower().startswith('basic '):
|
if authHeader.lower().startswith('basic '):
|
||||||
return authorizeBasic(baseDir,path,authHeader,debug)
|
return authorizeBasic(baseDir,path,authHeader,debug)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def createPassword(length=10):
|
||||||
|
validChars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
||||||
|
return ''.join((random.choice(validChars) for i in range(length)))
|
||||||
|
|
41
daemon.py
41
daemon.py
|
@ -144,6 +144,26 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
savePostToBox(self.server.baseDir,postId,self.postToNickname,self.server.domain,messageJson,'outbox')
|
savePostToBox(self.server.baseDir,postId,self.postToNickname,self.server.domain,messageJson,'outbox')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _updateInboxQueue(nickname: str,messageJson: {}) -> bool:
|
||||||
|
"""Update the inbox queue
|
||||||
|
"""
|
||||||
|
cacheFilename = \
|
||||||
|
savePostToInboxQueue(self.server.baseDir, \
|
||||||
|
self.server.httpPrefix, \
|
||||||
|
nickname, \
|
||||||
|
self.server.domain, \
|
||||||
|
messageJson,
|
||||||
|
self.headers['host'],
|
||||||
|
self.headers['signature'])
|
||||||
|
if cacheFilename:
|
||||||
|
if cacheFilename not in self.server.inboxQueue:
|
||||||
|
self.server.inboxQueue.append(cacheFilename)
|
||||||
|
self.send_response(201)
|
||||||
|
self.end_headers()
|
||||||
|
self.server.POSTbusy=False
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
print('DEBUG: GET from '+self.server.baseDir+' path: '+self.path+' busy: '+str(self.server.GETbusy))
|
print('DEBUG: GET from '+self.server.baseDir+' path: '+self.path+' busy: '+str(self.server.GETbusy))
|
||||||
|
@ -384,20 +404,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
else:
|
else:
|
||||||
self.postToNickname=pathUsersSection.split('/')[0]
|
self.postToNickname=pathUsersSection.split('/')[0]
|
||||||
if self.postToNickname:
|
if self.postToNickname:
|
||||||
cacheFilename = \
|
if _updateInboxQueue(self.postToNickname,messageJson):
|
||||||
savePostToInboxQueue(self.server.baseDir, \
|
|
||||||
self.server.httpPrefix, \
|
|
||||||
self.postToNickname, \
|
|
||||||
self.server.domain, \
|
|
||||||
messageJson,
|
|
||||||
self.headers['host'],
|
|
||||||
self.headers['signature'])
|
|
||||||
if cacheFilename:
|
|
||||||
if cacheFilename not in self.server.inboxQueue:
|
|
||||||
self.server.inboxQueue.append(cacheFilename)
|
|
||||||
self.send_response(201)
|
|
||||||
self.end_headers()
|
|
||||||
self.server.POSTbusy=False
|
|
||||||
return
|
return
|
||||||
self.send_response(403)
|
self.send_response(403)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
|
@ -406,10 +413,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
else:
|
else:
|
||||||
if self.path == '/sharedInbox':
|
if self.path == '/sharedInbox':
|
||||||
print('DEBUG: POST to shared inbox')
|
print('DEBUG: POST to shared inbox')
|
||||||
self.send_response(201)
|
if _updateInboxQueue('sharedinbox',messageJson):
|
||||||
self.end_headers()
|
return
|
||||||
self.server.POSTbusy=False
|
|
||||||
return
|
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.server.POSTbusy=False
|
self.server.POSTbusy=False
|
||||||
|
|
11
epicyon.py
11
epicyon.py
|
@ -7,6 +7,7 @@ __email__ = "bob@freedombone.net"
|
||||||
__status__ = "Production"
|
__status__ = "Production"
|
||||||
|
|
||||||
from person import createPerson
|
from person import createPerson
|
||||||
|
from person import createSharedInbox
|
||||||
from person import setPreferredNickname
|
from person import setPreferredNickname
|
||||||
from person import setBio
|
from person import setBio
|
||||||
from webfinger import webfingerHandle
|
from webfinger import webfingerHandle
|
||||||
|
@ -40,6 +41,7 @@ from config import setConfigParam
|
||||||
from config import getConfigParam
|
from config import getConfigParam
|
||||||
from auth import storeBasicCredentials
|
from auth import storeBasicCredentials
|
||||||
from auth import removePassword
|
from auth import removePassword
|
||||||
|
from auth import createPassword
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
def str2bool(v):
|
def str2bool(v):
|
||||||
|
@ -263,6 +265,13 @@ if federationList:
|
||||||
|
|
||||||
if not os.path.isdir(baseDir+'/accounts/'+nickname+'@'+domain):
|
if not os.path.isdir(baseDir+'/accounts/'+nickname+'@'+domain):
|
||||||
print('Creating default admin account '+nickname+'@'+domain)
|
print('Creating default admin account '+nickname+'@'+domain)
|
||||||
createPerson(baseDir,nickname,domain,port,httpPrefix,True)
|
print('See config.json for the password. You can remove the password from config.json after moving it elsewhere.')
|
||||||
|
adminPassword=createPassword(10)
|
||||||
|
setConfigParam(baseDir,'adminPassword',adminPassword)
|
||||||
|
createPerson(baseDir,nickname,domain,port,httpPrefix,True,adminPassword)
|
||||||
|
|
||||||
|
if not os.path.isdir(baseDir+'/accounts/sharedinbox@'+domain):
|
||||||
|
print('Creating shared inbox')
|
||||||
|
createSharedInbox(baseDir,'sharedinbox',domain,port,httpPrefix)
|
||||||
|
|
||||||
runDaemon(baseDir,domain,port,httpPrefix,federationList,useTor,debug)
|
runDaemon(baseDir,domain,port,httpPrefix,federationList,useTor,debug)
|
||||||
|
|
2
inbox.py
2
inbox.py
|
@ -101,7 +101,7 @@ def savePostToInboxQueue(baseDir: str,httpPrefix: str,nickname: str, domain: str
|
||||||
currTime=datetime.datetime.utcnow()
|
currTime=datetime.datetime.utcnow()
|
||||||
published=currTime.strftime("%Y-%m-%dT%H:%M:%SZ")
|
published=currTime.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
|
||||||
inboxQueueDir = createInboxQueueDir(nickname,domain,baseDir)
|
inboxQueueDir=createInboxQueueDir(nickname,domain,baseDir)
|
||||||
|
|
||||||
handle=nickname+'@'+domain
|
handle=nickname+'@'+domain
|
||||||
destination=baseDir+'/accounts/'+handle+'/inbox/'+postId.replace('/','#')+'.json'
|
destination=baseDir+'/accounts/'+handle+'/inbox/'+postId.replace('/','#')+'.json'
|
||||||
|
|
23
person.py
23
person.py
|
@ -22,12 +22,10 @@ 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(baseDir: str,nickname: str,domain: str,port: int, \
|
def createPersonBase(baseDir: str,nickname: str,domain: str,port: int, \
|
||||||
httpPrefix: str, saveToFile: bool,password=None) -> (str,str,{},{}):
|
httpPrefix: str, saveToFile: bool,password=None) -> (str,str,{},{}):
|
||||||
"""Returns the private key, public key, actor and webfinger endpoint
|
"""Returns the private key, public key, actor and webfinger endpoint
|
||||||
"""
|
"""
|
||||||
if not validNickname(nickname):
|
|
||||||
return None,None,None,None
|
|
||||||
privateKeyPem,publicKeyPem=generateRSAKey()
|
privateKeyPem,publicKeyPem=generateRSAKey()
|
||||||
webfingerEndpoint= \
|
webfingerEndpoint= \
|
||||||
createWebfingerEndpoint(nickname,domain,port,httpPrefix,publicKeyPem)
|
createWebfingerEndpoint(nickname,domain,port,httpPrefix,publicKeyPem)
|
||||||
|
@ -116,12 +114,26 @@ def createPerson(baseDir: str,nickname: str,domain: str,port: int, \
|
||||||
|
|
||||||
return privateKeyPem,publicKeyPem,newPerson,webfingerEndpoint
|
return privateKeyPem,publicKeyPem,newPerson,webfingerEndpoint
|
||||||
|
|
||||||
|
def createPerson(baseDir: str,nickname: str,domain: str,port: int, \
|
||||||
|
httpPrefix: str, saveToFile: bool,password=None) -> (str,str,{},{}):
|
||||||
|
"""Returns the private key, public key, actor and webfinger endpoint
|
||||||
|
"""
|
||||||
|
if not validNickname(nickname):
|
||||||
|
return None,None,None,None
|
||||||
|
return createPersonBase(baseDir,nickname,domain,port,httpPrefix,saveToFile,password)
|
||||||
|
|
||||||
|
def createSharedInbox(baseDir: str,nickname: str,domain: str,port: int, \
|
||||||
|
httpPrefix: str) -> (str,str,{},{}):
|
||||||
|
"""Generates the shared inbox
|
||||||
|
"""
|
||||||
|
return createPersonBase(baseDir,nickname,domain,port,httpPrefix,True,None)
|
||||||
|
|
||||||
def validNickname(nickname: str) -> bool:
|
def validNickname(nickname: str) -> bool:
|
||||||
forbiddenChars=['.',' ','/','?',':',';','@']
|
forbiddenChars=['.',' ','/','?',':',';','@']
|
||||||
for c in forbiddenChars:
|
for c in forbiddenChars:
|
||||||
if c in nickname:
|
if c in nickname:
|
||||||
return False
|
return False
|
||||||
reservedNames=['inbox','outbox','following','followers','sharedInbox']
|
reservedNames=['inbox','outbox','following','followers','sharedinbox']
|
||||||
if nickname in reservedNames:
|
if nickname in reservedNames:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
@ -276,4 +288,3 @@ def setBio(baseDir: str,nickname: str, domain: str, bio: str) -> bool:
|
||||||
with open(filename, 'w') as fp:
|
with open(filename, 'w') as fp:
|
||||||
commentjson.dump(personJson, fp, indent=4, sort_keys=False)
|
commentjson.dump(personJson, fp, indent=4, sort_keys=False)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue