Skip to content

Commit

Permalink
feat(mam): Register user ID with MAM channel seed
Browse files Browse the repository at this point in the history
Register user identity with MAM channel seed. The return user ID is
an UUID.

Asymmetric encryption for key exchange will be implemented in the
coming PR.

For DLTcollab#560
  • Loading branch information
howjmay committed Aug 17, 2020
1 parent d46c9a0 commit 100b191
Show file tree
Hide file tree
Showing 13 changed files with 309 additions and 7 deletions.
27 changes: 27 additions & 0 deletions accelerator/core/apis.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,33 @@ status_t api_fetch_txn_with_uuid(const ta_cache_t* const cache, const char* cons
return ret;
}

status_t api_register_mam_channel(const ta_cache_t* const cache, const char* const obj, char** json_result) {
status_t ret = SC_OK;
ta_register_mam_channel_req_t* req = ta_register_mam_channel_req_new();
char uuid[UUID_STR_LEN];

ret = register_mam_channel_req_deserialize(obj, req);
if (ret) {
ta_log_error("Failed to deserialize request of 'api_register_mam_channel'\n");
goto done;
}

ret = ta_register_mam_channel(cache, req, uuid);
if (ret) {
ta_log_error("%s\n", ta_error_to_string(ret));
goto done;
}

ret = register_mam_channel_res_serialize(uuid, json_result);
if (ret) {
ta_log_error("Failed to serialize response of 'api_register_mam_channel'\n");
}

done:
ta_register_mam_channel_req_free(&req);
return ret;
}

#ifdef DB_ENABLE
status_t api_find_transactions_by_id(const iota_client_service_t* const iota_service,
const db_client_service_t* const db_service, const char* const obj,
Expand Down
13 changes: 13 additions & 0 deletions accelerator/core/apis.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,19 @@ status_t api_get_node_status(const iota_client_service_t* const service, char**
*/
status_t api_fetch_txn_with_uuid(const ta_cache_t* const cache, const char* const uuid, char** json_result);

/**
* @brief Register user identity with MAM channel seed
*
* @param[in] cache Redis configuration variables
* @param[in] obj Request in JSON format
* @param[out] json_result Result contains the user id.
*
* @return
* - SC_OK on success
* - non-zero on error
*/
status_t api_register_mam_channel(const ta_cache_t* const cache, const char* const obj, char** json_result);

#ifdef DB_ENABLE
/**
* @brief Return transaction object with given single identity number.
Expand Down
6 changes: 3 additions & 3 deletions accelerator/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,9 +565,9 @@ status_t push_txn_to_buffer(const ta_cache_t* const cache, hash8019_array_p raw_
goto done;
}

uuid_t binuuid;
uuid_generate_random(binuuid);
uuid_unparse(binuuid, uuid);
uuid_t bin_uuid;
uuid_generate_random(bin_uuid);
uuid_unparse(bin_uuid, uuid);
if (!uuid[0]) {
ta_log_error("%s\n", "Failed to generate UUID");
goto done;
Expand Down
26 changes: 26 additions & 0 deletions accelerator/core/mam_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,3 +776,29 @@ status_t ta_recv_mam_message(const iota_config_t *const iconf, const iota_client
mam_encrypt_key_free(&mam_key);
return ret;
}

status_t ta_register_mam_channel(const ta_cache_t *const cache, const ta_register_mam_channel_req_t *const req,
char *uuid) {
if (!cache || !req || !uuid) {
ta_log_error("%s\n", ta_error_to_string(SC_NULL));
return SC_NULL;
}
status_t ret = SC_OK;

uuid_t bin_uuid;
uuid_generate_random(bin_uuid);
uuid_unparse(bin_uuid, uuid);
if (!uuid[0]) {
ta_log_error("%s\n", "Failed to generate UUID");
goto done;
}

ret = cache_set(uuid, UUID_STR_LEN - 1, req->seed, NUM_TRYTES_ADDRESS, cache->timeout);
if (ret) {
ta_log_error("%s\n", ta_error_to_string(ret));
goto done;
}

done:
return ret;
}
14 changes: 14 additions & 0 deletions accelerator/core/mam_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@ status_t ta_send_mam_message(const ta_config_t* const info, const iota_config_t*
status_t ta_recv_mam_message(const iota_config_t* const iconf, const iota_client_service_t* const service,
ta_recv_mam_req_t* const req, ta_recv_mam_res_t* const res);

/**
* @brief Register user identity with MAM channel seed.
*
* @param[in] cache redis configuration variables
* @param[in] req Request in 'ta_register_mam_channel_req_t' datatype
* @param[out] uuid Returned UUID
*
* @return
* - SC_OK on success
* - non-zero on error
*/
status_t ta_register_mam_channel(const ta_cache_t* const cache, const ta_register_mam_channel_req_t* const req,
char* uuid);

#ifdef __cplusplus
}
#endif
Expand Down
1 change: 1 addition & 0 deletions accelerator/core/request/request.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "ta_find_transaction_objects.h"
#include "ta_recv_mam.h"
#include "ta_register_mam_channel.h"
#include "ta_send_mam.h"
#include "ta_send_transfer.h"

Expand Down
14 changes: 14 additions & 0 deletions accelerator/core/request/ta_register_mam_channel.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "ta_register_mam_channel.h"

ta_register_mam_channel_req_t* ta_register_mam_channel_req_new() {
ta_register_mam_channel_req_t* req = (ta_register_mam_channel_req_t*)malloc(sizeof(ta_register_mam_channel_req_t));
if (req != NULL) {
return req;
}
return NULL;
}

void ta_register_mam_channel_req_free(ta_register_mam_channel_req_t** req) {
free(*req);
*req = NULL;
}
49 changes: 49 additions & 0 deletions accelerator/core/request/ta_register_mam_channel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2020 BiiLabs Co., Ltd. and Contributors
* All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the MIT license. A copy of the license can be found in the file
* "LICENSE" at the root of this distribution.
*/

#ifndef REQUEST_TA_REGISTER_MAM_CHANNEL_H_
#define REQUEST_TA_REGISTER_MAM_CHANNEL_H_

#include "common/model/transaction.h"
#include "common/ta_errors.h"
#include "utils/containers/hash/hash243_queue.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @file accelerator/core/request/ta_register_mam_channel.h
*/

/** struct of ta_register_mam_channel_req_t */
typedef struct ta_register_mam_channel_req {
char seed[NUM_TRYTES_ADDRESS + 1];
} ta_register_mam_channel_req_t;

/**
* @brief Allocate memory of ta_register_mam_channel_req_t
*
* @return
* - struct of ta_register_mam_channel_req_t on success
* - NULL on error
*/
ta_register_mam_channel_req_t* ta_register_mam_channel_req_new();

/**
* @brief Free memory of ta_register_mam_channel_req_t
*
* @param[in] req Data type of ta_register_mam_channel_req_t
*/
void ta_register_mam_channel_req_free(ta_register_mam_channel_req_t** req);

#ifdef __cplusplus
}
#endif

#endif // REQUEST_TA_REGISTER_MAM_CHANNEL_H_
79 changes: 79 additions & 0 deletions accelerator/core/serializer/ser_mam.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,82 @@ status_t recv_mam_message_res_serialize(ta_recv_mam_res_t* const res, char** obj
cJSON_Delete(json_root);
return ret;
}

status_t register_mam_channel_req_deserialize(const char* const obj, ta_register_mam_channel_req_t* req) {
if (obj == NULL || req == NULL) {
ta_log_error("%s\n", ta_error_to_string(SC_SERIALIZER_NULL));
return SC_SERIALIZER_NULL;
}
status_t ret = SC_OK;
cJSON* json_obj = cJSON_Parse(obj);
cJSON* json_elt = NULL;

if (json_obj == NULL) {
ret = SC_SERIALIZER_JSON_PARSE;
ta_log_error("%s\n", ta_error_to_string(ret));
goto done;
}

json_elt = cJSON_GetObjectItemCaseSensitive(json_obj, "seed");
if (json_elt != NULL && json_elt->valuestring != NULL && strlen(json_elt->valuestring) == NUM_TRYTES_ADDRESS) {
strncpy(req->seed, json_elt->valuestring, NUM_TRYTES_ADDRESS);
req->seed[NUM_TRYTES_ADDRESS] = 0;
} else {
ret = SC_SERIALIZER_INVALID_REQ;
ta_log_error("%s\n", ta_error_to_string(ret));
}

done:
cJSON_Delete(json_obj);
return ret;
}

status_t register_mam_channel_res_serialize(const char* const uuid, char** obj) {
if (uuid == NULL) {
ta_log_error("%s\n", ta_error_to_string(SC_SERIALIZER_NULL));
return SC_SERIALIZER_NULL;
}

status_t ret = SC_OK;
cJSON* json_root = cJSON_CreateObject();

cJSON_AddStringToObject(json_root, "user-id", uuid);

*obj = cJSON_PrintUnformatted(json_root);
if (*obj == NULL) {
ta_log_error("%s\n", ta_error_to_string(SC_SERIALIZER_JSON_PARSE));
ret = SC_SERIALIZER_JSON_PARSE;
}

cJSON_Delete(json_root);
return ret;
}

status_t register_mam_channel_res_deserialize(const char* const obj, char* user_id) {
if (obj == NULL || user_id == NULL) {
ta_log_error("%s\n", ta_error_to_string(SC_SERIALIZER_NULL));
return SC_SERIALIZER_NULL;
}
status_t ret = SC_OK;
cJSON* json_obj = cJSON_Parse(obj);
cJSON* json_elt = NULL;

if (json_obj == NULL) {
ret = SC_SERIALIZER_JSON_PARSE;
ta_log_error("%s\n", ta_error_to_string(ret));
goto done;
}

json_elt = cJSON_GetObjectItemCaseSensitive(json_obj, "user-id");
if (json_elt != NULL && json_elt->valuestring != NULL && strlen(json_elt->valuestring) == (UUID_STR_LEN - 1)) {
strncpy(user_id, json_elt->valuestring, UUID_STR_LEN - 1);
user_id[UUID_STR_LEN - 1] = 0;
} else {
ret = SC_SERIALIZER_INVALID_REQ;
ta_log_error("%s\n", ta_error_to_string(ret));
}

done:
cJSON_Delete(json_obj);
return ret;
}
48 changes: 48 additions & 0 deletions accelerator/core/serializer/ser_mam.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,54 @@ status_t recv_mam_message_res_deserialize(const char* const obj, ta_recv_mam_res
*/
status_t recv_mam_message_res_serialize(ta_recv_mam_res_t* const res, char** obj);

/**
* @brief Deserialize JSON string to type of ta_send_mam_req_t
*
* @param[in] obj Input values in JSON
* @param[out] req Request data in type of ta_send_mam_req_t
*
* @return
* - SC_OK on success
* - non-zero on error
*/
status_t send_mam_message_req_deserialize(const char* const obj, ta_send_mam_req_t* req);

/**
* @brief Deserialize JSON string to type of ta_register_mam_channel_req_t
*
* @param[in] obj Input values in JSON
* @param[out] req Request data in type of ta_register_mam_channel_req_t
*
* @return
* - SC_OK on success
* - non-zero on error
*/
status_t register_mam_channel_req_deserialize(const char* const obj, ta_register_mam_channel_req_t* req);

/**
* @brief Serialize response of register_mam_channel
*
* @param[in] uuid Returned UUID from tangle-accelerator
* @param[out] obj Response formed in JSON
*
* @return
* - SC_OK on success
* - non-zero on error
*/
status_t register_mam_channel_res_serialize(const char* const uuid, char** obj);

/**
* @brief Deserialize JSON string to user-id
*
* @param[in] obj Input values in JSON
* @param[out] user_id User ID in string
*
* @return
* - SC_OK on success
* - non-zero on error
*/
status_t register_mam_channel_res_deserialize(const char* const obj, char* user_id);

#ifdef __cplusplus
}
#endif
Expand Down
13 changes: 13 additions & 0 deletions tests/api/mam_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,18 @@ void test_encrypt_decrypt_psk(void) {
send_mam_res_free(&send_res);
}

void test_api_register_mam_channel(void) {
char* json_result;
const char* json = "{\"seed\":\"" TRYTES_81_1 "\"}";
char user_id[UUID_STR_LEN], seed[NUM_TRYTES_ADDRESS + 1];
TEST_ASSERT_EQUAL_INT32(SC_OK, api_register_mam_channel(&ta_core.cache, json, &json_result));

TEST_ASSERT_EQUAL_INT32(SC_OK, register_mam_channel_res_deserialize(json_result, user_id));
TEST_ASSERT_EQUAL_INT32(SC_OK, cache_get(user_id, seed));
TEST_ASSERT_EQUAL_INT32(SC_OK, cache_del(user_id));
free(json_result);
}

int main(int argc, char* argv[]) {
UNITY_BEGIN();
rand_trytes_init();
Expand All @@ -251,6 +263,7 @@ int main(int argc, char* argv[]) {
RUN_TEST(test_write_until_next_channel);
RUN_TEST(test_write_with_chid);
RUN_TEST(test_encrypt_decrypt_psk);
RUN_TEST(test_api_register_mam_channel);
ta_core_destroy(&ta_core);
return UNITY_END();
}
6 changes: 3 additions & 3 deletions tests/unit-test/test_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ void test_cache_timeout(void) {
}

void test_generate_uuid(void) {
uuid_t binuuid;
uuid_generate_random(binuuid);
uuid_unparse(binuuid, test_uuid);
uuid_t bin_uuid;
uuid_generate_random(bin_uuid);
uuid_unparse(bin_uuid, test_uuid);

TEST_ASSERT_TRUE(test_uuid[0]);
}
Expand Down
Loading

0 comments on commit 100b191

Please sign in to comment.