From ef4bae73d025c50da32a1b3c30b03c6e59b4ebe8 Mon Sep 17 00:00:00 2001 From: Daniel Lyubomirov <daniel.lyubomirov@vereign.com> Date: Fri, 26 Jun 2020 15:48:14 +0300 Subject: [PATCH] [17] grpc identity login apis --- cpp/proto | 2 +- cpp/src/vereign/grpc/identity_api.hh | 73 +++++++++++++++++++ cpp/src/vereign/grpc/passport_api.hh | 50 ------------- cpp/src/vereign/grpc/server.cc | 35 +++++++-- cpp/src/vereign/grpc/server.hh | 6 +- cpp/src/vereign/grpc/service_registry.hh | 27 +++++-- cpp/src/vereign/service/identity_service.cc | 12 +-- cpp/src/vereign/service/identity_service.hh | 6 +- .../service/gen/passport_service_test.cc | 2 +- .../vereign/service/identity_service_test.cc | 8 +- cpp/tests/vereign/test/device.cc | 8 +- 11 files changed, 148 insertions(+), 81 deletions(-) create mode 100644 cpp/src/vereign/grpc/identity_api.hh delete mode 100644 cpp/src/vereign/grpc/passport_api.hh diff --git a/cpp/proto b/cpp/proto index 9ef33cf..bc1195a 160000 --- a/cpp/proto +++ b/cpp/proto @@ -1 +1 @@ -Subproject commit 9ef33cf108f8665204929ea56d9df812cb378821 +Subproject commit bc1195ac831908c96f2ebc72362a4b876e8b04a9 diff --git a/cpp/src/vereign/grpc/identity_api.hh b/cpp/src/vereign/grpc/identity_api.hh new file mode 100644 index 0000000..375ba8c --- /dev/null +++ b/cpp/src/vereign/grpc/identity_api.hh @@ -0,0 +1,73 @@ +#ifndef __VEREIGN_GRPC_IDENTITY_API_HH +#define __VEREIGN_GRPC_IDENTITY_API_HH + +#include "vereign/client_library/common_types.pb.h" +#include "vereign/client_library/identity_types.pb.h" +#include <vereign/grpc/gen/identity_api.hh> +#include <boost/core/ignore_unused.hpp> + +namespace vereign::grpc { + +template <class VereignService> +class IdentityAPI final : public gen::IdentityAPI<VereignService> { +public: + static constexpr const char* Name = gen::IdentityAPI<VereignService>::Name; + + using VereignServiceType = VereignService; + using VereignServicePtr = std::unique_ptr<VereignService>; + + IdentityAPI(VereignServicePtr&& service) + : gen::IdentityAPI<VereignService>{std::move(service)} + {} + + IdentityAPI(const IdentityAPI&) = delete; + auto operator=(const IdentityAPI&) -> IdentityAPI& = delete; + + auto LoginWithNewDevice( + ::grpc::ServerContext* ctx, + const client_library::LoginFormNewDevice* req, + client_library::LoginFormNewDeviceResponse* resp + ) -> ::grpc::Status override { + boost::ignore_unused(ctx); + + try { + this->service_->LoginWithNewDevice(req, resp); + } catch (const std::exception& e) { + resp->set_code("500"); + resp->set_status("Internal Service Error"); + resp->set_error(e.what()); + } catch (...) { + resp->set_code("500"); + resp->set_status("Internal Service Error"); + resp->set_error("Internal Service Error"); + } + + return ::grpc::Status::OK; + } + + auto LoginWithPreviouslyAddedDevice( + ::grpc::ServerContext* ctx, + const client_library::LoginFormPreviousAddedDevice* req, + client_library::EmptyResponse* resp + ) -> ::grpc::Status override { + boost::ignore_unused(ctx); + + try { + this->service_->LoginWithPreviouslyAddedDevice(req, resp); + } catch (const std::exception& e) { + resp->set_code("500"); + resp->set_status("Internal Service Error"); + resp->set_error(e.what()); + } catch (...) { + resp->set_code("500"); + resp->set_status("Internal Service Error"); + resp->set_error("Internal Service Error"); + } + + return ::grpc::Status::OK; + } +}; + +} // namespace vereign::grpc + +#endif // __VEREIGN_GRPC_IDENTITY_API_HH diff --git a/cpp/src/vereign/grpc/passport_api.hh b/cpp/src/vereign/grpc/passport_api.hh deleted file mode 100644 index 02eb2b3..0000000 --- a/cpp/src/vereign/grpc/passport_api.hh +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __VEREIGN_GRPC_PASSPORT_API_HH -#define __VEREIGN_GRPC_PASSPORT_API_HH - -#include <vereign/grpc/gen/passport_api.hh> - -namespace vereign { -namespace grpc { - -template <class VereignService> -class PassportAPI final : public gen::PassportAPI<VereignService> { -public: - static constexpr const char* Name = gen::PassportAPI<VereignService>::Name; - - using VereignServiceType = VereignService; - using VereignServicePtr = std::unique_ptr<VereignService>; - - PassportAPI(VereignServicePtr&& service) - : gen::PassportAPI<VereignService>{std::move(service)} - {} - - PassportAPI(const PassportAPI&) = delete; - PassportAPI& operator=(const PassportAPI&) = delete; - - ::grpc::Status ListPassportsManually( - ::grpc::ServerContext*, - const client_library::ListPassportsForm* request, - client_library::ListPassportsFormResponse* response - ) override { - auto result_future = this->service_->ListPassports(request, response); - - try { - result_future.get(); - } catch (const std::exception& e) { - response->set_code("500"); - response->set_status("Internal Service Error"); - response->set_error(e.what()); - } catch (...) { - response->set_code("500"); - response->set_status("Internal Service Error"); - response->set_error("Internal Service Error"); - } - - return ::grpc::Status::OK; - } -}; - -} // namespace grpc -} // namespace vereign - -#endif // __VEREIGN_GRPC_PASSPORT_API_HH diff --git a/cpp/src/vereign/grpc/server.cc b/cpp/src/vereign/grpc/server.cc index b5a8597..5935e86 100644 --- a/cpp/src/vereign/grpc/server.cc +++ b/cpp/src/vereign/grpc/server.cc @@ -1,13 +1,18 @@ #include <vereign/grpc/server.hh> +#include <vereign/kvstore/crypto_storage.hh> +#include <vereign/kvstore/sqlite_storage.hh> +#include <vereign/kvstore/storage.hh> + #include <vereign/restapi/client.hh> #include <vereign/restapi/client_session.hh> // #include <vereign/service/gen/gen.hh> // #include <vereign/grpc/gen/gen.hh> #include <vereign/grpc/service_registry.hh> -#include <vereign/service/passport_service.hh> -#include <vereign/grpc/passport_api.hh> +// manually written api +#include <vereign/service/identity_service.hh> +#include <vereign/grpc/identity_api.hh> #include <grpcpp/server.h> #include <boost/asio/io_context.hpp> @@ -28,7 +33,8 @@ public: Impl( const std::string& listenAddress, const std::string& vereignHost, - const std::string& vereignPort + const std::string& vereignPort, + std::string storage_path ) : selected_port_{0}, work_guard_{asio::make_work_guard(ioc_)}, ssl_context_{asio::ssl::context::tlsv12_client}, @@ -36,8 +42,18 @@ public: ioc_, ssl_context_, vereignHost, vereignPort )}, client_session_{std::make_unique<restapi::ClientSession>(*client_)}, + kvstorage_{nullptr}, + crypto_storage_{nullptr}, + identity_provider_{nullptr}, server_{nullptr} { + if (storage_path == "") { + storage_path = "/home/daniel/ztrash/vereign/db"; + } + + kvstorage_ = std::make_unique<kvstore::SqliteStorage>(storage_path); + crypto_storage_ = std::make_unique<kvstore::CryptoStorage>(*kvstorage_); + identity_provider_ = std::make_unique<identity::Provider>(*crypto_storage_); // FIXME: Verify the remote server's certificate // ssl_context.set_verify_mode(ssl::verify_peer); @@ -49,7 +65,10 @@ public: ); // register manually written services - services_registry_.RegisterIfNotExist<PassportAPI<service::PassportService>>(*client_session_); + services_registry_.RegisterIfNotExist<IdentityAPI<service::IdentityService>>( + *client_session_, + *identity_provider_ + ); // register all generated services // grpc::gen::RegisterAll(*client_session_, services_registry_); @@ -96,6 +115,9 @@ private: std::unique_ptr<vereign::restapi::Client> client_; std::unique_ptr<vereign::restapi::ClientSession> client_session_; ServiceRegistry services_registry_; + std::unique_ptr<kvstore::Storage> kvstorage_; + std::unique_ptr<kvstore::CryptoStorage> crypto_storage_; + std::unique_ptr<identity::Provider> identity_provider_; std::unique_ptr<::grpc::Server> server_; std::thread server_thread_; std::thread service_thread_; @@ -104,9 +126,10 @@ private: Server::Server( const std::string& listenAddress, const std::string& vereignHost, - const std::string& vereignPort + const std::string& vereignPort, + const std::string& storage_path ) - : impl_{std::make_unique<Impl>(listenAddress, vereignHost, vereignPort)} + : impl_{std::make_unique<Impl>(listenAddress, vereignHost, vereignPort, storage_path)} { } diff --git a/cpp/src/vereign/grpc/server.hh b/cpp/src/vereign/grpc/server.hh index 9b992d5..16b65dc 100644 --- a/cpp/src/vereign/grpc/server.hh +++ b/cpp/src/vereign/grpc/server.hh @@ -33,12 +33,16 @@ public: * @param listenAddress gRPC listen address, for example "localhost:". * @param vereignHost Vereign restapi host. * @param vereignPort Vereign restapi port - https, 443... + * @param storage_path Path to directory that will be used for the crypto storage. + * If storage_path is empty string, a default is used - $HOME/vereign. + * * @throws BindError when the gRPC server could not start listening. */ explicit Server( const std::string& listenAddress, const std::string& vereignHost, - const std::string& vereignPort + const std::string& vereignPort, + const std::string& storage_path = "" ); /** diff --git a/cpp/src/vereign/grpc/service_registry.hh b/cpp/src/vereign/grpc/service_registry.hh index cddc32a..94c0fd3 100644 --- a/cpp/src/vereign/grpc/service_registry.hh +++ b/cpp/src/vereign/grpc/service_registry.hh @@ -3,18 +3,18 @@ #include <grpcpp/server_builder.h> #include <vereign/restapi/client_session.hh> +#include <vereign/identity/provider.hh> #include <unordered_map> -namespace vereign { -namespace grpc { +namespace vereign::grpc { class ServiceRegistry { public: void RegisterIntoBuilder(::grpc::ServerBuilder& builder); template <class API> - bool RegisterIfNotExist(restapi::ClientSession& client_session) { + auto RegisterIfNotExist(restapi::ClientSession& client_session) -> bool { auto it = services_.find(API::Name); if (it != services_.end()) { return false; @@ -26,11 +26,28 @@ public: return true; } + template <class API> + auto RegisterIfNotExist( + restapi::ClientSession& client_session, + identity::Provider& identity_provider + ) -> bool { + auto it = services_.find(API::Name); + if (it != services_.end()) { + return false; + } + + using Service = typename API::VereignServiceType; + services_[API::Name] = std::make_unique<API>( + std::make_unique<Service>(client_session, identity_provider) + ); + + return true; + } + private: std::unordered_map<std::string, std::unique_ptr<::grpc::Service>> services_; }; -} // namespace grpc -} // namespace vereign +} // namespace vereign::grpc #endif // __VEREIGN_GRPC_SERVICE_REGISTRY_HH diff --git a/cpp/src/vereign/service/identity_service.cc b/cpp/src/vereign/service/identity_service.cc index 3b6eae9..488c2f3 100644 --- a/cpp/src/vereign/service/identity_service.cc +++ b/cpp/src/vereign/service/identity_service.cc @@ -1,7 +1,7 @@ -#include "vereign/service/gen/identity_service.hh" -#include "vereign/client_library/common_types.pb.h" #include <vereign/service/identity_service.hh> +#include <vereign/service/gen/identity_service.hh> +#include <vereign/client_library/common_types.pb.h> #include <vereign/restapi/http_header.hh> #include <vereign/restapi/client_session.hh> #include <vereign/encoding/base64.hh> @@ -16,12 +16,12 @@ namespace { namespace vereign::service { IdentityService::IdentityService( - identity::Provider& identity_provider, - restapi::ClientSession& client_session + restapi::ClientSession& client_session, + identity::Provider& identity_provider ) : gen::IdentityService{client_session}, - identity_provider_{identity_provider}, - client_session_{client_session} + client_session_{client_session}, + identity_provider_{identity_provider} {} void IdentityService::LoginWithExistingPubKey( diff --git a/cpp/src/vereign/service/identity_service.hh b/cpp/src/vereign/service/identity_service.hh index 02acf73..51a77b4 100644 --- a/cpp/src/vereign/service/identity_service.hh +++ b/cpp/src/vereign/service/identity_service.hh @@ -24,8 +24,8 @@ using Result = restapi::PostResult<Request, Response>; class IdentityService : public gen::IdentityService { public: IdentityService( - identity::Provider& identity_provider, - restapi::ClientSession& client_session + restapi::ClientSession& client_session, + identity::Provider& identity_provider ); IdentityService(const IdentityService&) = delete; @@ -47,8 +47,8 @@ public: ); private: - identity::Provider& identity_provider_; restapi::ClientSession& client_session_; + identity::Provider& identity_provider_; }; } // namespace service diff --git a/cpp/tests/vereign/service/gen/passport_service_test.cc b/cpp/tests/vereign/service/gen/passport_service_test.cc index 74a9516..d6ddc18 100644 --- a/cpp/tests/vereign/service/gen/passport_service_test.cc +++ b/cpp/tests/vereign/service/gen/passport_service_test.cc @@ -41,7 +41,7 @@ TEST_CASE("PassportService::ListPassports", "[vereign/service/gen][.integration] auto kvstorage = vereign::kvstore::SqliteStorage(storage_path.string()); vereign::kvstore::CryptoStorage storage{kvstorage}; vereign::identity::Provider provider{storage}; - vereign::service::IdentityService idenity_service{provider, client_session}; + vereign::service::IdentityService idenity_service{client_session, provider}; std::thread ioc_thread([&ioc]{ ioc.run(); diff --git a/cpp/tests/vereign/service/identity_service_test.cc b/cpp/tests/vereign/service/identity_service_test.cc index 7c94edc..1f3b042 100644 --- a/cpp/tests/vereign/service/identity_service_test.cc +++ b/cpp/tests/vereign/service/identity_service_test.cc @@ -34,8 +34,8 @@ TEST_CASE("service::IdentityService::LoginWithNewDevice", "[vereign/service][.in auto rm_storage_path = core::RemoveFileGuard{storage_path}; auto service_context = test::ServiceContext{host, port, storage_path}; auto service = service::IdentityService{ - service_context.IdentityProvider(), - service_context.ClientSession() + service_context.ClientSession(), + service_context.IdentityProvider() }; // register new device @@ -94,8 +94,8 @@ TEST_CASE("service::IdentityService::LoginWithPreviouslyAddedDevice", "[vereign/ auto service_context = test::ServiceContext{host, port, storage_path}; auto service = service::IdentityService{ - service_context.IdentityProvider(), - service_context.ClientSession() + service_context.ClientSession(), + service_context.IdentityProvider() }; auto req = std::make_unique<vereign::client_library::LoginFormPreviousAddedDevice>(); diff --git a/cpp/tests/vereign/test/device.cc b/cpp/tests/vereign/test/device.cc index 6713ffb..a1dd39b 100644 --- a/cpp/tests/vereign/test/device.cc +++ b/cpp/tests/vereign/test/device.cc @@ -16,8 +16,8 @@ namespace vereign::test { Device::Device(ServiceContext& service_context) : service_context_{service_context}, identity_service_{std::make_unique<service::IdentityService>( - service_context_.IdentityProvider(), - service_context_.ClientSession() + service_context_.ClientSession(), + service_context_.IdentityProvider() )} { } @@ -85,8 +85,8 @@ void Device::AuthorizeDevice(const std::string& device_hash) { void Device::CreateNewDevice(ServiceContext& service_context, const std::string& pin) { auto service = service::IdentityService{ - service_context.IdentityProvider(), - service_context.ClientSession() + service_context.ClientSession(), + service_context.IdentityProvider() }; // register new device -- GitLab