main
Bob Mottram 2020-03-30 20:09:45 +01:00
parent e8ee692ce4
commit 8b4c1103e7
8 changed files with 139 additions and 70 deletions

View File

@ -136,14 +136,16 @@ def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
followedActor=messageJson['object']['object']
followedDomain,port=getDomainFromActor(followedActor)
if not followedDomain:
print('DEBUG: no domain found within Follow activity object '+followedActor)
print('DEBUG: no domain found within Follow activity object '+ \
followedActor)
return
followedDomainFull=followedDomain
if port:
followedDomainFull=followedDomain+':'+str(port)
followedNickname=getNicknameFromActor(followedActor)
if not followedNickname:
print('DEBUG: no nickname found within Follow activity object '+followedActor)
print('DEBUG: no nickname found within Follow activity object '+ \
followedActor)
return
acceptedDomainFull=acceptedDomain
@ -158,7 +160,8 @@ def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
messageJson['capabilities'])
# has this person already been unfollowed?
unfollowedFilename=baseDir+'/accounts/'+nickname+'@'+acceptedDomainFull+'/unfollowed.txt'
unfollowedFilename= \
baseDir+'/accounts/'+nickname+'@'+acceptedDomainFull+'/unfollowed.txt'
if os.path.isfile(unfollowedFilename):
if followedNickname+'@'+followedDomainFull in open(unfollowedFilename).read():
if debug:
@ -212,7 +215,8 @@ def receiveAcceptReject(session,baseDir: str, \
nickname='dev'
if debug:
print('DEBUG: '+messageJson['type']+ \
' does not contain a nickname. Assuming single user instance.')
' does not contain a nickname. '+ \
'Assuming single user instance.')
handle=nickname.lower()+'@'+domain.lower()
# receive follow accept
acceptFollow(baseDir,domain,messageJson,federationList,debug)

View File

@ -84,7 +84,8 @@ def undoAnnounceCollectionEntry(recentPostsCache: {}, \
"""
postJsonObject=loadJson(postFilename)
if postJsonObject:
# remove any cached version of this announce so that the announce icon is changed
# remove any cached version of this announce so that the announce
# icon is changed
nickname=getNicknameFromActor(actor)
cachedPostFilename= \
getCachedPostFilename(baseDir,nickname,domain,postJsonObject)

12
auth.py
View File

@ -17,7 +17,8 @@ def hashPassword(password: str) -> str:
"""Hash a password for storing
"""
salt=hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
pwdhash=hashlib.pbkdf2_hmac('sha512', \
pwdhash= \
hashlib.pbkdf2_hmac('sha512', \
password.encode('utf-8'), \
salt, 100000)
pwdhash=binascii.hexlify(pwdhash)
@ -28,7 +29,8 @@ def verifyPassword(storedPassword: str,providedPassword: str) -> bool:
"""
salt=storedPassword[:64]
storedPassword=storedPassword[64:]
pwdhash=hashlib.pbkdf2_hmac('sha512', \
pwdhash= \
hashlib.pbkdf2_hmac('sha512', \
providedPassword.encode('utf-8'), \
salt.encode('ascii'), \
100000)
@ -46,7 +48,8 @@ def authorizeBasic(baseDir: str,path: str,authHeader: str,debug: bool) -> bool:
"""
if ' ' not in authHeader:
if debug:
print('DEBUG: Authorixation header does not contain a space character')
print('DEBUG: Authorixation header does not '+ \
'contain a space character')
return False
if '/users/' not in path and \
'/channel/' not in path and \
@ -64,7 +67,8 @@ def authorizeBasic(baseDir: str,path: str,authHeader: str,debug: bool) -> bool:
plain=base64.b64decode(base64Str).decode('utf-8')
if ':' not in plain:
if debug:
print('DEBUG: Basic Auth header does not contain a ":" separator for username:password')
print('DEBUG: Basic Auth header does not contain a ":" '+ \
'separator for username:password')
return False
nickname=plain.split(':')[0]
if nickname!=nicknameFromPath:

View File

@ -448,9 +448,11 @@ def outboxUndoBlock(baseDir: str,httpPrefix: str, \
return
nicknameBlocked=getNicknameFromActor(messageJson['object']['object'])
if not nicknameBlocked:
print('WARN: unable to find nickname in '+messageJson['object']['object'])
print('WARN: unable to find nickname in '+ \
messageJson['object']['object'])
return
domainBlocked,portBlocked=getDomainFromActor(messageJson['object']['object'])
domainBlocked,portBlocked= \
getDomainFromActor(messageJson['object']['object'])
domainBlockedFull=domainBlocked
if portBlocked:
if portBlocked!=80 and portBlocked!=443:

13
blog.py
View File

@ -220,7 +220,8 @@ def htmlBlogPostContent(authorized: bool, \
if not linkedAuthor:
blogStr+= \
'<p class="about"><a class="about" href="'+httpPrefix+'://'+domainFull+ \
'<p class="about"><a class="about" href="'+ \
httpPrefix+'://'+domainFull+ \
'/users/'+nickname+'">'+translate['About the author']+'</a></p>\n'
replies= \
@ -347,14 +348,16 @@ def htmlBlogPage(authorized: bool, session, \
if pageNumber>1:
# show previous button
navigateStr+= \
'<a href="'+httpPrefix+'://'+domainFull+'/blog/'+nickname+'?page='+str(pageNumber-1)+'">'+ \
'<a href="'+httpPrefix+'://'+domainFull+'/blog/'+ \
nickname+'?page='+str(pageNumber-1)+'">'+ \
'<img loading="lazy" alt="<" title="<" '+ \
'src="/'+iconsDir+ \
'/prev.png" class="buttonprev"/></a>\n'
if len(timelineJson['orderedItems'])>=noOfItems:
# show next button
navigateStr+= \
'<a href="'+httpPrefix+'://'+domainFull+'/blog/'+nickname+'?page='+str(pageNumber+1)+'">'+ \
'<a href="'+httpPrefix+'://'+domainFull+'/blog/'+nickname+ \
'?page='+str(pageNumber+1)+'">'+ \
'<img loading="lazy" alt=">" title=">" '+ \
'src="/'+iconsDir+ \
'/prev.png" class="buttonnext"/></a>\n'
@ -552,7 +555,9 @@ def htmlEditBlog(mediaInstance: bool,translate: {}, \
iconsDir=getIconsDir(baseDir)
editBlogText='<p class="new-post-text">'+translate['Write your post text below.']+'</p>'
editBlogText= \
'<p class="new-post-text">'+ \
translate['Write your post text below.']+'</p>'
if os.path.isfile(baseDir+'/accounts/newpost.txt'):
with open(baseDir+'/accounts/newpost.txt', 'r') as file:

View File

@ -85,7 +85,8 @@ def undoBookmarksCollectionEntry(recentPostsCache: {}, \
saveJson(postJsonObject,postFilename)
# remove from the index
bookmarksIndexFilename=baseDir+'/accounts/'+nickname+'@'+domain+'/bookmarks.index'
bookmarksIndexFilename= \
baseDir+'/accounts/'+nickname+'@'+domain+'/bookmarks.index'
if not os.path.isfile(bookmarksIndexFilename):
return
if '/' in postFilename:
@ -192,7 +193,8 @@ def updateBookmarksCollection(recentPostsCache: {}, \
saveJson(postJsonObject,postFilename)
# prepend to the index
bookmarksIndexFilename=baseDir+'/accounts/'+nickname+'@'+domain+'/bookmarks.index'
bookmarksIndexFilename= \
baseDir+'/accounts/'+nickname+'@'+domain+'/bookmarks.index'
bookmarkIndex=postFilename.split('/')[-1]
if os.path.isfile(bookmarksIndexFilename):
if bookmarkIndex not in open(bookmarksIndexFilename).read():
@ -255,13 +257,15 @@ def bookmark(recentPostsCache: {}, \
bookmarkedPostPort=None
if actorBookmarked:
bookmarkedPostNickname=getNicknameFromActor(actorBookmarked)
bookmarkedPostDomain,bookmarkedPostPort=getDomainFromActor(actorBookmarked)
bookmarkedPostDomain,bookmarkedPostPort= \
getDomainFromActor(actorBookmarked)
else:
if '/users/' in objectUrl or \
'/channel/' in objectUrl or \
'/profile/' in objectUrl:
bookmarkedPostNickname=getNicknameFromActor(objectUrl)
bookmarkedPostDomain,bookmarkedPostPort=getDomainFromActor(objectUrl)
bookmarkedPostDomain,bookmarkedPostPort= \
getDomainFromActor(objectUrl)
if bookmarkedPostNickname:
postFilename=locatePost(baseDir,nickname,domain,objectUrl)
@ -278,7 +282,8 @@ def bookmark(recentPostsCache: {}, \
sendSignedJson(newBookmarkJson,session,baseDir, \
nickname,domain,port, \
bookmarkedPostNickname,bookmarkedPostDomain,bookmarkedPostPort, \
bookmarkedPostNickname, \
bookmarkedPostDomain,bookmarkedPostPort, \
'https://www.w3.org/ns/activitystreams#Public', \
httpPrefix,True,clientToServer,federationList, \
sendThreads,postLog,cachedWebfingers,personCache, \
@ -369,13 +374,15 @@ def undoBookmark(recentPostsCache: {}, \
bookmarkedPostPort=None
if actorBookmarked:
bookmarkedPostNickname=getNicknameFromActor(actorBookmarked)
bookmarkedPostDomain,bookmarkedPostPort=getDomainFromActor(actorBookmarked)
bookmarkedPostDomain,bookmarkedPostPort= \
getDomainFromActor(actorBookmarked)
else:
if '/users/' in objectUrl or \
'/channel/' in objectUrl or \
'/profile/' in objectUrl:
bookmarkedPostNickname=getNicknameFromActor(objectUrl)
bookmarkedPostDomain,bookmarkedPostPort=getDomainFromActor(objectUrl)
bookmarkedPostDomain,bookmarkedPostPort= \
getDomainFromActor(objectUrl)
if bookmarkedPostNickname:
postFilename=locatePost(baseDir,nickname,domain,objectUrl)
@ -400,8 +407,8 @@ def undoBookmark(recentPostsCache: {}, \
def undoBookmarkPost(session,baseDir: str,federationList: [], \
nickname: str,domain: str,port: int,httpPrefix: str, \
bookmarkNickname: str,bookmarkedomain: str,bookmarkPort: int, \
ccList: [], \
bookmarkNickname: str,bookmarkedomain: str, \
bookmarkPort: int,ccList: [], \
bookmarkStatusNumber: int,clientToServer: bool, \
sendThreads: [],postLog: [], \
personCache: {},cachedWebfingers: {}, \

View File

@ -12,7 +12,8 @@ import datetime
from utils import loadJson
from utils import saveJson
def storePersonInCache(baseDir: str,personUrl: str,personJson: {},personCache: {}) -> None:
def storePersonInCache(baseDir: str,personUrl: str, \
personJson: {},personCache: {}) -> None:
"""Store an actor in the cache
"""
currTime=datetime.datetime.utcnow()
@ -25,7 +26,8 @@ def storePersonInCache(baseDir: str,personUrl: str,personJson: {},personCache: {
# store to file
if os.path.isdir(baseDir+'/cache/actors'):
cacheFilename=baseDir+'/cache/actors/'+personUrl.replace('/','#')+'.json'
cacheFilename= \
baseDir+'/cache/actors/'+personUrl.replace('/','#')+'.json'
if not os.path.isfile(cacheFilename):
saveJson(personJson,cacheFilename)

122
daemon.py
View File

@ -1318,7 +1318,8 @@ class PubServer(BaseHTTPRequestHandler):
divertToLoginScreen=False
if divertToLoginScreen and not authorized:
if self.server.debug:
print('DEBUG: divertToLoginScreen='+str(divertToLoginScreen))
print('DEBUG: divertToLoginScreen='+ \
str(divertToLoginScreen))
print('DEBUG: authorized='+str(authorized))
print('DEBUG: path='+self.path)
self.send_response(303)
@ -1382,7 +1383,8 @@ class PubServer(BaseHTTPRequestHandler):
time.sleep(1)
tries+=1
if mediaBinary:
self._set_headers('image/png',len(mediaBinary),cookie,callingDomain)
self._set_headers('image/png',len(mediaBinary), \
cookie,callingDomain)
self._write(mediaBinary)
return
self._404()
@ -1407,7 +1409,8 @@ class PubServer(BaseHTTPRequestHandler):
time.sleep(1)
tries+=1
if mediaBinary:
self._set_headers('image/png',len(mediaBinary),cookie,callingDomain)
self._set_headers('image/png',len(mediaBinary), \
cookie,callingDomain)
self._write(mediaBinary)
return
self._404()
@ -1432,7 +1435,8 @@ class PubServer(BaseHTTPRequestHandler):
time.sleep(1)
tries+=1
if mediaBinary:
self._set_headers('image/png',len(mediaBinary),cookie,callingDomain)
self._set_headers('image/png',len(mediaBinary), \
cookie,callingDomain)
self._write(mediaBinary)
return
self._404()
@ -1460,7 +1464,9 @@ class PubServer(BaseHTTPRequestHandler):
mediaImageType='gif'
with open(emojiFilename, 'rb') as avFile:
mediaBinary=avFile.read()
self._set_headers('image/'+mediaImageType,len(mediaBinary),cookie,callingDomain)
self._set_headers('image/'+mediaImageType, \
len(mediaBinary), \
cookie,callingDomain)
self._write(mediaBinary)
return
self._404()
@ -1555,7 +1561,9 @@ class PubServer(BaseHTTPRequestHandler):
mediaFileType='gif'
with open(mediaFilename, 'rb') as avFile:
mediaBinary=avFile.read()
self._set_headers('image/'+mediaFileType,len(mediaBinary),cookie,callingDomain)
self._set_headers('image/'+mediaFileType, \
len(mediaBinary), \
cookie,callingDomain)
self._write(mediaBinary)
return
self._404()
@ -1572,14 +1580,16 @@ class PubServer(BaseHTTPRequestHandler):
self.server.baseDir+'/img/icons/'+mediaStr
if self.server.iconsCache.get(mediaStr):
mediaBinary=self.server.iconsCache[mediaStr]
self._set_headers('image/png',len(mediaBinary),cookie,callingDomain)
self._set_headers('image/png',len(mediaBinary), \
cookie,callingDomain)
self._write(mediaBinary)
return
else:
if os.path.isfile(mediaFilename):
with open(mediaFilename, 'rb') as avFile:
mediaBinary=avFile.read()
self._set_headers('image/png',len(mediaBinary),cookie,callingDomain)
self._set_headers('image/png',len(mediaBinary), \
cookie,callingDomain)
self._write(mediaBinary)
self.server.iconsCache[mediaStr]=mediaBinary
return
@ -1597,14 +1607,18 @@ class PubServer(BaseHTTPRequestHandler):
with open(mediaFilename, 'rb') as avFile:
mediaBinary=avFile.read()
if mediaFilename.endswith('.png'):
self._set_headers('image/png',len(mediaBinary),cookie,callingDomain)
self._set_headers('image/png',len(mediaBinary), \
cookie,callingDomain)
elif mediaFilename.endswith('.jpg'):
self._set_headers('image/jpeg',len(mediaBinary),cookie,callingDomain)
self._set_headers('image/jpeg',len(mediaBinary), \
cookie,callingDomain)
elif mediaFilename.endswith('.gif'):
self._set_headers('image/gif',len(mediaBinary),cookie,callingDomain)
self._set_headers('image/gif',len(mediaBinary), \
cookie,callingDomain)
else:
# default to jpeg
self._set_headers('image/jpeg',len(mediaBinary),cookie,callingDomain)
self._set_headers('image/jpeg',len(mediaBinary), \
cookie,callingDomain)
#self._404()
return
self._write(mediaBinary)
@ -1714,7 +1728,9 @@ class PubServer(BaseHTTPRequestHandler):
return
nickname=None
if '/users/' in self.path:
actor=self.server.httpPrefix+'://'+self.server.domainFull+self.path
actor= \
self.server.httpPrefix+'://'+ \
self.server.domainFull+self.path
nickname= \
getNicknameFromActor(actor)
hashtagStr= \
@ -1735,10 +1751,14 @@ class PubServer(BaseHTTPRequestHandler):
self._write(msg)
else:
originPathStr=self.path.split('/tags/')[0]
originPathStrAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+originPathStr
originPathStrAbsolute= \
self.server.httpPrefix+'://'+ \
self.server.domainFull+originPathStr
if callingDomain.endswith('.onion') and self.server.onionDomain:
originPathStrAbsolute='http://'+self.server.onionDomain+originPathStr
self._redirect_headers(originPathStrAbsolute+'/search',cookie,callingDomain)
originPathStrAbsolute='http://'+ \
self.server.onionDomain+originPathStr
self._redirect_headers(originPathStrAbsolute+'/search', \
cookie,callingDomain)
self.server.GETbusy=False
return
@ -1865,17 +1885,21 @@ class PubServer(BaseHTTPRequestHandler):
if not self.postToNickname:
print('WARN: unable to find nickname in '+actor)
self.server.GETbusy=False
actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor
actorAbsolute= \
self.server.httpPrefix+'://'+self.server.domainFull+actor
if callingDomain.endswith('.onion') and self.server.onionDomain:
actorAbsolute='http://'+self.server.onionDomain+actor
self._redirect_headers(actorAbsolute+'/'+timelineStr+ \
'?page='+str(pageNumber),cookie,callingDomain)
'?page='+str(pageNumber),cookie, \
callingDomain)
return
if not self.server.session:
self.server.session= \
createSession(self.server.useTor)
self.server.actorRepeat=self.path.split('?actor=')[1]
announceToStr=self.server.httpPrefix+'://'+self.server.domain+'/users/'+self.postToNickname+'/followers'
announceToStr= \
self.server.httpPrefix+'://'+self.server.domain+'/users/'+ \
self.postToNickname+'/followers'
if not repeatPrivate:
announceToStr='https://www.w3.org/ns/activitystreams#Public'
announceJson= \
@ -2073,7 +2097,8 @@ class PubServer(BaseHTTPRequestHandler):
if not self.postToNickname:
print('WARN: unable to find nickname in '+actor)
self.server.GETbusy=False
actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor
actorAbsolute= \
self.server.httpPrefix+'://'+self.server.domainFull+actor
if callingDomain.endswith('.onion') and self.server.onionDomain:
actorAbsolute='http://'+self.server.onionDomain+actor
self._redirect_headers(actorAbsolute+'/'+timelineStr+ \
@ -2099,7 +2124,8 @@ class PubServer(BaseHTTPRequestHandler):
}
self._postToOutbox(likeJson,self.server.projectVersion)
self.server.GETbusy=False
actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor
actorAbsolute= \
self.server.httpPrefix+'://'+self.server.domainFull+actor
if callingDomain.endswith('.onion') and self.server.onionDomain:
actorAbsolute='http://'+self.server.onionDomain+actor
self._redirect_headers(actorAbsolute+'/'+timelineStr+ \
@ -2138,7 +2164,8 @@ class PubServer(BaseHTTPRequestHandler):
if not self.postToNickname:
print('WARN: unable to find nickname in '+actor)
self.server.GETbusy=False
actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor
actorAbsolute= \
self.server.httpPrefix+'://'+self.server.domainFull+actor
if callingDomain.endswith('.onion') and self.server.onionDomain:
actorAbsolute='http://'+self.server.onionDomain+actor
self._redirect_headers(actorAbsolute+'/'+timelineStr+ \
@ -2208,7 +2235,8 @@ class PubServer(BaseHTTPRequestHandler):
if not self.postToNickname:
print('WARN: unable to find nickname in '+actor)
self.server.GETbusy=False
actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor
actorAbsolute= \
self.server.httpPrefix+'://'+self.server.domainFull+actor
if callingDomain.endswith('.onion') and self.server.onionDomain:
actorAbsolute='http://'+self.server.onionDomain+actor
self._redirect_headers(actorAbsolute+'/'+timelineStr+ \
@ -2230,7 +2258,8 @@ class PubServer(BaseHTTPRequestHandler):
}
self._postToOutbox(bookmarkJson,self.server.projectVersion)
self.server.GETbusy=False
actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor
actorAbsolute= \
self.server.httpPrefix+'://'+self.server.domainFull+actor
if callingDomain.endswith('.onion') and self.server.onionDomain:
actorAbsolute='http://'+self.server.onionDomain+actor
self._redirect_headers(actorAbsolute+'/'+timelineStr+ \
@ -2267,7 +2296,8 @@ class PubServer(BaseHTTPRequestHandler):
if not self.postToNickname:
print('WARN: unable to find nickname in '+actor)
self.server.GETbusy=False
actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor
actorAbsolute= \
self.server.httpPrefix+'://'+self.server.domainFull+actor
if callingDomain.endswith('.onion') and self.server.onionDomain:
actorAbsolute='http://'+self.server.onionDomain+actor
self._redirect_headers(actorAbsolute+'/'+timelineStr+ \
@ -2294,7 +2324,8 @@ class PubServer(BaseHTTPRequestHandler):
}
self._postToOutbox(undoBookmarkJson,self.server.projectVersion)
self.server.GETbusy=False
actorAbsolute=self.server.httpPrefix+'://'+self.server.domainFull+actor
actorAbsolute= \
self.server.httpPrefix+'://'+self.server.domainFull+actor
if callingDomain.endswith('.onion') and self.server.onionDomain:
actorAbsolute='http://'+self.server.onionDomain+actor
self._redirect_headers(actorAbsolute+'/'+timelineStr+ \
@ -2630,15 +2661,19 @@ class PubServer(BaseHTTPRequestHandler):
self.server.personCache, \
nickname,self.server.domain, \
self.server.port, \
authorized,postJsonObject, \
authorized, \
postJsonObject, \
self.server.httpPrefix, \
self.server.projectVersion).encode('utf-8')
self._set_headers('text/html',len(msg),cookie,callingDomain)
self._set_headers('text/html',len(msg), \
cookie,callingDomain)
self._write(msg)
else:
if self._fetchAuthenticated():
msg=json.dumps(postJsonObject,ensure_ascii=False).encode('utf-8')
self._set_headers('application/json',len(msg),None,callingDomain)
msg=json.dumps(postJsonObject, \
ensure_ascii=False).encode('utf-8')
self._set_headers('application/json',len(msg), \
None,callingDomain)
self._write(msg)
else:
self._404()
@ -2750,12 +2785,15 @@ class PubServer(BaseHTTPRequestHandler):
repliesJson, \
self.server.httpPrefix, \
self.server.projectVersion).encode('utf-8')
self._set_headers('text/html',len(msg),cookie,callingDomain)
self._set_headers('text/html',len(msg), \
cookie,callingDomain)
self._write(msg)
else:
if self._fetchAuthenticated():
msg=json.dumps(repliesJson,ensure_ascii=False).encode('utf-8')
self._set_headers('application/json',len(msg),None,callingDomain)
msg=json.dumps(repliesJson, \
ensure_ascii=False).encode('utf-8')
self._set_headers('application/json',len(msg), \
None,callingDomain)
self._write(msg)
else:
self._404()
@ -2797,12 +2835,15 @@ class PubServer(BaseHTTPRequestHandler):
self.server.personCache, \
actorJson['roles'], \
None,None).encode('utf-8')
self._set_headers('text/html',len(msg),cookie,callingDomain)
self._set_headers('text/html',len(msg), \
cookie,callingDomain)
self._write(msg)
else:
if self._fetchAuthenticated():
msg=json.dumps(actorJson['roles'],ensure_ascii=False).encode('utf-8')
self._set_headers('application/json',len(msg),None,callingDomain)
msg=json.dumps(actorJson['roles'], \
ensure_ascii=False).encode('utf-8')
self._set_headers('application/json',len(msg), \
None,callingDomain)
self._write(msg)
else:
self._404()
@ -2843,12 +2884,15 @@ class PubServer(BaseHTTPRequestHandler):
self.server.personCache, \
actorJson['skills'], \
None,None).encode('utf-8')
self._set_headers('text/html',len(msg),cookie,callingDomain)
self._set_headers('text/html',len(msg), \
cookie,callingDomain)
self._write(msg)
else:
if self._fetchAuthenticated():
msg=json.dumps(actorJson['skills'],ensure_ascii=False).encode('utf-8')
self._set_headers('application/json',len(msg),None,callingDomain)
msg=json.dumps(actorJson['skills'], \
ensure_ascii=False).encode('utf-8')
self._set_headers('application/json',len(msg), \
None,callingDomain)
self._write(msg)
else:
self._404()