Added bson support for user message protocol. (#99)

This commit is contained in:
Ravin Perera
2020-07-02 21:40:55 +05:30
committed by GitHub
parent 8103ef7af6
commit 96f23cb0ff
47 changed files with 1424 additions and 810 deletions

View File

@@ -3,12 +3,10 @@
#include "../util.hpp"
#include "../sc.hpp"
#include "../conf.hpp"
#include "../jsonschema/usrmsg_helpers.hpp"
#include "../msg/usrmsg_parser.hpp"
#include "usr.hpp"
#include "read_req.hpp"
namespace jusrmsg = jsonschema::usrmsg;
/**
* Helper functions for serving read requests from users.
*/
@@ -97,10 +95,12 @@ namespace read_req
std::string outputtosend;
outputtosend.swap(bufpair.output);
std::string msg;
jusrmsg::create_contract_read_response_container(msg, outputtosend);
const usr::connected_user &user = user_itr->second;
msg::usrmsg::usrmsg_parser parser(user.protocol);
std::vector<uint8_t> msg;
parser.create_contract_read_response_container(msg, outputtosend);
user.session.send(msg);
dispatch_count++;
}

View File

@@ -2,6 +2,7 @@
#define _HP_USR_USER_INPUT_
#include "../pchheader.hpp"
#include "../util.hpp"
namespace usr
{
@@ -9,18 +10,19 @@ namespace usr
/**
* Represents a signed contract input message a network user has submitted.
*/
struct user_submitted_message
struct user_input
{
const std::string content;
const std::string input_container;
const std::string sig;
const util::PROTOCOL protocol; // The encoding protocol used for the input container.
user_submitted_message(const std::string content, const std::string sig)
: content(std::move(content)), sig(std::move(sig))
user_input(const std::string input_container, const std::string sig, const util::PROTOCOL protocol)
: input_container(std::move(input_container)), sig(std::move(sig)), protocol(protocol)
{
}
user_submitted_message(std::string_view content, std::string_view sig)
: content(content), sig(sig)
user_input(std::string_view input_container, std::string_view sig, const util::PROTOCOL protocol)
: input_container(input_container), sig(sig), protocol(protocol)
{
}
};

View File

@@ -1,11 +1,11 @@
#include "../pchheader.hpp"
#include "../hplog.hpp"
#include "../jsonschema/usrmsg_helpers.hpp"
#include "../msg/json/usrmsg_json.hpp"
#include "../bill/corebill.h"
#include "usr.hpp"
#include "user_session_handler.hpp"
namespace jusrmsg = jsonschema::usrmsg;
namespace jusrmsg = msg::usrmsg::json;
namespace usr
{
@@ -25,9 +25,9 @@ int user_session_handler::on_connect(comm::comm_session &session) const
// As soon as a user connects, we issue them a challenge message. We remember the
// challenge we issued and later verify the user's response with it.
std::string msgstr;
jusrmsg::create_user_challenge(msgstr, session.issued_challenge);
session.send(msgstr);
std::vector<uint8_t> msg;
jusrmsg::create_user_challenge(msg, session.issued_challenge);
session.send(msg);
// Set the challenge-issued value to true.
session.challenge_status = comm::CHALLENGE_ISSUED;

View File

@@ -1,5 +1,7 @@
#include "../pchheader.hpp"
#include "../jsonschema/usrmsg_helpers.hpp"
#include "../msg/json/usrmsg_json.hpp"
#include "../msg/usrmsg_parser.hpp"
#include "../msg/usrmsg_common.hpp"
#include "../comm/comm_server.hpp"
#include "../comm/comm_session.hpp"
#include "../util.hpp"
@@ -10,8 +12,6 @@
#include "user_session_handler.hpp"
#include "user_input.hpp"
namespace jusrmsg = jsonschema::usrmsg;
namespace usr
{
@@ -78,8 +78,10 @@ namespace usr
}
std::string userpubkeyhex;
std::string protocol_code;
std::string_view original_challenge = session.issued_challenge;
if (jusrmsg::verify_user_challenge_response(userpubkeyhex, message, original_challenge) == 0)
if (msg::usrmsg::json::verify_user_handshake_response(userpubkeyhex, protocol_code, message, original_challenge) == 0)
{
// Challenge signature verification successful.
@@ -98,8 +100,10 @@ namespace usr
// All good. Unique public key.
// Promote the connection from pending-challenges to authenticated users.
const util::PROTOCOL user_protocol = (protocol_code == "json" ? util::PROTOCOL::JSON : util::PROTOCOL::BSON);
session.challenge_status = comm::CHALLENGE_VERIFIED; // Set as challenge verified
add_user(session, userpubkey); // Add the user to the global authed user list
add_user(session, userpubkey, user_protocol); // Add the user to the global authed user list
session.issued_challenge.clear(); // Remove the stored challenge
LOG_DBG << "User connection " << session.uniqueid << " authenticated. Public key "
@@ -127,17 +131,17 @@ namespace usr
*/
int handle_user_message(connected_user &user, std::string_view message)
{
rapidjson::Document d;
const char *msg_type = jusrmsg::MSGTYPE_UNKNOWN;
msg::usrmsg::usrmsg_parser parser(user.protocol);
if (jusrmsg::parse_user_message(d, message) == 0)
if (parser.parse(message) == 0)
{
const char *msg_type = d[jusrmsg::FLD_TYPE].GetString();
std::string msg_type;
parser.extract_type(msg_type);
if (d[jusrmsg::FLD_TYPE] == jusrmsg::MSGTYPE_CONTRACT_READ_REQUEST)
if (msg_type == msg::usrmsg::MSGTYPE_CONTRACT_READ_REQUEST)
{
std::string content;
if (jusrmsg::extract_read_request(content, d) == 0)
if (parser.extract_read_request(content) == 0)
{
std::lock_guard<std::mutex> lock(ctx.users_mutex);
@@ -147,50 +151,51 @@ namespace usr
}
else
{
send_input_status(user.session, jusrmsg::STATUS_REJECTED, jusrmsg::REASON_BAD_MSG_FORMAT, "");
send_input_status(parser, user.session, msg::usrmsg::STATUS_REJECTED, msg::usrmsg::REASON_BAD_MSG_FORMAT, "");
return -1;
}
}
else if (d[jusrmsg::FLD_TYPE] == jusrmsg::MSGTYPE_CONTRACT_INPUT)
else if (msg_type == msg::usrmsg::MSGTYPE_CONTRACT_INPUT)
{
// Message is a contract input message.
std::string input_container_json;
std::string input_container;
std::string sig;
if (jusrmsg::extract_signed_input_container(input_container_json, sig, d) == 0)
if (parser.extract_signed_input_container(input_container, sig) == 0)
{
std::lock_guard<std::mutex> lock(ctx.users_mutex);
//Add to the submitted input list.
user.submitted_inputs.push_back(user_submitted_message(
std::move(input_container_json),
std::move(sig)));
user.submitted_inputs.push_back(user_input(
std::move(input_container),
std::move(sig),
user.protocol));
return 0;
}
else
{
send_input_status(user.session, jusrmsg::STATUS_REJECTED, jusrmsg::REASON_BAD_SIG, sig);
send_input_status(parser, user.session, msg::usrmsg::STATUS_REJECTED, msg::usrmsg::REASON_BAD_SIG, sig);
return -1;
}
}
else if (d[jusrmsg::FLD_TYPE] == jusrmsg::MSGTYPE_STAT)
else if (msg_type == msg::usrmsg::MSGTYPE_STAT)
{
std::string msg;
jusrmsg::create_status_response(msg);
std::vector<uint8_t> msg;
parser.create_status_response(msg);
user.session.send(msg);
return 0;
}
else
{
LOG_DBG << "Invalid user message type: " << msg_type;
send_input_status(user.session, jusrmsg::STATUS_REJECTED, jusrmsg::REASON_INVALID_MSG_TYPE, "");
send_input_status(parser, user.session, msg::usrmsg::STATUS_REJECTED, msg::usrmsg::REASON_INVALID_MSG_TYPE, "");
return -1;
}
}
else
{
// Bad message.
send_input_status(user.session, jusrmsg::STATUS_REJECTED, jusrmsg::REASON_BAD_MSG_FORMAT, "");
send_input_status(parser, user.session, msg::usrmsg::STATUS_REJECTED, msg::usrmsg::REASON_BAD_MSG_FORMAT, "");
return -1;
}
}
@@ -198,10 +203,11 @@ namespace usr
/**
* Send the specified contract input status result via the provided session.
*/
void send_input_status(const comm::comm_session &session, std::string_view status, std::string_view reason, std::string_view input_sig)
void send_input_status(const msg::usrmsg::usrmsg_parser &parser, const comm::comm_session &session,
std::string_view status, std::string_view reason, std::string_view input_sig)
{
std::string msg;
jusrmsg::create_contract_input_status(msg, status, reason, input_sig);
std::vector<uint8_t> msg;
parser.create_contract_input_status(msg, status, reason, input_sig);
session.send(msg);
}
@@ -211,9 +217,10 @@ namespace usr
*
* @param session User socket session.
* @param pubkey User's binary public key.
* @param protocol Messaging protocol used by user.
* @return 0 on successful additions. -1 on failure.
*/
int add_user(const comm::comm_session &session, const std::string &pubkey)
int add_user(const comm::comm_session &session, const std::string &pubkey, const util::PROTOCOL protocol)
{
const std::string &sessionid = session.uniqueid;
if (ctx.users.count(sessionid) == 1)
@@ -224,7 +231,7 @@ namespace usr
{
std::lock_guard<std::mutex> lock(ctx.users_mutex);
ctx.users.emplace(sessionid, usr::connected_user(session, pubkey));
ctx.users.emplace(sessionid, usr::connected_user(session, pubkey, protocol));
}
// Populate sessionid map so we can lookup by user pubkey.

View File

@@ -5,6 +5,7 @@
#include "../util.hpp"
#include "../comm/comm_server.hpp"
#include "../comm/comm_session.hpp"
#include "../msg/usrmsg_parser.hpp"
#include "user_session_handler.hpp"
#include "user_input.hpp"
@@ -13,7 +14,6 @@
*/
namespace usr
{
/**
* Holds information about an authenticated (challenge-verified) user
* connected to the HotPocket node.
@@ -24,7 +24,7 @@ namespace usr
const std::string pubkey;
// Holds the unprocessed user inputs collected from websocket.
std::list<user_submitted_message> submitted_inputs;
std::list<user_input> submitted_inputs;
// Holds the unprocessed read requests collected from websocket.
std::list<std::string> read_requests;
@@ -33,12 +33,15 @@ namespace usr
// We don't need to own the session object since the lifetime of user and session are coupled.
const comm::comm_session &session;
// The messaging protocol used by this user.
const util::PROTOCOL protocol;
/**
* @param session The web socket session the user is connected to.
* @param pubkey The public key of the user in binary format.
*/
connected_user(const comm::comm_session &session, std::string_view pubkey)
: session(session), pubkey(pubkey)
connected_user(const comm::comm_session &session, std::string_view pubkey, util::PROTOCOL protocol)
: session(session), pubkey(pubkey), protocol(protocol)
{
}
};
@@ -72,9 +75,10 @@ namespace usr
int handle_user_message(connected_user &user, std::string_view message);
void send_input_status(const comm::comm_session &session, std::string_view status, std::string_view reason, std::string_view input_sig);
void send_input_status(const msg::usrmsg::usrmsg_parser &parser, const comm::comm_session &session,
std::string_view status, std::string_view reason, std::string_view input_sig);
int add_user(const comm::comm_session &session, const std::string &pubkey);
int add_user(const comm::comm_session &session, const std::string &pubkey, const util::PROTOCOL protocol);
int remove_user(const std::string &sessionid);