mirror of https://gitlab.com/bashrc2/epicyon
Merge
commit
e72cbecf50
2
Makefile
2
Makefile
|
|
@ -23,4 +23,4 @@ clean:
|
|||
rm -f deploy/*~
|
||||
rm -f translations/*~
|
||||
rm -rf __pycache__
|
||||
rm calendar.css blog.css epicyon.css follow.css login.css options.css search.css suspended.css
|
||||
rm -f calendar.css blog.css epicyon.css follow.css login.css options.css search.css suspended.css
|
||||
|
|
|
|||
34
cache.py
34
cache.py
|
|
@ -8,11 +8,45 @@ __status__ = "Production"
|
|||
|
||||
import os
|
||||
import datetime
|
||||
from session import urlExists
|
||||
from utils import loadJson
|
||||
from utils import saveJson
|
||||
from utils import getFileCaseInsensitive
|
||||
|
||||
|
||||
def _removePersonFromCache(baseDir: str, personUrl: str,
|
||||
personCache: {}) -> bool:
|
||||
"""Removes an actor from the cache
|
||||
"""
|
||||
cacheFilename = baseDir + '/cache/actors/' + \
|
||||
personUrl.replace('/', '#')+'.json'
|
||||
if os.path.isfile(cacheFilename):
|
||||
try:
|
||||
os.remove(cacheFilename)
|
||||
except BaseException:
|
||||
pass
|
||||
if personCache.get(personUrl):
|
||||
del personCache[personUrl]
|
||||
|
||||
|
||||
def checkForChangedActor(session, baseDir: str,
|
||||
httpPrefix: str, domainFull: str,
|
||||
personUrl: str, avatarUrl: str, personCache: {},
|
||||
timeoutSec: int):
|
||||
"""Checks if the avatar url exists and if not then
|
||||
the actor has probably changed without receiving an actor/Person Update.
|
||||
So clear the actor from the cache and it will be refreshed when the next
|
||||
post from them is sent
|
||||
"""
|
||||
if not session or not avatarUrl:
|
||||
return
|
||||
if domainFull in avatarUrl:
|
||||
return
|
||||
if urlExists(session, avatarUrl, timeoutSec, httpPrefix, domainFull):
|
||||
return
|
||||
_removePersonFromCache(baseDir, personUrl, personCache)
|
||||
|
||||
|
||||
def storePersonInCache(baseDir: str, personUrl: str,
|
||||
personJson: {}, personCache: {},
|
||||
allowWriteToFile: bool) -> None:
|
||||
|
|
|
|||
20
daemon.py
20
daemon.py
|
|
@ -228,6 +228,7 @@ from content import extractMediaInFormPOST
|
|||
from content import saveMediaInFormPOST
|
||||
from content import extractTextFieldsInPOST
|
||||
from media import removeMetaData
|
||||
from cache import checkForChangedActor
|
||||
from cache import storePersonInCache
|
||||
from cache import getPersonFromCache
|
||||
from httpsig import verifyPostHeaders
|
||||
|
|
@ -5488,6 +5489,15 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
PGPfingerprint = getPGPfingerprint(actorJson)
|
||||
if actorJson.get('alsoKnownAs'):
|
||||
alsoKnownAs = actorJson['alsoKnownAs']
|
||||
|
||||
if self.server.session:
|
||||
checkForChangedActor(self.server.session,
|
||||
self.server.baseDir,
|
||||
self.server.httpPrefix,
|
||||
self.server.domainFull,
|
||||
optionsActor, optionsProfileUrl,
|
||||
self.server.personCache, 5)
|
||||
|
||||
msg = htmlPersonOptions(self.server.defaultTimeline,
|
||||
self.server.cssCache,
|
||||
self.server.translate,
|
||||
|
|
@ -10051,6 +10061,16 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
# replace https://domain/@nick with https://domain/users/nick
|
||||
if self.path.startswith('/@'):
|
||||
self.path = self.path.replace('/@', '/users/')
|
||||
# replace https://domain/@nick/statusnumber
|
||||
# with https://domain/users/nick/statuses/statusnumber
|
||||
nickname = self.path.split('/users/')[1]
|
||||
if '/' in nickname:
|
||||
statusNumberStr = nickname.split('/')[1]
|
||||
if statusNumberStr.isdigit():
|
||||
nickname = nickname.split('/')[0]
|
||||
self.path = \
|
||||
self.path.replace('/users/' + nickname + '/',
|
||||
'/users/' + nickname + '/statuses/')
|
||||
|
||||
# turn off dropdowns on new post screen
|
||||
noDropDown = False
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
49
inbox.py
49
inbox.py
|
|
@ -2726,6 +2726,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
|||
print('DEBUG: checking http header signature')
|
||||
pprint(queueJson['httpHeaders'])
|
||||
postStr = json.dumps(queueJson['post'])
|
||||
httpSignatureFailed = False
|
||||
if not verifyPostHeaders(httpPrefix,
|
||||
pubKey,
|
||||
queueJson['httpHeaders'],
|
||||
|
|
@ -2733,19 +2734,17 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
|||
queueJson['digest'],
|
||||
postStr,
|
||||
debug):
|
||||
httpSignatureFailed = True
|
||||
print('Queue: Header signature check failed')
|
||||
if debug:
|
||||
pprint(queueJson['httpHeaders'])
|
||||
if os.path.isfile(queueFilename):
|
||||
os.remove(queueFilename)
|
||||
if len(queue) > 0:
|
||||
queue.pop(0)
|
||||
continue
|
||||
|
||||
else:
|
||||
if debug:
|
||||
print('DEBUG: http header signature check success')
|
||||
|
||||
# check if a json signature exists on this post
|
||||
checkJsonSignature = False
|
||||
hasJsonSignature = False
|
||||
jwebsigType = None
|
||||
originalJson = queueJson['original']
|
||||
if originalJson.get('@context') and \
|
||||
originalJson.get('signature'):
|
||||
|
|
@ -2754,27 +2753,41 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
|||
jwebsig = originalJson['signature']
|
||||
# signature exists and is of the expected type
|
||||
if jwebsig.get('type') and jwebsig.get('signatureValue'):
|
||||
if jwebsig['type'] == 'RsaSignature2017':
|
||||
jwebsigType = jwebsig['type']
|
||||
if jwebsigType == 'RsaSignature2017':
|
||||
if hasValidContext(originalJson):
|
||||
checkJsonSignature = True
|
||||
hasJsonSignature = True
|
||||
else:
|
||||
print('unrecognised @context: ' +
|
||||
str(originalJson['@context']))
|
||||
|
||||
# strict enforcement of json signatures
|
||||
if verifyAllSignatures and \
|
||||
not checkJsonSignature:
|
||||
print('inbox post does not have a jsonld signature ' +
|
||||
if not hasJsonSignature:
|
||||
if httpSignatureFailed:
|
||||
if jwebsigType:
|
||||
print('Queue: Header signature check failed and does ' +
|
||||
'not have a recognised jsonld signature type ' +
|
||||
jwebsigType)
|
||||
else:
|
||||
print('Queue: Header signature check failed and ' +
|
||||
'does not have jsonld signature')
|
||||
if debug:
|
||||
pprint(queueJson['httpHeaders'])
|
||||
|
||||
if verifyAllSignatures:
|
||||
print('Queue: inbox post does not have a jsonld signature ' +
|
||||
keyId + ' ' + str(originalJson))
|
||||
|
||||
if httpSignatureFailed or verifyAllSignatures:
|
||||
if os.path.isfile(queueFilename):
|
||||
os.remove(queueFilename)
|
||||
if len(queue) > 0:
|
||||
queue.pop(0)
|
||||
continue
|
||||
|
||||
if checkJsonSignature and verifyAllSignatures:
|
||||
# use the original json message received, not one which may have
|
||||
# been modified along the way
|
||||
else:
|
||||
if httpSignatureFailed or verifyAllSignatures:
|
||||
# use the original json message received, not one which
|
||||
# may have been modified along the way
|
||||
if not verifyJsonSignature(originalJson, pubKey):
|
||||
if debug:
|
||||
print('WARN: jsonld inbox signature check failed ' +
|
||||
|
|
@ -2787,6 +2800,10 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
|||
if len(queue) > 0:
|
||||
queue.pop(0)
|
||||
continue
|
||||
else:
|
||||
if httpSignatureFailed:
|
||||
print('jsonld inbox signature check success ' +
|
||||
'via relay ' + keyId)
|
||||
else:
|
||||
print('jsonld inbox signature check success ' + keyId)
|
||||
|
||||
|
|
|
|||
32
session.py
32
session.py
|
|
@ -53,6 +53,37 @@ def createSession(proxyType: str):
|
|||
return session
|
||||
|
||||
|
||||
def urlExists(session, url: str, timeoutSec=3,
|
||||
httpPrefix='https', domain='testdomain') -> bool:
|
||||
if not isinstance(url, str):
|
||||
print('url: ' + str(url))
|
||||
print('ERROR: urlExists failed, url should be a string')
|
||||
return False
|
||||
sessionParams = {}
|
||||
sessionHeaders = {}
|
||||
sessionHeaders['User-Agent'] = 'Epicyon/' + __version__
|
||||
if domain:
|
||||
sessionHeaders['User-Agent'] += \
|
||||
'; +' + httpPrefix + '://' + domain + '/'
|
||||
if not session:
|
||||
print('WARN: urlExists failed, no session specified')
|
||||
return True
|
||||
try:
|
||||
result = session.get(url, headers=sessionHeaders,
|
||||
params=sessionParams,
|
||||
timeout=timeoutSec)
|
||||
if result:
|
||||
if result.status_code == 200 or \
|
||||
result.status_code == 304:
|
||||
return True
|
||||
else:
|
||||
print('urlExists for ' + url + ' returned ' +
|
||||
str(result.status_code))
|
||||
except BaseException:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
def getJson(session, url: str, headers: {}, params: {},
|
||||
version='1.2.0', httpPrefix='https',
|
||||
domain='testdomain') -> {}:
|
||||
|
|
@ -72,6 +103,7 @@ def getJson(session, url: str, headers: {}, params: {},
|
|||
'; +' + httpPrefix + '://' + domain + '/'
|
||||
if not session:
|
||||
print('WARN: getJson failed, no session specified for getJson')
|
||||
return None
|
||||
try:
|
||||
result = session.get(url, headers=sessionHeaders, params=sessionParams)
|
||||
return result.json()
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 131 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 131 KiB |
Loading…
Reference in New Issue