Skip to content

Commit

Permalink
Merge branch 'develop' into nasdf/feat/min-max-aggregate
Browse files Browse the repository at this point in the history
  • Loading branch information
nasdf authored Oct 2, 2024
2 parents 4f8b79c + c986312 commit 3cff29d
Show file tree
Hide file tree
Showing 83 changed files with 10,134 additions and 381 deletions.
28 changes: 25 additions & 3 deletions .github/workflows/check-vulnerabilities.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,32 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Run govulncheck
uses: golang/govulncheck-action@v1
- name: Checkout code into the directory
uses: actions/checkout@v4

- name: Setup Go environment explicitly
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
check-latest: true
cache: false
go-package: ./...

- name: Install govulncheck
run: make deps:vulncheck

- name: Run govulncheck scan
run: govulncheck -C . -format text ./... | tee govulncheck.txt

- name: Check if only known vulnerabilities were found (there are new vulnerabilities if this fails)
run: cat govulncheck.txt | grep "Your code is affected by 2 vulnerabilities from 1 module."

# Use the steps below once the x/crisis (crisis.init) bug is fixed or if the
# ability to silence is implemented: https://github.com/golang/go/issues/61211
#steps:
# - name: Run govulncheck
# uses: golang/govulncheck-action@v1
# with:
# go-version-file: 'go.mod'
# check-latest: true
# cache: false
# go-package: ./...
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ else
$(info YAML linter 'yamllint' already installed.)
endif

.PHONY: deps\:vulncheck
deps\:vulncheck:
go install golang.org/x/vuln/cmd/govulncheck@latest

.PHONY: deps\:lint
deps\:lint:
@$(MAKE) deps:lint-go && \
Expand Down Expand Up @@ -172,6 +176,7 @@ deps:
$(MAKE) deps:bench && \
$(MAKE) deps:chglog && \
$(MAKE) deps:lint && \
$(MAKE) deps:vulncheck && \
$(MAKE) deps:test && \
$(MAKE) deps:mocks

Expand Down
203 changes: 203 additions & 0 deletions acp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,209 @@ Error:

### Execute Explain example (coming soon)

### Sharing Private Documents With Others

To share a document (or grant a more restricted access) with another actor, we must add a relationship between the
actor and the document. Inorder to make the relationship we require all of the following:

1) **Target DocID**: The `docID` of the document we want to make a relationship for.
2) **Collection Name**: The name of the collection that has the `Target DocID`.
3) **Relation Name**: The type of relation (name must be defined within the linked policy on collection).
4) **Target Identity**: The identity of the actor the relationship is being made with.
5) **Requesting Identity**: The identity of the actor that is making the request.

Note:
- ACP must be available (i.e. ACP can not be disabled).
- The collection with the target document must have a valid policy and resource linked.
- The target document must be registered with ACP already (private document).
- The requesting identity MUST either be the owner OR the manager (manages the relation) of the resource.
- If the specified relation was not granted the miminum DPI permissions (read or write) within the policy,
and a relationship is formed, the subject/actor will still not be able to access (read or write) the resource.
- If the relationship already exists, then it will just be a no-op.

Consider the following policy that we have under `examples/dpi_policy/user_dpi_policy_with_manages.yml`:

```yaml
name: An Example Policy

description: A Policy

actor:
name: actor

resources:
users:
permissions:
read:
expr: owner + reader + writer

write:
expr: owner + writer

nothing:
expr: dummy

relations:
owner:
types:
- actor

reader:
types:
- actor

writer:
types:
- actor

admin:
manages:
- reader
types:
- actor

dummy:
types:
- actor
```
Add the policy:
```sh
defradb client acp policy add -f examples/dpi_policy/user_dpi_policy_with_manages.yml \
--identity e3b722906ee4e56368f581cd8b18ab0f48af1ea53e635e3f7b8acd076676f6ac
```

Result:
```json
{
"PolicyID": "ec11b7e29a4e195f95787e2ec9b65af134718d16a2c9cd655b5e04562d1cabf9"
}
```

Add schema, linking to the users resource and our policyID:
```sh
defradb client schema add '
type Users @policy(
id: "ec11b7e29a4e195f95787e2ec9b65af134718d16a2c9cd655b5e04562d1cabf9",
resource: "users"
) {
name: String
age: Int
}
'
```

Result:
```json
[
{
"Name": "Users",
"ID": 1,
"RootID": 1,
"SchemaVersionID": "bafkreihhd6bqrjhl5zidwztgxzeseveplv3cj3fwtn3unjkdx7j2vr2vrq",
"Sources": [],
"Fields": [
{
"Name": "_docID",
"ID": 0,
"Kind": null,
"RelationName": null,
"DefaultValue": null
},
{
"Name": "age",
"ID": 1,
"Kind": null,
"RelationName": null,
"DefaultValue": null
},
{
"Name": "name",
"ID": 2,
"Kind": null,
"RelationName": null,
"DefaultValue": null
}
],
"Indexes": [],
"Policy": {
"ID": "ec11b7e29a4e195f95787e2ec9b65af134718d16a2c9cd655b5e04562d1cabf9",
"ResourceName": "users"
},
"IsMaterialized": true
}
]
```

Create a private document:
```sh
defradb client collection create --name Users '[{ "name": "SecretShahzadLone" }]' \
--identity e3b722906ee4e56368f581cd8b18ab0f48af1ea53e635e3f7b8acd076676f6ac
```

Only the owner can see it:
```sh
defradb client collection docIDs --identity e3b722906ee4e56368f581cd8b18ab0f48af1ea53e635e3f7b8acd076676f6ac
```

Result:
```json
{
"docID": "bae-ff3ceb1c-b5c0-5e86-a024-dd1b16a4261c",
"error": ""
}
```

Another actor can not:
```sh
defradb client collection docIDs --identity 4d092126012ebaf56161716018a71630d99443d9d5217e9d8502bb5c5456f2c5
```

**Result is empty from the above command**


Now let's make the other actor a reader of the document by adding a relationship:
```sh
defradb client acp relationship add \
--collection Users \
--docID bae-ff3ceb1c-b5c0-5e86-a024-dd1b16a4261c \
--relation reader \
--actor did:key:z7r8os2G88XXBNBTLj3kFR5rzUJ4VAesbX7PgsA68ak9B5RYcXF5EZEmjRzzinZndPSSwujXb4XKHG6vmKEFG6ZfsfcQn \
--identity e3b722906ee4e56368f581cd8b18ab0f48af1ea53e635e3f7b8acd076676f6ac
```

Result:
```json
{
"ExistedAlready": false
}
```

**Note: If the same relationship is created again the `ExistedAlready` would then be true, indicating no-op**

Now the other actor can read:
```sh
defradb client collection docIDs --identity 4d092126012ebaf56161716018a71630d99443d9d5217e9d8502bb5c5456f2c5
```

Result:
```json
{
"docID": "bae-ff3ceb1c-b5c0-5e86-a024-dd1b16a4261c",
"error": ""
}
```

But, they still can not perform an update as they were only granted a read permission (through `reader` relation):
```sh
defradb client collection update --name Users --docID "bae-ff3ceb1c-b5c0-5e86-a024-dd1b16a4261c" \
--identity 4d092126012ebaf56161716018a71630d99443d9d5217e9d8502bb5c5456f2c5 '{ "name": "SecretUpdatedShahzad" }'
```

Result:
```sh
Error: document not found or not authorized to access
```

## DAC Usage HTTP:

Expand Down
16 changes: 16 additions & 0 deletions acp/acp.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,22 @@ type ACP interface {
docID string,
) (bool, error)

// AddDocActorRelationship creates a relationship between document and the target actor.
//
// If failure occurs, the result will return an error. Upon success the boolean value will
// be true if the relationship already existed (no-op), and false if a new relationship was made.
//
// Note: The request actor must either be the owner or manager of the document.
AddDocActorRelationship(
ctx context.Context,
policyID string,
resourceName string,
docID string,
relation string,
requestActor identity.Identity,
targetActor string,
) (bool, error)

// SupportsP2P returns true if the implementation supports ACP across a peer network.
SupportsP2P() bool
}
31 changes: 31 additions & 0 deletions acp/acp_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,34 @@ func (l *ACPLocal) VerifyAccessRequest(

return resp.Valid, nil
}

func (l *ACPLocal) AddActorRelationship(
ctx context.Context,
policyID string,
resourceName string,
objectID string,
relation string,
requester identity.Identity,
targetActor string,
creationTime *protoTypes.Timestamp,
) (bool, error) {
principal, err := auth.NewDIDPrincipal(requester.DID)
if err != nil {
return false, newErrInvalidActorID(err, requester.DID)
}

ctx = auth.InjectPrincipal(ctx, principal)

setRelationshipRequest := types.SetRelationshipRequest{
PolicyId: policyID,
Relationship: types.NewActorRelationship(resourceName, objectID, relation, targetActor),
CreationTime: creationTime,
}

setRelationshipResponse, err := l.engine.SetRelationship(ctx, &setRelationshipRequest)
if err != nil {
return false, err
}

return setRelationshipResponse.RecordExisted, nil
}
Loading

0 comments on commit 3cff29d

Please sign in to comment.