Refactor SDK Core to keep all users from all backends in memory

All users for all backend are kept in memory.
Added unit tests.

Closes: MAASMOB-63


Project: 
http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/commit/cad661fe
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/tree/cad661fe
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/diff/cad661fe

Branch: refs/heads/master
Commit: cad661feca828cbc706c477ef660cd2e6b168498
Parents: 0c9b7fa
Author: slav.klenov <[email protected]>
Authored: Tue Apr 26 18:23:29 2016 +0300
Committer: slav.klenov <[email protected]>
Committed: Wed Apr 27 17:00:56 2016 +0300

----------------------------------------------------------------------
 src/mpin_sdk.cpp     | 371 +++++++++++++++++++++-------------------------
 src/mpin_sdk.h       |  17 +--
 src/version.h        |   2 +-
 tests/unit_tests.cpp |   6 +-
 4 files changed, 185 insertions(+), 211 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/cad661fe/src/mpin_sdk.cpp
----------------------------------------------------------------------
diff --git a/src/mpin_sdk.cpp b/src/mpin_sdk.cpp
index 65608aa..41d34b3 100644
--- a/src/mpin_sdk.cpp
+++ b/src/mpin_sdk.cpp
@@ -121,11 +121,21 @@ User::User(const String& id, const String& deviceName) : 
m_id(id), m_deviceName(
 {
 }
 
+String User::GetKey() const
+{
+    return String().Format("%s@%s", m_id.c_str(), m_backend.c_str());
+}
+
 const String& User::GetId() const
 {
     return m_id;
 }
 
+const String& User::GetBackend() const
+{
+    return m_backend;
+}
+
 const String& User::GetDeviceName() const
 {
     return m_deviceName;
@@ -161,6 +171,11 @@ void User::CacheTimePermit(const String& timePermit, int 
date)
     m_timePermitCache.Set(timePermit, date);
 }
 
+void User::SetBackend(const String& backend)
+{
+    m_backend = backend;
+}
+
 void User::SetStartedRegistration(const String& mpinIdHex, const String& 
regOTT)
 {
     m_state = STARTED_REGISTRATION;
@@ -193,8 +208,9 @@ void User::Block()
     m_state = BLOCKED;
 }
 
-Status User::RestoreState(const String& stateString, const String& mpinIdHex, 
const String& regOTT)
+Status User::RestoreState(const String& stateString, const String& mpinIdHex, 
const String& regOTT, const String& backend)
 {
+    SetBackend(backend);
     SetStartedRegistration(mpinIdHex, regOTT);
 
     State state = StringToState(stateString);
@@ -637,6 +653,12 @@ Status MPinSDK::Init(const StringMap& config, IContext* 
ctx)
         return Status(Status::FLOW_ERROR, String("CRYPTO_TEE crypto type is 
currently not supported"));
     }
 
+       Status s = LoadUsersFromStorage();
+    if(s != Status::OK)
+    {
+        return s;
+    }
+
     m_state = INITIALIZED;
     
     String backend = config.Get(CONFIG_BACKEND);
@@ -738,12 +760,6 @@ Status MPinSDK::SetBackend(const String& backend, const 
String& rpsPrefix)
         return s;
     }
 
-       s = LoadUsersFromStorage();
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
     m_state = BACKEND_SET;
     return Status(Status::OK);
 }
@@ -828,7 +844,8 @@ Status MPinSDK::RequestRegistration(UserPtr user, const 
String& activateCode, co
     bool userIsNew = (user->GetState() == User::INVALID);
     if(userIsNew)
     {
-        AddUser(user);
+        user->SetBackend(MakeBackendKey(m_RPAServer));
+           m_users[user->GetKey()] = user;
     }
 
     String mpinIdHex = response.GetJsonData().GetStringParam("mpinId");
@@ -837,7 +854,7 @@ Status MPinSDK::RequestRegistration(UserPtr user, const 
String& activateCode, co
 
     if(userIsNew || userDataChanged)
     {
-       user->SetStartedRegistration(mpinIdHex, regOTT);
+        user->SetStartedRegistration(mpinIdHex, regOTT);
         writeUsersToStorage = true;
     }
 
@@ -1374,53 +1391,69 @@ Status MPinSDK::GetSessionDetails(const String& 
accessCode, OUT SessionDetails&
     return Status::OK;
 }
 
-void MPinSDK::DeleteUser(UserPtr user)
+Status MPinSDK::CheckUserState(UserPtr user, User::State expectedState)
 {
-    DeleteUser(user, m_RPAServer);
-}
+    UsersMap::iterator i = m_users.find(user->GetKey());
+    if(expectedState == User::INVALID)
+    {
+        if(i != m_users.end())
+        {
+            return Status(Status::FLOW_ERROR, String().Format("User '%s' was 
already added", user->GetId().c_str()));
+        }
 
-void MPinSDK::DeleteUser(INOUT UserPtr user, const String& backend)
-{
-    if(MakeBackendKey(backend) == MakeBackendKey(m_RPAServer))
+        if(user->GetState() != User::INVALID)
+        {
+            return Status(Status::FLOW_ERROR, String().Format("Invalid '%s' 
user state: current state=%s, expected state=%s",
+                user->GetId().c_str(), User::StateToString( user->GetState() 
).c_str(), User::StateToString( expectedState ).c_str()));
+        }
+
+        return Status(Status::OK);
+    }
+
+    if(i == m_users.end())
     {
-        DeleteUser(user, m_RPAServer, m_users);
+        return Status(Status::FLOW_ERROR, String().Format("User '%s' was not 
added or has been deleted", user->GetId().c_str()));
     }
-    else
+
+    if(user != i->second)
     {
-        UsersMap usersMap;
-        LoadUsersFromStorage(backend, usersMap);
-        DeleteUser(user, backend, usersMap);
+        return Status(Status::FLOW_ERROR, String().Format("Different user 
object with the '%s' id was previously added", user->GetId().c_str()));
     }
-}
 
-void MPinSDK::DeleteUser(INOUT UserPtr user, const String& backend, UsersMap& 
usersMap)
-{
-    UsersMap::iterator i = usersMap.find(user->GetId());
-    //if(i == m_users.end() || user != i->second)
-    // TODO: Get back to the full user check after the SDK is refactored to 
store full user list (for all backends)
-    if(i == m_users.end())
+    if(user->GetBackend() != MakeBackendKey(m_RPAServer))
     {
-        return;
+        return Status(Status::FLOW_ERROR, String().Format("User '%s' is 
registered within a different backend than the current one", 
user->GetId().c_str()));
     }
 
-       m_crypto->DeleteRegOTT(i->second->GetMPinId());
-    m_crypto->DeleteToken(i->second->GetMPinId());
-    i->second->Invalidate();
-    m_logoutData.erase(i->second);
-    usersMap.erase(i);
-    WriteUsersToStorage(backend, usersMap);
+    if(user->GetState() != expectedState)
+    {
+        return Status(Status::FLOW_ERROR, String().Format("Invalid '%s' user 
state: current state=%s, expected state=%s",
+            user->GetId().c_str(), User::StateToString( user->GetState() 
).c_str(), User::StateToString( expectedState ).c_str()));
+    }
+
+    return Status(Status::OK);
 }
 
-Status MPinSDK::ListUsers(std::vector<UserPtr>& users) const
+void MPinSDK::DeleteUser(UserPtr user)
 {
-    Status s = CheckIfBackendIsSet();
+    Status s = CheckIfIsInitialized();
     if(s != Status::OK)
     {
-        return s;
+        return;
     }
 
-    ListUsers(users, m_users);
-    return Status::OK;
+    UsersMap::iterator i = m_users.find(user->GetKey());
+    if(i == m_users.end() || user != i->second)
+    {
+        return;
+    }
+
+       m_crypto->DeleteRegOTT(i->second->GetMPinId());
+    m_crypto->DeleteToken(i->second->GetMPinId());
+    i->second->Invalidate();
+    m_logoutData.erase(i->second);
+    m_users.erase(i);
+    WriteUsersToStorage();
 }
 
 Status MPinSDK::ListUsers(OUT std::vector<UserPtr>& users, const String& 
backend) const
@@ -1431,68 +1464,73 @@ Status MPinSDK::ListUsers(OUT std::vector<UserPtr>& 
users, const String& backend
         return s;
     }
 
-    UsersMap usersMap;
-    s = LoadUsersFromStorage(backend, usersMap);
-    if(s != Status::OK)
+    users.clear();
+    users.reserve(m_users.size());
+
+    String backendKey = MakeBackendKey(backend);
+
+    for(UsersMap::const_iterator i = m_users.begin(); i != m_users.end(); ++i)
     {
-        return s;
+        if(backendKey.empty() || backendKey == i->second->GetBackend())
+        {
+            users.push_back(i->second);
+        }
     }
 
-    ListUsers(users, usersMap);
     return Status::OK;
 }
 
-void MPinSDK::ListUsers(OUT std::vector<UserPtr>& users, const UsersMap& 
usersMap) const
+Status MPinSDK::ListUsers(OUT std::vector<UserPtr>& users) const
 {
-    users.clear();
-    users.reserve(usersMap.size());
-    for(UsersMap::const_iterator i = usersMap.begin(); i != usersMap.end(); 
++i)
+    Status s = CheckIfBackendIsSet();
+    if(s != Status::OK)
     {
-        users.push_back(i->second);
+        return s;
     }
+
+    return ListUsers(users, m_RPAServer);
 }
 
-void MPinSDK::AddUser(UserPtr user)
+Status MPinSDK::ListAllUsers(OUT std::vector<UserPtr>& users) const
 {
-       m_users[user->GetId()] = user;
+    return ListUsers(users, "");
 }
 
-Status MPinSDK::CheckUserState(UserPtr user, User::State expectedState)
+Status MPinSDK::ListBackends(OUT std::vector<String>& backends) const
 {
-    UsersMap::iterator i = m_users.find(user->GetId());
-    if(expectedState == User::INVALID)
+    Status s = CheckIfIsInitialized();
+    if(s != Status::OK)
     {
-        if(i != m_users.end())
-        {
-            return Status(Status::FLOW_ERROR, String().Format("User '%s' was 
already added", user->GetId().c_str()));
-        }
-
-        if(user->GetState() != User::INVALID)
-        {
-            return Status(Status::FLOW_ERROR, String().Format("Invalid '%s' 
user state: current state=%s, expected state=%s",
-                user->GetId().c_str(), User::StateToString( user->GetState() 
).c_str(), User::StateToString( expectedState ).c_str()));
-        }
-
-        return Status(Status::OK);
+        return s;
     }
 
-    if(i == m_users.end())
+    backends.clear();
+
+    String data;
+    m_context->GetStorage(IStorage::NONSECURE)->GetData(data);
+    data.Trim();
+       if(data.empty())
     {
-        return Status(Status::FLOW_ERROR, String().Format("User '%s' was not 
added or has been deleted", user->GetId().c_str()));
-    }
+               return Status::OK;
+       }
 
-    if(user != i->second)
+       try
     {
-        return Status(Status::FLOW_ERROR, String().Format("Different user with 
the '%s' id was previously added", user->GetId().c_str()));
-    }
+        json::Object allBackendsObject;
+        std::istringstream str(data);
+        json::Reader::Read(allBackendsObject, str);
 
-    if(user->GetState() != expectedState)
+        for(json::Object::const_iterator i = allBackendsObject.Begin(); i != 
allBackendsObject.End(); ++i)
+        {
+            backends.push_back(i->name);
+        }
+    }
+    catch(const json::Exception& e)
     {
-        return Status(Status::FLOW_ERROR, String().Format("Invalid '%s' user 
state: current state=%s, expected state=%s",
-            user->GetId().c_str(), User::StateToString( user->GetState() 
).c_str(), User::StateToString( expectedState ).c_str()));
+        return Status(Status::STORAGE_ERROR, e.what());
     }
 
-    return Status(Status::OK);
+    return Status::OK;
 }
 
 String MPinSDK::MakeBackendKey(const String& backendServer) const
@@ -1506,31 +1544,10 @@ String MPinSDK::MakeBackendKey(const String& 
backendServer) const
 
 Status MPinSDK::WriteUsersToStorage() const
 {
-    return WriteUsersToStorage(m_RPAServer, m_users);
-}
-
-Status MPinSDK::WriteUsersToStorage(const String& backendServer, const 
UsersMap& usersMap) const
-{
-       IStorage* storage = m_context->GetStorage(IStorage::NONSECURE);
-       String data;
-       storage->GetData(data);
-    data.Trim();
-       
        try
        {
-        json::Object allBackendsObject;
-        if(!data.empty())
-        {
-            std::istringstream strIn(data);
-            json::Reader::Read(allBackendsObject, strIn);
-        }
-
-        String backend = MakeBackendKey(backendServer);
-
-        json::Object& rootObject = (json::Object&) allBackendsObject[backend];
-        rootObject.Clear();
-               
-               for (UsersMap::const_iterator i = usersMap.begin(); i != 
usersMap.end(); ++i)
+        json::Object rootObject;
+        for (UsersMap::const_iterator i = m_users.begin(); i != m_users.end(); 
++i)
                {
                        UserPtr user = i->second;
 
@@ -1548,8 +1565,8 @@ Status MPinSDK::WriteUsersToStorage(const String& 
backendServer, const UsersMap&
 
             userObject["state"] = json::String(user->GetStateString());
 
-            rootObject[user->GetMPinIdHex()] = userObject;
-                       
+            ((json::Object&) 
rootObject[user->GetBackend()])[user->GetMPinIdHex()] = userObject;
+
             Status s;
             switch(user->GetState())
             {
@@ -1567,32 +1584,26 @@ Status MPinSDK::WriteUsersToStorage(const String& 
backendServer, const UsersMap&
                        {
                                return s;
                        }
-               }
+        }
 
                std::stringstream strOut;
-               json::Writer::Write(allBackendsObject, strOut);
-               storage->SetData(strOut.str());
-               
+               json::Writer::Write(rootObject, strOut);
+               
m_context->GetStorage(IStorage::NONSECURE)->SetData(strOut.str());
        }
     catch(const json::Exception& e)
     {
         return Status(Status::STORAGE_ERROR, e.what());
     }
-    
-    return Status(Status::OK);
+
+    return Status::OK;
 }
 
 Status MPinSDK::LoadUsersFromStorage()
 {
     ClearUsers();
-    return LoadUsersFromStorage(m_RPAServer, m_users);
-}
 
-Status MPinSDK::LoadUsersFromStorage(const String& backendServer, UsersMap& 
usersMap) const
-{
-       IStorage* storage = m_context->GetStorage(IStorage::NONSECURE);
        String data;
-       storage->GetData(data);
+       m_context->GetStorage(IStorage::NONSECURE)->GetData(data);
     data.Trim();
        if(data.empty())
     {
@@ -1601,94 +1612,54 @@ Status MPinSDK::LoadUsersFromStorage(const String& 
backendServer, UsersMap& user
 
        try
     {
-        json::Object allBackendsObject;
+        json::Object rootObject;
         std::istringstream str(data);
-        json::Reader::Read(allBackendsObject, str);
-
-        String backend = MakeBackendKey(backendServer);
+        json::Reader::Read(rootObject, str);
 
-        json::Object::const_iterator i = allBackendsObject.Find(backend);
-        if(i == allBackendsObject.End())
+        for(json::Object::const_iterator backendsIter = rootObject.Begin(); 
backendsIter != rootObject.End(); ++backendsIter)
         {
-            return Status(Status::OK);
-        }
+            const json::Object& backendObject = (const json::Object&) 
backendsIter->element;
 
-        const json::Object& rootObject = (const json::Object&) i->element;
-        for(i = rootObject.Begin(); i != rootObject.End(); ++i)
-        {
-            const String& mpinIdHex = i->name;
-                       String mpinId = util::HexDecode(mpinIdHex);
-                       util::JsonObject mpinIdJson;
-                       if(!mpinIdJson.Parse(mpinId.c_str()))
-            {
-                return Status(Status::STORAGE_ERROR, String().Format("Failed 
to parse mpinId json: '%s'", mpinId.c_str()));
-            }
-            const json::Object& userObject = (const json::Object&) i->element;
-                       const std::string& id = ((const json::String&) 
mpinIdJson["userID"]).Value();
-            std::string deviceName;
-            json::Object::const_iterator dni = userObject.Find("deviceName");
-            if(dni != userObject.End())
+            for(json::Object::const_iterator usersIter = 
backendObject.Begin(); usersIter != backendObject.End(); ++usersIter)
             {
-                deviceName = ((const json::String&) dni->element).Value();
+                const String& mpinIdHex = usersIter->name;
+                           String mpinId = util::HexDecode(mpinIdHex);
+                           util::JsonObject mpinIdJson;
+                           if(!mpinIdJson.Parse(mpinId.c_str()))
+                {
+                    return Status(Status::STORAGE_ERROR, 
String().Format("Failed to parse mpinId json: '%s'", mpinId.c_str()));
+                }
+                const json::Object& userObject = (const json::Object&) 
usersIter->element;
+                           const std::string& id = ((const json::String&) 
mpinIdJson["userID"]).Value();
+                std::string deviceName;
+                json::Object::const_iterator dni = 
userObject.Find("deviceName");
+                if(dni != userObject.End())
+                {
+                    deviceName = ((const json::String&) dni->element).Value();
+                }
+
+                           String regOTT;
+                Status s = m_crypto->LoadRegOTT(mpinId, regOTT);
+                           if(s != Status::OK)
+                           {
+                                   return s;
+                           }
+
+                UserPtr user = MakeNewUser(id, deviceName);
+                s = user->RestoreState(((const json::String&) 
userObject["state"]).Value(), mpinIdHex, regOTT, backendsIter->name);
+                if(s != Status::OK)
+                {
+                    return s;
+                }
+
+                const json::Object& timePermitCacheObject = (const 
json::Object&) userObject["timePermitCache"];
+                int date = (int) ((const json::Number&) 
timePermitCacheObject["date"]).Value();
+                const String& timePermit = util::HexDecode(((const 
json::String&) timePermitCacheObject["timePermit"]).Value());
+
+                user->CacheTimePermit(timePermit, date);
+
+                m_users[user->GetKey()] = user;
             }
-
-                       String regOTT;
-            Status s = m_crypto->LoadRegOTT(mpinId, regOTT);
-                       if(s != Status::OK)
-                       {
-                               return s;
-                       }
-
-            UserPtr user = MakeNewUser(id, deviceName);
-            s = user->RestoreState(((const json::String&) 
userObject["state"]).Value(), mpinIdHex, regOTT);
-            if(s != Status::OK)
-            {
-                return s;
-            }
-
-            const json::Object& timePermitCacheObject = (const json::Object&) 
userObject["timePermitCache"];
-            int date = (int) ((const json::Number&) 
timePermitCacheObject["date"]).Value();
-            const String& timePermit = util::HexDecode(((const json::String&) 
timePermitCacheObject["timePermit"]).Value());
-
-            user->CacheTimePermit(timePermit, date);
-
-            usersMap[id] = user;
-               }
-    }
-    catch(const json::Exception& e)
-    {
-        return Status(Status::STORAGE_ERROR, e.what());
-    }
-
-       return Status(Status::OK);
-}
-
-Status MPinSDK::ListBackends(OUT std::vector<String>& backends) const
-{
-    Status s = CheckIfIsInitialized();
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-    IStorage* storage = m_context->GetStorage(IStorage::NONSECURE);
-       String data;
-       storage->GetData(data);
-    data.Trim();
-       if(data.empty())
-    {
-               return Status::OK;
-       }
-
-       try
-    {
-        json::Object allBackendsObject;
-        std::istringstream str(data);
-        json::Reader::Read(allBackendsObject, str);
-
-        for(json::Object::const_iterator i = allBackendsObject.Begin(); i != 
allBackendsObject.End(); ++i)
-        {
-            backends.push_back(i->name);
         }
     }
     catch(const json::Exception& e)
@@ -1699,11 +1670,6 @@ Status MPinSDK::ListBackends(OUT std::vector<String>& 
backends) const
     return Status::OK;
 }
 
-const char * MPinSDK::GetVersion()
-{
-    return MPIN_SDK_V2_VERSION;
-}
-
 bool MPinSDK::CanLogout(UserPtr user)
 {
        LogoutDataMap::iterator i = m_logoutData.find(user);
@@ -1773,3 +1739,8 @@ String MPinSDK::GetClientParam(const String& key)
        m_clientSettings[key].Accept(sv);
        return sv.GetData();
 }
+
+const char * MPinSDK::GetVersion()
+{
+    return MPIN_SDK_V2_VERSION;
+}

http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/cad661fe/src/mpin_sdk.h
----------------------------------------------------------------------
diff --git a/src/mpin_sdk.h b/src/mpin_sdk.h
index bd7a2f1..77ca6f6 100644
--- a/src/mpin_sdk.h
+++ b/src/mpin_sdk.h
@@ -173,29 +173,33 @@ public:
         };
 
         const String& GetId() const;
+        const String& GetBackend() const;
         const String& GetMPinId() const;
         State GetState() const;
 
     private:
         friend class MPinSDK;
         User(const String& id, const String& deviceName);
+        String GetKey() const;
         const String& GetDeviceName() const;
         const String& GetMPinIdHex() const;
         const String& GetRegOTT() const;
         const TimePermitCache& GetTimePermitCache() const;
         void CacheTimePermit(const String& timePermit, int date);
+        void SetBackend(const String& backend);
         void SetStartedRegistration(const String& mpinIdHex, const String& 
regOTT);
         void SetActivated();
         void SetRegistered();
         void Invalidate();
         void Block();
-        Status RestoreState(const String& stateString, const String& 
mpinIdHex, const String& regOTT);
+        Status RestoreState(const String& stateString, const String& 
mpinIdHex, const String& regOTT, const String& backend);
         String GetStateString() const;
         static String StateToString(State state);
         static State StringToState(const String& stateString);
 
     private:
         String m_id;
+        String m_backend;
         String m_deviceName;
         State m_state;
         String m_mpinId;
@@ -256,14 +260,14 @@ public:
     Status GetSessionDetails(const String& accessCode, OUT SessionDetails& 
sessionDetails);
 
     void DeleteUser(INOUT UserPtr user);
-    void DeleteUser(INOUT UserPtr user, const String& backend);
-    Status ListUsers(OUT std::vector<UserPtr>& users) const;
     Status ListUsers(OUT std::vector<UserPtr>& users, const String& backend) 
const;
+    Status ListUsers(OUT std::vector<UserPtr>& users) const;
+    Status ListAllUsers(OUT std::vector<UserPtr>& users) const;
     Status ListBackends(OUT std::vector<String>& backends) const;
-    const char * GetVersion();
     bool CanLogout(IN UserPtr user);
     bool Logout(IN UserPtr user);
        String GetClientParam(const String& key);
+    const char * GetVersion();
 
     static const char *CONFIG_BACKEND;
     static const char *CONFIG_RPS_PREFIX;
@@ -361,15 +365,10 @@ private:
     Status GetCertivoxTimePermitShare(INOUT UserPtr user, const 
util::JsonObject& cutomerTimePermitData, OUT String& resultTimePermit);
     bool ValidateAccessNumber(const String& accessNumber);
     bool ValidateAccessNumberChecksum(const String& accessNumber);
-    void AddUser(IN UserPtr user);
     Status CheckUserState(IN UserPtr user, User::State expectedState);
-    void DeleteUser(INOUT UserPtr user, const String& backend, UsersMap& 
usersMap);
     String MakeBackendKey(const String& backendServer) const;
        Status WriteUsersToStorage() const;
-       Status WriteUsersToStorage(const String& backendServer, const UsersMap& 
usersMap) const;
        Status LoadUsersFromStorage();
-    Status LoadUsersFromStorage(const String& backendServer, UsersMap& 
usersMap) const;
-    void ListUsers(OUT std::vector<UserPtr>& users, const UsersMap& usersMap) 
const;
 
     static const char *DEFAULT_RPS_PREFIX;
     static const int AN_WITH_CHECKSUM_LEN = 7;

http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/cad661fe/src/version.h
----------------------------------------------------------------------
diff --git a/src/version.h b/src/version.h
index a9b268d..1ae5af5 100644
--- a/src/version.h
+++ b/src/version.h
@@ -25,6 +25,6 @@ under the License.
 #define _MPIN_SDK_VERSION_H_
 
 #define MPIN_SDK_VERSION "1.0.0"
-#define MPIN_SDK_V2_VERSION "2.1.0"
+#define MPIN_SDK_V2_VERSION "2.2.0"
 
 #endif // _MPIN_SDK_VERSION_H_

http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/cad661fe/tests/unit_tests.cpp
----------------------------------------------------------------------
diff --git a/tests/unit_tests.cpp b/tests/unit_tests.cpp
index 055d7ee..f963195 100644
--- a/tests/unit_tests.cpp
+++ b/tests/unit_tests.cpp
@@ -191,10 +191,14 @@ BOOST_AUTO_TEST_CASE(testUsers2)
     }
 
     users.clear();
+    sdk.ListAllUsers(users);
+    BOOST_CHECK_EQUAL(users.size(), 1);
+
+    users.clear();
     sdk.ListUsers(users, backend);
     BOOST_CHECK_EQUAL(users.size(), 1);
 
-    sdk.DeleteUser(users[0], backend);
+    sdk.DeleteUser(users[0]);
     users.clear();
     sdk.ListUsers(users, backend);
     BOOST_CHECK(users.empty());

Reply via email to