Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: map permission and permissions docs section #436

Merged
merged 7 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 68 additions & 48 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,14 @@ import {
encodeValueContent,
decodeValueContent,
} from './lib/encoder';
import { internalSupportsInterface, checkPermissions } from './lib/detector';
import { internalSupportsInterface } from './lib/detector';
import { decodeMappingKey } from './lib/decodeMappingKey';
import { encodePermissions, decodePermissions } from './lib/permissions';
import {
encodePermissions,
decodePermissions,
checkPermissions,
mapPermission,
} from './lib/permissions';
import { AssetURLEncode } from './types/encodeData';
import { URLDataToEncode, URLDataWithHash, Verification } from './types';

Expand All @@ -95,8 +100,12 @@ export {
decodeValueContent,
} from './lib/encoder';
export { getDataFromExternalSources } from './lib/getDataFromExternalSources';
export { encodePermissions, decodePermissions } from './lib/permissions';
export { checkPermissions } from './lib/detector';
export {
encodePermissions,
decodePermissions,
checkPermissions,
mapPermission,
} from './lib/permissions';
export { getSchema } from './lib/schemaParser';

// PRIVATE FUNCTION
Expand Down Expand Up @@ -502,50 +511,6 @@ export class ERC725 {
);
}

/**
* Encode permissions into a hexadecimal string as defined by the LSP6 KeyManager Standard.
*
* @link https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-6-KeyManager.md LSP6 KeyManager Standard.
* @param permissions The permissions you want to specify to be included or excluded. Any ommitted permissions will default to false.
* @returns {*} The permissions encoded as a hexadecimal string as defined by the LSP6 Standard.
*/
static encodePermissions(permissions: Permissions): string {
return encodePermissions(permissions);
}

/**
* Encode permissions into a hexadecimal string as defined by the LSP6 KeyManager Standard.
*
* @link https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-6-KeyManager.md LSP6 KeyManager Standard.
* @param permissions The permissions you want to specify to be included or excluded. Any ommitted permissions will default to false.
* @returns {*} The permissions encoded as a hexadecimal string as defined by the LSP6 Standard.
*/
encodePermissions(permissions: Permissions): string {
return encodePermissions(permissions);
}

/**
* Decodes permissions from hexadecimal as defined by the LSP6 KeyManager Standard.
*
* @link https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-6-KeyManager.md LSP6 KeyManager Standard.
* @param permissionHex The permission hexadecimal value to be decoded.
* @returns Object specifying whether default LSP6 permissions are included in provided hexademical string.
*/
static decodePermissions(permissionHex: string) {
return decodePermissions(permissionHex);
}

/**
* Decodes permissions from hexadecimal as defined by the LSP6 KeyManager Standard.
*
* @link https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-6-KeyManager.md LSP6 KeyManager Standard.
* @param permissionHex The permission hexadecimal value to be decoded.
* @returns Object specifying whether default LSP6 permissions are included in provided hexademical string.
*/
decodePermissions(permissionHex: string) {
return decodePermissions(permissionHex);
}

/**
* Hashes a key name for use on an ERC725Y contract according to LSP2 ERC725Y JSONSchema standard.
*
Expand Down Expand Up @@ -634,6 +599,53 @@ export class ERC725 {
return supportsInterface(interfaceIdOrName, options);
}

// Permissions related functions
// -----------------------------

/**
* Encode permissions into a hexadecimal string as defined by the LSP6 KeyManager Standard.
*
* @link https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-6-KeyManager.md LSP6 KeyManager Standard.
* @param permissions The permissions you want to specify to be included or excluded. Any ommitted permissions will default to false.
* @returns {*} The permissions encoded as a hexadecimal string as defined by the LSP6 Standard.
*/
static encodePermissions(permissions: Permissions): string {
return encodePermissions(permissions);
}

/**
* Encode permissions into a hexadecimal string as defined by the LSP6 KeyManager Standard.
*
* @link https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-6-KeyManager.md LSP6 KeyManager Standard.
* @param permissions The permissions you want to specify to be included or excluded. Any ommitted permissions will default to false.
* @returns {*} The permissions encoded as a hexadecimal string as defined by the LSP6 Standard.
*/
encodePermissions(permissions: Permissions): string {
return encodePermissions(permissions);
}

/**
* Decodes permissions from hexadecimal as defined by the LSP6 KeyManager Standard.
*
* @link https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-6-KeyManager.md LSP6 KeyManager Standard.
* @param permissionHex The permission hexadecimal value to be decoded.
* @returns Object specifying whether default LSP6 permissions are included in provided hexademical string.
*/
static decodePermissions(permissionHex: string) {
return decodePermissions(permissionHex);
}

/**
* Decodes permissions from hexadecimal as defined by the LSP6 KeyManager Standard.
*
* @link https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-6-KeyManager.md LSP6 KeyManager Standard.
* @param permissionHex The permission hexadecimal value to be decoded.
* @returns Object specifying whether default LSP6 permissions are included in provided hexademical string.
*/
decodePermissions(permissionHex: string) {
return decodePermissions(permissionHex);
}

/**
* Check if the required permissions are included in the granted permissions as defined by the LSP6 KeyManager Standard.
*
Expand Down Expand Up @@ -664,6 +676,14 @@ export class ERC725 {
return checkPermissions(requiredPermissions, grantedPermissions);
}

static mapPermission(permission: string): string | null {
return mapPermission(permission);
}

mapPermission(permission: string): string | null {
return mapPermission(permission);
}

encodeDataSourceWithHash(
verification: undefined | Verification,
dataSource: string,
Expand Down
164 changes: 1 addition & 163 deletions src/lib/detector.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { expect } from 'chai';
import * as sinon from 'sinon';
import { INTERFACE_IDS_0_12_0 } from '../constants/interfaces';

import { internalSupportsInterface, checkPermissions } from './detector';
import { internalSupportsInterface } from './detector';

describe('supportsInterface', () => {
it('it should return true if the contract supports the interface with name', async () => {
Expand Down Expand Up @@ -66,165 +66,3 @@ describe('supportsInterface', () => {
expect(doesSupportInterface).to.be.true;
});
});

describe('checkPermissions', () => {
describe('test with single permission', () => {
it('should throw an error when given an invalid permission string', async () => {
const requiredPermissions = 'INVALIDPERMISSION';
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000ff51';
expect(() =>
checkPermissions(requiredPermissions, grantedPermissions),
).to.throw(
'Invalid permission string. It must be a valid 32-byte hex string or a known permission name.',
);
});

it('should throw an error when given an invalid 32-byte hex string', async () => {
const requiredPermissions = '0xinvalidhexstring';
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000ff51';
expect(() =>
checkPermissions(requiredPermissions, grantedPermissions),
).to.throw(
'Invalid permission string. It must be a valid 32-byte hex string or a known permission name.',
);
});

it('should throw an error when given an invalid grantedPermission 32-byte hex string', async () => {
const requiredPermissions = 'CHANGEOWNER';
const grantedPermissions = '0xinvalidgrantedpermissionhexstring';
expect(() =>
checkPermissions(requiredPermissions, grantedPermissions),
).to.throw(
'Invalid grantedPermissions string. It must be a valid 32-byte hex string.',
);
});

it('should return true when single literal permission matches granted permissions', async () => {
const requiredPermissions = 'CHANGEOWNER';
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000ff51';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.true;
});

it('should return true when single bytes32 permission matches granted permissions', async () => {
const requiredPermissions =
'0x0000000000000000000000000000000000000000000000000000000000000001';
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000ff51';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.true;
});

it('should return false when single bytes32 permission does not match granted permissions', async () => {
const requiredPermissions =
'0x0000000000000000000000000000000000000000000000000000000000000001';
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000fff2';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.false;
});

it('should return false when single literal permission does not match granted permissions', async () => {
const requiredPermissions = 'CHANGEOWNER';
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000fff2';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.false;
});
});

describe('test with multiple permissions', () => {
it('should throw an error when given an array containing an invalid permission string', async () => {
const requiredPermissions = ['CHANGEOWNER', 'INVALIDPERMISSION'];
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000ff51';
expect(() =>
checkPermissions(requiredPermissions, grantedPermissions),
).to.throw(
'Invalid permission string. It must be a valid 32-byte hex string or a known permission name.',
);
});

it('should throw an error when given an array containing an invalid 32-byte hex string', async () => {
const requiredPermissions = ['CHANGEOWNER', '0xinvalidhexstring'];
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000ff51';
expect(() =>
checkPermissions(requiredPermissions, grantedPermissions),
).to.throw(
'Invalid permission string. It must be a valid 32-byte hex string or a known permission name.',
);
});

it('should return false when one of the literal permissions does not match granted permissions', async () => {
const requiredPermissions = ['EDITPERMISSIONS', 'CALL'];
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000ff51';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.false;
});

it('should return false when one of the bytes32 permissions does not match granted permissions', async () => {
const requiredPermissions = [
'0x0000000000000000000000000000000000000000000000000000000000000004',
'0x0000000000000000000000000000000000000000000000000000000000000800',
];
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000ff51';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.false;
});

it('should return true when all the mixed literal and bytes32 permissions match granted permissions', async () => {
const requiredPermissions = [
'EDITPERMISSIONS',
'0x0000000000000000000000000000000000000000000000000000000000000800',
];
const grantedPermissions =
'0x000000000000000000000000000000000000000000000000000000000000ff54';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.true;
});

it('should return false when not all multiple literal permissions match granted permissions', async () => {
const requiredPermissions = ['CHANGEOWNER', 'CALL'];
const grantedPermissions =
'0x0000000000000000000000000000000000000000000000000000000000000051';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.false;
});

it('should return true when all multiple literal permissions match granted permissions', async () => {
const requiredPermissions = ['CHANGEOWNER', 'CALL'];
const grantedPermissions =
'0x0000000000000000000000000000000000000000000000000000000000000801';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.true;
});

it('should return false when not all multiple bytes32 permissions match granted permissions', async () => {
const requiredPermissions = [
'0x0000000000000000000000000000000000000000000000000000000000000001',
'0x0000000000000000000000000000000000000000000000000000000000000800',
];
const grantedPermissions =
'0x0000000000000000000000000000000000000000000000000000000000000051';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.false;
});

it('should return false when not all mixed literal and bytes32 permissions match granted permissions', async () => {
const requiredPermissions = [
'CHANGEOWNER',
'0x0000000000000000000000000000000000000000000000000000000000000800',
];
const grantedPermissions =
'0x0000000000000000000000000000000000000000000000000000000000000051';
const result = checkPermissions(requiredPermissions, grantedPermissions);
expect(result).to.be.false;
});
});
});
Loading
Loading