Skip to content
This repository has been archived by the owner on Jan 3, 2022. It is now read-only.

Commit

Permalink
Add hasPermissions methods (#123)
Browse files Browse the repository at this point in the history
* Add hasPermissions methods

* Add tests, update coverage scripts
  • Loading branch information
rekmarks authored Dec 10, 2020
1 parent 5f7542e commit 3888429
Show file tree
Hide file tree
Showing 14 changed files with 173 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ dist/
.python-version
*.log
.nyc_output
coverage
4 changes: 0 additions & 4 deletions .nycrc

This file was deleted.

38 changes: 34 additions & 4 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@ export class CapabilitiesController extends BaseController<any, any> implements
return engine;
}

/**
* Checks the permissions for the given domain, or an empty array.
*
* @param domain - The domain whose permissions to retrieve.
* @returns The permissions for the domain.
*/
getPermissionsForDomain (domain: string): IOcapLdCapability[] {
const { domains = {} } = this.state;
if (domains[domain]) {
Expand All @@ -324,19 +330,43 @@ export class CapabilitiesController extends BaseController<any, any> implements
* Follows the delegation chain of the first matching permission found.
*
* @param {string} domain - The domain whose permission to retrieve.
* @param {string} method - The method
* @param {string} method - The method of the permission to retrieve.
*/
getPermission (domain: string, method: string): IOcapLdCapability | undefined {
const permissions = this.getPermissionsForDomain(domain).filter(p => {
return p.parentCapability === method;
});
const permissions = this.getPermissionsForDomain(domain)
.filter(permission => {
return permission.parentCapability === method;
});
if (permissions.length > 0) {
return permissions.shift();
}

return undefined;
}

/**
* Checks whether the given domain has permissions.
*
* @param domain - The domain to check.
* @returns Whether the given domain has any permissions.
*/
hasPermissions (domain: string): boolean {
return Boolean(this.state.domains?.[domain]);
}

/**
* Checks whether the given domain has the given permission.
*
* @param domain - The domain to check.
* @param method - The method of the permission to check for.
* @returns Whether the given domain has the given permission.
*/
hasPermission (domain: string, method: string): boolean {
return this.getPermissionsForDomain(domain).some(permission => {
return permission.parentCapability === method;
});
}

/**
* Gets current permissions request objects.
* Useful for displaying information for user consent.
Expand Down
3 changes: 3 additions & 0 deletions nyc.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: '@istanbuljs/nyc-config-typescript',
};
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"lint:fix": "eslint --ext .ts,.js --fix .",
"prepublishOnly": "yarn build",
"test": "yarn build:typescript && node test",
"test:coverage": "nyc node test"
"coverage": "nyc node test",
"coverage:html": "nyc --reporter=html node test"
},
"keywords": [],
"author": "",
Expand All @@ -29,11 +30,12 @@
"@types/uuid": "^3.4.4",
"@typescript-eslint/eslint-plugin": "^2.17.0",
"@typescript-eslint/parser": "^2.17.0",
"clone": "^2.1.2",
"eslint": "^6.8.0",
"fast-deep-equal": "^2.0.1",
"nyc": "^15.0.0",
"tape": "^4.9.2",
"typescript": "^4.0.3"
"typescript": "^4.1.2"
},
"dependencies": {
"@metamask/controllers": "^5.0.0",
Expand Down
4 changes: 2 additions & 2 deletions test/caveats.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// / <reference path="../index.ts" />

const test = require('tape');
const CapabilitiesController = require('../dist').CapabilitiesController;
const sendRpcMethodWithResponse = require('./lib/utils').sendRpcMethodWithResponse;
const { CapabilitiesController } = require('../dist');
const { sendRpcMethodWithResponse } = require('./lib/utils');

const UNAUTHORIZED_CODE = require('eth-rpc-errors').ERROR_CODES.provider.unauthorized;

Expand Down
2 changes: 1 addition & 1 deletion test/dependentPermissions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const test = require('tape');
const CapabilitiesController = require('../dist').CapabilitiesController;
const { CapabilitiesController } = require('../dist');
const JsonRpcEngine = require('json-rpc-engine');

test('restricted permission gets restricted provider', async (t) => {
Expand Down
2 changes: 1 addition & 1 deletion test/forwarding.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const test = require('tape');
const CapabilitiesController = require('../dist').CapabilitiesController;
const { CapabilitiesController } = require('../dist');

const UNAUTHORIZED_CODE = require('eth-rpc-errors').ERROR_CODES.provider.unauthorized;
const METHOD_NOT_FOUND_CODE = require('eth-rpc-errors').ERROR_CODES.rpc.methodNotFound;
Expand Down
2 changes: 1 addition & 1 deletion test/getPermissions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const test = require('tape');
const CapabilitiesController = require('../dist').CapabilitiesController;
const { CapabilitiesController } = require('../dist');
const equal = require('fast-deep-equal');

function noop () {}
Expand Down
118 changes: 118 additions & 0 deletions test/hasPermissions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
const test = require('tape');
const { CapabilitiesController } = require('../dist');
const clone = require('clone');

function noop () {}

const domain1 = 'foo.com';
const domain2 = 'bar.io';

const method1 = 'restricted';
const method2 = 'restricted2';

const domains = {
[domain1]: {
permissions: [
{
parentCapability: method1,
id: 'abc',
},
],
},
[domain2]: {
permissions: [
{
parentCapability: method2,
id: 'xyz',
},
],
},
};

test('hasPermissions returns false if no permissions', (t) => {
const ctrl = new CapabilitiesController({
requestUserApproval: noop,
});

t.equal(ctrl.hasPermissions(domain1), false, 'should return false');
t.end();
});

test('hasPermission returns false if no permissions', (t) => {
const ctrl = new CapabilitiesController({
requestUserApproval: noop,
});

t.equal(ctrl.hasPermissions(domain1, method1), false, 'should return false');
t.end();
});

test('hasPermissions returns true with permissions', (t) => {
const ctrl = new CapabilitiesController({
requestUserApproval: noop,
},
{
domains: clone(domains),
});

t.equal(ctrl.hasPermissions(domain1), true, 'should return true for domain1');
t.equal(ctrl.hasPermissions(domain2), true, 'should return true for domain2');
t.end();
});

test('hasPermission returns true with permissions and correct method', (t) => {
const ctrl = new CapabilitiesController({
requestUserApproval: noop,
},
{
domains: clone(domains),
});

t.equal(
ctrl.hasPermission(domain1, method1),
true,
'should return true for domain1 and method1'
);
t.equal(
ctrl.hasPermission(domain2, method2),
true,
'should return true for domain2 and method2'
);
t.end();
});

test('hasPermissions returns with permissions but wrong domain', (t) => {
const ctrl = new CapabilitiesController({
requestUserApproval: noop,
},
{
domains: {
[domain1]: clone(domains[domain1]),
},
});

t.equal(ctrl.hasPermissions(domain1), true, 'should return true for domain1');
t.equal(ctrl.hasPermissions(domain2), false, 'should return false for domain2');
t.end();
});

test('hasPermission returns false with permissions but wrong method', (t) => {
const ctrl = new CapabilitiesController({
requestUserApproval: noop,
},
{
domains: clone(domains),
});

t.equal(
ctrl.hasPermission(domain1, method2),
false,
'should return false for domain1 and method2'
);
t.equal(
ctrl.hasPermission(domain2, method1),
false,
'should return false for domain2 and method1'
);
t.end();
});
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require('./forwarding');
require('./getPermissions');
require('./hasPermissions');
require('./requestPermissions');
require('./caveats');
require('./wildcardPermissions');
Expand Down
2 changes: 1 addition & 1 deletion test/requestPermissions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const test = require('tape');
const CapabilitiesController = require('../dist').CapabilitiesController;
const { CapabilitiesController } = require('../dist');
const equal = require('fast-deep-equal');
const rpcErrors = require('eth-rpc-errors');

Expand Down
2 changes: 1 addition & 1 deletion test/wildcardPermissions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const test = require('tape');
const CapabilitiesController = require('../dist').CapabilitiesController;
const { CapabilitiesController } = require('../dist');

const UNAUTHORIZED_CODE = require('eth-rpc-errors').ERROR_CODES.provider.unauthorized;

Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ cliui@^6.0.0:
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"

clone@^2.0.0, clone@^2.1.1:
clone@^2.0.0, clone@^2.1.1, clone@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
Expand Down Expand Up @@ -3482,10 +3482,10 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"

typescript@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.3.tgz#153bbd468ef07725c1df9c77e8b453f8d36abba5"
integrity sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg==
typescript@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.2.tgz#6369ef22516fe5e10304aae5a5c4862db55380e9"
integrity sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==

unorm@^1.3.3:
version "1.6.0"
Expand Down

0 comments on commit 3888429

Please sign in to comment.