Skip to content

Conversation

@MaxBlaushild
Copy link
Contributor

Implements policy constrained record appending and persistent record based policies.

Users now have the option to check against policies when appending data. These policies are stored, and again checked when user grants access for file to new users.

Also allows users to add and remove policies for their records.

@codecov-io
Copy link

codecov-io commented Oct 29, 2018

Codecov Report

Merging #108 into master will decrease coverage by 1.84%.
The diff coverage is 87.75%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #108      +/-   ##
==========================================
- Coverage    96.6%   94.75%   -1.85%     
==========================================
  Files           8        9       +1     
  Lines         206      248      +42     
  Branches       48       57       +9     
==========================================
+ Hits          199      235      +36     
- Misses          7       13       +6
Impacted Files Coverage Δ
contracts/mock/PolicyMock.sol 100% <ø> (ø)
contracts/LinniaPermissions.sol 98.03% <100%> (-0.18%) ⬇️
contracts/LinniaHub.sol 95.45% <100%> (+1.33%) ⬆️
contracts/LinniaPolicies.sol 80% <80%> (ø)
contracts/LinniaRecords.sol 97.11% <90.9%> (-1.67%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9f2b1a5...ad50229. Read the comment docs.

'sender': user1
};

assert.equal(tx.logs[0].event, 'LinniaPolicyChecked');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to check for the new event logs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new event logs aren't available in the returned transaction logs. I test for them in the method that emits them though



contract /* interface */ PermissionPolicyMock is PermissionPolicyI {
contract /* interface */ PolicyMock is PolicyI {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove /* interface */

Copy link
Contributor

@godfreyhobbs godfreyhobbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this makes sense to have the policies in a different contract. If we update the new policy contract we will remove all of the records policies. This seems to be a security hole.

I think this all needs to be in the same contract until we have a way of migrating data when contracts are updated.

@MaxBlaushild MaxBlaushild force-pushed the feat/policiesForRecords branch from 836308a to ad50229 Compare November 2, 2018 16:24
const LinniaRecords = artifacts.require('./LinniaRecords.sol');
const LinniaPolicies = artifacts.require('./LinniaPolicies.sol');
const irisScoreProvider = artifacts.require('./mock/IrisScoreProviderMock.sol');
const Policy = artifacts.require('./mock/PolicyMock.sol');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider naming PolicyMock

@godfreyhobbs
Copy link
Contributor

consider adding the following to the 3_records_test.js and 5_records-token_test.js

  beforeEach('set up a LinniaPolicies contract', async () => {
    policiesInstance = await LinniaPolicies.new(hub.address);
    await hub.setPoliciesContract(policiesInstance.address);
  });
```

/* @param viewer the address of the person being given access the record */
/* @param dataUri where the record is */
/* @param policies an array of the policy conforming addresses */
function policyIsValid(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be internal

/* @param dataHash the dataHash of the record being checked */
/* @param viewer the address of the person being given access the record */
/* @param dataUri where the record is */
function followsExistingPolicies(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be internal

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I'll change

/* @param viewer the address of the person being given access the record */
/* @param dataUri where the record is */
/* @param policies an array of the policy conforming addresses */
function policiesAreValid(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be internal

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

People may want to reveal to people which policies their records and permissions can/will conform with from a UI. Keeping public also allows people to surface better error messages from the UI

public
returns (bool)
{
return policiesAreValid(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not inline this method. Seems easier to be calling policiesAreValid directly rather than using this wrapper and spending gas.


/* @dev allows a record owner to add a policy to a record as long as it conforms */
/* @param dataHash the record the owner is adding a policy to */
/* @param policy an address of a contract that conforms to the policy interface to add */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider rewording:
an address of a contract that conforms to the policy interface to add

require(hub.policiesContract().policyIsValid(
dataHash,
msg.sender,
records[dataHash].dataUri,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure why this check is needed. Can you explain?

policy
));

policies[dataHash].push(policy);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things:

  1. It would be good to revert if the policy has already been added.
  2. Also would be good to check for address(0)
  3. It would be good to check that this address conforms to the interface (not sure how todo this)

external
returns (bool)
{
/* @dev search through the policies for the record */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider reverting if nothing is deleted.

returns (bool)
{
/* @dev search through the policies for the record */
for (uint i = 0; i < policies[dataHash].length; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider saving policies[dataHash].length to local var. This may be doing the lookup for every loop.

}
}

return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would only return true if something was actually deleted.

/* @dev if one is found */
if (policies[dataHash][i] == policy) {
/* @dev remove the policy by shifting everything over and shortening array */
while (i < policies[dataHash].length - 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the swap method here it will use much less gas.

i++;
}

policies[dataHash].length--;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move return true here.

returns (bool)
{

require(_addRecord(dataHash, msg.sender, metadata, dataUri));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this come after the policy check? Please add a comment on why this is first.

require(_addRecord(dataHash, msg.sender, metadata, dataUri));

for (uint i = 0; i < newPolicies.length; i++) {
/* @dev make sure the record conforms with each of the policies,then add*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment suggest adding is after this but it is before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants