From fe0e02a4214b74808c811638e5a0937f34714d1d Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 21 Feb 2020 10:31:10 -0500 Subject: [PATCH] restrict access to metadata --- lib/commands/channel.js | 2 ++ lib/commands/metadata.js | 31 +++++++++++++++++++++++++++++-- lib/hk-util.js | 4 ++-- lib/rpc.js | 10 +++++----- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/commands/channel.js b/lib/commands/channel.js index 6296aee0e..da4fb6685 100644 --- a/lib/commands/channel.js +++ b/lib/commands/channel.js @@ -261,6 +261,8 @@ Channel.writePrivateMessage = function (Env, args, cb, Server) { msg // the actual message content. Generally a string ]; + // XXX RESTRICT respect allow lists + // historyKeeper already knows how to handle metadata and message validation, so we just pass it off here // if the message isn't valid it won't be stored. Env.historyKeeper.channelMessage(Server, channelStruct, fullMessage); diff --git a/lib/commands/metadata.js b/lib/commands/metadata.js index 5b6d17493..21132dd23 100644 --- a/lib/commands/metadata.js +++ b/lib/commands/metadata.js @@ -2,16 +2,21 @@ const Data = module.exports; const Meta = require("../metadata"); -const BatchRead = require("../batch-read"); const WriteQueue = require("../write-queue"); const Core = require("./core"); const Util = require("../common-util"); const HK = require("../hk-util"); -Data.getMetadata = function (Env, channel, cb/* , Server */) { +Data.getMetadataRaw = function (Env, channel /* channelName */, _cb) { + const cb = Util.once(Util.mkAsync(_cb)); if (!Core.isValidId(channel)) { return void cb('INVALID_CHAN'); } if (channel.length !== HK.STANDARD_CHANNEL_LENGTH) { return cb("INVALID_CHAN_LENGTH"); } + var cached = Env.metadata_cache[channel]; + if (HK.isMetadataMessage(cached)) { + return void cb(void 0, cached); + } + Env.batchMetadata(channel, cb, function (done) { var ref = {}; var lineHandler = Meta.createLineHandler(ref, Env.Log.error); @@ -25,6 +30,28 @@ Data.getMetadata = function (Env, channel, cb/* , Server */) { }); }; +Data.getMetadata = function (Env, channel, cb, Server, netfluxId) { + Data.getMetadataRaw(Env, channel, function (err, metadata) { + if (err) { return void cb(err); } + + if (!(metadata && metadata.restricted)) { + // if it's not restricted then just call back + return void cb(void 0, metadata); + } + + const session = HK.getNetfluxSession(Env, netfluxId); + const allowed = HK.listAllowedUsers(metadata); + + if (!HK.isUserSessionAllowed(allowed, session)) { + return void cb(void 0, { + restricted: metadata.restricted, + allowed: allowed, + }); + } + cb(void 0, metadata); + }); +}; + /* setMetadata - write a new line to the metadata log if a valid command is provided - data is an object: { diff --git a/lib/hk-util.js b/lib/hk-util.js index e14975a1a..fe14c47dc 100644 --- a/lib/hk-util.js +++ b/lib/hk-util.js @@ -71,7 +71,7 @@ const sliceCpIndex = function (cpIndex, line) { return start.concat(end); }; -const isMetadataMessage = function (parsed) { +const isMetadataMessage = HK.isMetadataMessage = function (parsed) { return Boolean(parsed && parsed.channel); }; @@ -186,7 +186,7 @@ const getMetadata = HK.getMetadata = function (Env, channelName, _cb) { return void cb(undefined, metadata); } - MetaRPC.getMetadata(Env, channelName, function (err, metadata) { + MetaRPC.getMetadataRaw(Env, channelName, function (err, metadata) { if (err) { console.error(err); return void cb(err); diff --git a/lib/rpc.js b/lib/rpc.js index ad6ccde5c..c54edf31d 100644 --- a/lib/rpc.js +++ b/lib/rpc.js @@ -19,15 +19,15 @@ const UNAUTHENTICATED_CALLS = { GET_DELETED_PADS: Pinning.getDeletedPads, IS_CHANNEL_PINNED: Pinning.isChannelPinned, IS_NEW_CHANNEL: Channel.isNewChannel, - WRITE_PRIVATE_MESSAGE: Channel.writePrivateMessage, // XXX RESTRICT - GET_METADATA: Metadata.getMetadata, // XXX RESTRICT + WRITE_PRIVATE_MESSAGE: Channel.writePrivateMessage, + GET_METADATA: Metadata.getMetadata, }; var isUnauthenticateMessage = function (msg) { return msg && msg.length === 2 && typeof(UNAUTHENTICATED_CALLS[msg[0]]) === 'function'; }; -var handleUnauthenticatedMessage = function (Env, msg, respond, Server) { +var handleUnauthenticatedMessage = function (Env, msg, respond, Server, netfluxId) { Env.Log.silly('LOG_RPC', msg[0]); var method = UNAUTHENTICATED_CALLS[msg[0]]; @@ -37,7 +37,7 @@ var handleUnauthenticatedMessage = function (Env, msg, respond, Server) { return void respond(err); } respond(err, [null, value, null]); - }, Server); + }, Server, netfluxId); }; const AUTHENTICATED_USER_TARGETED = { @@ -137,7 +137,7 @@ var rpc = function (Env, Server, userId, data, respond) { } if (isUnauthenticateMessage(msg)) { - return handleUnauthenticatedMessage(Env, msg, respond, Server); + return handleUnauthenticatedMessage(Env, msg, respond, Server, userId); } var signature = msg.shift();