forked from indymedia/epicyon
Example json
parent
258fa7abf3
commit
3e3e4fec4e
49
README.md
49
README.md
|
@ -40,23 +40,23 @@ This is one proposed way that OCAP could work.
|
|||
Default capabilities are initially set up when a follow request is made. The Accept activity sent back from a follow request can be received by any instance. A capabilities accept activity is attached to the follow accept.
|
||||
|
||||
``` text
|
||||
Actor A
|
||||
Alice
|
||||
|
|
||||
V
|
||||
Follow Request
|
||||
|
|
||||
V
|
||||
Actor B
|
||||
Bob
|
||||
|
|
||||
V
|
||||
Create/store default Capabilities
|
||||
for Actor A
|
||||
for Alice
|
||||
|
|
||||
V
|
||||
Follow Accept + default Capabilities
|
||||
|
|
||||
V
|
||||
Actor A
|
||||
Alice
|
||||
|
|
||||
V
|
||||
Store Granted Capabilities
|
||||
|
@ -64,18 +64,51 @@ Default capabilities are initially set up when a follow request is made. The Acc
|
|||
|
||||
The default capabilities could be *any preferred policy* of the instance. They could be no capabilities at all, read only or full access to everything.
|
||||
|
||||
Example Follow request from **Alice** to **Bob**:
|
||||
|
||||
``` json
|
||||
{'actor': 'http://alicedomain.net/users/alice',
|
||||
'cc': ['https://www.w3.org/ns/activitystreams#Public'],
|
||||
'id': 'http://alicedomain.net/users/alice/statuses/1562507338839876',
|
||||
'object': 'http://bobdomain.net/users/bob',
|
||||
'published': '2019-07-07T13:48:58Z',
|
||||
'to': ['http://bobdomain.net/users/bob'],
|
||||
'type': 'Follow'}
|
||||
```
|
||||
|
||||
Follow Accept from **Bob** to **Alice** with attached capabilities.
|
||||
|
||||
``` json
|
||||
{'actor': 'http://bobdomain.net/users/bob',
|
||||
'capabilities': {'actor': 'http://bobdomain.net/users/bob',
|
||||
'capability': ['inbox:write', 'objects:read'],
|
||||
'id': 'http://bobdomain.net/caps/rOYtHApyr4ZWDUgEE1KqjhTe0kI3T2wJ',
|
||||
'scope': 'http://alicedomain.net/users/alice',
|
||||
'type': 'Capability'},
|
||||
'cc': [],
|
||||
'object': {'actor': 'http://alicedomain.net/users/alice',
|
||||
'cc': ['https://www.w3.org/ns/activitystreams#Public'],
|
||||
'id': 'http://alicedomain.net/users/alice/statuses/1562507338839876',
|
||||
'object': 'http://bobdomain.net/users/bob',
|
||||
'published': '2019-07-07T13:48:58Z',
|
||||
'to': ['http://bobdomain.net/users/bob'],
|
||||
'type': 'Follow'},
|
||||
'to': ['http://alicedomain.net/users/alice'],
|
||||
'type': 'Accept'}
|
||||
```
|
||||
|
||||
When posts are subsequently sent from the following instance (server-to-server) they should have the corresponding capability id string attached within the Create wrapper.
|
||||
|
||||
``` text
|
||||
Actor A
|
||||
Alice
|
||||
|
|
||||
V
|
||||
Send Post
|
||||
Attach id from Stored Capabilities
|
||||
granted by Actor B
|
||||
granted by Bob
|
||||
|
|
||||
V
|
||||
Actor B
|
||||
Bob
|
||||
|
|
||||
V
|
||||
Check Capability id matches
|
||||
|
@ -88,7 +121,7 @@ When posts are subsequently sent from the following instance (server-to-server)
|
|||
Accept or reject incoming post
|
||||
```
|
||||
|
||||
Subsequently **Actor B** could change the stored capabilities for **Actor A** in its database, giving the new object a different id. This could be sent back to **Actor A**, perhaps as another **follow Accept** activity with attached capabilities. This could then change the way in which **Actor A** can interact with **Actor B**, for example by adding or removing the ability to like or reply to posts.
|
||||
Subsequently **Bob** could change the stored capabilities for **Alice** in their database, giving the new object a different id. This could be sent back to **Alice**, perhaps as another **follow Accept** activity with attached capabilities. This could then change the way in which **Alice** can interact with **Bob**, for example by adding or removing the ability to like or reply to posts.
|
||||
|
||||
## Install
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ def createAccept(baseDir: str,federationList: [],ocapGranted: {}, \
|
|||
toUrl: str,ccUrl: str,httpPrefix: str, \
|
||||
objectJson: {}) -> {}:
|
||||
# create capabilities accept
|
||||
ocapNew=capabilitiesAccept(baseDir,httpPrefix,nickname,domain, toUrl, True)
|
||||
ocapNew=capabilitiesAccept(baseDir,httpPrefix,nickname,domain,port,toUrl,True)
|
||||
return createAcceptReject(baseDir,federationList,ocapGranted, \
|
||||
nickname,domain,port, \
|
||||
toUrl,ccUrl,httpPrefix, \
|
||||
|
@ -85,6 +85,15 @@ def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
|
|||
return
|
||||
if not messageJson['object']['type']=='Follow':
|
||||
return
|
||||
if not messageJson.get('to'):
|
||||
if debug:
|
||||
print('DEBUG: No "to" parameter in follow Accept')
|
||||
return
|
||||
if len(messageJson['object']['to'])!=1:
|
||||
if debug:
|
||||
print('DEBUG: "to" does not contain a single recipient')
|
||||
print(str(messageJson['object']['to']))
|
||||
return
|
||||
if debug:
|
||||
print('DEBUG: follow Accept received')
|
||||
thisActor=messageJson['object']['actor']
|
||||
|
@ -94,22 +103,27 @@ def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
|
|||
if debug:
|
||||
print('DEBUG: domain not found in '+thisActor)
|
||||
return
|
||||
if acceptedDomain != domain:
|
||||
if debug:
|
||||
print('DEBUG: domain mismatch '+acceptedDomain+' != '+domain)
|
||||
return
|
||||
#if acceptedDomain != domain:
|
||||
# if debug:
|
||||
# print('DEBUG: domain mismatch '+acceptedDomain+' != '+domain)
|
||||
# return
|
||||
if not nickname:
|
||||
if debug:
|
||||
print('DEBUG: nickname not found in '+thisActor)
|
||||
return
|
||||
if acceptedPort:
|
||||
if not '/'+domain+':'+str(acceptedPort)+'/users/'+nickname in thisActor:
|
||||
if not '/'+acceptedDomain+':'+str(acceptedPort)+'/users/'+nickname in thisActor:
|
||||
if debug:
|
||||
print('Port: '+str(acceptedPort))
|
||||
print('Expected: /'+acceptedDomain+':'+str(acceptedPort)+'/users/'+nickname)
|
||||
print('Actual: '+thisActor)
|
||||
print('DEBUG: unrecognized actor '+thisActor)
|
||||
return
|
||||
else:
|
||||
if not '/'+domain+'/users/'+nickname in thisActor:
|
||||
if not '/'+acceptedDomain+'/users/'+nickname in thisActor:
|
||||
if debug:
|
||||
print('Expected: /'+acceptedDomain+'/users/'+nickname)
|
||||
print('Actual: '+thisActor)
|
||||
print('DEBUG: unrecognized actor '+thisActor)
|
||||
return
|
||||
followedActor=messageJson['object']['object']
|
||||
|
@ -128,14 +142,15 @@ def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
|
|||
if isinstance(messageJson['object']['capabilities'], dict):
|
||||
capabilitiesGrantedSave(baseDir,messageJson['object']['capabilities'])
|
||||
|
||||
if followPerson(baseDir,nickname,domain, \
|
||||
if followPerson(baseDir, \
|
||||
nickname,acceptedDomain, \
|
||||
followedNickname,followedDomain, \
|
||||
federationList,debug):
|
||||
if debug:
|
||||
print('DEBUG: '+nickname+'@'+domain+' followed '+followedNickname+'@'+followedDomain)
|
||||
print('DEBUG: '+nickname+'@'+acceptedDomain+' followed '+followedNickname+'@'+followedDomain)
|
||||
else:
|
||||
if debug:
|
||||
print('DEBUG: Unable to create follow - '+nickname+'@'+domain+' -> '+followedNickname+'@'+followedDomain)
|
||||
print('DEBUG: Unable to create follow - '+nickname+'@'+acceptedDomain+' -> '+followedNickname+'@'+followedDomain)
|
||||
|
||||
def receiveAcceptReject(session,baseDir: str, \
|
||||
httpPrefix: str,domain :str,port: int, \
|
||||
|
|
|
@ -40,7 +40,8 @@ def capabilitiesRequest(baseDir: str,httpPrefix: str,domain: str, \
|
|||
}
|
||||
return ocapRequest
|
||||
|
||||
def capabilitiesAccept(baseDir: str,httpPrefix: str,nickname: str,domain: str, \
|
||||
def capabilitiesAccept(baseDir: str,httpPrefix: str, \
|
||||
nickname: str,domain: str, port: int, \
|
||||
acceptedActor: str, saveToFile: bool, \
|
||||
acceptedCaps=["inbox:write","objects:read"]) -> {}:
|
||||
# This gets returned to capabilities requester
|
||||
|
@ -50,6 +51,10 @@ def capabilitiesAccept(baseDir: str,httpPrefix: str,nickname: str,domain: str, \
|
|||
if len(acceptedActor)>256:
|
||||
return None
|
||||
|
||||
fullDomain=domain
|
||||
if port!=80 and port !=443:
|
||||
fullDomain=domain+':'+str(port)
|
||||
|
||||
# make directories to store capabilities
|
||||
capabilitiesMakeDirs(baseDir)
|
||||
filename=baseDir+'/ocap/accept/'+acceptedActor.replace('/','#')+'.json'
|
||||
|
@ -63,14 +68,14 @@ def capabilitiesAccept(baseDir: str,httpPrefix: str,nickname: str,domain: str, \
|
|||
if not ocapAccept:
|
||||
ocapId=createPassword(32)
|
||||
ocapAccept = {
|
||||
"id": httpPrefix+"://"+domain+"/caps/"+ocapId,
|
||||
"id": httpPrefix+"://"+fullDomain+"/caps/"+ocapId,
|
||||
"type": "Capability",
|
||||
"capability": acceptedCaps,
|
||||
"scope": acceptedActor,
|
||||
"actor": httpPrefix+"://"+domain
|
||||
"actor": httpPrefix+"://"+fullDomain
|
||||
}
|
||||
if nickname:
|
||||
ocapAccept['actor']=httpPrefix+"://"+domain+'/users/'+nickname
|
||||
ocapAccept['actor']=httpPrefix+"://"+fullDomain+'/users/'+nickname
|
||||
|
||||
if saveToFile:
|
||||
with open(filename, 'w') as fp:
|
||||
|
|
|
@ -282,7 +282,7 @@ def receiveFollowRequest(session,baseDir: str,httpPrefix: str, \
|
|||
nicknameToFollow+'@'+domainToFollow+' back to '+nickname+'@'+domain)
|
||||
personUrl=messageJson['actor']
|
||||
acceptJson=createAccept(baseDir,federationList,ocapGranted, \
|
||||
nickname,domain,port, \
|
||||
nicknameToFollow,domainToFollow,port, \
|
||||
personUrl,'',httpPrefix,messageJson)
|
||||
if debug:
|
||||
pprint(acceptJson)
|
||||
|
@ -310,9 +310,11 @@ def sendFollowRequest(session,baseDir: str, \
|
|||
"""
|
||||
if not domainPermitted(followDomain,federationList):
|
||||
return None
|
||||
|
||||
|
||||
fullDomain=domain
|
||||
followActor=httpPrefix+'://'+domain+'/users/'+nickname
|
||||
if port!=80 and port!=443:
|
||||
fullDomain=domain+':'+str(port)
|
||||
followActor=httpPrefix+'://'+domain+':'+str(port)+'/users/'+nickname
|
||||
|
||||
requestDomain=followDomain
|
||||
|
@ -329,7 +331,7 @@ def sendFollowRequest(session,baseDir: str, \
|
|||
followedId=followHttpPrefix+'://'+requestDomain+'/users/'+followNickname
|
||||
|
||||
newFollowJson = {
|
||||
'id': httpPrefix+'://'+domain+'/users/'+nickname+'/statuses/'+statusNumber,
|
||||
'id': httpPrefix+'://'+fullDomain+'/users/'+nickname+'/statuses/'+statusNumber,
|
||||
'type': 'Follow',
|
||||
'actor': followActor,
|
||||
'object': followedId,
|
||||
|
|
Loading…
Reference in New Issue