S2S: Project: Accept: Switch from basic to full OCAP verification
This commit is contained in:
parent
bce8079cb5
commit
ff2c5659af
1 changed files with 150 additions and 107 deletions
|
@ -94,6 +94,24 @@ import Vervis.Web.Collab
|
||||||
-- * Otherwise, i.e. sender isn't the component:
|
-- * Otherwise, i.e. sender isn't the component:
|
||||||
-- * Verify I've seen the component-Accept for this Add
|
-- * Verify I've seen the component-Accept for this Add
|
||||||
-- * Verify the new Accept is authorized
|
-- * Verify the new Accept is authorized
|
||||||
|
--
|
||||||
|
-- * Give me a new child active SourceOriginUs
|
||||||
|
-- * Verify we haven't yet seen child's Accept
|
||||||
|
-- * Give me a new child passive SourceOriginThem
|
||||||
|
-- * Option 1: We haven't seen child's Accept yet
|
||||||
|
-- * Verify sender is the child
|
||||||
|
-- * Option 2: We saw it, but not my collaborator's Accept
|
||||||
|
-- * Verify the Accept is authorized
|
||||||
|
-- * Otherwise respond with error, no Accept is needed
|
||||||
|
-- * Give me a new parent active DestOriginUs
|
||||||
|
-- * Respond with error, we aren't supposed to get any Accept
|
||||||
|
-- * Give me a new parent passive DestOriginThem
|
||||||
|
-- * Option 1: I haven't yet seen parent's Accept
|
||||||
|
-- * Verify sender is the parent
|
||||||
|
-- * Option 2: I saw it, but not my collaborator's Accept
|
||||||
|
-- * Verify the accept is authorized
|
||||||
|
-- * Otherwise respond with error, no Accept is needed
|
||||||
|
--
|
||||||
-- * If it's none of these, respond with error
|
-- * If it's none of these, respond with error
|
||||||
--
|
--
|
||||||
-- * In collab mode, verify the Collab isn't enabled yet
|
-- * In collab mode, verify the Collab isn't enabled yet
|
||||||
|
@ -112,9 +130,22 @@ import Vervis.Web.Collab
|
||||||
-- * Otherwise, i.e. sender isn't the component, record the Accept and
|
-- * Otherwise, i.e. sender isn't the component, record the Accept and
|
||||||
-- enable the Component in DB
|
-- enable the Component in DB
|
||||||
--
|
--
|
||||||
|
-- * In child-active mode,
|
||||||
|
-- * If sender is the child, record the Accept into the Source record
|
||||||
|
-- * Prepare to send degelator-Grant
|
||||||
|
-- * Otherwise nothing to do
|
||||||
|
-- * In child-passive mode,
|
||||||
|
-- * Option 1: Record child's Accept in Source record
|
||||||
|
-- * Option 2: Record my collaborator's Accept
|
||||||
|
-- * Prepare to send delegator-Grant
|
||||||
|
-- * In parent-passive mode,
|
||||||
|
-- * Option 1: Record parent's Accept in the Dest record
|
||||||
|
-- * Option 2: Record my collaborator's Accept in the Dest record
|
||||||
|
-- * Prepare to send my own Accept
|
||||||
|
--
|
||||||
-- * Forward the Accept to my followers
|
-- * Forward the Accept to my followers
|
||||||
--
|
--
|
||||||
-- * Possibly send a Grant:
|
-- * Possibly send a Grant/Accept:
|
||||||
-- * For Invite-collab mode:
|
-- * For Invite-collab mode:
|
||||||
-- * Regular collaborator-Grant
|
-- * Regular collaborator-Grant
|
||||||
-- * To: Accepter (i.e. Invite target)
|
-- * To: Accepter (i.e. Invite target)
|
||||||
|
@ -138,6 +169,32 @@ import Vervis.Web.Collab
|
||||||
-- - Component's followers
|
-- - Component's followers
|
||||||
-- - My followers
|
-- - My followers
|
||||||
-- - The Accept's sender
|
-- - The Accept's sender
|
||||||
|
--
|
||||||
|
-- * Child-active
|
||||||
|
-- * If sender is the child
|
||||||
|
-- * delegator-Grant
|
||||||
|
-- * To: Child
|
||||||
|
-- * CC:
|
||||||
|
-- - Child's followers
|
||||||
|
-- - My followers
|
||||||
|
-- * Child-passive
|
||||||
|
-- * In option 2
|
||||||
|
-- * delegator-Grant
|
||||||
|
-- * To: Child
|
||||||
|
-- * CC:
|
||||||
|
-- - Child's followers
|
||||||
|
-- - My followers
|
||||||
|
-- - The Accept sender (my collaborator)
|
||||||
|
-- * Parent-passive
|
||||||
|
-- * In option 2
|
||||||
|
-- * Accept
|
||||||
|
-- * Object: The Add
|
||||||
|
-- * Fulfills: My collaborator's Accept
|
||||||
|
-- * To: Parent
|
||||||
|
-- * CC:
|
||||||
|
-- - Parent's followers
|
||||||
|
-- - My followers
|
||||||
|
-- - The Accept sender (my collaborator)
|
||||||
projectAccept
|
projectAccept
|
||||||
:: UTCTime
|
:: UTCTime
|
||||||
-> ProjectId
|
-> ProjectId
|
||||||
|
@ -148,22 +205,9 @@ projectAccept now projectID (Verse authorIdMsig body) accept = do
|
||||||
|
|
||||||
-- Check input
|
-- Check input
|
||||||
acceptee <- parseAccept accept
|
acceptee <- parseAccept accept
|
||||||
|
let muCap = AP.activityCapability $ actbActivity body
|
||||||
|
|
||||||
-- Verify that the capability URI, if specified, is one of:
|
collabOrComp <- withDBExcept $ do
|
||||||
-- * Outbox item URI of a local actor, i.e. a local activity
|
|
||||||
-- * A remote URI
|
|
||||||
maybeCap <-
|
|
||||||
traverse
|
|
||||||
(nameExceptT "Accept capability" . parseActivityURI')
|
|
||||||
(AP.activityCapability $ actbActivity body)
|
|
||||||
|
|
||||||
maybeNew <- withDBExcept $ do
|
|
||||||
|
|
||||||
-- Grab me from DB
|
|
||||||
(recipActorID, recipActor) <- lift $ do
|
|
||||||
recip <- getJust projectID
|
|
||||||
let actorID = projectActor recip
|
|
||||||
(actorID,) <$> getJust actorID
|
|
||||||
|
|
||||||
-- Find the accepted activity in our DB
|
-- Find the accepted activity in our DB
|
||||||
accepteeDB <- do
|
accepteeDB <- do
|
||||||
|
@ -174,104 +218,103 @@ projectAccept now projectID (Verse authorIdMsig body) accept = do
|
||||||
-- URI is the resource, grabbing the Collab record from our DB,
|
-- URI is the resource, grabbing the Collab record from our DB,
|
||||||
-- Or if the accepted activity is an Invite or Add where my components
|
-- Or if the accepted activity is an Invite or Add where my components
|
||||||
-- URI is the resource, grabbing the Component record from our DB
|
-- URI is the resource, grabbing the Component record from our DB
|
||||||
collabOrComp <- do
|
let adapt = maybe (Right Nothing) (either Left (Right . Just))
|
||||||
let adapt = maybe (Right Nothing) (either Left (Right . Just))
|
maybeCollab <-
|
||||||
maybeCollab <-
|
ExceptT $ fmap adapt $ runMaybeT $
|
||||||
ExceptT $ fmap adapt $ runMaybeT $
|
runExceptT (Left <$> tryInviteCollab accepteeDB) <|>
|
||||||
runExceptT (Left <$> tryInviteCollab accepteeDB) <|>
|
runExceptT (Left <$> tryJoinCollab accepteeDB) <|>
|
||||||
runExceptT (Left <$> tryJoinCollab accepteeDB) <|>
|
runExceptT (Right <$> tryInviteComp accepteeDB) <|>
|
||||||
runExceptT (Right <$> tryInviteComp accepteeDB) <|>
|
runExceptT (Right <$> tryAddComp accepteeDB)
|
||||||
runExceptT (Right <$> tryAddComp accepteeDB)
|
fromMaybeE
|
||||||
fromMaybeE
|
maybeCollab
|
||||||
maybeCollab
|
"Accepted activity isn't an Invite/Join/Add I'm aware of"
|
||||||
"Accepted activity isn't an Invite/Join/Add I'm aware of"
|
|
||||||
|
|
||||||
idsForAccept <- bitraverse
|
idsForAccept <- bitraverse
|
||||||
|
|
||||||
(\ (collabID, fulfills, inviterOrJoiner) -> (collabID,inviterOrJoiner,) <$> bitraverse
|
(\ (collabID, fulfills, inviterOrJoiner) -> (collabID,inviterOrJoiner,) <$> bitraverse
|
||||||
|
|
||||||
-- If accepting an Invite, find the Collab recipient and verify
|
-- If accepting an Invite, find the Collab recipient and verify
|
||||||
-- it's the sender of the Accept
|
-- it's the sender of the Accept
|
||||||
(\ fulfillsID -> do
|
(\ fulfillsID -> withDBExcept $ do
|
||||||
recip <-
|
recip <-
|
||||||
lift $
|
lift $
|
||||||
requireEitherAlt
|
requireEitherAlt
|
||||||
(getBy $ UniqueCollabRecipLocal collabID)
|
(getBy $ UniqueCollabRecipLocal collabID)
|
||||||
(getBy $ UniqueCollabRecipRemote collabID)
|
(getBy $ UniqueCollabRecipRemote collabID)
|
||||||
"Found Collab with no recip"
|
"Found Collab with no recip"
|
||||||
"Found Collab with multiple recips"
|
"Found Collab with multiple recips"
|
||||||
case (recip, authorIdMsig) of
|
case (recip, authorIdMsig) of
|
||||||
(Left (Entity crlid crl), Left (LocalActorPerson personID, _, _))
|
(Left (Entity crlid crl), Left (LocalActorPerson personID, _, _))
|
||||||
| collabRecipLocalPerson crl == personID ->
|
| collabRecipLocalPerson crl == personID ->
|
||||||
return (fulfillsID, Left crlid)
|
return (fulfillsID, Left crlid)
|
||||||
(Right (Entity crrid crr), Right (author, _, _))
|
(Right (Entity crrid crr), Right (author, _, _))
|
||||||
| collabRecipRemoteActor crr == remoteAuthorId author ->
|
| collabRecipRemoteActor crr == remoteAuthorId author ->
|
||||||
return (fulfillsID, Right crrid)
|
return (fulfillsID, Right crrid)
|
||||||
_ -> throwE "Accepting an Invite whose recipient is someone else"
|
_ -> throwE "Accepting an Invite whose recipient is someone else"
|
||||||
)
|
|
||||||
|
|
||||||
-- If accepting a Join, verify accepter has permission
|
|
||||||
(\ fulfillsID -> do
|
|
||||||
capID <- fromMaybeE maybeCap "No capability provided"
|
|
||||||
capability <-
|
|
||||||
case capID of
|
|
||||||
Left (capActor, _, capItem) -> return (capActor, capItem)
|
|
||||||
Right _ -> throwE "Capability is a remote URI, i.e. not authored by the local resource"
|
|
||||||
verifyCapability'
|
|
||||||
capability
|
|
||||||
authorIdMsig
|
|
||||||
(LocalActorProject projectID)
|
|
||||||
AP.RoleAdmin
|
|
||||||
return fulfillsID
|
|
||||||
)
|
|
||||||
|
|
||||||
fulfills
|
|
||||||
)
|
)
|
||||||
|
|
||||||
(\ (componentID, ident, inviteOrAdd) -> (componentID, ident,) <$> bitraverse
|
-- If accepting a Join, verify accepter has permission
|
||||||
|
(\ fulfillsID -> do
|
||||||
-- If accepting an Invite-component, there's nothing to check
|
uCap <- fromMaybeE muCap "No capability provided"
|
||||||
-- at this point
|
verifyCapability''
|
||||||
pure
|
uCap
|
||||||
|
authorIdMsig
|
||||||
-- If accepting an Add-component:
|
(LocalActorProject projectID)
|
||||||
-- * If the sender is the component, verify I haven't seen
|
AP.RoleAdmin
|
||||||
-- a component-Accept on this Add
|
return fulfillsID
|
||||||
-- * Otherwise, verify I've seen the component-Accept for
|
|
||||||
-- this Add and that the new Accept is authorized
|
|
||||||
(\ () -> do
|
|
||||||
maybeComponentAccept <-
|
|
||||||
lift $
|
|
||||||
case bimap fst fst ident of
|
|
||||||
Left localID -> (() <$) <$> getBy (UniqueComponentAcceptLocal localID)
|
|
||||||
Right remoteID -> (() <$) <$> getBy (UniqueComponentAcceptRemote remoteID)
|
|
||||||
if componentIsAuthor ident
|
|
||||||
then
|
|
||||||
verifyNothingE
|
|
||||||
maybeComponentAccept
|
|
||||||
"I've already seen a ComponentAccept* on \
|
|
||||||
\that Add"
|
|
||||||
else do
|
|
||||||
fromMaybeE
|
|
||||||
maybeComponentAccept
|
|
||||||
"I haven't yet seen the Component's Accept on \
|
|
||||||
\the Add"
|
|
||||||
capID <- fromMaybeE maybeCap "No capability provided"
|
|
||||||
capability <-
|
|
||||||
case capID of
|
|
||||||
Left (capActor, _, capItem) -> return (capActor, capItem)
|
|
||||||
Right _ -> throwE "Capability is a remote URI, i.e. not authored by me"
|
|
||||||
verifyCapability'
|
|
||||||
capability
|
|
||||||
authorIdMsig
|
|
||||||
(LocalActorProject projectID)
|
|
||||||
AP.RoleAdmin
|
|
||||||
)
|
|
||||||
|
|
||||||
inviteOrAdd
|
|
||||||
)
|
)
|
||||||
|
|
||||||
collabOrComp
|
fulfills
|
||||||
|
)
|
||||||
|
|
||||||
|
(\ (componentID, ident, inviteOrAdd) -> (componentID, ident,) <$> bitraverse
|
||||||
|
|
||||||
|
-- If accepting an Invite-component, there's nothing to check
|
||||||
|
-- at this point
|
||||||
|
pure
|
||||||
|
|
||||||
|
-- If accepting an Add-component:
|
||||||
|
-- * If the sender is the component, verify I haven't seen
|
||||||
|
-- a component-Accept on this Add
|
||||||
|
-- * Otherwise, verify I've seen the component-Accept for
|
||||||
|
-- this Add and that the new Accept is authorized
|
||||||
|
(\ () -> do
|
||||||
|
maybeComponentAccept <-
|
||||||
|
lift $ withDB $
|
||||||
|
case bimap fst fst ident of
|
||||||
|
Left localID -> (() <$) <$> getBy (UniqueComponentAcceptLocal localID)
|
||||||
|
Right remoteID -> (() <$) <$> getBy (UniqueComponentAcceptRemote remoteID)
|
||||||
|
if componentIsAuthor ident
|
||||||
|
then
|
||||||
|
verifyNothingE
|
||||||
|
maybeComponentAccept
|
||||||
|
"I've already seen a ComponentAccept* on \
|
||||||
|
\that Add"
|
||||||
|
else do
|
||||||
|
fromMaybeE
|
||||||
|
maybeComponentAccept
|
||||||
|
"I haven't yet seen the Component's Accept on \
|
||||||
|
\the Add"
|
||||||
|
uCap <- fromMaybeE muCap "No capability provided"
|
||||||
|
verifyCapability''
|
||||||
|
uCap
|
||||||
|
authorIdMsig
|
||||||
|
(LocalActorProject projectID)
|
||||||
|
AP.RoleAdmin
|
||||||
|
)
|
||||||
|
|
||||||
|
inviteOrAdd
|
||||||
|
)
|
||||||
|
|
||||||
|
collabOrComp
|
||||||
|
|
||||||
|
maybeNew <- withDBExcept $ do
|
||||||
|
|
||||||
|
-- Grab me from DB
|
||||||
|
(recipActorID, recipActor) <- lift $ do
|
||||||
|
recip <- getJust projectID
|
||||||
|
let actorID = projectActor recip
|
||||||
|
(actorID,) <$> getJust actorID
|
||||||
|
|
||||||
-- In collab mode, verify the Collab isn't already validated
|
-- In collab mode, verify the Collab isn't already validated
|
||||||
-- In component mode, verify the Component isn't already validated
|
-- In component mode, verify the Component isn't already validated
|
||||||
|
|
Loading…
Reference in a new issue