Skip to content

Commit

Permalink
PR(MAIN): Assume read if only has write permission.
Browse files Browse the repository at this point in the history
  • Loading branch information
shahzadlone committed Oct 7, 2024
1 parent 2bdbbd4 commit 729c34d
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 81 deletions.
5 changes: 3 additions & 2 deletions acp/acp.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,11 @@ type ACP interface {
// Otherwise if check failed then an error is returned (and the boolean result should not be used).
//
// Note(s):
// - permission here is a valid DPI permission we are checking for ("read" or "write").
// - permissions here is a valid DPI permission we are checking for ("read" or "write").
// - returns true if has access to ANY of the given permissions.
CheckDocAccess(
ctx context.Context,
permission DPIPermission,
permissions []DPIPermission,
actorID string,
policyID string,
resourceName string,
Expand Down
40 changes: 20 additions & 20 deletions acp/acp_local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ func Test_LocalACP_InMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErrorOtherw
// Invalid empty arguments such that we can't check doc access.
hasAccess, errCheckDocAccess := localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity1.DID,
validPolicyID,
"",
Expand All @@ -498,7 +498,7 @@ func Test_LocalACP_InMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErrorOtherw
// Check document accesss for a document that does not exist.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity1.DID,
validPolicyID,
"users",
Expand All @@ -520,7 +520,7 @@ func Test_LocalACP_InMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErrorOtherw
// Now check using correct identity if it has access.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity1.DID,
validPolicyID,
"users",
Expand All @@ -532,7 +532,7 @@ func Test_LocalACP_InMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErrorOtherw
// Now check using wrong identity, it should not have access.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand Down Expand Up @@ -571,7 +571,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr
// Invalid empty arguments such that we can't check doc access.
hasAccess, errCheckDocAccess := localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity1.DID,
validPolicyID,
"",
Expand All @@ -584,7 +584,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr
// Check document accesss for a document that does not exist.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity1.DID,
validPolicyID,
"users",
Expand All @@ -606,7 +606,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr
// Now check using correct identity if it has access.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity1.DID,
validPolicyID,
"users",
Expand All @@ -618,7 +618,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr
// Now check using wrong identity, it should not have access.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand All @@ -638,7 +638,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr
// Now check again after the restart using correct identity if it still has access.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity1.DID,
validPolicyID,
"users",
Expand All @@ -650,7 +650,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr
// Now check again after restart using wrong identity, it should continue to not have access.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand Down Expand Up @@ -696,7 +696,7 @@ func Test_LocalACP_InMemory_AddDocActorRelationship_FalseIfExistsBeforeTrueIfNoO
// Other identity does not have access yet.
hasAccess, errCheckDocAccess := localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand Down Expand Up @@ -734,7 +734,7 @@ func Test_LocalACP_InMemory_AddDocActorRelationship_FalseIfExistsBeforeTrueIfNoO
// Now the other identity has access.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand Down Expand Up @@ -783,7 +783,7 @@ func Test_LocalACP_PersistentMemory_AddDocActorRelationship_FalseIfExistsBeforeT
// Other identity does not have access yet.
hasAccess, errCheckDocAccess := localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand Down Expand Up @@ -821,7 +821,7 @@ func Test_LocalACP_PersistentMemory_AddDocActorRelationship_FalseIfExistsBeforeT
// Now the other identity has access.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand All @@ -841,7 +841,7 @@ func Test_LocalACP_PersistentMemory_AddDocActorRelationship_FalseIfExistsBeforeT
// Now check again after the restart that the second identity still has access.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand Down Expand Up @@ -900,7 +900,7 @@ func Test_LocalACP_InMemory_DeleteDocActorRelationship_TrueIfFoundAndDeletedFals
// Now the other identity has access.
hasAccess, errCheckDocAccess := localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand Down Expand Up @@ -938,7 +938,7 @@ func Test_LocalACP_InMemory_DeleteDocActorRelationship_TrueIfFoundAndDeletedFals
// Other identity now has no access again.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand Down Expand Up @@ -1000,7 +1000,7 @@ func Test_LocalACP_PersistentMemory_DeleteDocActorRelationship_TrueIfFoundAndDel
// Now the other identity has access.
hasAccess, errCheckDocAccess := localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand Down Expand Up @@ -1038,7 +1038,7 @@ func Test_LocalACP_PersistentMemory_DeleteDocActorRelationship_TrueIfFoundAndDel
// Other identity now has no access again.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand All @@ -1058,7 +1058,7 @@ func Test_LocalACP_PersistentMemory_DeleteDocActorRelationship_TrueIfFoundAndDel
// Now check again after the restart that the second identity still has no access.
hasAccess, errCheckDocAccess = localACP.CheckDocAccess(
ctx,
ReadPermission,
[]DPIPermission{ReadPermission},
identity2.DID,
validPolicyID,
"users",
Expand Down
8 changes: 8 additions & 0 deletions acp/dpi.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ const (
WritePermission
)

// PermissionsThatImplyRead is a list of any permissions that if we have, we assume that the user can read.
// This is because for DefraDB's purposes if an identity has access to the write permission, then they don't
// need to explicitly have read permission inorder to read, we can just imply that they have read access.
var PermissionsThatImplyRead = []DPIPermission{
ReadPermission,
WritePermission,
}

// List of all valid DPI permissions, the order of permissions in this list must match
// the above defined ordering such that iota matches the index position within the list.
var dpiRequiredPermissions = []string{
Expand Down
2 changes: 2 additions & 0 deletions acp/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func NewErrFailedToCheckIfDocIsRegisteredWithACP(
func NewErrFailedToVerifyDocAccessWithACP(
inner error,
Type string,
permission string,
policyID string,
actorID string,
resourceName string,
Expand All @@ -138,6 +139,7 @@ func NewErrFailedToVerifyDocAccessWithACP(
errFailedToVerifyDocAccessWithACP,
inner,
errors.NewKV("Type", Type),
errors.NewKV("Permission", permission),
errors.NewKV("PolicyID", policyID),
errors.NewKV("ActorID", actorID),
errors.NewKV("ResourceName", resourceName),
Expand Down
68 changes: 38 additions & 30 deletions acp/source_hub_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package acp

import (
"context"
"strconv"

protoTypes "github.com/cosmos/gogoproto/types"
"github.com/sourcenetwork/corelog"
Expand Down Expand Up @@ -336,45 +337,52 @@ func (a *sourceHubBridge) IsDocRegistered(

func (a *sourceHubBridge) CheckDocAccess(
ctx context.Context,
permission DPIPermission,
permissions []DPIPermission,
actorID string,
policyID string,
resourceName string,
docID string,
) (bool, error) {
isValid, err := a.client.VerifyAccessRequest(
ctx,
permission,
actorID,
policyID,
resourceName,
docID,
)
if err != nil {
return false, NewErrFailedToVerifyDocAccessWithACP(err, "Local", policyID, actorID, resourceName, docID)
}
var hasAccess bool = false
var err error

if isValid {
log.InfoContext(
for _, permission := range permissions {
hasAccess, err = a.client.VerifyAccessRequest(
ctx,
"Document accessible",
corelog.Any("PolicyID", policyID),
corelog.Any("ActorID", actorID),
corelog.Any("Resource", resourceName),
corelog.Any("DocID", docID),
)
return true, nil
} else {
log.InfoContext(
ctx,
"Document inaccessible",
corelog.Any("PolicyID", policyID),
corelog.Any("ActorID", actorID),
corelog.Any("Resource", resourceName),
corelog.Any("DocID", docID),
permission,
actorID,
policyID,
resourceName,
docID,
)
return false, nil

if err != nil {
return false, NewErrFailedToVerifyDocAccessWithACP(
err,
"Local",
permission.String(),
policyID,
actorID,
resourceName,
docID,
)
}

if hasAccess {
break
}
}

log.InfoContext(
ctx,
"Document accessible="+strconv.FormatBool(hasAccess),
corelog.Any("PolicyID", policyID),
corelog.Any("Resource", resourceName),
corelog.Any("ActorID", actorID),
corelog.Any("DocID", docID),
)

return hasAccess, nil
}

func (a *sourceHubBridge) AddDocActorRelationship(
Expand Down
6 changes: 3 additions & 3 deletions internal/db/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ func (c *collection) getAllDocIDsChan(

canRead, err := c.checkAccessOfDocWithACP(
ctx,
acp.ReadPermission,
acp.PermissionsThatImplyRead,
docID.String(),
)

Expand Down Expand Up @@ -524,7 +524,7 @@ func (c *collection) update(
// Stop the update if the correct permissions aren't there.
canUpdate, err := c.checkAccessOfDocWithACP(
ctx,
acp.WritePermission,
[]acp.DPIPermission{acp.WritePermission},
doc.ID().String(),
)
if err != nil {
Expand Down Expand Up @@ -890,7 +890,7 @@ func (c *collection) exists(
) (exists bool, isDeleted bool, err error) {
canRead, err := c.checkAccessOfDocWithACP(
ctx,
acp.ReadPermission,
acp.PermissionsThatImplyRead,
primaryKey.DocID,
)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/db/collection_acp.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (c *collection) registerDocWithACP(

func (c *collection) checkAccessOfDocWithACP(
ctx context.Context,
dpiPermission acp.DPIPermission,
dpiPermissions []acp.DPIPermission,
docID string,
) (bool, error) {
// If acp is not available, then we have unrestricted access.
Expand All @@ -61,7 +61,7 @@ func (c *collection) checkAccessOfDocWithACP(
identity,
c.db.acp.Value(),
c,
dpiPermission,
dpiPermissions,
docID,
)
}
2 changes: 1 addition & 1 deletion internal/db/collection_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (c *collection) applyDelete(
// Stop deletion of document if the correct permissions aren't there.
canDelete, err := c.checkAccessOfDocWithACP(
ctx,
acp.WritePermission,
[]acp.DPIPermission{acp.WritePermission},
primaryKey.DocID,
)

Expand Down
2 changes: 1 addition & 1 deletion internal/db/fetcher/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ func (df *DocumentFetcher) fetchNext(ctx context.Context) (EncodedDocument, Exec
df.identity,
df.acp.Value(),
df.col,
acp.ReadPermission,
acp.PermissionsThatImplyRead,
df.kv.Key.DocID,
)

Expand Down
4 changes: 2 additions & 2 deletions internal/db/permission/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func CheckAccessOfDocOnCollectionWithACP(
identity immutable.Option[acpIdentity.Identity],
acpSystem acp.ACP,
collection client.Collection,
permission acp.DPIPermission,
permissions []acp.DPIPermission,
docID string,
) (bool, error) {
// Even if acp exists, but there is no policy on the collection (unpermissioned collection)
Expand Down Expand Up @@ -77,7 +77,7 @@ func CheckAccessOfDocOnCollectionWithACP(
// Now actually check using the signature if this identity has access or not.
hasAccess, err := acpSystem.CheckDocAccess(
ctx,
permission,
permissions,
identity.Value().DID,
policyID,
resourceName,
Expand Down
Loading

0 comments on commit 729c34d

Please sign in to comment.