Skip to content

Commit

Permalink
WIP - #259 replacing un/shareVault with vaultsPermissionSet, `vau…
Browse files Browse the repository at this point in the history
…ltsPermissionGet` and `vaultsPermissionUnset`.
  • Loading branch information
tegefaulkes committed Feb 28, 2022
1 parent 5ad9d40 commit a23b7a9
Show file tree
Hide file tree
Showing 19 changed files with 392 additions and 1,004 deletions.
1 change: 1 addition & 0 deletions src/PolykeyAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ class PolykeyAgent {
sessionManager: this.sessionManager,
vaultManager: this.vaultManager,
sigchain: this.sigchain,
acl: this.acl,
grpcServerClient: this.grpcServerClient,
grpcServerAgent: this.grpcServerAgent,
fwdProxy: this.fwdProxy,
Expand Down
4 changes: 2 additions & 2 deletions src/bin/vaults/CommandPermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ class CommandPermissions extends CommandPolykey {

const data: Array<string> = [];
await binUtils.retryAuthentication(async (auth) => {
const permissionStream = pkClient.grpcClient.vaultsPermissionsGet(
const permissionStream = pkClient.grpcClient.vaultsPermissionGet(
vaultMessage,
auth,
);
for await (const permission of permissionStream) {
const nodeId = permission.getNode()?.getNodeId();
const actions = permission.getActionsList().join(', ');
const actions = permission.getVaultPermissionsList().join(', ');
data.push(`${nodeId}: ${actions}`);
}
return true;
Expand Down
15 changes: 10 additions & 5 deletions src/bin/vaults/CommandShare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,19 @@ class CommandShare extends CommandPolykey {
logger: this.logger.getChild(PolykeyClient.name),
});
const vaultMessage = new vaultsPB.Vault();
const nodeMessage = new nodesPB.Node();
const setVaultPermsMessage = new vaultsPB.PermSet();
setVaultPermsMessage.setVault(vaultMessage);
setVaultPermsMessage.setNode(nodeMessage);
vaultMessage.setNameOrId(vaultName);
const nodeMessage = new nodesPB.Node();
nodeMessage.setNodeId(nodesUtils.encodeNodeId(nodeId));
const vaultsPermissionsList = new vaultsPB.Permissions();
vaultsPermissionsList.setVault(vaultMessage);
vaultsPermissionsList.setNode(nodeMessage);
vaultsPermissionsList.setVaultPermissionsList(['pull', 'clone']);
await binUtils.retryAuthentication(
(auth) => pkClient.grpcClient.vaultsShare(setVaultPermsMessage, auth),
(auth) =>
pkClient.grpcClient.vaultsPermissionSet(
vaultsPermissionsList,
auth,
),
meta,
);
} finally {
Expand Down
14 changes: 9 additions & 5 deletions src/bin/vaults/CommandUnshare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,20 @@ class CommandUnshare extends CommandPolykey {
port: clientOptions.clientPort,
logger: this.logger.getChild(PolykeyClient.name),
});
const unsetVaultPermsMessage = new vaultsPB.PermUnset();
const vaultsPermissionsMessage = new vaultsPB.Permissions();
const vaultMessage = new vaultsPB.Vault();
const nodeMessage = new nodesPB.Node();
unsetVaultPermsMessage.setVault(vaultMessage);
unsetVaultPermsMessage.setNode(nodeMessage);
vaultMessage.setNameOrId(vaultName);
const nodeMessage = new nodesPB.Node();
nodeMessage.setNodeId(nodesUtils.encodeNodeId(nodeId));
vaultsPermissionsMessage.setVault(vaultMessage);
vaultsPermissionsMessage.setNode(nodeMessage);
vaultsPermissionsMessage.setVaultPermissionsList(['clone', 'pull']);
await binUtils.retryAuthentication(
(auth) =>
pkClient.grpcClient.vaultsUnshare(unsetVaultPermsMessage, auth),
pkClient.grpcClient.vaultsPermissionUnset(
vaultsPermissionsMessage,
auth,
),
meta,
);
} finally {
Expand Down
14 changes: 7 additions & 7 deletions src/client/GRPCClientClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,26 +186,26 @@ class GRPCClientClient extends GRPCClient<ClientServiceClient> {
}

@ready(new clientErrors.ErrorClientClientDestroyed())
public vaultsPermissionsGet(...args) {
return grpcUtils.promisifyReadableStreamCall<permissionsPB.NodeActions>(
public vaultsPermissionGet(...args) {
return grpcUtils.promisifyReadableStreamCall<vaultsPB.Permissions>(
this.client,
this.client.vaultsPermissionsGet,
this.client.vaultsPermissionGet,
)(...args);
}

@ready(new clientErrors.ErrorClientClientDestroyed())
public vaultsShare(...args) {
public vaultsPermissionSet(...args) {
return grpcUtils.promisifyUnaryCall<utilsPB.StatusMessage>(
this.client,
this.client.vaultsShare,
this.client.vaultsPermissionSet,
)(...args);
}

@ready(new clientErrors.ErrorClientClientDestroyed())
public vaultsUnshare(...args) {
public vaultsPermissionUnset(...args) {
return grpcUtils.promisifyUnaryCall<utilsPB.StatusMessage>(
this.client,
this.client.vaultsUnshare,
this.client.vaultsPermissionUnset,
)(...args);
}

Expand Down
14 changes: 8 additions & 6 deletions src/client/service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { NotificationsManager } from '../../notifications';
import type { Discovery } from '../../discovery';
import type { Sigchain } from '../../sigchain';
import type { GRPCServer } from '../../grpc';
import type ACL from '../../acl/ACL';
import type ForwardProxy from '../../network/ForwardProxy';
import type ReverseProxy from '../../network/ReverseProxy';
import type { IClientServiceServer } from '../../proto/js/polykey/v1/client_service_grpc_pb';
Expand Down Expand Up @@ -66,12 +67,12 @@ import vaultsCreate from './vaultsCreate';
import vaultsDelete from './vaultsDelete';
import vaultsList from './vaultsList';
import vaultsLog from './vaultsLog';
import vaultsPermissionsGet from './vaultsPermissionsGet';
import vaultsPermissionGet from './vaultsPermissionGet';
import vaultsPermissionSet from './vaultsPermissionSet';
import vaultsPermissionUnset from './vaultsPermissionUnset';
import vaultsPull from './vaultsPull';
import vaultsRename from './vaultsRename';
import vaultsScan from './vaultsScan';
import vaultsShare from './vaultsShare';
import vaultsUnshare from './vaultsUnshare';
import vaultsVersion from './vaultsVersion';
import vaultsSecretsDelete from './vaultsSecretsDelete';
import vaultsSecretsEdit from './vaultsSecretsEdit';
Expand Down Expand Up @@ -104,6 +105,7 @@ function createService({
notificationsManager: NotificationsManager;
discovery: Discovery;
sigchain: Sigchain;
acl: ACL;
grpcServerClient: GRPCServer;
grpcServerAgent: GRPCServer;
fwdProxy: ForwardProxy;
Expand Down Expand Up @@ -169,12 +171,12 @@ function createService({
vaultsDelete: vaultsDelete(container),
vaultsList: vaultsList(container),
vaultsLog: vaultsLog(container),
vaultsPermissionsGet: vaultsPermissionsGet(container),
vaultsPermissionSet: vaultsPermissionSet(container),
vaultsPermissionUnset: vaultsPermissionUnset(container),
vaultsPermissionGet: vaultsPermissionGet(container),
vaultsPull: vaultsPull(container),
vaultsRename: vaultsRename(container),
vaultsScan: vaultsScan(container),
vaultsShare: vaultsShare(container),
vaultsUnshare: vaultsUnshare(container),
vaultsVersion: vaultsVersion(container),
vaultsSecretsDelete: vaultsSecretsDelete(container),
vaultsSecretsEdit: vaultsSecretsEdit(container),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import type { Authenticate } from '../types';
import type { VaultManager } from '../../vaults';
import type { VaultName } from '../../vaults/types';
import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb';
import type * as grpc from '@grpc/grpc-js';
import { utils as grpcUtils } from '../../grpc';
import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb';
import * as permissionsPB from '../../proto/js/polykey/v1/permissions/permissions_pb';
import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb';
import * as validationUtils from '../../validation/utils';

function vaultsPermissionsGet({
function vaultsPermissionGet({
authenticate,
vaultManager,
}: {
authenticate: Authenticate;
vaultManager: VaultManager;
}) {
return async (
call: grpc.ServerWritableStream<vaultsPB.Vault, permissionsPB.NodeActions>,
call: grpc.ServerWritableStream<vaultsPB.Vault, vaultsPB.Permissions>,
): Promise<void> => {
const genWritable = grpcUtils.generatorWritable(call);
try {
Expand All @@ -29,20 +28,18 @@ function vaultsPermissionsGet({
vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId);

const permissionList = await vaultManager.getVaultPermission(vaultId);
const nodeActionsMessage = new permissionsPB.NodeActions();
const vaultPermissionsMessage = new vaultsPB.Permissions();
vaultPermissionsMessage.setVault(vaultMessage);
const nodeMessage = new nodesPB.Node();

// Constructing the message.
for (const nodeId in permissionList) {
nodeMessage.setNodeId(nodeId);
nodeActionsMessage.setNode(nodeMessage);
nodeActionsMessage.clearActionsList();
for (const action in permissionList[nodeId]) {
nodeActionsMessage.addActions(action);
}
await genWritable.next(nodeActionsMessage);
vaultPermissionsMessage.setNode(nodeMessage);
const actions = Object.keys(permissionList[nodeId]);
vaultPermissionsMessage.setVaultPermissionsList(actions);
await genWritable.next(vaultPermissionsMessage);
}

await genWritable.next(null);
return;
} catch (err) {
Expand All @@ -52,4 +49,4 @@ function vaultsPermissionsGet({
};
}

export default vaultsPermissionsGet;
export default vaultsPermissionGet;
82 changes: 82 additions & 0 deletions src/client/service/vaultsPermissionSet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import type { Authenticate } from '../types';
import type { VaultName } from '../../vaults/types';
import type { VaultManager } from '../../vaults';
import type GestaltGraph from '../../gestalts/GestaltGraph';
import type ACL from '../../acl/ACL';
import type NotificationsManager from '../../notifications/NotificationsManager';
import type { VaultActions } from '../../vaults/types';
import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb';
import * as grpc from '@grpc/grpc-js';
import * as vaultsUtils from 'vaults/utils';
import * as vaultsErrors from 'vaults/errors';
import * as validationUtils from '../../validation/utils';
import { utils as grpcUtils } from '../../grpc';
import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb';

function vaultsPermissionSet({
vaultManager,
authenticate,
gestaltGraph,
acl,
notificationsManager,
}: {
vaultManager: VaultManager;
authenticate: Authenticate;
gestaltGraph: GestaltGraph;
acl: ACL;
notificationsManager: NotificationsManager;
}) {
return async (
call: grpc.ServerUnaryCall<vaultsPB.Permissions, utilsPB.StatusMessage>,
callback: grpc.sendUnaryData<utilsPB.StatusMessage>,
): Promise<void> => {
try {
// Checking session token
const metadata = await authenticate(call.metadata);
call.sendMetadata(metadata);
const vaultsPermissionsMessage = call.request;
const vaultMessage = vaultsPermissionsMessage.getVault();
const nodeMessage = vaultsPermissionsMessage.getNode();
if (vaultMessage == null || nodeMessage == null) {
callback({ code: grpc.status.NOT_FOUND }, null);
return;
}
// Parsing VaultId
const nameOrId = vaultMessage.getNameOrId();
let vaultId = await vaultManager.getVaultId(nameOrId as VaultName);
vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId);
// Parsing NodeId
const nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId());
// Parsing actions
const actions = vaultsPermissionsMessage
.getVaultPermissionsList()
.map((vaultAction) => validationUtils.parseVaultAction(vaultAction));
// Checking if vault exists
const vaultMeta = await vaultManager.getVaultMeta(vaultId);
if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined();
// Setting permissions
await gestaltGraph.setGestaltActionByNode(nodeId, 'scan');
const actionsSet: VaultActions = {};
for (const action of actions) {
await acl.setVaultAction(vaultId, nodeId, action);
actionsSet[action] = null;
}
// Sending notification
await notificationsManager.sendNotification(nodeId, {
type: 'VaultShare',
vaultId: vaultsUtils.encodeVaultId(vaultId),
vaultName: vaultMeta.vaultName,
actions: actionsSet,
});
// Formatting response
const response = new utilsPB.StatusMessage().setSuccess(true);
callback(null, response);
return;
} catch (e) {
callback(grpcUtils.fromError(e));
return;
}
};
}

export default vaultsPermissionSet;
77 changes: 77 additions & 0 deletions src/client/service/vaultsPermissionUnset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import type { Authenticate } from '../types';
import type { VaultName } from '../../vaults/types';
import type { VaultManager } from '../../vaults';
import type GestaltGraph from '../../gestalts/GestaltGraph';
import type ACL from '../../acl/ACL';
import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb';
import * as grpc from '@grpc/grpc-js';
import * as vaultsErrors from 'vaults/errors';
import * as validationUtils from '../../validation/utils';
import { utils as grpcUtils } from '../../grpc';
import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb';

function vaultsPermissionUnset({
vaultManager,
authenticate,
gestaltGraph,
acl,
}: {
vaultManager: VaultManager;
authenticate: Authenticate;
gestaltGraph: GestaltGraph;
acl: ACL;
}) {
return async (
call: grpc.ServerUnaryCall<vaultsPB.Permissions, utilsPB.StatusMessage>,
callback: grpc.sendUnaryData<utilsPB.StatusMessage>,
): Promise<void> => {
try {
// Checking session token
const metadata = await authenticate(call.metadata);
call.sendMetadata(metadata);
const vaultsPermissionsMessage = call.request;
const vaultMessage = vaultsPermissionsMessage.getVault();
const nodeMessage = vaultsPermissionsMessage.getNode();
if (vaultMessage == null || nodeMessage == null) {
callback({ code: grpc.status.NOT_FOUND }, null);
return;
}
// Parsing VaultId
const nameOrId = vaultMessage.getNameOrId();
let vaultId = await vaultManager.getVaultId(nameOrId as VaultName);
vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId);
// Parsing NodeId
const nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId());
// Parsing actions
const actions = vaultsPermissionsMessage
.getVaultPermissionsList()
.map((vaultAction) => validationUtils.parseVaultAction(vaultAction));
// Checking if vault exists
const vaultMeta = await vaultManager.getVaultMeta(vaultId);
if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined();
// Unsetting permissions
await gestaltGraph.setGestaltActionByNode(nodeId, 'scan');
for (const action of actions) {
await acl.unsetVaultAction(vaultId, nodeId, action);
}
// We need to check if there are still shared vaults.
const nodePermissions = await acl.getNodePerm(nodeId);
// Remove scan permissions if no more shared vaults
if (
nodePermissions != null &&
Object.keys(nodePermissions.vaults).length === 0
) {
await gestaltGraph.unsetGestaltActionByNode(nodeId, 'scan');
}
// Formatting response
const response = new utilsPB.StatusMessage().setSuccess(true);
callback(null, response);
return;
} catch (e) {
callback(grpcUtils.fromError(e));
return;
}
};
}

export default vaultsPermissionUnset;
Loading

0 comments on commit a23b7a9

Please sign in to comment.