Split initialization from constructor of ClientRequest 90/308990/1
authorYonggoo Kang <ygace.kang@samsung.com>
Wed, 3 Apr 2024 09:01:47 +0000 (18:01 +0900)
committerYonggoo Kang <ygace.kang@samsung.com>
Wed, 3 Apr 2024 09:01:47 +0000 (18:01 +0900)
Change-Id: I0d82a955f0dc88e9317bcc74fe82e09b138f6882

srcs/client/client-request.h
srcs/client/client.cpp
srcs/common/connection.cpp
tests/client-request-test.cpp

index d15b81b578db6461294c72aeaab0aa30a0ed1237..c7f105701a11812903f4e129bdd4c497fa4bd77a 100644 (file)
@@ -37,15 +37,9 @@ namespace WA {
 
 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()
@@ -64,10 +58,17 @@ public:
 
     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())
@@ -77,24 +78,31 @@ public:
 
     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;
@@ -102,26 +110,42 @@ public:
 
     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;
@@ -130,29 +154,64 @@ public:
 
     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>
@@ -192,6 +251,9 @@ int wauthn_process(const wauthn_client_data_s *client_data,
             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();
index ab6f4bdd5a5fc451e490ebcbe780068160e9311b..671ff3712bc98b7425110d6f59b817b30df401c2 100644 (file)
@@ -43,6 +43,7 @@ int wauthn_cancel()
 {
     return try_catch([&]() -> int {
         ClientRequest request(WebAuthnCall::CANCEL);
+        request.Init();
         if (request.sendRequest().failed())
             LogError("Error on cancel request, Response: " << wauthn_error_to_string(request.getStatus()));
         return request.getStatus();
index 5498ec38bccabbf0121590d1069da629486afe7d..b6a8b783749ab1c90201a8bba2b07a23c396a034 100644 (file)
@@ -131,10 +131,6 @@ public:
         if (-1 == retval) {
             int err = errno;
             LogWithErrno(err, "connecting socket");
-            if (err == EACCES)
-                return WAUTHN_ERROR_ACCESS_DENIED;
-            if (err == ENOTSOCK)
-                return WAUTHN_ERROR_NO_SUCH_SERVICE;
             return WAUTHN_ERROR_SOCKET;
         }
 
@@ -149,8 +145,6 @@ private:
     int m_sock;
 };
 
-
-
 Connection::Connection()
 {
     m_sock = new SockRAII();
@@ -161,15 +155,12 @@ Connection::~Connection()
     delete m_sock;
 }
 
-
 int Connection::createConnect(char const * const interface)
 {
     int ret = WAUTHN_ERROR_NONE;
-
     if (WAUTHN_ERROR_NONE != (ret = m_sock->Connect(interface))) {
         LogError("Error in SockRAII");
     }
-
     return ret;
 }
 
index 48240c900ea2be73e57ea346e19617cd98fe1692..1a2a52666671aba19d3b36699d8d0dcd1bd7dc1d 100644 (file)
@@ -32,8 +32,29 @@ namespace WA {
 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
@@ -164,7 +185,8 @@ protected:
         // Do deinitialization if needed.
     }
 };
-TEST_F(ClientRequestTest, constructor_P)
+
+TEST_F(ClientRequestTest, client_request_child_constructor_P)
 {
     int ret = 0;
     try{
@@ -176,6 +198,37 @@ TEST_F(ClientRequestTest, constructor_P)
     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;
@@ -447,6 +500,7 @@ TEST_F(ClientRequestTest, cancel_P)
 
             sleep(1);
             TestClientRequest request(WebAuthnCall::CANCEL);
+            request.Init();
             if (request.sendRequest().failed())
                 LogError("Error on cancel request, Response: "
                     << wauthn_error_to_string(request.getStatus()));