{
}
- int getStatus() const
+ int GetStatus() const
{
return m_status;
}
- bool failed() const
+ bool Failed() const
{
- return m_status != WAUTHN_ERROR_NONE;
+ return m_status < WAUTHN_ERROR_NONE;
}
- GenericClientRequest &send()
+ bool Incompleted() const
{
- if (failed())
+ return m_status == WAUTHN_ERROR_NONE_AND_WAIT;
+ }
+
+ GenericClientRequest &Send()
+ {
+ if (Failed())
{
m_status = WAUTHN_ERROR_INVALID_STATE;
return *this;
}
m_sent = true;
m_status = m_conn->send(m_buffer);
- if (failed())
+ if (Failed())
LogError("Error in send. Error code: " << m_status);
return *this;
}
- template <typename... T> GenericClientRequest &send(const T&... args)
+ template <typename... T> GenericClientRequest &Send(const T&... args)
{
- if (failed())
+ if (Failed())
{
m_status = WAUTHN_ERROR_INVALID_STATE;
return *this;
}
Serialization::Serialize(m_buffer, args...);
- return send();
+ return Send();
}
- GenericClientRequest &recv()
+ GenericClientRequest &Recv()
{
- if (failed())
+ if (Failed())
{
m_status = WAUTHN_ERROR_INVALID_STATE;
return *this;
return *this;
}
m_status = m_conn->recv(m_buffer);
- if (failed())
+ if (Failed())
LogError("Error in recv: " << wauthn_error_to_string(m_status));
else
Deserialization::Deserialize(m_buffer, m_status);
return *this;
}
- template <typename... T> GenericClientRequest &recv(T&... args)
+ template <typename... T> GenericClientRequest &Recv(T&... args)
{
- if (failed())
+ if (Failed())
{
m_status = WAUTHN_ERROR_INVALID_STATE;
return *this;
}
- recv();
- if (failed())
+ Recv();
+ if (Failed())
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)
+ template <typename... T> GenericClientRequest &Recv(T&&... args)
{
- if (failed())
+ if (Failed())
{
m_status = WAUTHN_ERROR_INVALID_STATE;
return *this;
}
- recv();
- if (failed())
+ Recv();
+ if (Failed())
{
LogError("Error in recv: " << wauthn_error_to_string(m_status));
}
return *this;
}
- template <typename... T> GenericClientRequest &sendRequest(const T&... args)
+ template <typename... T> GenericClientRequest &SendRequest(const T&... args)
{
- if (failed())
+ if (Failed())
{
m_status = WAUTHN_ERROR_INVALID_STATE;
return *this;
}
Serialization::Serialize(m_buffer, args...);
- if (send().failed())
+ if (Send().Failed())
return *this;
- return recv();
+ return Recv();
}
- GenericClientRequest &sendRequest()
+ GenericClientRequest &SendRequest()
{
- if (failed())
+ if (Failed())
{
m_status = WAUTHN_ERROR_INVALID_STATE;
return *this;
}
- if (send().failed())
+ if (Send().Failed())
return *this;
- return recv();
+ return Recv();
}
virtual int Init() = 0;
void cb_worker(std::shared_ptr<GenericClientRequest> request, A &callbacks, B cred)
{
int ret = try_catch([&]() -> int {
- if (callbacks == nullptr || callbacks->response_callback == nullptr){
- LogError("Invalid callback parameter");
- return WAUTHN_ERROR_INVALID_PARAMETER;
- }
if (callbacks->qrcode_callback == nullptr)
LogDebug("There is no qrcode_callback");
else{ //callbacks->qrcode_callback != nullptr
std::string qr_code;
- if (request->recv(qr_code).failed())
+ if (request->Recv(qr_code).Failed())
LogError("Error on receive qrcode");
LogDebug("Received qr_contents: " << qr_code);
callbacks->qrcode_callback(qr_code.c_str(), callbacks->user_data);
}
- if(request->recv(&cred).failed())
- LogError("Error on receive response");
+ request->Recv(&cred);
+ callbacks->response_callback(cred, wauthn_error_e(request->GetStatus()),
+ callbacks->user_data);
+ if(request->Failed())
+ {
+ LogError("Error on receive response: " << request->GetStatus());
+ return WAUTHN_ERROR_INVALID_STATE;
+ }
+
+ wauthn_hybrid_linked_data_s *linked_data = nullptr;
+
+ while (request->Recv(&linked_data).Incompleted())
+ {
+ callbacks->linked_data_callback(linked_data, wauthn_error_e(request->GetStatus()),
+ callbacks->user_data);
+ LogDebug("More update linked_data can be received. Waiting to recv()");
+ }
+ LogDebug("There is no more updated linked_data");
+ callbacks->linked_data_callback(linked_data, wauthn_error_e(request->GetStatus()),
+ callbacks->user_data);
return WAUTHN_ERROR_NONE;
});
- callbacks->response_callback(cred, wauthn_error_e(ret), callbacks->user_data);
+ if (ret != WAUTHN_ERROR_NONE)
+ LogError("Error on handling callbacks");
}
template <typename T>
if (ret != WAUTHN_ERROR_NONE)
return ret;
- if (request->sendRequest(client_data, options).failed())
- return request->getStatus();
- LogDebug("Response: " << wauthn_error_to_string(request->getStatus()));
+ if (request->SendRequest(client_data, options).Failed())
+ return request->GetStatus();
+ LogDebug("Response: " << wauthn_error_to_string(request->GetStatus()));
- typename T::PubKeyCred *cred = NULL;
+ typename T::PubKeyCred *cred = nullptr;
std::thread worker([request, callbacks, cred]{cb_worker(std::move(request), callbacks, cred);});
worker.detach();
return WAUTHN_ERROR_NONE;
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();
+ if (request.SendRequest().Failed())
+ LogError("Error on cancel request, Response: "
+ << wauthn_error_to_string(request.GetStatus()));
+ return request.GetStatus();
});
}
// For wauthn_error_e
void __checkValidity(const wauthn_error_e data) {
- if (data > WAUTHN_ERROR_NONE || data < WAUTHN_ERROR_CANCELLED)
+ if (data > WAUTHN_ERROR_NONE_AND_WAIT || data < WAUTHN_ERROR_TIMEOUT)
ThrowMsg(SerializationException::InvalidStreamData,
"Invalid value for wauthn_error_e: value=" << data);
}
}
void checkParameters(wauthn_mc_callbacks_s *callbacks)
{
- if (callbacks == nullptr || callbacks->response_callback == nullptr)
+ if (callbacks == nullptr || callbacks->response_callback == nullptr
+ || callbacks->linked_data_callback == nullptr)
ThrowMsg(ClientException::InvalidParameter, "Invalid callback");
}
void checkParameters(wauthn_ga_callbacks_s *callbacks)
{
- if (callbacks == nullptr || callbacks->response_callback == nullptr)
+ if (callbacks == nullptr || callbacks->response_callback == nullptr
+ || callbacks->linked_data_callback == nullptr)
ThrowMsg(ClientException::InvalidParameter, "Invalid callback");
}
void checkParameters(wauthn_hybrid_linked_data_s *linked_device,
MessageBuffer buffer(userData->service->GetSocketManager()->newMessage());
Serialization::Serialize(buffer, result, pubkey_cred);
userData->service->GetSocketManager()->Write(userData->connectionID, std::move(buffer));
+ userData->service->UnsetBusy();
}
else
{
MessageBuffer buffer(userData->service->GetSocketManager()->newMessage());
Serialization::Serialize(buffer, result, pubkey_cred);
userData->service->GetSocketManager()->Write(userData->connectionID, std::move(buffer));
+ userData->service->UnsetBusy();
}
else
{
LogError("Cannot write qr_contents to client");
}
+ static void UpdateLinkedDataCallback(const wauthn_hybrid_linked_data_s *linked_data,
+ wauthn_error_e result,
+ void *user_data)
+ {
+ user_data_s *userData = GetUserData(user_data);
+ if (userData != nullptr)
+ {
+ MessageBuffer buffer(userData->service->GetSocketManager()->newMessage());
+ Serialization::Serialize(buffer, result, linked_data);
+ userData->service->GetSocketManager()->Write(userData->connectionID, std::move(buffer));
+ }
+ else
+ LogError("Cannot write updated linked_data to client");
+ }
+
protected:
static user_data_s *GetUserData(void *user_data)
{
typename T::Callbacks callbacks;
callbacks.qrcode_callback = &(Request::QRCallback);
callbacks.response_callback = &(T::ResponseCallback);
- //checkParameters(clientData, options, &callbacks);
+ callbacks.linked_data_callback = &(Request::UpdateLinkedDataCallback);
+
if (options->linked_device != nullptr) // The qrcode_callback should not be called.
{
LogDebug("Adjust qrcode_callback to nullptr");
});
if (ret != WAUTHN_ERROR_NONE)
LogError("Unhandled Error: " << wauthn_error_to_string(ret));
- UnsetBusy();
}
template <typename T>
*/
SocketManager *GetSocketManager();
+ /**
+ * Unset to server is not busy
+ */
+ void UnsetBusy();
+
virtual SocketManager::ServiceDescription GetServiceDescription() = 0;
private:
*/
int GetCredentials(SocketManager::ConnectionID connectionID, Cred *creds);
- /**
- * Unset to server is not busy
- */
- void UnsetBusy();
-
bool PluginEnabled();
int HandleNotSupported(Event &&msg);
sleep(1);
if (callbacks != nullptr && callbacks->response_callback != nullptr)
callbacks->response_callback(nullptr, WAUTHN_ERROR_NONE, callbacks->user_data);
+
+ if (callbacks != nullptr && callbacks->linked_data_callback != nullptr)
+ {
+ int callTimes = g_target_times_update_linked_data;
+ std::cout << "Calling linked_data_callback for " << callTimes << " times.." <<
+ std::endl;
+ while (callTimes > 1)
+ {
+ sleep(1);
+ callbacks->linked_data_callback(nullptr, WAUTHN_ERROR_NONE_AND_WAIT,
+ callbacks->user_data);
+ callTimes -= 1;
+ }
+ sleep(1);
+ callbacks->linked_data_callback(nullptr, WAUTHN_ERROR_NONE, callbacks->user_data);
+ }
}
void wah_get_assertion(const wauthn_client_data_s *client_data,
sleep(1);
if (callbacks != nullptr && callbacks->response_callback != nullptr)
callbacks->response_callback(nullptr, WAUTHN_ERROR_NONE, callbacks->user_data);
+
+ if (callbacks != nullptr && callbacks->linked_data_callback != nullptr)
+ {
+ int callTimes = g_target_times_update_linked_data;
+ std::cout << "Calling linked_data_callback for " << callTimes << " times.." <<
+ std::endl;
+ while (callTimes > 1)
+ {
+ sleep(1);
+ callbacks->linked_data_callback(nullptr, WAUTHN_ERROR_NONE_AND_WAIT,
+ callbacks->user_data);
+ callTimes -= 1;
+ }
+ sleep(1);
+ callbacks->linked_data_callback(nullptr, WAUTHN_ERROR_NONE, callbacks->user_data);
+ }
}
int wah_cancel()
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);
+ EXPECT_EQ(invalidRequest.GetStatus(), WAUTHN_ERROR_SOCKET);
+ invalidRequest.Send();
+ EXPECT_EQ(invalidRequest.GetStatus(), WAUTHN_ERROR_INVALID_STATE);
} catch (...) {
ret = -1;
}
callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
callbacks->qrcode_callback = test_cb_display_qrcode;
callbacks->response_callback = test_cb_mc_response;
+ callbacks->linked_data_callback = test_cb_update_linked_data;
test_user_data_s *userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s));
userdata->test_data = (char*)("user data");
userdata->test_int = 999;
+ userdata->called_qr = false;
+ userdata->called_response = false;
+ g_target_times_update_linked_data = 1;
+ userdata->times_update_linked_data = 0;
callbacks->user_data = userdata;
retVal = wauthn_process<TestClientRequestMC>(&TestCommonData::clientData,
&TestCommonData::pubkeyCredCreationOptions, callbacks);
EXPECT_EQ(retVal, WAUTHN_ERROR_NOT_SUPPORTED)
- << "[wauthn_process<TestClientRequestMC>] failed. "
- << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+ << "[wauthn_process<TestClientRequestMC>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
sleep(1);
+ EXPECT_EQ(userdata->called_qr, false)
+ << "The QR callback should not be called by cancel" << std::endl;
+ EXPECT_EQ(userdata->called_response, false)
+ << "The response callback should not be called by cancel" << std::endl;
+ EXPECT_EQ(0, userdata->times_update_linked_data)
+ << "The update_linked_data callback should not be called by cancel"
+ << std::endl;
+
free(userdata);
free(callbacks);
}
EXPECT_EQ(ret, 0);
}
-TEST_F(ClientRequestTest, MC_without_QR_callback_P)
+TEST_F(ClientRequestTest, MC_with_LD_and_not_call_QR_callback_P)
{
int ret = 1;
WA::SocketManager manager;
callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
callbacks->qrcode_callback = test_cb_display_qrcode;
callbacks->response_callback = test_cb_mc_response;
+ callbacks->linked_data_callback = test_cb_update_linked_data;
test_user_data_s *userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s));
userdata->test_data = (char*)("user data");
userdata->test_int = 999;
+ userdata->called_qr = false;
+ userdata->called_response = false;
+ g_target_times_update_linked_data = 1;
+ userdata->times_update_linked_data = 0;
callbacks->user_data = userdata;
retVal = wauthn_process<TestClientRequestMC>(&TestCommonData::clientData,
&TestCommonData::pubkeyCredCreationOptions, callbacks);
EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
- << "[wauthn_process<TestClientRequestMC>] failed. "
- << "retVal=" << wauthn_error_to_string(ret) << std::endl;
- sleep(5);
+ << "[wauthn_process<TestClientRequestMC>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+
+ // Waiting for called the callbacks
+ sleep(g_target_times_update_linked_data + 5);
+ EXPECT_EQ(userdata->called_qr, false)
+ << "The QR callback should not be called" << std::endl;
+ EXPECT_EQ(userdata->called_response, true)
+ << "The response callback should be called" << std::endl;
+ EXPECT_EQ(g_target_times_update_linked_data,
+ userdata->times_update_linked_data)
+ << "The update_linked_data callback should be called for setted times"
+ << std::endl;
free(userdata);
free(callbacks);
}
- sleep(1);
ret = 0;
} catch (...) {
std::cout << "Error in starting service, unknown exception occurred" << std::endl;
EXPECT_EQ(ret, 0);
}
-TEST_F(ClientRequestTest, MC_with_QR_callback_P)
+TEST_F(ClientRequestTest, MC_without_LD_and_call_QR_callback_P)
{
int ret = 1;
WA::SocketManager manager;
callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
callbacks->qrcode_callback = test_cb_display_qrcode;
callbacks->response_callback = test_cb_mc_response;
+ callbacks->linked_data_callback = test_cb_update_linked_data;
test_user_data_s *userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s));
userdata->test_data = (char*)("user data");
userdata->test_int = 999;
+ userdata->called_qr = false;
+ userdata->called_response = false;
+ g_target_times_update_linked_data = 1;
+ userdata->times_update_linked_data = 0;
callbacks->user_data = userdata;
retVal = wauthn_process<TestClientRequestMC>(&TestCommonData::clientData,
- &TestCommonData::pubkeyCredCreationOptionsWithQR, callbacks);
+ &TestCommonData::pubkeyCredCreationOptionsNoLD, callbacks);
EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
- << "[wauthn_process<TestClientRequestMC>] failed. "
- << "retVal=" << wauthn_error_to_string(ret) << std::endl;
- sleep(5);
+ << "[wauthn_process<TestClientRequestMC>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+
+ // Waiting for called the callbacks
+ sleep(g_target_times_update_linked_data + 5);
+ EXPECT_EQ(userdata->called_qr, true)
+ << "The QR callback should be called" << std::endl;
+ EXPECT_EQ(userdata->called_response, true)
+ << "The response callback should be called" << std::endl;
+ EXPECT_EQ(g_target_times_update_linked_data,
+ userdata->times_update_linked_data)
+ << "The update_linked_data callback should be called for setted times"
+ << std::endl;
+
free(userdata);
free(callbacks);
}
}
-TEST_F(ClientRequestTest, GA_without_QR_callback_P)
+TEST_F(ClientRequestTest, GA_with_LD_and_not_call_QR_callback_P)
{
int ret = 1;
WA::SocketManager manager;
callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
callbacks->qrcode_callback = test_cb_display_qrcode;
callbacks->response_callback = test_cb_ga_response;
+ callbacks->linked_data_callback = test_cb_update_linked_data;
test_user_data_s *userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s));
userdata->test_data = (char*)("user data");
userdata->test_int = 999;
+ userdata->called_qr = false;
+ userdata->called_response = false;
+ g_target_times_update_linked_data = 1;
+ userdata->times_update_linked_data = 0;
callbacks->user_data = userdata;
retVal = wauthn_process<TestClientRequestGA>(&TestCommonData::clientData,
&TestCommonData::pubkeyCredRequestOptions, callbacks);
EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
- << "[wauthn_process<TestClientRequestGA>] failed. "
- << "retVal=" << wauthn_error_to_string(ret) << std::endl;
- sleep(5);
+ << "[wauthn_process<TestClientRequestGA>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+
+ // Waiting for called the callbacks
+ sleep(g_target_times_update_linked_data + 5);
+ EXPECT_EQ(userdata->called_qr, false)
+ << "The QR callback should not be called" << std::endl;
+ EXPECT_EQ(userdata->called_response, true)
+ << "The response callback should be called" << std::endl;
+ EXPECT_EQ(g_target_times_update_linked_data,
+ userdata->times_update_linked_data)
+ << "The update_linked_data callback should be called for setted times"
+ << std::endl;
+
free(userdata);
free(callbacks);
}
EXPECT_EQ(ret, 0);
}
-TEST_F(ClientRequestTest, GA_with_QR_callback_P)
+TEST_F(ClientRequestTest, GA_without_LD_and_call_QR_callback_P)
{
int ret = 1;
WA::SocketManager manager;
callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
callbacks->qrcode_callback = test_cb_display_qrcode;
callbacks->response_callback = test_cb_ga_response;
+ callbacks->linked_data_callback = test_cb_update_linked_data;
test_user_data_s *userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s));
userdata->test_data = (char*)("user data");
userdata->test_int = 999;
+ userdata->called_qr = false;
+ userdata->called_response = false;
+ g_target_times_update_linked_data = 1;
+ userdata->times_update_linked_data = 0;
callbacks->user_data = userdata;
retVal = wauthn_process<TestClientRequestGA>(&TestCommonData::clientData,
- &TestCommonData::pubkeyCredRequestOptionsWithQR, callbacks);
+ &TestCommonData::pubkeyCredRequestOptionsNoLD, callbacks);
EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
- << "[wauthn_process<TestClientRequestGA>] failed. "
- << "retVal=" << wauthn_error_to_string(ret) << std::endl;
- sleep(5);
+ << "[wauthn_process<TestClientRequestGA>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+
+ // Waiting for called the callbacks
+ sleep(g_target_times_update_linked_data + 5);
+ EXPECT_EQ(userdata->called_qr, true)
+ << "The QR callback should be called" << std::endl;
+ EXPECT_EQ(userdata->called_response, true)
+ << "The response callback should be called" << std::endl;
+ EXPECT_EQ(g_target_times_update_linked_data,
+ userdata->times_update_linked_data)
+ << "The update_linked_data callback should be called for setted times"
+ << std::endl;
+
free(userdata);
free(callbacks);
}
mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
mc_callbacks->qrcode_callback = test_cb_display_qrcode;
mc_callbacks->response_callback = test_cb_mc_response;
+ mc_callbacks->linked_data_callback = test_cb_update_linked_data;
test_user_data_s *mc_userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s));
mc_userdata->test_data = (char*)("user data");
mc_userdata->test_int = 999;
+ mc_userdata->called_qr = false;
+ mc_userdata->called_response = false;
+ g_target_times_update_linked_data = 1;
+ mc_userdata->times_update_linked_data = 0;
mc_callbacks->user_data = mc_userdata;
retVal = wauthn_process<TestClientRequestMC>(&TestCommonData::clientData,
- &TestCommonData::pubkeyCredCreationOptions, mc_callbacks);
+ &TestCommonData::pubkeyCredCreationOptionsNoLD, mc_callbacks);
EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
<< "[wauthn_process<TestClientRequestMC>] failed. "
ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
ga_callbacks->qrcode_callback = test_cb_display_qrcode;
ga_callbacks->response_callback = test_cb_ga_response;
+ ga_callbacks->linked_data_callback = test_cb_update_linked_data;
test_user_data_s *ga_userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s));
ga_userdata->test_data = (char*)("user data");
ga_userdata->test_int = 999;
+ ga_userdata->called_qr = false;
+ ga_userdata->called_response = false;
+ ga_userdata->times_update_linked_data = 0;
ga_callbacks->user_data = ga_userdata;
retVal = wauthn_process<TestClientRequestGA>(&TestCommonData::clientData,
&TestCommonData::pubkeyCredRequestOptions, ga_callbacks);
<< "[wauthn_process<TestClientRequestGA>] failed. "
<< "ret=" << wauthn_error_to_string(retVal) << std::endl;
- sleep(5);
+ // Waiting for called the callbacks
+ sleep(g_target_times_update_linked_data + 5);
+ EXPECT_EQ(mc_userdata->called_qr, true)
+ << "The QR callback for MC should be called" << std::endl;
+ EXPECT_EQ(mc_userdata->called_response, true)
+ << "The response callback for MC should be called" << std::endl;
+ EXPECT_EQ(g_target_times_update_linked_data,
+ mc_userdata->times_update_linked_data)
+ << "The update_linked_data callback for MC should be called for setted times"
+ << std::endl;
+
+ EXPECT_EQ(ga_userdata->called_qr, false)
+ << "The QR callback for GA should not be called by not allowed" << std::endl;
+ EXPECT_EQ(ga_userdata->called_response, false)
+ << "The response callback for GA should not be called by not allowed" << std::endl;
+ EXPECT_EQ(0, ga_userdata->times_update_linked_data)
+ << "The update_linked_data callback for GA should not be called by not allowed"
+ << std::endl;
+
free(mc_userdata);
free(ga_userdata);
free(mc_callbacks);
EXPECT_EQ(ret, 0);
}
-
TEST_F(ClientRequestTest, cancel_P)
{
int ret = 1;
mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
mc_callbacks->qrcode_callback = test_cb_display_qrcode;
mc_callbacks->response_callback = test_cb_mc_response;
+ mc_callbacks->linked_data_callback = test_cb_update_linked_data;
test_user_data_s *mc_userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s));
mc_userdata->test_data = (char*)("user data");
mc_userdata->test_int = 999;
+ mc_userdata->called_qr = false;
+ mc_userdata->called_response = false;
+ g_target_times_update_linked_data = 1;
+ mc_userdata->times_update_linked_data = 0;
mc_callbacks->user_data = mc_userdata;
retVal = wauthn_process<TestClientRequestMC>(&TestCommonData::clientData,
&TestCommonData::pubkeyCredCreationOptions, mc_callbacks);
<< "[wauthn_process<TestClientRequestMC>] failed. "
<< "retVal=" << wauthn_error_to_string(ret) << std::endl;
- sleep(1);
TestClientRequest request(WebAuthnCall::CANCEL);
request.Init();
- if (request.sendRequest().failed())
+ if (request.SendRequest().Failed())
LogError("Error on cancel request, Response: "
- << wauthn_error_to_string(request.getStatus()));
- retVal = request.getStatus();
+ << wauthn_error_to_string(request.GetStatus()));
+ retVal = request.GetStatus();
EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
<< "[wauthn_cancel] failed. "
<< "ret=" << wauthn_error_to_string(retVal) << std::endl;
- sleep(5);
+
+ EXPECT_EQ(mc_userdata->called_qr, false)
+ << "The QR callback should not be called by cancel" << std::endl;
+ EXPECT_EQ(mc_userdata->called_response, false)
+ << "The response callback should not be called by cancel" << std::endl;
+ EXPECT_EQ(0, mc_userdata->times_update_linked_data)
+ << "The update_linked_data callback should not be called by cancel"
+ << std::endl;
+
+ // Waiting for called the callbacks
+ sleep(g_target_times_update_linked_data + 5);
+ free(mc_userdata);
+ free(mc_callbacks);
+ }
+ ret = 0;
+ } catch (...) {
+ std::cout << "Error in starting service, unknown exception occurred" << std::endl;
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(ClientRequestTest, MC_multiple_update_linked_data_P)
+{
+ int ret = 1;
+ WA::SocketManager manager;
+ try{
+ auto service = std::make_unique<WA::TestService>(std::make_shared<TestDLLoader>());
+ manager.RegisterSocketService(std::move(service));
+ SocketManagerLoop loop(manager);
+ {
+ int retVal = WAUTHN_ERROR_NONE;
+ wauthn_mc_callbacks_s *mc_callbacks = nullptr;
+ mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
+ mc_callbacks->qrcode_callback = test_cb_display_qrcode;
+ mc_callbacks->response_callback = test_cb_mc_response;
+ mc_callbacks->linked_data_callback = test_cb_update_linked_data;
+ test_user_data_s *mc_userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s));
+ mc_userdata->test_data = (char*)("user data");
+ mc_userdata->test_int = 999;
+ mc_userdata->called_qr = false;
+ mc_userdata->called_response = false;
+ g_target_times_update_linked_data = 5;
+ mc_userdata->times_update_linked_data = 0;
+ mc_callbacks->user_data = mc_userdata;
+ retVal = wauthn_process<TestClientRequestMC>(&TestCommonData::clientData,
+ &TestCommonData::pubkeyCredCreationOptionsNoLD, mc_callbacks);
+
+ EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
+ << "[wauthn_process<TestClientRequestMC>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+
+ // Waiting for called the callbacks
+ sleep(g_target_times_update_linked_data + 5);
+
+ EXPECT_EQ(mc_userdata->called_qr, true)
+ << "The QR callback should be called" << std::endl;
+ EXPECT_EQ(mc_userdata->called_response, true)
+ << "The response callback should be called" << std::endl;
+ EXPECT_EQ(g_target_times_update_linked_data,
+ mc_userdata->times_update_linked_data)
+ << "The update_linked_data callback should be called for setted times"
+ << std::endl;
+
free(mc_userdata);
free(mc_callbacks);
}
EXPECT_EQ(ret, 0);
}
+TEST_F(ClientRequestTest, GA_multiple_update_linked_data_P)
+{
+ int ret = 1;
+ WA::SocketManager manager;
+ try{
+ auto service = std::make_unique<WA::TestService>(std::make_shared<TestDLLoader>());
+ manager.RegisterSocketService(std::move(service));
+ SocketManagerLoop loop(manager);
+ {
+ int retVal = WAUTHN_ERROR_NONE;
+ wauthn_ga_callbacks_s *ga_callbacks = nullptr;
+ ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
+ ga_callbacks->qrcode_callback = test_cb_display_qrcode;
+ ga_callbacks->response_callback = test_cb_ga_response;
+ ga_callbacks->linked_data_callback = test_cb_update_linked_data;
+ test_user_data_s *ga_userdata = (test_user_data_s*) calloc(1, sizeof(test_user_data_s));
+ ga_userdata->test_data = (char*)("user data");
+ ga_userdata->test_int = 999;
+ ga_userdata->called_qr = false;
+ ga_userdata->called_response = false;
+ g_target_times_update_linked_data = 5;
+ ga_userdata->times_update_linked_data = 0;
+ ga_callbacks->user_data = ga_userdata;
+ retVal = wauthn_process<TestClientRequestGA>(&TestCommonData::clientData,
+ &TestCommonData::pubkeyCredRequestOptionsNoLD, ga_callbacks);
+
+ EXPECT_EQ(retVal, WAUTHN_ERROR_NONE)
+ << "[wauthn_process<TestClientRequestGA>] failed. "
+ << "retVal=" << wauthn_error_to_string(ret) << std::endl;
+
+ // Waiting for called the callbacks
+ sleep(g_target_times_update_linked_data + 5);
+
+ EXPECT_EQ(ga_userdata->called_qr, true)
+ << "The QR callback should be called" << std::endl;
+ EXPECT_EQ(ga_userdata->called_response, true)
+ << "The response callback should be called" << std::endl;
+ EXPECT_EQ(g_target_times_update_linked_data,
+ ga_userdata->times_update_linked_data)
+ << "The update_linked_data callback should be called for setted times"
+ << std::endl;
+
+ free(ga_userdata);
+ free(ga_callbacks);
+ }
+ sleep(1);
+ ret = 0;
+ } catch (...) {
+ std::cout << "Error in starting service, unknown exception occurred" << std::endl;
+ ret = -1;
+ }
+ EXPECT_EQ(ret, 0);
+}
+
} // namespace WebAuthn
auto testContents = static_cast<TestContents *>(data);
if (testContents->path.empty() || !qr_contents) {
std::cout << "qrcode_callback failed" << std::endl;
- std::cout << "QRcode path: " << testContents->path << std::endl;
- std::cout << "qr_contents: " << qr_contents << std::endl;
testContents->status = false;
return;
}
+ else
+ {
+ std::cout << "QRcode path: " << testContents->path << std::endl;
+ std::cout << "qr_contents: " << qr_contents << std::endl;
+ }
if (testContents->negative)
GenerateAndDisplayQR("https://tinyurl.com/5x2bcwjy", *testContents);
else
}
testContents->status = 2;
}
-
+/* TBD
+void UpdateLinkedDataCallback(const wauthn_hybrid_linked_data_s *linked_data,
+ wauthn_error_e result,
+ void *user_data)
+{
+}
+*/
bool Test(struct TestContents &testContents)
{
/* MakeCredential */
wauthn_mc_callbacks_s mcCallbacks;
mcCallbacks.qrcode_callback = DisplayQRCallback;
mcCallbacks.response_callback = MCCallback;
+ // TODO: Add UpdateLinkedDataCallback with the webauthn-ble's update
mcCallbacks.user_data = &testContents;
int ret = wauthn_make_credential(&clientData, &mcOptions, &mcCallbacks);
wauthn_ga_callbacks_s gaCallbacks;
gaCallbacks.qrcode_callback = DisplayQRCallback;
gaCallbacks.response_callback = GACallback;
+ // TODO: Add UpdateLinkedDataCallback with the webauthn-ble's update
gaCallbacks.user_data = &testContents;
ret = wauthn_get_assertion(&clientData, &gaOptions, &gaCallbacks);
TestContents testContents = {0, "/tmp/webauthn-qrcode.png",
{}, {}, WAUTHN_TRANSPORT_NONE};
- if (argc > 1 && std::string_view("-n") == argv[1])
- testContents.negative = true;
+ if (argc == 2)
+ {
+ if (std::string_view("-n") == argv[1])
+ testContents.negative = true;
+ else
+ {
+ std::cout << "only -\"n\" option is supported" << std::endl;
+ return true;
+ }
+ }
+ else if (argc > 2)
+ {
+ std::cout << "Invalid parameters" << std::endl;
+ return true;
+ }
int err = TurnBluetoothOn();
if (err != BT_ERROR_NONE) {
ret = true;
}
- if (system("killall /usr/apps/org.tizen.image-viewer_common/bin/image-viewer")) {
+ if (system("/usr/bin/killall /usr/apps/org.tizen.image-viewer_common/bin/image-viewer")) {
std::cout << "Cannot close org.tizen.image-viewer\n";
ret = true;
}
WAuthnCtypeSerializer::deserialize(buffer, &deserialized, &deserialized_len);
EXPECT_EQ(data_size, deserialized_len);
- if (deserialized_len != 0) { // If deserialized_len is zero, memcmp is guaranteed to return zero
+ if (data_size != 0 && deserialized_len != 0) {
+ // If deserialized_len is zero, memcmp is guaranteed to return zero
EXPECT_EQ(memcmp(data, deserialized, deserialized_len), 0);
}
else {
TEST_F(WAuthnSerializationTest, wauthn_error_e_P)
{
__testSerialization(WAUTHN_ERROR_NONE, __compareWAuthErrorE);
+ __testSerialization(WAUTHN_ERROR_NONE_AND_WAIT, __compareWAuthErrorE);
__testSerialization(WAUTHN_ERROR_NOT_ALLOWED, __compareWAuthErrorE);
__testSerialization(WAUTHN_ERROR_ENCODING_FAILED, __compareWAuthErrorE);
__testSerialization(WAUTHN_ERROR_CANCELLED, __compareWAuthErrorE);
+ __testSerialization(WAUTHN_ERROR_TIMEOUT, __compareWAuthErrorE);
}
TEST_F(WAuthnSerializationTest, wauthn_error_e_N1)
{// serialize: invalid wauthn_error_e
- wauthn_error_e data1 = static_cast<wauthn_error_e>(WAUTHN_ERROR_NONE + 1);
+ wauthn_error_e data1 = static_cast<wauthn_error_e>(WAUTHN_ERROR_NONE_AND_WAIT + 1);
__testSerializeForInvalidMember(data1);
- wauthn_error_e data2 = static_cast<wauthn_error_e>(WAUTHN_ERROR_CANCELLED - 1);
+ wauthn_error_e data2 = static_cast<wauthn_error_e>(WAUTHN_ERROR_TIMEOUT - 1);
__testSerializeForInvalidMember(data2);
}
TEST_F(WAuthnSerializationTest, wauthn_error_e_N2)
{// deserialize: invalid wauthn_error_e
MessageBuffer buffer;
wauthn_error_e deserialized;
- __fillBufferWithTestCommonData(buffer, WAUTHN_ERROR_NONE + 1, nullptr, 0);
+ __fillBufferWithTestCommonData(buffer, WAUTHN_ERROR_NONE_AND_WAIT + 1, nullptr, 0);
try {
WAuthnCtypeSerializer::deserialize(buffer, &deserialized);
EXPECT_TRUE(false);
}
MessageBuffer buffer1;
- __fillBufferWithTestCommonData(buffer1, WAUTHN_ERROR_CANCELLED - 1, nullptr, 0);
+ __fillBufferWithTestCommonData(buffer1, WAUTHN_ERROR_TIMEOUT - 1, nullptr, 0);
try {
WAuthnCtypeSerializer::deserialize(buffer1, &deserialized);
EXPECT_TRUE(false);
wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptions = {&rpEntity, &userEntity,
&pubkeyCredParams2, timeout, &pubkeyCredDescriptors2, &authenticatorSelCri, &pubkeyCredHints2,
attestation, &attestationFormats1, &authenticationExts2, &hybridLinkedData};
- wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsWithQR = {&rpEntity, &userEntity,
+ wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsNoLD = {&rpEntity, &userEntity,
&pubkeyCredParams2, timeout, &pubkeyCredDescriptors2, &authenticatorSelCri, &pubkeyCredHints2,
attestation, &attestationFormats1, &authenticationExts2, nullptr};
wauthn_pubkey_cred_creation_options_s emptyPubkeyCredCreationOptions = {nullptr, nullptr,
wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptions = {timeout, const_cast<char *>(rpId),
&pubkeyCredDescriptors2, user_verification, &pubkeyCredHints2, attestation, &attestationFormats1,
&authenticationExts2, &hybridLinkedData};
- wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsWithQR = {timeout, const_cast<char *>(rpId),
+ wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsNoLD = {timeout, const_cast<char *>(rpId),
&pubkeyCredDescriptors2, user_verification, &pubkeyCredHints2, attestation, &attestationFormats1,
&authenticationExts2, nullptr};
wauthn_pubkey_cred_request_options_s emptyPubkeyCredRequestOptions = {0, nullptr,
int test_int;
bool called_qr;
bool called_response;
+ int times_update_linked_data;
} test_user_data_s;
+inline int g_target_times_update_linked_data;
inline void _print_user_data(void *user_data)
{
- std::cout << "user_data is not null, data=" <<
- (static_cast<test_user_data_s*>(user_data))->test_data <<
- ", int=" << (static_cast<test_user_data_s*>(user_data))->test_int << std::endl;
+ if (user_data == nullptr)
+ std::cout << "user_data is null" << std::endl;
+ else{
+ test_user_data_s *userData = static_cast<test_user_data_s*>(user_data);
+
+ std::cout << "user_data is not null, data=" <<
+ userData->test_data << ", int=" << userData->test_int <<
+ ", qr=" << userData->called_qr << ", response=" <<
+ ", target update times=" << g_target_times_update_linked_data <<
+ ", update times=" << userData->times_update_linked_data << std::endl;
+ }
}
inline void test_cb_display_qrcode(const char *qr_contents, void *user_data)
{
std::cout << "QR Code: " << std::string(qr_contents) << std::endl;
- if (user_data == nullptr)
- std::cout << "user_data is null" << std::endl;
- else
- {
- _print_user_data(user_data);
+ _print_user_data(user_data);
+ if (user_data != nullptr)
(static_cast<test_user_data_s*>(user_data))->called_qr = true;
- }
}
inline void test_cb_mc_response(
std::cout << "pubkey_cred is not null: " <<
pubkey_cred->type << ", " <<
pubkey_cred->authenticator_attachment << std::endl;
- if (user_data == nullptr)
- std::cout << "user_data is null" << std::endl;
- else
- {
- _print_user_data(user_data);
+ _print_user_data(user_data);
+ if (user_data != nullptr)
(static_cast<test_user_data_s*>(user_data))->called_response = true;
- }
}
inline void test_cb_ga_response(
std::cout << "pubkey_cred is null" << std::endl;
else
std::cout << "pubkey_cred is not null" << std::endl;
- if (user_data == nullptr)
- std::cout << "user_data is null" << std::endl;
- else
- {
- _print_user_data(user_data);
+ _print_user_data(user_data);
+ if (user_data != nullptr)
(static_cast<test_user_data_s*>(user_data))->called_response = true;
- }
+}
+
+inline void test_cb_update_linked_data(
+ const wauthn_hybrid_linked_data_s *linked_data,
+ wauthn_error_e result,
+ void *user_data)
+{
+ std::cout << "update_linked_data, result: " << wauthn_error_to_string(result) << std::endl;
+ if (linked_data == nullptr)
+ std::cout << "linked_data is null" << std::endl;
+ else
+ std::cout << "linked_data is not null" << std::endl;
+ (static_cast<test_user_data_s*>(user_data))->times_update_linked_data += 1;
+ _print_user_data(user_data);
}
namespace TestCommonData {
extern unsigned long timeout;
extern wauthn_attestation_pref_e attestation;
extern wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptions;
- extern wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsWithQR;
+ extern wauthn_pubkey_cred_creation_options_s pubkeyCredCreationOptionsNoLD;
extern wauthn_pubkey_cred_creation_options_s emptyPubkeyCredCreationOptions;
extern const char *rpId;
extern wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptions;
- extern wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsWithQR;
+ extern wauthn_pubkey_cred_request_options_s pubkeyCredRequestOptionsNoLD;
extern wauthn_pubkey_cred_request_options_s emptyPubkeyCredRequestOptions;
extern wauthn_pubkey_credential_attestation_s pubkeyCredentialAttestation;
mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
mc_callbacks->qrcode_callback = test_cb_display_qrcode;
mc_callbacks->response_callback = test_cb_mc_response;
+ mc_callbacks->linked_data_callback = test_cb_update_linked_data;
ret = wauthn_make_credential(nullptr,
&TestCommonData::pubkeyCredCreationOptions,
mc_callbacks);
ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
ga_callbacks->qrcode_callback = test_cb_display_qrcode;
ga_callbacks->response_callback = test_cb_ga_response;
+ ga_callbacks->linked_data_callback = test_cb_update_linked_data;
ret = wauthn_get_assertion(nullptr,
&TestCommonData::pubkeyCredRequestOptions,
ga_callbacks);
mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
mc_callbacks->qrcode_callback = test_cb_display_qrcode;
mc_callbacks->response_callback = test_cb_mc_response;
+ mc_callbacks->linked_data_callback = test_cb_update_linked_data;
ret = wauthn_make_credential(&TestCommonData::clientData,
nullptr,
mc_callbacks);
ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
ga_callbacks->qrcode_callback = test_cb_display_qrcode;
ga_callbacks->response_callback = test_cb_ga_response;
+ ga_callbacks->linked_data_callback = test_cb_update_linked_data;
ret = wauthn_get_assertion(&TestCommonData::clientData,
nullptr,
ga_callbacks);
mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
mc_callbacks->qrcode_callback = test_cb_display_qrcode;
mc_callbacks->response_callback = nullptr;
+ mc_callbacks->linked_data_callback = test_cb_update_linked_data;
+ ret = wauthn_make_credential(&TestCommonData::clientData,
+ &TestCommonData::pubkeyCredCreationOptions,
+ mc_callbacks);
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[invalid_callbacks_N] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
+
+ ret = WAUTHN_ERROR_NONE;
+ mc_callbacks->response_callback = test_cb_mc_response;
+ mc_callbacks->linked_data_callback = nullptr;
ret = wauthn_make_credential(&TestCommonData::clientData,
&TestCommonData::pubkeyCredCreationOptions,
mc_callbacks);
ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
ga_callbacks->qrcode_callback = test_cb_display_qrcode;
ga_callbacks->response_callback = nullptr;
+ ga_callbacks->linked_data_callback = test_cb_update_linked_data;
+ ret = wauthn_get_assertion(&TestCommonData::clientData,
+ &TestCommonData::pubkeyCredRequestOptions,
+ ga_callbacks);
+ EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
+ << "[invalid_callbacks_N] failed. "
+ << "ret=" << wauthn_error_to_string(ret) << std::endl;
+
+ ret = WAUTHN_ERROR_NONE;
+ ga_callbacks->response_callback = test_cb_ga_response;
+ ga_callbacks->linked_data_callback = nullptr;
ret = wauthn_get_assertion(&TestCommonData::clientData,
&TestCommonData::pubkeyCredRequestOptions,
ga_callbacks);
mc_callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
mc_callbacks->qrcode_callback = nullptr;
mc_callbacks->response_callback = test_cb_mc_response;
+ mc_callbacks->linked_data_callback = test_cb_update_linked_data;
ret = wauthn_make_credential(&TestCommonData::clientData,
- &TestCommonData::pubkeyCredCreationOptionsWithQR,
+ &TestCommonData::pubkeyCredCreationOptionsNoLD,
mc_callbacks);
EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
<< "[miss_qr_callback_without_linked_data_N] failed. "
ga_callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
ga_callbacks->qrcode_callback = nullptr;
ga_callbacks->response_callback = test_cb_ga_response;
+ ga_callbacks->linked_data_callback = test_cb_update_linked_data;
ret = wauthn_get_assertion(&TestCommonData::clientData,
- &TestCommonData::pubkeyCredRequestOptionsWithQR,
+ &TestCommonData::pubkeyCredRequestOptionsNoLD,
nullptr);
EXPECT_EQ(ret, WAUTHN_ERROR_INVALID_PARAMETER)
<< "[miss_qr_callback_without_linked_data_N] failed. "