Commit 1dc40bd1 authored by johan's avatar johan
Browse files

Add is_user API to check if a user is active in local storage

parent af311a2a
......@@ -165,6 +165,15 @@ namespace lime {
*/
void delete_user(const std::string &localDeviceId, const limeCallback &callback);
/**
* @brief Check if a user is present and active in local storage
*
* @param[in] localDeviceId used to identify which local account looking up, shall be the GRUU
*
* @return true if the user is active in the local storage, false otherwise
*/
bool is_user(const std::string &localDeviceId);
/**
* @brief Encrypt a buffer (text or file) for a given list of recipient devices
*
......
......@@ -52,7 +52,8 @@ enum LIME_FFI_ERROR {
LIME_FFI_SUCCESS = 0,
LIME_FFI_INVALID_CURVE_ARGUMENT = -1,
LIME_FFI_INTERNAL_ERROR = -2,
LIME_FFI_OUTPUT_BUFFER_TOO_SMALL = -3
LIME_FFI_OUTPUT_BUFFER_TOO_SMALL = -3,
LIME_FFI_USER_NOT_FOUND = -4
};
/** Identifies the elliptic curve used in lime, the values assigned are used in localStorage and X3DH server
......@@ -203,6 +204,14 @@ int lime_ffi_create_user(lime_manager_t manager, const char *localDeviceId,
*/
int lime_ffi_delete_user(lime_manager_t manager, const char *localDeviceId, const lime_ffi_Callback callback, void *callbackUserData);
/**
* @brief Check if a user is present and active in local storage
*
* @param[in] localDeviceId used to identify which local account looking up, shall be the GRUU (Null terminated string)
*
* @return LIME_FFI_SUCCESS if the user is active in the local storage, LIME_FFI_USER_NOT_FOUND otherwise
*/
int lime_ffi_is_user(lime_manager_t manager, const char *localDeviceId);
/**
* @brief Compute the maximum buffer sizes for the encryption outputs: DRmessage and cipherMessage
......
......@@ -99,6 +99,15 @@ public class LimeManager {
*/
public native void delete_user(String localDeviceId, LimeStatusCallback statusObj) throws LimeException;
/**
* @brief Check if a user is present and active in local storage
*
* @param[in] localDeviceId Identify the local user acount to use, it must be unique and is also be used as Id on the X3DH key server, it shall be the GRUU
*
* @return true if the user is active in the local storage, false otherwise
*/
public native boolean is_user(String localDeviceId) throws LimeException;
/**
* @brief Encrypt a buffer (text or file) for a given list of recipient devices
*
......
......@@ -219,6 +219,19 @@ int lime_ffi_delete_user(lime_manager_t manager, const char *localDeviceId, cons
return LIME_FFI_SUCCESS;
}
int lime_ffi_is_user(lime_manager_t manager, const char *localDeviceId) {
try {
if (manager->context->is_user(std::string(localDeviceId))) {
return LIME_FFI_SUCCESS;
} else {
return LIME_FFI_USER_NOT_FOUND;
}
} catch (exception const &e) { // catch anything (BctbxException are already taken care of by is_user, but other kind may arise)
LIME_LOGE<<"FFI failed to delete user: "<<e.what();
return LIME_FFI_INTERNAL_ERROR;
}
}
int lime_ffi_encryptOutBuffersMaximumSize(const size_t plainMessageSize, const enum lime_ffi_CurveId curve, size_t *DRmessageSize, size_t *cipherMessageSize) {
/* cipherMessage maximum size is plain message size + auth tag size */
*cipherMessageSize = plainMessageSize + lime::settings::DRMessageAuthTagSize;
......
......@@ -275,6 +275,19 @@ struct jLimeManager {
}
}
jni::jboolean is_user(jni::JNIEnv &env, const jni::String &localDeviceId ) {
try {
if (m_manager->is_user(jni::Make<std::string>(env, localDeviceId))) {
return JNI_TRUE;
} else {
return JNI_FALSE;
}
} catch (std::exception const &e) { // catch anything, BctbxException are managed in is_user, so there is a real problem if we get there.
ThrowJavaLimeException(env, e.what());
return JNI_FALSE;
}
}
void encrypt(jni::JNIEnv &env, const jni::String &jlocalDeviceId, const jni::String &jrecipientUserId, jni::Array<jni::Object<jRecipientData>> &jrecipients,
jni::Array<jni::jbyte> &jplainMessage,
jni::Object<jLimeOutputBuffer> &jcipherMessage,
......@@ -488,6 +501,7 @@ jni::RegisterNativePeer<jLimeManager>(env, jni::Class<jLimeManager>::Find(env),
"nativeDestructor",
METHOD(&jLimeManager::create_user, "n_create_user"),
METHOD(&jLimeManager::delete_user, "delete_user"),
METHOD(&jLimeManager::is_user, "is_user"),
METHOD(&jLimeManager::encrypt, "n_encrypt"),
METHOD(&jLimeManager::decrypt, "n_decrypt"),
METHOD(&jLimeManager::update, "n_update"),
......
......@@ -23,6 +23,7 @@
#include "lime_lime.hpp"
#include "lime_localStorage.hpp"
#include "lime_settings.hpp"
#include "bctoolbox/exception.hh"
using namespace::std;
......@@ -82,6 +83,20 @@ namespace lime {
user->delete_user(managerDeleteCallback);
}
bool LimeManager::is_user(const std::string &localDeviceId) {
try {
// Load user object
std::shared_ptr<LimeGeneric> user;
LimeManager::load_user(user, localDeviceId);
return true; // If we are able to load the user, it means it exists
} catch (BctbxException const &e) { // we get an exception if the user is not found
// swallow it and return false
return false;
}
}
void LimeManager::encrypt(const std::string &localDeviceId, std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<RecipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback, const lime::EncryptionPolicy encryptionPolicy) {
// Load user object
std::shared_ptr<LimeGeneric> user;
......
......@@ -61,10 +61,16 @@ public class LimeLimeTester {
String AliceDeviceId = "alice."+UUID.randomUUID().toString();
try {
// Check alice is not already there
assert(aliceManager.is_user(AliceDeviceId) == false);
aliceManager.create_user(AliceDeviceId, x3dhServerUrl, curveId, 10, statusCallback);
expected_success+= 1;
assert (statusCallback.wait_for_success(expected_success));
// Check alice is there
assert(aliceManager.is_user(AliceDeviceId) == true);
// Get alice x3dh server url
assert(aliceManager.get_x3dhServerUrl(AliceDeviceId).equals(x3dhServerUrl));
......@@ -75,6 +81,7 @@ public class LimeLimeTester {
aliceManager.nativeDestructor();
aliceManager = null;
aliceManager = new LimeManager(aliceDbFilename, postObj);
assert(aliceManager.is_user(AliceDeviceId) == true); // Check again after LimeManager reload that Alice is in local storage
assert(aliceManager.get_x3dhServerUrl(AliceDeviceId).equals("https://testing.testing:12345"));
// Set it back to the regular one to be able to complete the test
aliceManager.set_x3dhServerUrl(AliceDeviceId, x3dhServerUrl);
......
......@@ -584,6 +584,9 @@ static void ffi_basic_test(const enum lime_ffi_CurveId curve, const char *dbBase
lime_ffi_manager_init(&bobManager1, dbFilenameBob1, X3DHServerPost, NULL);
lime_ffi_manager_init(&bobManager2, dbFilenameBob2, X3DHServerPost, NULL);
/*** Check if Alice exists in the database ***/
BC_ASSERT_TRUE(lime_ffi_is_user(aliceManager, aliceDeviceId) == LIME_FFI_USER_NOT_FOUND);
/*** create users ***/
lime_ffi_create_user(aliceManager, aliceDeviceId, x3dh_server_url, curve, ffi_defaultInitialOPkBatchSize, statusCallback, NULL);
lime_ffi_create_user(bobManager1, bobDeviceId1, x3dh_server_url, curve, ffi_defaultInitialOPkBatchSize, statusCallback, NULL);
......@@ -599,6 +602,11 @@ static void ffi_basic_test(const enum lime_ffi_CurveId curve, const char *dbBase
managerClean(&bobManager2, dbFilenameBob2);
}
/*** Check the device we created exists in DB ***/
BC_ASSERT_TRUE(lime_ffi_is_user(aliceManager, aliceDeviceId) == LIME_FFI_SUCCESS);
BC_ASSERT_TRUE(lime_ffi_is_user(bobManager1, bobDeviceId1) == LIME_FFI_SUCCESS);
BC_ASSERT_TRUE(lime_ffi_is_user(bobManager2, bobDeviceId2) == LIME_FFI_SUCCESS);
/*** Set/Get X3DH server URL functionality checks ***/
/* Get alice x3dh server url */
serverUrlSize = sizeof(serverUrl);
......
......@@ -3201,11 +3201,17 @@ static void user_management_test(const lime::CurveId curve, const std::string &d
auto aliceDeviceName = lime_tester::makeRandomDeviceName("alice.");
try {
/*Check if Alice exists in the database */
BC_ASSERT_FALSE(Manager->is_user(*aliceDeviceName));
/* create a user in a fresh database */
Manager->create_user(*aliceDeviceName, x3dh_server_url, curve, lime_tester::OPkInitialBatchSize, callback);
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success,++expected_success,lime_tester::wait_for_timeout));
if (counters.operation_failed == 1) return; // skip the end of the test if we can't do this
/*Check if Alice exists in the database */
BC_ASSERT_TRUE(Manager->is_user(*aliceDeviceName));
/* load alice from from DB */
auto alice = load_LimeUser(dbFilenameAlice, *aliceDeviceName, X3DHServerPost);
/* no need to wait here, it shall load alice immediately */
......@@ -3219,6 +3225,7 @@ static void user_management_test(const lime::CurveId curve, const std::string &d
// Force a reload of data from local storage just to be sure the modification was perform correctly
Manager = nullptr;
Manager = std::unique_ptr<LimeManager>(new LimeManager(dbFilenameAlice, X3DHServerPost));
BC_ASSERT_TRUE(Manager->is_user(*aliceDeviceName)); // Check again just after LimeManager reload that Alice is in local storage
BC_ASSERT_TRUE(Manager->get_x3dhServerUrl(*aliceDeviceName) == "https://testing.testing:12345");
// Set it back to the regular one to be able to complete the test
Manager->set_x3dhServerUrl(*aliceDeviceName, x3dh_server_url);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment