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;
136 ctx.tx, member_id, raw_recovery_share);
139 raw_recovery_share.data(), raw_recovery_share.size());
141 catch (
const std::exception& e)
144 raw_recovery_share.data(), raw_recovery_share.size());
146 constexpr auto error_msg =
"Error submitting recovery shares.";
149 detail::set_gov_error(
151 HTTP_STATUS_INTERNAL_SERVER_ERROR,
152 errors::InternalError,
157 const auto threshold =
162 std::string message = fmt::format(
163 "{}/{} recovery shares successfully submitted",
164 submitted_shares_count,
167 if (submitted_shares_count >= threshold)
169 message +=
"\nEnd of recovery procedure initiated";
175 node_operation->initiate_private_recovery(ctx.tx);
177 catch (
const std::exception& e)
181 constexpr auto error_msg =
"Failed to initiate private recovery.";
185 ctx.rpc_ctx->set_apply_writes(
true);
186 detail::set_gov_error(
188 HTTP_STATUS_INTERNAL_SERVER_ERROR,
189 errors::InternalError,
195 auto response_body = nlohmann::json::object();
196 response_body[
"message"] = message;
197 response_body[
"submittedCount"] = submitted_shares_count;
198 response_body[
"recoveryThreshold"] = threshold;
200 ctx.rpc_ctx->set_response_json(response_body, HTTP_STATUS_OK);
207 "/recovery/members/{memberId}:recover",
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
Definition node_context.h:12
std::shared_ptr< T > get_subsystem(const std::string &name) const
Definition node_context.h:37