mirror of https://gitlab.com/bashrc2/epicyon
Private pinned post json endpoint
parent
924232a0d4
commit
7d9a31ab91
76
daemon.py
76
daemon.py
|
@ -73,6 +73,7 @@ from person import removeAccount
|
||||||
from person import canRemovePost
|
from person import canRemovePost
|
||||||
from person import personSnooze
|
from person import personSnooze
|
||||||
from person import personUnsnooze
|
from person import personUnsnooze
|
||||||
|
from posts import hasPrivatePinnedPost
|
||||||
from posts import getOriginalPostFromAnnounceUrl
|
from posts import getOriginalPostFromAnnounceUrl
|
||||||
from posts import savePostToBox
|
from posts import savePostToBox
|
||||||
from posts import getInstanceActorKey
|
from posts import getInstanceActorKey
|
||||||
|
@ -100,6 +101,7 @@ from inbox import runInboxQueue
|
||||||
from inbox import runInboxQueueWatchdog
|
from inbox import runInboxQueueWatchdog
|
||||||
from inbox import savePostToInboxQueue
|
from inbox import savePostToInboxQueue
|
||||||
from inbox import populateReplies
|
from inbox import populateReplies
|
||||||
|
from follow import isFollowerOfPerson
|
||||||
from follow import followerApprovalActive
|
from follow import followerApprovalActive
|
||||||
from follow import isFollowingActor
|
from follow import isFollowingActor
|
||||||
from follow import getFollowingFeed
|
from follow import getFollowingFeed
|
||||||
|
@ -654,12 +656,9 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _secureMode(self) -> bool:
|
def _secureModeActor(self) -> str:
|
||||||
"""http authentication of GET requests for json
|
"""Returns the actor from the signed GET keyId
|
||||||
"""
|
"""
|
||||||
if not self.server.secureMode:
|
|
||||||
return True
|
|
||||||
|
|
||||||
signature = None
|
signature = None
|
||||||
if self.headers.get('signature'):
|
if self.headers.get('signature'):
|
||||||
signature = self.headers['signature']
|
signature = self.headers['signature']
|
||||||
|
@ -669,9 +668,9 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
# check that the headers are signed
|
# check that the headers are signed
|
||||||
if not signature:
|
if not signature:
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
print('AUTH: secure mode, ' +
|
print('AUTH: secure mode actor, ' +
|
||||||
'GET has no signature in headers')
|
'GET has no signature in headers')
|
||||||
return False
|
return None
|
||||||
|
|
||||||
# get the keyId, which is typically the instance actor
|
# get the keyId, which is typically the instance actor
|
||||||
keyId = None
|
keyId = None
|
||||||
|
@ -680,17 +679,25 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if signatureItem.startswith('keyId='):
|
if signatureItem.startswith('keyId='):
|
||||||
if '"' in signatureItem:
|
if '"' in signatureItem:
|
||||||
keyId = signatureItem.split('"')[1]
|
keyId = signatureItem.split('"')[1]
|
||||||
break
|
# remove #main-key
|
||||||
|
if '#' in keyId:
|
||||||
|
keyId = keyId.split('#')[0]
|
||||||
|
return keyId
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _secureMode(self, force: bool = False) -> bool:
|
||||||
|
"""http authentication of GET requests for json
|
||||||
|
"""
|
||||||
|
if not self.server.secureMode and not force:
|
||||||
|
return True
|
||||||
|
|
||||||
|
keyId = self._secureModeActor()
|
||||||
if not keyId:
|
if not keyId:
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
print('AUTH: secure mode, ' +
|
print('AUTH: secure mode, ' +
|
||||||
'failed to obtain keyId from signature')
|
'failed to obtain keyId from signature')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# remove #main-key
|
|
||||||
if '#' in keyId:
|
|
||||||
keyId = keyId.split('#')[0]
|
|
||||||
|
|
||||||
# is the keyId (actor) valid?
|
# is the keyId (actor) valid?
|
||||||
if not urlPermitted(keyId, self.server.federationList):
|
if not urlPermitted(keyId, self.server.federationList):
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
|
@ -12980,6 +12987,51 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
nickname = self.path.split('/users/')[1]
|
nickname = self.path.split('/users/')[1]
|
||||||
if '/' in nickname:
|
if '/' in nickname:
|
||||||
nickname = nickname.split('/')[0]
|
nickname = nickname.split('/')[0]
|
||||||
|
showPinned = True
|
||||||
|
# is the pinned post for followers only?
|
||||||
|
if hasPrivatePinnedPost(self.server.baseDir,
|
||||||
|
self.server.httpPrefix,
|
||||||
|
nickname, self.server.domain,
|
||||||
|
self.server.domainFull,
|
||||||
|
self.server.systemLanguage):
|
||||||
|
if not self._secureMode(True):
|
||||||
|
# GET request signature failed
|
||||||
|
showPinned = False
|
||||||
|
else:
|
||||||
|
# the GET signature passes, but is this someone
|
||||||
|
# that follows us?
|
||||||
|
followerActor = self._secureModeActor()
|
||||||
|
followerNickname = getNicknameFromActor(followerActor)
|
||||||
|
followerDomain, followerPort = \
|
||||||
|
getDomainFromActor(followerActor)
|
||||||
|
followerDomainFull = \
|
||||||
|
getFullDomain(followerDomain, followerPort)
|
||||||
|
if not isFollowerOfPerson(self.server.baseDir,
|
||||||
|
nickname, self.server.domain,
|
||||||
|
followerNickname,
|
||||||
|
followerDomainFull):
|
||||||
|
showPinned = False
|
||||||
|
if not showPinned:
|
||||||
|
# follower check failed, so just return an empty collection
|
||||||
|
postContext = getIndividualPostContext()
|
||||||
|
actor = \
|
||||||
|
self.server.httpPrefix + '://' + \
|
||||||
|
self.server.domainFull + '/users/' + nickname
|
||||||
|
emptyCollectionJson = {
|
||||||
|
'@context': postContext,
|
||||||
|
'id': actor + '/collections/featured',
|
||||||
|
'orderedItems': [],
|
||||||
|
'totalItems': 0,
|
||||||
|
'type': 'OrderedCollection'
|
||||||
|
}
|
||||||
|
msg = json.dumps(emptyCollectionJson,
|
||||||
|
ensure_ascii=False).encode('utf-8')
|
||||||
|
msglen = len(msg)
|
||||||
|
self._set_headers('application/json',
|
||||||
|
msglen, None, callingDomain, False)
|
||||||
|
self._write(msg)
|
||||||
|
return
|
||||||
|
# return the featured posts collection
|
||||||
self._getFeaturedCollection(callingDomain,
|
self._getFeaturedCollection(callingDomain,
|
||||||
self.server.baseDir,
|
self.server.baseDir,
|
||||||
self.path,
|
self.path,
|
||||||
|
|
16
posts.py
16
posts.py
|
@ -1648,6 +1648,22 @@ def jsonPinPost(baseDir: str, httpPrefix: str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def hasPrivatePinnedPost(baseDir: str, httpPrefix: str,
|
||||||
|
nickname: str, domain: str,
|
||||||
|
domainFull: str, systemLanguage: str) -> bool:
|
||||||
|
"""Whether the given account has a private pinned post
|
||||||
|
"""
|
||||||
|
pinnedPostJson = \
|
||||||
|
getPinnedPostAsJson(baseDir, httpPrefix,
|
||||||
|
nickname, domain,
|
||||||
|
domainFull, systemLanguage)
|
||||||
|
if not pinnedPostJson:
|
||||||
|
return False
|
||||||
|
if not isPublicPost(pinnedPostJson):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def regenerateIndexForBox(baseDir: str,
|
def regenerateIndexForBox(baseDir: str,
|
||||||
nickname: str, domain: str, boxName: str) -> None:
|
nickname: str, domain: str, boxName: str) -> None:
|
||||||
"""Generates an index for the given box if it doesn't exist
|
"""Generates an index for the given box if it doesn't exist
|
||||||
|
|
Loading…
Reference in New Issue