Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
249 changes: 207 additions & 42 deletions packages/snaps-controllers/src/snaps/SnapController.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6074,6 +6074,19 @@ describe('SnapController', () => {
() => ({}),
);

rootMessenger.registerActionHandler(
Copy link
Member Author

Choose a reason for hiding this comment

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

Made changes to some tests that were improperly emulating the PermissionController and would cause the permissions re-sync when unnecessary

'PermissionController:grantPermissions',
() => {
// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

return {};
},
);

const preinstalledSnaps = [
{
snapId: MOCK_SNAP_ID,
Expand Down Expand Up @@ -6120,12 +6133,6 @@ describe('SnapController', () => {
true,
);

// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

const result = await snapController.handleRequest({
snapId: MOCK_SNAP_ID,
origin: MOCK_ORIGIN,
Expand Down Expand Up @@ -6236,6 +6243,19 @@ describe('SnapController', () => {
() => ({}),
);

rootMessenger.registerActionHandler(
'PermissionController:grantPermissions',
() => {
// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

return {};
},
);

const initialConnections = {
'npm:filsnap': {},
'https://snaps.metamask.io': {},
Expand Down Expand Up @@ -6279,12 +6299,6 @@ describe('SnapController', () => {
},
};

// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

expect(snapControllerOptions.messenger.call).toHaveBeenCalledWith(
'PermissionController:grantPermissions',
{ approvedPermissions, subject: { origin: 'npm:filsnap' } },
Expand All @@ -6311,6 +6325,19 @@ describe('SnapController', () => {
() => ({}),
);

rootMessenger.registerActionHandler(
'PermissionController:grantPermissions',
() => {
// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

return {};
},
);

const preinstalledSnaps = [
{
snapId: MOCK_SNAP_ID,
Expand Down Expand Up @@ -6350,12 +6377,6 @@ describe('SnapController', () => {
},
);

// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

expect(
await snapController.installSnaps(MOCK_ORIGIN, {
[MOCK_SNAP_ID]: {},
Expand Down Expand Up @@ -6403,6 +6424,29 @@ describe('SnapController', () => {
},
];

rootMessenger.registerActionHandler(
'PermissionController:grantPermissions',
() => {
// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => ({
[SnapEndowments.Rpc]: MOCK_SNAP_PERMISSIONS[SnapEndowments.Rpc],
// eslint-disable-next-line @typescript-eslint/naming-convention
snap_getEntropy: {
caveats: null,
date: 1664187844588,
id: 'izn0WGUO8cvq_jqvLQuQP',
invoker: MOCK_SNAP_ID,
parentCapability: 'snap_getEntropy',
},
}),
);

return {};
},
);

const snapControllerOptions = getSnapControllerWithEESOptions({
preinstalledSnaps,
rootMessenger,
Expand Down Expand Up @@ -6447,22 +6491,6 @@ describe('SnapController', () => {
true,
);

// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => ({
[SnapEndowments.Rpc]: MOCK_SNAP_PERMISSIONS[SnapEndowments.Rpc],
// eslint-disable-next-line @typescript-eslint/naming-convention
snap_getEntropy: {
caveats: null,
date: 1664187844588,
id: 'izn0WGUO8cvq_jqvLQuQP',
invoker: MOCK_SNAP_ID,
parentCapability: 'snap_getEntropy',
},
}),
);

const result = await snapController.handleRequest({
snapId: MOCK_SNAP_ID,
origin: MOCK_ORIGIN,
Expand Down Expand Up @@ -6516,6 +6544,19 @@ describe('SnapController', () => {
() => ({}),
);

rootMessenger.registerActionHandler(
'PermissionController:grantPermissions',
() => {
// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

return {};
},
);

const { manifest } = await getMockSnapFilesWithUpdatedChecksum({
manifest: getSnapManifest({
proposedName: '{{ proposedName }}',
Expand Down Expand Up @@ -6567,12 +6608,6 @@ describe('SnapController', () => {
},
);

// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

const result = await snapController.handleRequest({
snapId: MOCK_SNAP_ID,
origin: MOCK_ORIGIN,
Expand Down Expand Up @@ -6674,6 +6709,19 @@ describe('SnapController', () => {
() => ({}),
);

rootMessenger.registerActionHandler(
'PermissionController:grantPermissions',
() => {
// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

return {};
},
);

const preinstalledSnaps = [
{
snapId: MOCK_SNAP_ID,
Expand Down Expand Up @@ -6713,6 +6761,19 @@ describe('SnapController', () => {
() => ({}),
);

rootMessenger.registerActionHandler(
'PermissionController:grantPermissions',
() => {
// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

return {};
},
);

const preinstalledSnaps = [
{
snapId: MOCK_SNAP_ID,
Expand Down Expand Up @@ -6742,6 +6803,83 @@ describe('SnapController', () => {
snapController.destroy();
});

it('recovers if preinstalled permissions are out of sync', async () => {
const rootMessenger = getControllerMessenger();
jest.spyOn(rootMessenger, 'call');
const log = jest.spyOn(console, 'warn').mockImplementation();

// Never persist any granted permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => ({}),
);

const preinstalledSnaps = [
{
snapId: MOCK_SNAP_ID,
manifest: getSnapManifest(),
hidden: true,
files: [
{
path: DEFAULT_SOURCE_PATH,
value: stringToBytes(DEFAULT_SNAP_BUNDLE),
},
{
path: DEFAULT_ICON_PATH,
value: stringToBytes(DEFAULT_SNAP_ICON),
},
],
},
];

const snapControllerOptions = getSnapControllerWithEESOptions({
preinstalledSnaps,
rootMessenger,
});
const [snapController] = getSnapControllerWithEES(snapControllerOptions);

expect(log).toHaveBeenCalledWith(
'The permissions for "npm:@metamask/example-snap" were out of sync and have been automatically restored. If you see this message, please file a bug report.',
);

// We expect two calls as we mock the PermissionController to always return an empty set.
expect(snapControllerOptions.messenger.call).toHaveBeenNthCalledWith(
3,
'PermissionController:grantPermissions',
{
approvedPermissions: {
// eslint-disable-next-line @typescript-eslint/naming-convention
snap_dialog: {},
[SnapEndowments.Rpc]: {
caveats: [
{ type: 'rpcOrigin', value: { dapps: false, snaps: true } },
],
},
},
subject: { origin: MOCK_SNAP_ID },
},
);

expect(snapControllerOptions.messenger.call).toHaveBeenNthCalledWith(
6,
'PermissionController:grantPermissions',
{
approvedPermissions: {
// eslint-disable-next-line @typescript-eslint/naming-convention
snap_dialog: {},
[SnapEndowments.Rpc]: {
caveats: [
{ type: 'rpcOrigin', value: { dapps: false, snaps: true } },
],
},
},
subject: { origin: MOCK_SNAP_ID },
},
);

snapController.destroy();
});

it('supports onInstall for preinstalled Snaps', async () => {
const rootMessenger = getControllerMessenger();
jest.spyOn(rootMessenger, 'call');
Expand Down Expand Up @@ -6782,7 +6920,7 @@ describe('SnapController', () => {
await new Promise((resolve) => setTimeout(resolve, 10));

expect(messenger.call).toHaveBeenNthCalledWith(
6,
7,
'ExecutionService:handleRpcRequest',
MOCK_SNAP_ID,
{
Expand Down Expand Up @@ -6848,7 +6986,7 @@ describe('SnapController', () => {
await new Promise((resolve) => setTimeout(resolve, 10));

expect(messenger.call).toHaveBeenNthCalledWith(
6,
7,
'ExecutionService:handleRpcRequest',
MOCK_SNAP_ID,
{
Expand Down Expand Up @@ -10438,6 +10576,33 @@ describe('SnapController', () => {
];

const rootMessenger = getControllerMessenger();

rootMessenger.registerActionHandler(
'PermissionController:revokeAllPermissions',
() => {
// After revoking the snap should have no permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => ({}),
);

return {};
},
);

rootMessenger.registerActionHandler(
'PermissionController:grantPermissions',
() => {
// After install the snap should have permissions
rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => MOCK_SNAP_PERMISSIONS,
);

return {};
},
);

const messenger = getSnapControllerMessenger(rootMessenger);
const snapController = getSnapController(
getSnapControllerOptions({
Expand Down
Loading
Loading