17 auto get_encrypted_share_for_member =
31 auto encrypted_share =
34 if (!encrypted_share.has_value())
36 detail::set_gov_error(
38 HTTP_STATUS_NOT_FOUND,
39 ccf::errors::ResourceNotFound,
41 "Recovery share not found for member {}.", member_id));
45 auto response_body = nlohmann::json::object();
46 response_body[
"memberId"] = member_id;
47 response_body[
"encryptedShare"] =
50 ctx.rpc_ctx->set_response_json(response_body, HTTP_STATUS_OK);
57 "/recovery/encrypted-shares/{memberId}",
60 ccf::no_auth_required)
64 auto submit_recovery_share = [&](
auto& ctx,
ApiVersion api_version) {
75 detail::set_gov_error(
77 HTTP_STATUS_FORBIDDEN,
78 errors::ServiceNotWaitingForRecoveryShares,
79 "Service is not waiting for recovery shares.");
85 if (node_operation ==
nullptr)
87 detail::set_gov_error(
89 HTTP_STATUS_INTERNAL_SERVER_ERROR,
90 ccf::errors::InternalError,
91 "Could not access NodeOperation subsystem.");
95 if (node_operation->is_reading_private_ledger())
97 detail::set_gov_error(
99 HTTP_STATUS_FORBIDDEN,
100 errors::NodeAlreadyRecovering,
101 "Node is already recovering private ledger.");
111 const auto& cose_ident =
112 ctx.template get_caller<ccf::MemberCOSESign1AuthnIdentity>();
114 auto params = nlohmann::json::parse(cose_ident.content);
115 if (cose_ident.member_id != member_id)
117 detail::set_gov_error(
119 HTTP_STATUS_BAD_REQUEST,
120 ccf::errors::InvalidAuthenticationInfo,
122 "Member ID from path parameter ({}) does not match "
123 "member ID from body signature ({}).",
125 cose_ident.member_id));
130 params[
"share"].
template get<std::string>());
132 size_t submitted_shares_count = 0;
133 bool full_key_submitted =
false;
137 ctx.tx, member_id, raw_recovery_share);
142 raw_recovery_share.data(), raw_recovery_share.size());
144 catch (
const std::exception& e)
147 raw_recovery_share.data(), raw_recovery_share.size());
149 constexpr auto error_msg =
"Error submitting recovery shares.";
152 detail::set_gov_error(
154 HTTP_STATUS_INTERNAL_SERVER_ERROR,
155 errors::InternalError,
160 const auto threshold =
164 if (full_key_submitted)
166 message =
"Full recovery key successfully submitted";
172 message = fmt::format(
173 "{}/{} recovery shares successfully submitted",
174 submitted_shares_count,
178 if (submitted_shares_count >= threshold || full_key_submitted)
180 message +=
"\nEnd of recovery procedure initiated";
186 node_operation->initiate_private_recovery(ctx.tx);
188 catch (
const std::exception& e)
192 constexpr auto error_msg =
"Failed to initiate private recovery.";
196 ctx.rpc_ctx->set_apply_writes(
true);
197 detail::set_gov_error(
199 HTTP_STATUS_INTERNAL_SERVER_ERROR,
200 errors::InternalError,
206 auto response_body = nlohmann::json::object();
207 response_body[
"message"] = message;
208 response_body[
"submittedCount"] = submitted_shares_count;
209 response_body[
"recoveryThreshold"] = threshold;
210 response_body[
"fullKeySubmitted"] = full_key_submitted;
212 ctx.rpc_ctx->set_response_json(response_body, HTTP_STATUS_OK);
219 "/recovery/members/{memberId}:recover",
Definition node_operation_interface.h:23
Definition base_endpoint_registry.h:121
static std::optional< ServiceStatus > get_service_status(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:692
static size_t get_recovery_threshold(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:973
Definition share_manager.h:167
static std::optional< EncryptedShare > get_encrypted_share(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition share_manager.h:492
size_t submit_recovery_share(ccf::kv::Tx &tx, MemberId member_id, const std::vector< uint8_t > &submitted_recovery_share)
Definition share_manager.h:627
static bool is_full_key(const std::vector< uint8_t > &submitted_recovery_share)
Definition share_manager.h:609
static void clear_submitted_recovery_shares(ccf::kv::Tx &tx)
Definition share_manager.h:649
virtual Endpoint make_endpoint(const std::string &method, RESTVerb verb, const EndpointFunction &f, const AuthnPolicies &ap)
Definition endpoint_registry.cpp:204
virtual Endpoint make_read_only_endpoint(const std::string &method, RESTVerb verb, const ReadOnlyEndpointFunction &f, const AuthnPolicies &ap)
Definition endpoint_registry.cpp:235
#define GOV_FAIL_FMT
Definition gov_logging.h:11
#define GOV_DEBUG_FMT
Definition gov_logging.h:8
#define GOV_INFO_FMT
Definition gov_logging.h:10
std::vector< uint8_t > raw_from_b64(const std::string_view &b64_string)
Definition base64.cpp:12
std::string b64_from_raw(const uint8_t *data, size_t size)
Definition base64.cpp:41
bool try_parse_member_id(const std::shared_ptr< ccf::RpcContext > &rpc_ctx, ccf::MemberId &member_id)
Definition helpers.h:63
AuthnPolicies active_member_sig_only_policies(const std::string &gov_msg_type)
Definition helpers.h:16
Definition api_version.h:11
void init_recovery_handlers(ccf::BaseEndpointRegistry ®istry, ShareManager &share_manager, ccf::AbstractNodeContext &node_context)
Definition recovery.h:12
auto api_version_adapter(Fn &&f, ApiVersion min_accepted=ApiVersion::MIN)
Definition api_version.h:101
ApiVersion
Definition api_version.h:13
@ WAITING_FOR_RECOVERY_SHARES
Definition node_context.h:12
std::shared_ptr< T > get_subsystem(const std::string &name) const
Definition node_context.h:37
Endpoint & set_openapi_hidden(bool hidden)
Definition endpoint.cpp:10
void install()
Definition endpoint.cpp:122