blob: 6892270ca6994b28aa07d853d3fcc25f3a5552fd [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#include "mpin_sdk.h"
#include "contexts/auto_context.h"
#include "common/http_request.h"
#include "common/access_number_thread.h"
#include "CvTime.h"
#include "CvLogger.h"
#define BOOST_TEST_MODULE Simple testcases
#include "boost/test/included/unit_test.hpp"
typedef MPinSDK::User User;
typedef MPinSDK::UserPtr UserPtr;
typedef MPinSDK::Status Status;
typedef MPinSDK::String String;
static AutoContext context;
static MPinSDK sdk;
static MPinSDK::StringMap config;
static const char *backend = "http://192.168.98.98:8005";
using namespace boost::unit_test;
static std::ostream& operator<<(std::ostream& ostr, const Status& s)
{
ostr << s.GetStatusCode();
return ostr;
}
BOOST_AUTO_TEST_CASE(testNoInit)
{
unit_test_log.set_threshold_level(log_messages);
BOOST_MESSAGE("Starting testNoInit...");
CvShared::InitLogger("cvlog.txt", CvShared::enLogLevel_None);
int argc = framework::master_test_suite().argc;
if(argc > 1)
{
char **argv = framework::master_test_suite().argv;
backend = argv[1];
}
Status s = sdk.TestBackend("12354");
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
s = sdk.SetBackend("12354");
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
UserPtr user = sdk.MakeNewUser("testUser");
s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
s = sdk.RestartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
s = sdk.ConfirmRegistration(user);
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
s = sdk.FinishRegistration(user, "");
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
s = sdk.StartAuthentication(user);
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
s = sdk.FinishAuthentication(user, "");
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
String authResultData;
s = sdk.FinishAuthentication(user, "", authResultData);
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
MPinSDK::OTP otp;
s = sdk.FinishAuthenticationOTP(user, "", otp);
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
s = sdk.FinishAuthenticationAN(user, "", "");
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
BOOST_MESSAGE(" testNoInit finished");
}
BOOST_AUTO_TEST_CASE(testInit)
{
BOOST_MESSAGE("Starting testInit...");
config.Put(MPinSDK::CONFIG_BACKEND, backend);
Status s = sdk.Init(config, &context);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_MESSAGE(" testInit finished");
}
BOOST_AUTO_TEST_CASE(testBackend)
{
BOOST_MESSAGE("Starting testBackend...");
Status s = sdk.TestBackend("https://m-pindemo.certivox.org");
BOOST_CHECK_EQUAL(s, Status::OK);
s = sdk.TestBackend("https://blabla.certivox.org");
BOOST_CHECK_NE(s, Status::OK);
BOOST_MESSAGE(" testBackend finished");
}
BOOST_AUTO_TEST_CASE(setBackend)
{
BOOST_MESSAGE("Starting setBackend...");
Status s = sdk.SetBackend("https://blabla.certivox.org");
BOOST_CHECK_NE(s, Status::OK);
s = sdk.SetBackend(backend);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_MESSAGE(" setBackend finished");
}
BOOST_AUTO_TEST_CASE(testUsers1)
{
BOOST_MESSAGE("Starting testUsers1...");
UserPtr user = sdk.MakeNewUser("testUser");
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
sdk.DeleteUser(user);
std::vector<UserPtr> users;
sdk.ListUsers(users);
BOOST_CHECK(users.empty());
BOOST_MESSAGE(" testUsers1 finished");
}
BOOST_AUTO_TEST_CASE(testUsers2)
{
BOOST_MESSAGE("Starting testUsers2...");
UserPtr user = sdk.MakeNewUser("testUser");
Status s = sdk.StartRegistration(user);
std::vector<UserPtr> users;
sdk.ListUsers(users);
BOOST_CHECK_EQUAL(users.size(), 1);
std::vector<String> backends;
sdk.ListBackends(backends);
BOOST_CHECK_EQUAL(backends.size(), 1);
if(!backends.empty())
{
users.clear();
sdk.ListUsers(users, backends[0]);
BOOST_CHECK_EQUAL(users.size(), 1);
}
users.clear();
sdk.ListUsers(users, backend);
BOOST_CHECK_EQUAL(users.size(), 1);
sdk.DeleteUser(user);
BOOST_MESSAGE(" testUsers2 finished");
}
BOOST_AUTO_TEST_CASE(testUsers3)
{
BOOST_MESSAGE("Starting testUsers3...");
UserPtr user = sdk.MakeNewUser("testUser");
Status s = sdk.StartAuthentication(user);
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
s = sdk.FinishRegistration(user, "");
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
s = sdk.RestartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
BOOST_MESSAGE(" testUsers3 finished");
}
BOOST_AUTO_TEST_CASE(testUsers4)
{
BOOST_MESSAGE("Starting testUsers4...");
int count = 10;
for(int i = 0; i < count; ++i)
{
String id;
id.Format("testUser%03d", i);
UserPtr user = sdk.MakeNewUser(id);
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
}
std::vector<UserPtr> users;
sdk.ListUsers(users);
BOOST_CHECK_EQUAL(users.size(), count);
for(std::vector<UserPtr>::iterator i = users.begin(); i != users.end(); ++i)
{
UserPtr user = *i;
sdk.DeleteUser(user);
}
sdk.ListUsers(users);
BOOST_CHECK(users.empty());
BOOST_MESSAGE(" testUsers4 finished");
}
BOOST_AUTO_TEST_CASE(testUsers5)
{
BOOST_MESSAGE("Starting testUsers5...");
UserPtr user = sdk.MakeNewUser("testUser");
sdk.StartRegistration(user);
BOOST_CHECK(!sdk.CanLogout(user));
BOOST_CHECK(!sdk.Logout(user));
sdk.DeleteUser(user);
BOOST_MESSAGE(" testUsers5 finished");
}
BOOST_AUTO_TEST_CASE(testRegister1)
{
BOOST_MESSAGE("Starting testRegister1...");
UserPtr user = sdk.MakeNewUser("testUser");
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.ConfirmRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.FinishRegistration(user, "1234");
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
sdk.DeleteUser(user);
BOOST_MESSAGE(" testRegister1 finished");
}
BOOST_AUTO_TEST_CASE(testRegister2)
{
BOOST_MESSAGE("Starting testRegister2...");
UserPtr user = sdk.MakeNewUser("testUser");
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.RestartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
sdk.DeleteUser(user);
BOOST_MESSAGE(" testRegister2 finished");
}
BOOST_AUTO_TEST_CASE(testRegister3)
{
BOOST_MESSAGE("Starting testRegister3...");
UserPtr user = sdk.MakeNewUser("");
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::HTTP_REQUEST_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
s = sdk.FinishRegistration(user, "");
BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
sdk.DeleteUser(user);
BOOST_MESSAGE(" testRegister3 finished");
}
BOOST_AUTO_TEST_CASE(testRegister4)
{
BOOST_MESSAGE("Starting testRegister4...");
UserPtr user = sdk.MakeNewUser("testUser");
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.ConfirmRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.FinishRegistration(user, "");
BOOST_CHECK_EQUAL(s, Status::PIN_INPUT_CANCELED);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
sdk.DeleteUser(user);
BOOST_MESSAGE(" testRegister4 finished");
}
BOOST_AUTO_TEST_CASE(testAuthenticate1)
{
BOOST_MESSAGE("Starting testAuthenticate1...");
UserPtr user = sdk.MakeNewUser("testUser");
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.ConfirmRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.FinishRegistration(user, "1234");
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
s = sdk.StartAuthentication(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
s = sdk.FinishAuthentication(user, "1234");
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
String authData;
//s = sdk.StartAuthentication(user);
s = sdk.FinishAuthentication(user, "1234", authData);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
//s = sdk.StartAuthentication(user);
s = sdk.FinishAuthentication(user, "1235");
BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
//s = sdk.StartAuthentication(user);
s = sdk.FinishAuthentication(user, "1234");
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
sdk.DeleteUser(user);
BOOST_MESSAGE(" testAuthenticate1 finished");
}
BOOST_AUTO_TEST_CASE(testAuthenticate2)
{
BOOST_MESSAGE("Starting testAuthenticate2...");
UserPtr user = sdk.MakeNewUser("testUser");
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.ConfirmRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.FinishRegistration(user, "1234");
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
s = sdk.StartAuthentication(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
s = sdk.FinishAuthentication(user, "1111");
BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
//s = sdk.StartAuthentication(user);
s = sdk.FinishAuthentication(user, "1111");
BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
//s = sdk.StartAuthentication(user);
s = sdk.FinishAuthentication(user, "1111");
BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
BOOST_CHECK_EQUAL(user->GetState(), User::BLOCKED);
sdk.DeleteUser(user);
BOOST_MESSAGE(" testAuthenticate2 finished");
}
BOOST_AUTO_TEST_CASE(testAuthenticateOTP)
{
BOOST_MESSAGE("Starting testAuthenticateOTP...");
UserPtr user = sdk.MakeNewUser("testUser");
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.ConfirmRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.FinishRegistration(user, "1234");
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
s = sdk.StartAuthentication(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
MPinSDK::OTP otp;
s = sdk.FinishAuthenticationOTP(user, "1234", otp);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
BOOST_CHECK_EQUAL(otp.status, Status::RESPONSE_PARSE_ERROR);
sdk.DeleteUser(user);
BOOST_MESSAGE(" testAuthenticateOTP finished");
}
static AccessNumberThread g_accessNumberThread;
BOOST_AUTO_TEST_CASE(testAuthenticateAN1)
{
BOOST_MESSAGE("Starting testAuthenticateAN1...");
// Register user
UserPtr user = sdk.MakeNewUser("testUser");
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.ConfirmRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.FinishRegistration(user, "1234");
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
// Request access number
HttpRequest req;
HttpRequest::StringMap headers;
headers.Put("Content-Type", "application/json");
headers.Put("Accept", "*/*");
req.SetHeaders(headers);
String url = String().Format("%s/rps/getAccessNumber", backend);
bool res = req.Execute(MPinSDK::IHttpRequest::POST, url);
BOOST_CHECK(res);
BOOST_CHECK_EQUAL(req.GetHttpStatusCode(), 200);
String data = req.GetResponseData();
util::JsonObject json;
res = json.Parse(data.c_str());
BOOST_CHECK(res);
String accessNumber = json.GetStringParam("accessNumber");
BOOST_CHECK(accessNumber.length() > 0);
// Start access number thread
g_accessNumberThread.Start(backend, json.GetStringParam("webOTT"), sdk.GetClientParam("authenticateURL"));
// Authenticate with access number
s = sdk.StartAuthentication(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
s = sdk.FinishAuthenticationAN(user, "1234", accessNumber);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
// The backend *must* support logout data
BOOST_CHECK(sdk.CanLogout(user));
BOOST_CHECK(sdk.Logout(user));
sdk.DeleteUser(user);
BOOST_MESSAGE(" testAuthenticateAN1 finished");
}
BOOST_AUTO_TEST_CASE(testAuthenticateAN2)
{
BOOST_MESSAGE("Starting testAuthenticateAN2...");
// Register user
UserPtr user = sdk.MakeNewUser("testUser");
Status s = sdk.StartRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.ConfirmRegistration(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
s = sdk.FinishRegistration(user, "1234");
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
// Request access number
HttpRequest req;
HttpRequest::StringMap headers;
headers.Put("Content-Type", "application/json");
headers.Put("Accept", "*/*");
req.SetHeaders(headers);
String url = String().Format("%s/rps/getAccessNumber", backend);
bool res = req.Execute(MPinSDK::IHttpRequest::POST, url);
BOOST_CHECK(res);
BOOST_CHECK_EQUAL(req.GetHttpStatusCode(), 200);
String data = req.GetResponseData();
util::JsonObject json;
res = json.Parse(data.c_str());
BOOST_CHECK(res);
String accessNumber = json.GetStringParam("accessNumber");
BOOST_CHECK(accessNumber.length() > 0);
// Simulate wrong access number
String originalAccessNumber = accessNumber;
accessNumber[3] += (char) 1;
if(accessNumber[3] > '9')
{
accessNumber[3] = '0';
}
// Start access number thread
g_accessNumberThread.Start(backend, json.GetStringParam("webOTT"), sdk.GetClientParam("authenticateURL"));
// Authenticate with access number
s = sdk.StartAuthentication(user);
BOOST_CHECK_EQUAL(s, Status::OK);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
s = sdk.FinishAuthenticationAN(user, "1234", accessNumber);
BOOST_CHECK_EQUAL(s, Status::INCORRECT_ACCESS_NUMBER);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
// The backend *must* support logout data
BOOST_CHECK(!sdk.CanLogout(user));
// Simulate wrong pin - must fail on access number validation too
//s = sdk.StartAuthentication(user);
s = sdk.FinishAuthenticationAN(user, "1233", accessNumber);
BOOST_CHECK_EQUAL(s, Status::INCORRECT_ACCESS_NUMBER);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
// Fix access number - must fail with incorrect pin already
accessNumber = originalAccessNumber;
//s = sdk.StartAuthentication(user);
s = sdk.FinishAuthenticationAN(user, "1233", accessNumber);
BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
sdk.DeleteUser(user);
// Wait the AccessNumberThread to complete
CvShared::SleepFor(CvShared::Millisecs(AccessNumberThread::RETRY_INTERVAL_MILLISEC * AccessNumberThread::MAX_TRIES).Value());
BOOST_MESSAGE(" testAuthenticateAN2 finished");
}