mirror of https://gitlab.com/bashrc2/epicyon
Set pgp public key from desktop client
parent
806209b3b5
commit
67f63c5119
|
@ -35,6 +35,7 @@ from announce import sendAnnounceViaServer
|
|||
from pgp import pgpDecrypt
|
||||
from pgp import hasLocalPGPkey
|
||||
from pgp import pgpEncryptToActor
|
||||
from pgp import pgpPublicKeyUpload
|
||||
|
||||
|
||||
def _desktopHelp() -> None:
|
||||
|
@ -850,8 +851,21 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str,
|
|||
newRepliesExist = False
|
||||
newDMsExist = False
|
||||
currPostId = ''
|
||||
pgpKeyUpload = False
|
||||
while (1):
|
||||
session = createSession(proxyType)
|
||||
|
||||
if not pgpKeyUpload:
|
||||
pgpKey = \
|
||||
pgpPublicKeyUpload(baseDir, session,
|
||||
nickname, password,
|
||||
domain, port, httpPrefix,
|
||||
cachedWebfingers, personCache,
|
||||
debug, False)
|
||||
if pgpKey:
|
||||
print('PGP public key uploaded')
|
||||
pgpKeyUpload = True
|
||||
|
||||
notifyJson = None
|
||||
speakerJson = \
|
||||
getSpeakerFromServer(baseDir, session, nickname, password,
|
||||
|
|
20
epicyon.py
20
epicyon.py
|
@ -48,6 +48,7 @@ from follow import sendUnfollowRequestViaServer
|
|||
from tests import testPostMessageBetweenServers
|
||||
from tests import testFollowBetweenServers
|
||||
from tests import testClientToServer
|
||||
from tests import testUpdateActor
|
||||
from tests import runAllTests
|
||||
from auth import storeBasicCredentials
|
||||
from auth import createPassword
|
||||
|
@ -531,6 +532,7 @@ if args.testsnetwork:
|
|||
testPostMessageBetweenServers()
|
||||
testFollowBetweenServers()
|
||||
testClientToServer()
|
||||
testUpdateActor()
|
||||
print('All tests succeeded')
|
||||
sys.exit()
|
||||
|
||||
|
@ -2121,7 +2123,7 @@ if args.testdata:
|
|||
|
||||
testFollowersOnly = False
|
||||
testSaveToFile = True
|
||||
testClientToServer = False
|
||||
testC2S = False
|
||||
testCommentsEnabled = True
|
||||
testAttachImageFilename = None
|
||||
testMediaType = None
|
||||
|
@ -2131,7 +2133,7 @@ if args.testdata:
|
|||
"like this is totally just a #test man",
|
||||
testFollowersOnly,
|
||||
testSaveToFile,
|
||||
testClientToServer,
|
||||
testC2S,
|
||||
testCommentsEnabled,
|
||||
testAttachImageFilename,
|
||||
testMediaType, testImageDescription)
|
||||
|
@ -2139,7 +2141,7 @@ if args.testdata:
|
|||
"Zoiks!!!",
|
||||
testFollowersOnly,
|
||||
testSaveToFile,
|
||||
testClientToServer,
|
||||
testC2S,
|
||||
testCommentsEnabled,
|
||||
testAttachImageFilename,
|
||||
testMediaType, testImageDescription)
|
||||
|
@ -2147,7 +2149,7 @@ if args.testdata:
|
|||
"Hey scoob we need like a hundred more #milkshakes",
|
||||
testFollowersOnly,
|
||||
testSaveToFile,
|
||||
testClientToServer,
|
||||
testC2S,
|
||||
testCommentsEnabled,
|
||||
testAttachImageFilename,
|
||||
testMediaType, testImageDescription)
|
||||
|
@ -2155,7 +2157,7 @@ if args.testdata:
|
|||
"Getting kinda spooky around here",
|
||||
testFollowersOnly,
|
||||
testSaveToFile,
|
||||
testClientToServer,
|
||||
testC2S,
|
||||
testCommentsEnabled,
|
||||
testAttachImageFilename,
|
||||
testMediaType, testImageDescription,
|
||||
|
@ -2165,7 +2167,7 @@ if args.testdata:
|
|||
"if it wasn't for those pesky hackers",
|
||||
testFollowersOnly,
|
||||
testSaveToFile,
|
||||
testClientToServer,
|
||||
testC2S,
|
||||
testCommentsEnabled,
|
||||
'img/logo.png', 'image/png',
|
||||
'Description of image')
|
||||
|
@ -2173,7 +2175,7 @@ if args.testdata:
|
|||
"man these centralized sites are like the worst!",
|
||||
testFollowersOnly,
|
||||
testSaveToFile,
|
||||
testClientToServer,
|
||||
testC2S,
|
||||
testCommentsEnabled,
|
||||
testAttachImageFilename,
|
||||
testMediaType, testImageDescription)
|
||||
|
@ -2181,7 +2183,7 @@ if args.testdata:
|
|||
"another mystery solved #test",
|
||||
testFollowersOnly,
|
||||
testSaveToFile,
|
||||
testClientToServer,
|
||||
testC2S,
|
||||
testCommentsEnabled,
|
||||
testAttachImageFilename,
|
||||
testMediaType, testImageDescription)
|
||||
|
@ -2189,7 +2191,7 @@ if args.testdata:
|
|||
"let's go bowling",
|
||||
testFollowersOnly,
|
||||
testSaveToFile,
|
||||
testClientToServer,
|
||||
testC2S,
|
||||
testCommentsEnabled,
|
||||
testAttachImageFilename,
|
||||
testMediaType, testImageDescription)
|
||||
|
|
|
@ -1028,7 +1028,7 @@ def sendFollowRequestViaServer(baseDir: str, session,
|
|||
postJson(session, newFollowJson, [], inboxUrl, headers, 30, True)
|
||||
if not postResult:
|
||||
if debug:
|
||||
print('DEBUG: POST announce failed for c2s to ' + inboxUrl)
|
||||
print('DEBUG: POST follow failed for c2s to ' + inboxUrl)
|
||||
return 5
|
||||
|
||||
if debug:
|
||||
|
|
122
outbox.py
122
outbox.py
|
@ -21,6 +21,8 @@ from utils import removeIdEnding
|
|||
from utils import getDomainFromActor
|
||||
from utils import dangerousMarkup
|
||||
from utils import isFeaturedWriter
|
||||
from utils import loadJson
|
||||
from utils import saveJson
|
||||
from blocking import isBlockedDomain
|
||||
from blocking import outboxBlock
|
||||
from blocking import outboxUndoBlock
|
||||
|
@ -42,6 +44,119 @@ from shares import outboxShareUpload
|
|||
from shares import outboxUndoShareUpload
|
||||
|
||||
|
||||
def _outboxPersonReceiveUpdate(recentPostsCache: {},
|
||||
baseDir: str, httpPrefix: str,
|
||||
nickname: str, domain: str, port: int,
|
||||
messageJson: {}, debug: bool) -> None:
|
||||
""" Receive an actor update from c2s
|
||||
For example, setting the PGP key from the desktop client
|
||||
"""
|
||||
# these attachments are updatable via c2s
|
||||
updatableAttachments = ('PGP', 'OpenPGP', 'Email')
|
||||
|
||||
if not messageJson.get('type'):
|
||||
return
|
||||
print("messageJson['type'] " + messageJson['type'])
|
||||
if messageJson['type'] != 'Update':
|
||||
return
|
||||
if not messageJson.get('object'):
|
||||
return
|
||||
if not isinstance(messageJson['object'], dict):
|
||||
if debug:
|
||||
print('DEBUG: c2s actor update object is not dict')
|
||||
return
|
||||
if not messageJson['object'].get('type'):
|
||||
if debug:
|
||||
print('DEBUG: c2s actor update - no type')
|
||||
return
|
||||
if messageJson['object']['type'] != 'Person':
|
||||
if debug:
|
||||
print('DEBUG: not a c2s actor update')
|
||||
return
|
||||
if not messageJson.get('to'):
|
||||
if debug:
|
||||
print('DEBUG: c2s actor update has no "to" field')
|
||||
return
|
||||
if not messageJson.get('actor'):
|
||||
if debug:
|
||||
print('DEBUG: c2s actor update has no actor field')
|
||||
return
|
||||
if not messageJson.get('id'):
|
||||
if debug:
|
||||
print('DEBUG: c2s actor update has no id field')
|
||||
return
|
||||
actor = \
|
||||
httpPrefix + '://' + getFullDomain(domain, port) + '/users/' + nickname
|
||||
if len(messageJson['to']) != 1:
|
||||
if debug:
|
||||
print('DEBUG: c2s actor update - to does not contain one actor ' +
|
||||
messageJson['to'])
|
||||
return
|
||||
if messageJson['to'][0] != actor:
|
||||
if debug:
|
||||
print('DEBUG: c2s actor update - to does not contain actor ' +
|
||||
messageJson['to'] + ' ' + actor)
|
||||
return
|
||||
if not messageJson['id'].startswith(actor + '#updates/'):
|
||||
if debug:
|
||||
print('DEBUG: c2s actor update - unexpected id ' +
|
||||
messageJson['id'])
|
||||
return
|
||||
updatedActorJson = messageJson['object']
|
||||
# load actor from file
|
||||
actorFilename = baseDir + '/accounts/' + nickname + '@' + domain + '.json'
|
||||
if not os.path.isfile(actorFilename):
|
||||
print('actorFilename not found: ' + actorFilename)
|
||||
return
|
||||
actorJson = loadJson(actorFilename)
|
||||
if not actorJson:
|
||||
return
|
||||
actorChanged = False
|
||||
# update fields within actor
|
||||
if 'attachment' in updatedActorJson:
|
||||
for newPropertyValue in updatedActorJson['attachment']:
|
||||
if not newPropertyValue.get('name'):
|
||||
continue
|
||||
if newPropertyValue['name'] not in updatableAttachments:
|
||||
continue
|
||||
if not newPropertyValue.get('type'):
|
||||
continue
|
||||
if not newPropertyValue.get('value'):
|
||||
continue
|
||||
if newPropertyValue['type'] != 'PropertyValue':
|
||||
continue
|
||||
if 'attachment' in actorJson:
|
||||
found = False
|
||||
for propertyValue in actorJson['attachment']:
|
||||
if propertyValue != 'PropertyValue':
|
||||
continue
|
||||
if propertyValue['name'] == newPropertyValue['name']:
|
||||
if propertyValue['value'] != \
|
||||
newPropertyValue['value']:
|
||||
propertyValue['value'] = \
|
||||
newPropertyValue['value']
|
||||
actorChanged = True
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
actorJson['attachment'].append({
|
||||
"name": newPropertyValue['name'],
|
||||
"type": "PropertyValue",
|
||||
"value": newPropertyValue['value']
|
||||
})
|
||||
actorChanged = True
|
||||
# save actor to file
|
||||
if actorChanged:
|
||||
saveJson(actorJson, actorFilename)
|
||||
if debug:
|
||||
print('actor saved: ' + actorFilename)
|
||||
if debug:
|
||||
print('New attachment: ' + str(actorJson['attachment']))
|
||||
messageJson['object'] = actorJson
|
||||
if debug:
|
||||
print('DEBUG: actor update via c2s - ' + nickname + '@' + domain)
|
||||
|
||||
|
||||
def postMessageToOutbox(session, translate: {},
|
||||
messageJson: {}, postToNickname: str,
|
||||
server, baseDir: str, httpPrefix: str,
|
||||
|
@ -408,6 +523,13 @@ def postMessageToOutbox(session, translate: {},
|
|||
postToNickname, domain,
|
||||
port, messageJson, debug)
|
||||
|
||||
if debug:
|
||||
print('DEBUG: handle actor updates from c2s')
|
||||
_outboxPersonReceiveUpdate(recentPostsCache,
|
||||
baseDir, httpPrefix,
|
||||
postToNickname, domain, port,
|
||||
messageJson, debug)
|
||||
|
||||
if debug:
|
||||
print('DEBUG: sending c2s post to named addresses')
|
||||
if messageJson.get('to'):
|
||||
|
|
33
person.py
33
person.py
|
@ -1106,6 +1106,8 @@ def getActorJson(handle: str, http: bool, gnunet: bool,
|
|||
debug: bool, quiet=False) -> {}:
|
||||
"""Returns the actor json
|
||||
"""
|
||||
if debug:
|
||||
print('getActorJson for ' + handle)
|
||||
originalActor = handle
|
||||
if '/@' in handle or \
|
||||
'/users/' in handle or \
|
||||
|
@ -1117,8 +1119,8 @@ def getActorJson(handle: str, http: bool, gnunet: bool,
|
|||
handle = handle.replace(prefix, '')
|
||||
handle = handle.replace('/@', '/users/')
|
||||
if not hasUsersPath(handle):
|
||||
if not quiet:
|
||||
print('Expected actor format: ' +
|
||||
if not quiet or debug:
|
||||
print('getActorJson: Expected actor format: ' +
|
||||
'https://domain/@nick or https://domain/users/nick')
|
||||
return None
|
||||
if '/users/' in handle:
|
||||
|
@ -1145,13 +1147,13 @@ def getActorJson(handle: str, http: bool, gnunet: bool,
|
|||
# format: @nick@domain
|
||||
if '@' not in handle:
|
||||
if not quiet:
|
||||
print('Syntax: --actor nickname@domain')
|
||||
print('getActorJson Syntax: --actor nickname@domain')
|
||||
return None
|
||||
if handle.startswith('@'):
|
||||
handle = handle[1:]
|
||||
if '@' not in handle:
|
||||
if not quiet:
|
||||
print('Syntax: --actor nickname@domain')
|
||||
print('getActorJsonSyntax: --actor nickname@domain')
|
||||
return None
|
||||
nickname = handle.split('@')[0]
|
||||
domain = handle.split('@')[1]
|
||||
|
@ -1168,7 +1170,10 @@ def getActorJson(handle: str, http: bool, gnunet: bool,
|
|||
httpPrefix = 'gnunet'
|
||||
proxyType = 'gnunet'
|
||||
else:
|
||||
httpPrefix = 'https'
|
||||
if '127.0.' not in domain and '192.168.' not in domain:
|
||||
httpPrefix = 'https'
|
||||
else:
|
||||
httpPrefix = 'http'
|
||||
session = createSession(proxyType)
|
||||
if nickname == 'inbox':
|
||||
nickname = domain
|
||||
|
@ -1179,12 +1184,12 @@ def getActorJson(handle: str, http: bool, gnunet: bool,
|
|||
None, __version__, debug)
|
||||
if not wfRequest:
|
||||
if not quiet:
|
||||
print('Unable to webfinger ' + handle)
|
||||
print('getActorJson Unable to webfinger ' + handle)
|
||||
return None
|
||||
if not isinstance(wfRequest, dict):
|
||||
if not quiet:
|
||||
print('Webfinger for ' + handle + ' did not return a dict. ' +
|
||||
str(wfRequest))
|
||||
print('getActorJson Webfinger for ' + handle +
|
||||
' did not return a dict. ' + str(wfRequest))
|
||||
return None
|
||||
|
||||
if not quiet:
|
||||
|
@ -1192,11 +1197,13 @@ def getActorJson(handle: str, http: bool, gnunet: bool,
|
|||
|
||||
personUrl = None
|
||||
if wfRequest.get('errors'):
|
||||
if not quiet:
|
||||
print('wfRequest error: ' + str(wfRequest['errors']))
|
||||
if not quiet or debug:
|
||||
print('getActorJson wfRequest error: ' + str(wfRequest['errors']))
|
||||
if hasUsersPath(handle):
|
||||
personUrl = originalActor
|
||||
else:
|
||||
if debug:
|
||||
print('No users path in ' + handle)
|
||||
return None
|
||||
|
||||
profileStr = 'https://www.w3.org/ns/activitystreams'
|
||||
|
@ -1228,8 +1235,9 @@ def getActorJson(handle: str, http: bool, gnunet: bool,
|
|||
getJson(session, personUrl, asHeader, None,
|
||||
debug, __version__, httpPrefix, None, 20, quiet)
|
||||
if personJson:
|
||||
if not quiet:
|
||||
if not quiet or debug:
|
||||
pprint(personJson)
|
||||
return personJson
|
||||
else:
|
||||
profileStr = 'https://www.w3.org/ns/activitystreams'
|
||||
asHeader = {
|
||||
|
@ -1238,8 +1246,9 @@ def getActorJson(handle: str, http: bool, gnunet: bool,
|
|||
personJson = \
|
||||
getJson(session, personUrl, asHeader, None,
|
||||
debug, __version__, httpPrefix, None)
|
||||
if not quiet:
|
||||
if not quiet or debug:
|
||||
if personJson:
|
||||
print('getActorJson returned actor')
|
||||
pprint(personJson)
|
||||
else:
|
||||
print('Failed to get ' + personUrl)
|
||||
|
|
205
pgp.py
205
pgp.py
|
@ -7,11 +7,18 @@ __email__ = "bob@freedombone.net"
|
|||
__status__ = "Production"
|
||||
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from person import getActorJson
|
||||
from utils import containsPGPPublicKey
|
||||
from utils import isPGPEncrypted
|
||||
from utils import getFullDomain
|
||||
from utils import getStatusNumber
|
||||
from webfinger import webfingerHandle
|
||||
from posts import getPersonBox
|
||||
from auth import createBasicAuthHeader
|
||||
from session import postJson
|
||||
|
||||
|
||||
def getEmailAddress(actorJson: {}) -> str:
|
||||
|
@ -395,3 +402,201 @@ def pgpDecrypt(content: str, fromHandle: str) -> str:
|
|||
return content
|
||||
decryptResult = decryptResult.decode('utf-8').strip()
|
||||
return decryptResult
|
||||
|
||||
|
||||
def _pgpLocalPublicKeyId() -> str:
|
||||
"""Gets the local pgp public key ID
|
||||
"""
|
||||
cmdStr = \
|
||||
"gpgconf --list-options gpg | " + \
|
||||
"awk -F: '$1 == \"default-key\" {print $10}'"
|
||||
proc = subprocess.Popen([cmdStr],
|
||||
stdout=subprocess.PIPE, shell=True)
|
||||
(result, err) = proc.communicate()
|
||||
if err:
|
||||
return None
|
||||
if not result:
|
||||
return None
|
||||
if len(result) < 5:
|
||||
return None
|
||||
return result.replace('"', '').strip()
|
||||
|
||||
|
||||
def _pgpLocalPublicKey() -> str:
|
||||
"""Gets the local pgp public key
|
||||
"""
|
||||
keyId = _pgpLocalPublicKey()
|
||||
if not keyId:
|
||||
return None
|
||||
cmdStr = "gpg --armor --export " + keyId
|
||||
proc = subprocess.Popen([cmdStr],
|
||||
stdout=subprocess.PIPE, shell=True)
|
||||
(result, err) = proc.communicate()
|
||||
if err:
|
||||
return None
|
||||
if not result:
|
||||
return None
|
||||
return extractPGPPublicKey(result)
|
||||
|
||||
|
||||
def pgpPublicKeyUpload(baseDir: str, session,
|
||||
nickname: str, password: str,
|
||||
domain: str, port: int,
|
||||
httpPrefix: str,
|
||||
cachedWebfingers: {}, personCache: {},
|
||||
debug: bool, test: str) -> {}:
|
||||
if debug:
|
||||
print('pgpPublicKeyUpload')
|
||||
|
||||
if not session:
|
||||
if debug:
|
||||
print('WARN: No session for pgpPublicKeyUpload')
|
||||
return None
|
||||
|
||||
if not test:
|
||||
if debug:
|
||||
print('Getting PGP public key')
|
||||
PGPpubKey = _pgpLocalPublicKey()
|
||||
if not PGPpubKey:
|
||||
return None
|
||||
PGPpubKeyId = _pgpLocalPublicKeyId()
|
||||
else:
|
||||
if debug:
|
||||
print('Testing with PGP public key ' + test)
|
||||
PGPpubKey = test
|
||||
PGPpubKeyId = None
|
||||
|
||||
domainFull = getFullDomain(domain, port)
|
||||
if debug:
|
||||
print('PGP test domain: ' + domainFull)
|
||||
|
||||
handle = nickname + '@' + domainFull
|
||||
|
||||
if debug:
|
||||
print('Getting actor for ' + handle)
|
||||
|
||||
actorJson = getActorJson(handle, False, False, True)
|
||||
if not actorJson:
|
||||
if debug:
|
||||
print('No actor returned for ' + handle)
|
||||
return None
|
||||
|
||||
if debug:
|
||||
print('Actor for ' + handle + ' obtained')
|
||||
|
||||
actor = httpPrefix + '://' + domainFull + '/users/' + nickname
|
||||
handle = actor.replace('/users/', '/@')
|
||||
|
||||
# check that this looks like the correct actor
|
||||
if not actorJson.get('id'):
|
||||
if debug:
|
||||
print('Actor has no id')
|
||||
return None
|
||||
if not actorJson.get('url'):
|
||||
if debug:
|
||||
print('Actor has no url')
|
||||
return None
|
||||
if not actorJson.get('type'):
|
||||
if debug:
|
||||
print('Actor has no type')
|
||||
return None
|
||||
if actorJson['id'] != actor:
|
||||
if debug:
|
||||
print('Actor id is not ' + actor +
|
||||
' instead is ' + actorJson['id'])
|
||||
return None
|
||||
if actorJson['url'] != handle:
|
||||
if debug:
|
||||
print('Actor url is not ' + handle)
|
||||
return None
|
||||
if actorJson['type'] != 'Person':
|
||||
if debug:
|
||||
print('Actor type is not Person')
|
||||
return None
|
||||
|
||||
# set the pgp details
|
||||
if PGPpubKeyId:
|
||||
setPGPfingerprint(actorJson, PGPpubKeyId)
|
||||
else:
|
||||
if debug:
|
||||
print('No PGP key Id. Continuing anyway.')
|
||||
|
||||
if debug:
|
||||
print('Setting PGP key within ' + actor)
|
||||
setPGPpubKey(actorJson, PGPpubKey)
|
||||
|
||||
# create an actor update
|
||||
statusNumber, published = getStatusNumber()
|
||||
actorUpdate = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': actor + '#updates/' + statusNumber,
|
||||
'type': 'Update',
|
||||
'actor': actor,
|
||||
'to': [actor],
|
||||
'cc': [],
|
||||
'object': actorJson
|
||||
}
|
||||
if debug:
|
||||
print('actor update is ' + str(actorUpdate))
|
||||
|
||||
# lookup the inbox for the To handle
|
||||
wfRequest = \
|
||||
webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
|
||||
domain, __version__, debug)
|
||||
if not wfRequest:
|
||||
if debug:
|
||||
print('DEBUG: pgp actor update webfinger failed for ' +
|
||||
handle)
|
||||
return None
|
||||
if not isinstance(wfRequest, dict):
|
||||
if debug:
|
||||
print('WARN: Webfinger for ' + handle +
|
||||
' did not return a dict. ' + str(wfRequest))
|
||||
return None
|
||||
|
||||
postToBox = 'outbox'
|
||||
|
||||
# get the actor inbox for the To handle
|
||||
(inboxUrl, pubKeyId, pubKey,
|
||||
fromPersonId, sharedInbox, avatarUrl,
|
||||
displayName) = getPersonBox(baseDir, session, wfRequest, personCache,
|
||||
__version__, httpPrefix, nickname,
|
||||
domain, postToBox, 52025)
|
||||
|
||||
if not inboxUrl:
|
||||
if debug:
|
||||
print('DEBUG: No ' + postToBox + ' was found for ' + handle)
|
||||
return None
|
||||
if not fromPersonId:
|
||||
if debug:
|
||||
print('DEBUG: No actor was found for ' + handle)
|
||||
return None
|
||||
|
||||
authHeader = createBasicAuthHeader(nickname, password)
|
||||
|
||||
headers = {
|
||||
'host': domain,
|
||||
'Content-type': 'application/json',
|
||||
'Authorization': authHeader
|
||||
}
|
||||
tries = 0
|
||||
quiet = not debug
|
||||
while tries < 4:
|
||||
postResult = \
|
||||
postJson(session, actorUpdate, [], inboxUrl,
|
||||
headers, 30, quiet)
|
||||
if postResult:
|
||||
break
|
||||
time.sleep(2)
|
||||
tries += 1
|
||||
|
||||
if postResult is None:
|
||||
if debug:
|
||||
print('DEBUG: POST pgp actor update failed for c2s to ' +
|
||||
inboxUrl)
|
||||
return None
|
||||
|
||||
if debug:
|
||||
print('DEBUG: c2s POST pgp actor update success')
|
||||
|
||||
return actorUpdate
|
||||
|
|
119
tests.py
119
tests.py
|
@ -53,6 +53,7 @@ from utils import getFollowersOfPerson
|
|||
from utils import removeHtml
|
||||
from utils import dangerousMarkup
|
||||
from pgp import extractPGPPublicKey
|
||||
from pgp import pgpPublicKeyUpload
|
||||
from utils import containsPGPPublicKey
|
||||
from follow import followerOfPerson
|
||||
from follow import unfollowAccount
|
||||
|
@ -1574,7 +1575,7 @@ def testClientToServer():
|
|||
|
||||
sessionAlice = createSession(proxyType)
|
||||
followersOnly = False
|
||||
attachedImageFilename = baseDir+'/img/logo.png'
|
||||
attachedImageFilename = baseDir + '/img/logo.png'
|
||||
mediaType = getAttachmentMediaType(attachedImageFilename)
|
||||
attachedImageDescription = 'Logo'
|
||||
isArticle = False
|
||||
|
@ -3447,6 +3448,122 @@ def testExtractPGPPublicKey():
|
|||
assert result == pubKey
|
||||
|
||||
|
||||
def testUpdateActor():
|
||||
print('Testing update of actor properties')
|
||||
|
||||
global testServerAliceRunning
|
||||
testServerAliceRunning = False
|
||||
|
||||
httpPrefix = 'http'
|
||||
proxyType = None
|
||||
federationList = []
|
||||
|
||||
baseDir = os.getcwd()
|
||||
if os.path.isdir(baseDir + '/.tests'):
|
||||
shutil.rmtree(baseDir + '/.tests')
|
||||
os.mkdir(baseDir + '/.tests')
|
||||
|
||||
# create the server
|
||||
aliceDir = baseDir + '/.tests/alice'
|
||||
aliceDomain = '127.0.0.11'
|
||||
alicePort = 61792
|
||||
aliceSendThreads = []
|
||||
bobAddress = '127.0.0.84:6384'
|
||||
|
||||
global thrAlice
|
||||
if thrAlice:
|
||||
while thrAlice.is_alive():
|
||||
thrAlice.stop()
|
||||
time.sleep(1)
|
||||
thrAlice.kill()
|
||||
|
||||
thrAlice = \
|
||||
threadWithTrace(target=createServerAlice,
|
||||
args=(aliceDir, aliceDomain, alicePort, bobAddress,
|
||||
federationList, False, False,
|
||||
aliceSendThreads),
|
||||
daemon=True)
|
||||
|
||||
thrAlice.start()
|
||||
assert thrAlice.is_alive() is True
|
||||
|
||||
# wait for server to be running
|
||||
ctr = 0
|
||||
while not testServerAliceRunning:
|
||||
time.sleep(1)
|
||||
ctr += 1
|
||||
if ctr > 60:
|
||||
break
|
||||
print('Alice online: ' + str(testServerAliceRunning))
|
||||
|
||||
print('\n\n*******************************************************')
|
||||
print('Alice updates her PGP key')
|
||||
|
||||
sessionAlice = createSession(proxyType)
|
||||
cachedWebfingers = {}
|
||||
personCache = {}
|
||||
password = 'alicepass'
|
||||
outboxPath = aliceDir + '/accounts/alice@' + aliceDomain + '/outbox'
|
||||
actorFilename = aliceDir + '/accounts/' + 'alice@' + aliceDomain + '.json'
|
||||
assert os.path.isfile(actorFilename)
|
||||
assert len([name for name in os.listdir(outboxPath)
|
||||
if os.path.isfile(os.path.join(outboxPath, name))]) == 0
|
||||
pubKey = \
|
||||
'-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n' + \
|
||||
'mDMEWZBueBYJKwYBBAHaRw8BAQdAKx1t6wL0RTuU6/' + \
|
||||
'IBjngMbVJJ3Wg/3UW73/PV\n' + \
|
||||
'I47xKTS0IUJvYiBNb3R0cmFtIDxib2JAZnJlZWRvb' + \
|
||||
'WJvbmUubmV0PoiQBBMWCAA4\n' + \
|
||||
'FiEEmruCwAq/OfgmgEh9zCU2GR+nwz8FAlmQbngCG' + \
|
||||
'wMFCwkIBwMFFQoJCAsFFgID\n' + \
|
||||
'AQACHgECF4AACgkQzCU2GR+nwz/9sAD/YgsHnVszH' + \
|
||||
'Nz1zlVc5EgY1ByDupiJpHj0\n' + \
|
||||
'XsLYk3AbNRgBALn45RqgD4eWHpmOriH09H5Rc5V9i' + \
|
||||
'N4+OiGUn2AzJ6oHuDgEWZBu\n' + \
|
||||
'eBIKKwYBBAGXVQEFAQEHQPRBG2ZQJce475S3e0Dxe' + \
|
||||
'b0Fz5WdEu2q3GYLo4QG+4Ry\n' + \
|
||||
'AwEIB4h4BBgWCAAgFiEEmruCwAq/OfgmgEh9zCU2G' + \
|
||||
'R+nwz8FAlmQbngCGwwACgkQ\n' + \
|
||||
'zCU2GR+nwz+OswD+JOoyBku9FzuWoVoOevU2HH+bP' + \
|
||||
'OMDgY2OLnST9ZSyHkMBAMcK\n' + \
|
||||
'fnaZ2Wi050483Sj2RmQRpb99Dod7rVZTDtCqXk0J\n' + \
|
||||
'=gv5G\n' + \
|
||||
'-----END PGP PUBLIC KEY BLOCK-----'
|
||||
actorUpdate = \
|
||||
pgpPublicKeyUpload(aliceDir, sessionAlice,
|
||||
'alice', password,
|
||||
aliceDomain, alicePort,
|
||||
httpPrefix,
|
||||
cachedWebfingers, personCache,
|
||||
True, pubKey)
|
||||
print('actor update result: ' + str(actorUpdate))
|
||||
assert actorUpdate
|
||||
|
||||
# load alice actor
|
||||
print('Loading actor: ' + actorFilename)
|
||||
actorJson = loadJson(actorFilename)
|
||||
assert actorJson
|
||||
if len(actorJson['attachment']) == 0:
|
||||
print("actorJson['attachment'] has no contents")
|
||||
assert len(actorJson['attachment']) > 0
|
||||
propertyFound = False
|
||||
for propertyValue in actorJson['attachment']:
|
||||
if propertyValue['name'] == 'PGP':
|
||||
print('PGP property set within attachment')
|
||||
assert pubKey in propertyValue['value']
|
||||
propertyFound = True
|
||||
assert propertyFound
|
||||
|
||||
# stop the server
|
||||
thrAlice.kill()
|
||||
thrAlice.join()
|
||||
assert thrAlice.is_alive() is False
|
||||
|
||||
os.chdir(baseDir)
|
||||
if os.path.isdir(baseDir + '/.tests'):
|
||||
shutil.rmtree(baseDir + '/.tests')
|
||||
|
||||
|
||||
def runAllTests():
|
||||
print('Running tests...')
|
||||
testFunctions()
|
||||
|
|
Loading…
Reference in New Issue