diff --git a/lib/historyKeeper.js b/lib/historyKeeper.js index a77a95740..1b306681e 100644 --- a/lib/historyKeeper.js +++ b/lib/historyKeeper.js @@ -113,6 +113,10 @@ module.exports.create = function (config, cb) { channelOpen: function (Server, channelName, userId) { Env.channel_cache[channelName] = Env.channel_cache[channelName] || {}; + //const metadata = Env.metadata_cache[channelName]; + // chainpad-server@4.0.3 supports a removeFromChannel method + // Server.removeFromChannel(channelName, userId); + // this lets us kick users from restricted channels // XXX RESTRICT // this event is emitted whenever a user joins a channel. diff --git a/lib/hk-util.js b/lib/hk-util.js index 3c5fe887c..c94a67bd5 100644 --- a/lib/hk-util.js +++ b/lib/hk-util.js @@ -75,6 +75,29 @@ const isMetadataMessage = function (parsed) { return Boolean(parsed && parsed.channel); }; +const isChannelRestricted = function (metadata) { // XXX RESTRICT + metadata = metadata; + return false; +}; + +const isUserAllowed = function (metadata, userId) { // XXX RESTRICT +/* + + at this point all we have is the user's netflux id. + the allow-list is encoded for 'unsafeKeys' (URL-unsafe base64 encoded public signing keys). + + we need a lookup table: netfluxId => public keys with which this netflux session has authenticated. + from there we can check whether the user has authenticated for any of the allowed keys this session. + + owners are implicitly allowed to view any file they own. + pending_owners too. + otherwise check metadata.allowed. + +*/ + userId = userId; + return false; +}; + // validateKeyStrings supplied by clients must decode to 32-byte Uint8Arrays const isValidValidateKeyString = function (key) { try { @@ -646,6 +669,16 @@ const handleGetHistory = function (Env, Server, seq, userId, parsed) { // And then check if the channel is expired. If it is, send the error and abort // FIXME this is hard to read because 'checkExpired' has side effects if (checkExpired(Env, Server, channelName)) { return void waitFor.abort(); } + + // XXX RESTRICT + // once we've loaded the metadata we can check whether the channel is restricted + // and notify the user if they're not included in the list + if (isChannelRestricted(index.metadata) && isUserAllowed(index.metadata, userId)) { + // XXX RESTRICT send a message indicating that they need to authenticate + // for a list of private keys... + return void waitFor.abort(); + } + // always send metadata with GET_HISTORY requests Server.send(userId, [0, HISTORY_KEEPER_ID, 'MSG', userId, JSON.stringify(index.metadata)], w); })); @@ -817,6 +850,10 @@ HK.onDirectMessage = function (Env, Server, seq, userId, json) { // have to abort later (once we know the expiration time) if (checkExpired(Env, Server, parsed[1])) { return; } + // XXX RESTRICT + // metadata might already be in memory. + // rejecting unauthorized users here is an optimization + // look up the appropriate command in the map of commands or fall back to RPC var command = directMessageCommands[parsed[0]] || handleRPC;