class GenericClientRequest {
public:
- explicit GenericClientRequest(WebAuthnCall action, const char *interface) :
- m_action(action), m_conn(std::make_unique<Connection>())
+ explicit GenericClientRequest(WebAuthnCall action) :
+ m_action(action)
{
- int ret = m_conn->createConnect(interface);
- if (ret != WAUTHN_ERROR_NONE)
- ThrowMsg(ServiceException::InActive, "Error in createConnect");
- m_buffer.InitForStreaming();
- Serialization::Serialize(m_buffer, static_cast<int>(m_action));
- LogDebug("GenericClientRequest " << WebAuthnCallToString(m_action));
}
virtual ~GenericClientRequest()
GenericClientRequest &send()
{
+ if (failed())
+ {
+ m_status = WAUTHN_ERROR_INVALID_STATE;
+ return *this;
+ }
if (m_sent)
- throw std::logic_error(
- "Only one call to send() is allowed");
-
+ {
+ LogError("Only one call to send() is allowed");
+ m_status = WAUTHN_ERROR_NOT_ALLOWED;
+ return *this;
+ }
m_sent = true;
m_status = m_conn->send(m_buffer);
if (failed())
template <typename... T> GenericClientRequest &send(const T&... args)
{
+ if (failed())
+ {
+ m_status = WAUTHN_ERROR_INVALID_STATE;
+ return *this;
+ }
Serialization::Serialize(m_buffer, args...);
return send();
}
GenericClientRequest &recv()
{
- if (!m_sent)
- throw std::logic_error(
- "Call to send() must happen before call to recv()");
if (failed())
- throw std::logic_error(
- "recv() not allowed if the request failed");
+ {
+ m_status = WAUTHN_ERROR_INVALID_STATE;
+ return *this;
+ }
+ if (!m_sent)
+ {
+ LogError("Call to send() must happen before call to recv()");
+ m_status = WAUTHN_ERROR_NOT_ALLOWED;
+ return *this;
+ }
m_status = m_conn->recv(m_buffer);
if (failed())
- {
LogError("Error in recv: " << wauthn_error_to_string(m_status));
- m_status = WAUTHN_ERROR_SOCKET;
- }
else
Deserialization::Deserialize(m_buffer, m_status);
return *this;
template <typename... T> GenericClientRequest &recv(T&... args)
{
+ if (failed())
+ {
+ m_status = WAUTHN_ERROR_INVALID_STATE;
+ return *this;
+ }
recv();
if (failed())
- throw std::logic_error(
- "recv() is failed. Pass to receiving response.");
- Deserialization::Deserialize(m_buffer, args...);
+ LogError("Error in recv: " << wauthn_error_to_string(m_status));
+ else
+ Deserialization::Deserialize(m_buffer, args...);
return *this;
}
template <typename... T> GenericClientRequest &recv(T&&... args)
{
+ if (failed())
+ {
+ m_status = WAUTHN_ERROR_INVALID_STATE;
+ return *this;
+ }
recv();
if (failed())
- throw std::logic_error(
- "recv() is failed. Pass to receiving response.");
+ {
+ LogError("Error in recv: " << wauthn_error_to_string(m_status));
+ }
Deserialization::Deserialize(m_buffer, args...);
return *this;
}
template <typename... T> GenericClientRequest &sendRequest(const T&... args)
{
+ if (failed())
+ {
+ m_status = WAUTHN_ERROR_INVALID_STATE;
+ return *this;
+ }
Serialization::Serialize(m_buffer, args...);
if (send().failed())
return *this;
GenericClientRequest &sendRequest()
{
+ if (failed())
+ {
+ m_status = WAUTHN_ERROR_INVALID_STATE;
+ return *this;
+ }
if (send().failed())
return *this;
return recv();
}
+ virtual int Init() = 0;
+
+protected:
+ int InitRequest(const char *interface)
+ {
+ m_status = CreateConnect(interface);
+ if (m_status != WAUTHN_ERROR_NONE)
+ return m_status;
+ InitAction();
+ return WAUTHN_ERROR_NONE;
+ }
+
private:
bool m_sent = false;
int m_status = WAUTHN_ERROR_NONE;
MessageBuffer m_buffer;
WebAuthnCall m_action;
std::unique_ptr<Connection> m_conn;
+
+ int CreateConnect(const char *interface)
+ {
+ m_conn = std::make_unique<Connection>();
+ return m_conn->createConnect(interface);
+ }
+
+ void InitAction()
+ {
+ m_buffer.InitForStreaming();
+ Serialization::Serialize(m_buffer, static_cast<int>(m_action));
+ LogDebug("GenericClientRequest " << WebAuthnCallToString(m_action));
+ }
};
class ClientRequest : public GenericClientRequest {
public:
explicit ClientRequest(WebAuthnCall action) :
- GenericClientRequest(action, SERVICE_SOCKET)
+ GenericClientRequest(action)
{
}
virtual ~ClientRequest()
{
}
+
+ int Init () override
+ {
+ return InitRequest(SERVICE_SOCKET);
+ }
};
template <typename A, typename B>
callbacks->qrcode_callback = nullptr;
}
std::shared_ptr<T> request = std::make_shared<T>();
+ int ret = request->Init();
+ if (ret != WAUTHN_ERROR_NONE)
+ return ret;
if (request->sendRequest(client_data, options).failed())
return request->getStatus();
class TestClientRequest : public GenericClientRequest {
public:
explicit TestClientRequest(WebAuthnCall action) :
- GenericClientRequest(action, TEST_SERVICE_SOCKET) {}
+ GenericClientRequest(action) {}
virtual ~TestClientRequest() {}
+ int Init () override
+ {
+ return InitRequest(TEST_SERVICE_SOCKET);
+ }
+};
+
+class TestInvalidClientRequest : public GenericClientRequest {
+public:
+ explicit TestInvalidClientRequest(WebAuthnCall action) :
+ GenericClientRequest(action) {}
+ virtual ~TestInvalidClientRequest() {}
+ int Init () override
+ {
+ return InitRequest("invalid_path");
+ }
+ int InitLongPath()
+ {
+ return InitRequest("invalid_path_longer_than_length(108)_of_the_clientAddr.sun_path_\
+ 12345678901234567890123456789012345678901234567890123456789012345678901234567890\
+ 123456789012345678901234567890123456789012345678901234567890");
+ }
};
class TestClientRequestMC : public TestClientRequest
// Do deinitialization if needed.
}
};
-TEST_F(ClientRequestTest, constructor_P)
+
+TEST_F(ClientRequestTest, client_request_child_constructor_P)
{
int ret = 0;
try{
EXPECT_EQ(ret, 0);
}
+
+
+TEST_F(ClientRequestTest, invalid_interface_N)
+{
+ int ret = 0;
+ try{
+ TestInvalidClientRequest invalidRequest(WebAuthnCall::MAKE_CREDENTIAL);
+ EXPECT_EQ(invalidRequest.Init(), WAUTHN_ERROR_SOCKET);
+ TestInvalidClientRequest invalidRequest2(WebAuthnCall::MAKE_CREDENTIAL);
+ EXPECT_EQ(invalidRequest2.InitLongPath(), WAUTHN_ERROR_NO_SUCH_SERVICE);
+ } catch (...) {
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(ClientRequestTest, send_failed_N)
+{
+ int ret = 0;
+ try{
+ TestInvalidClientRequest invalidRequest(WebAuthnCall::MAKE_CREDENTIAL);
+ EXPECT_EQ(invalidRequest.Init(), WAUTHN_ERROR_SOCKET);
+ EXPECT_EQ(invalidRequest.getStatus(), WAUTHN_ERROR_SOCKET);
+ invalidRequest.send();
+ EXPECT_EQ(invalidRequest.getStatus(), WAUTHN_ERROR_INVALID_STATE);
+ } catch (...) {
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
TEST_F(ClientRequestTest, request_to_not_supported_server_N)
{
int ret = 1;
sleep(1);
TestClientRequest request(WebAuthnCall::CANCEL);
+ request.Init();
if (request.sendRequest().failed())
LogError("Error on cancel request, Response: "
<< wauthn_error_to_string(request.getStatus()));