From 67dab68cd80a39257e561f92f4ab95fae885d2d0 Mon Sep 17 00:00:00 2001 From: eeff <33566201+eeff@users.noreply.github.com> Date: Fri, 18 Mar 2022 14:01:07 +0800 Subject: [PATCH 1/7] Add get license json-api doc --- docs/json-api/neu_json_license.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/json-api/neu_json_license.json b/docs/json-api/neu_json_license.json index b7756c49..d37ac59c 100644 --- a/docs/json-api/neu_json_license.json +++ b/docs/json-api/neu_json_license.json @@ -1,5 +1,18 @@ { "set_license_req": { "license": "xxxxx" + }, + "get_license_resp": { + "error": 0, + "license_type": "trial", + "valid": true, + "valid_since": "2021-05-13 09:36:56", + "valid_until": "2022-05-13 09:36:56", + "max_nodes": 100, + "max_node_tags": 1000, + "enabled_plugins": [ + "modbus-plus-tcp", + "modbus-rtu" + ] } } From 7e5e4bf290688121dd19e373265371e18de34323 Mon Sep 17 00:00:00 2001 From: eeff <33566201+eeff@users.noreply.github.com> Date: Fri, 18 Mar 2022 14:02:07 +0800 Subject: [PATCH 2/7] Add get license json parser code --- include/json/neu_json_license.h | 16 ++++++++ src/parser/neu_json_license.c | 66 +++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/include/json/neu_json_license.h b/include/json/neu_json_license.h index ceb9980e..4ceec089 100644 --- a/include/json/neu_json_license.h +++ b/include/json/neu_json_license.h @@ -31,6 +31,22 @@ extern "C" { #endif +typedef char *neu_json_get_license_resp_enabled_plugin_t; + +typedef struct { + bool valid; + int n_enabled_plugin; + neu_json_get_license_resp_enabled_plugin_t *enabled_plugins; + int64_t max_node_tags; + char * license_type; + int64_t error; + char * valid_until; + char * valid_since; + int64_t max_nodes; +} neu_json_get_license_resp_t; + +int neu_json_encode_get_license_resp(void *json_object, void *param); + typedef struct { char *license; } neu_json_set_license_req_t; diff --git a/src/parser/neu_json_license.c b/src/parser/neu_json_license.c index 47a13ac0..48a5719e 100644 --- a/src/parser/neu_json_license.c +++ b/src/parser/neu_json_license.c @@ -29,6 +29,72 @@ #include "json/neu_json_license.h" +int neu_json_encode_get_license_resp(void *json_object, void *param) +{ + int ret = 0; + neu_json_get_license_resp_t *resp = (neu_json_get_license_resp_t *) param; + + void *enabled_plugin_array = neu_json_array(); + neu_json_get_license_resp_enabled_plugin_t *p_enabled_plugin = + resp->enabled_plugins; + for (int i = 0; i < resp->n_enabled_plugin; i++) { + neu_json_elem_t enabled_plugin_elems[] = { { + .name = NULL, + .t = NEU_JSON_STR, + .v.val_str = *p_enabled_plugin, + } }; + enabled_plugin_array = neu_json_encode_array_value( + enabled_plugin_array, enabled_plugin_elems, + NEU_JSON_ELEM_SIZE(enabled_plugin_elems)); + p_enabled_plugin++; + } + + neu_json_elem_t resp_elems[] = { { + .name = "valid_until", + .t = NEU_JSON_STR, + .v.val_str = resp->valid_until, + }, + { + .name = "valid_since", + .t = NEU_JSON_STR, + .v.val_str = resp->valid_since, + }, + { + .name = "valid", + .t = NEU_JSON_BOOL, + .v.val_bool = resp->valid, + }, + { + .name = "max_nodes", + .t = NEU_JSON_INT, + .v.val_int = resp->max_nodes, + }, + { + .name = "max_node_tags", + .t = NEU_JSON_INT, + .v.val_int = resp->max_node_tags, + }, + { + .name = "license_type", + .t = NEU_JSON_STR, + .v.val_str = resp->license_type, + }, + { + .name = "error", + .t = NEU_JSON_INT, + .v.val_int = resp->error, + }, + { + .name = "enabled_plugins", + .t = NEU_JSON_OBJECT, + .v.val_object = enabled_plugin_array, + } }; + ret = neu_json_encode_field(json_object, resp_elems, + NEU_JSON_ELEM_SIZE(resp_elems)); + + return ret; +} + int neu_json_decode_set_license_req(char * buf, neu_json_set_license_req_t **result) { From e312ccf722274022349d256507748ed922738a96 Mon Sep 17 00:00:00 2001 From: eeff <33566201+eeff@users.noreply.github.com> Date: Fri, 18 Mar 2022 14:07:16 +0800 Subject: [PATCH 3/7] Add license utility function plugin_bit_str --- plugins/restful/license.c | 13 +++++++++++++ plugins/restful/license.h | 3 +++ 2 files changed, 16 insertions(+) diff --git a/plugins/restful/license.c b/plugins/restful/license.c index 31eeed94..f3068236 100644 --- a/plugins/restful/license.c +++ b/plugins/restful/license.c @@ -159,6 +159,14 @@ static const char *const g_license_type_str_map_[] = { [LICENSE_TYPE_SME] = "small-enterprise", }; +static const char *const g_plugin_bit_str_map[] = { + [PLUGIN_BIT_MODBUS_PLUS_TCP] = "modbus-plus-tcp", + [PLUGIN_BIT_MODBUS_RTU] = "modbus-rtu", + [PLUGIN_BIT_OPCUA] = "opcua", + [PLUGIN_BIT_S7COMM] = "s7comm", + [PLUGIN_BIT_MAX] = NULL, +}; + static license_type_e scan_licese_type(const char *s) { license_type_e t = LICENSE_TYPE_MAX; @@ -307,6 +315,11 @@ const char *license_type_str(license_type_e t) return g_license_type_str_map_[t]; } +const char *plugin_bit_str(plugin_bit_e b) +{ + return g_plugin_bit_str_map[b]; +} + void license_print(license_t *license) { struct tm tm = {}; diff --git a/plugins/restful/license.h b/plugins/restful/license.h index e38fb104..dddf7dad 100644 --- a/plugins/restful/license.h +++ b/plugins/restful/license.h @@ -75,8 +75,11 @@ typedef enum { PLUGIN_BIT_MODBUS_RTU = 1, PLUGIN_BIT_OPCUA = 2, PLUGIN_BIT_S7COMM = 3, + PLUGIN_BIT_MAX, } plugin_bit_e; +const char *plugin_bit_str(plugin_bit_e); + // Representing a single license. typedef struct { license_type_e type_; // license type From 0e21c4604f5ab41f48c825422bc468b030b8d4a7 Mon Sep 17 00:00:00 2001 From: eeff <33566201+eeff@users.noreply.github.com> Date: Fri, 18 Mar 2022 14:07:50 +0800 Subject: [PATCH 4/7] Update license utility functions --- plugins/restful/license.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/restful/license.h b/plugins/restful/license.h index dddf7dad..24b49eff 100644 --- a/plugins/restful/license.h +++ b/plugins/restful/license.h @@ -107,8 +107,19 @@ static inline const char *license_get_file_name(const license_t *license) return license->fname_; } +static inline license_type_e license_get_type(const license_t *license) +{ + return license->type_; +} + // Get license expiry date. -static inline uint64_t license_get_expiry_timestamp(const license_t *license) +static inline uint64_t license_not_before(const license_t *license) +{ + return license->since_; +} + +// Get license expiry date. +static inline uint64_t license_not_after(const license_t *license) { return license->until_; } From 43a06439996a993e9345c00142ce04c1f72a6178 Mon Sep 17 00:00:00 2001 From: eeff <33566201+eeff@users.noreply.github.com> Date: Fri, 18 Mar 2022 14:10:09 +0800 Subject: [PATCH 5/7] Implement restful get license handler --- plugins/restful/license_handle.c | 83 ++++++++++++++++++++++++++++++++ plugins/restful/license_handle.h | 1 + 2 files changed, 84 insertions(+) diff --git a/plugins/restful/license_handle.c b/plugins/restful/license_handle.c index 1ccd935e..a660fb9e 100644 --- a/plugins/restful/license_handle.c +++ b/plugins/restful/license_handle.c @@ -24,6 +24,7 @@ #include "neu_errcodes.h" #include "neu_file.h" #include "neu_plugin.h" +#include "neu_vector.h" #include "json/neu_json_error.h" #include "json/neu_json_fn.h" #include "json/neu_json_license.h" @@ -37,6 +38,72 @@ static int set_license(const char *lic_str); int backup_license_file(const char *lic_fname); +int get_plugin_names(const license_t *lic, vector_t *plugin_names); + +void handle_get_license(nng_aio *aio) +{ + int rv = 0; + license_t lic = {}; + neu_json_get_license_resp_t resp = {}; + time_t since = 0; + time_t until = 0; + char valid_since[20] = {}; + char valid_until[20] = {}; + struct tm tm = {}; + vector_t plugin_names = {}; + char * result = NULL; + + VALIDATE_JWT(aio); + + vector_init(&plugin_names, PLUGIN_BIT_MAX, sizeof(char *)); + license_init(&lic); + rv = license_read(&lic, LICENSE_PATH); + if (0 != rv) { + goto final; + } + + since = license_not_before(&lic); + gmtime_r(&since, &tm); + if (0 == + strftime(valid_since, sizeof(valid_since), "%Y-%m-%d %H:%M:%S", &tm)) { + rv = NEU_ERR_EINTERNAL; + goto final; + } + + until = license_not_after(&lic); + gmtime_r(&until, &tm); + if (0 == + strftime(valid_until, sizeof(valid_until), "%Y-%m-%d %H:%M:%S", &tm)) { + rv = NEU_ERR_EINTERNAL; + goto final; + } + + resp.license_type = (char *) license_type_str(license_get_type(&lic)); + resp.valid = !license_is_expired(&lic); + resp.valid_since = valid_since; + resp.valid_until = valid_until; + resp.max_nodes = license_get_max_nodes(&lic); + resp.max_node_tags = license_get_max_node_tags(&lic); + + rv = get_plugin_names(&lic, &plugin_names); + if (0 != rv) { + goto final; + } + resp.n_enabled_plugin = plugin_names.size; + resp.enabled_plugins = plugin_names.data; + +final: + if (0 == rv) { + neu_json_encode_by_fn(&resp, neu_json_encode_get_license_resp, &result); + } else { + neu_json_error_resp_t error_code = { .error = rv }; + neu_json_encode_by_fn(&error_code, neu_json_encode_error_resp, &result); + } + http_response(aio, rv, result); + free(result); + license_fini(&lic); + vector_uninit(&plugin_names); +} void handle_set_license(nng_aio *aio) { @@ -133,3 +200,19 @@ int backup_license_file(const char *lic_fname) return link(lic_fname, fname_bak); } + +int get_plugin_names(const license_t *lic, vector_t *plugin_names) +{ + for (plugin_bit_e b = PLUGIN_BIT_MODBUS_PLUS_TCP; b < PLUGIN_BIT_MAX; ++b) { + if (license_is_plugin_enabled(lic, b)) { + const char *s = plugin_bit_str(b); + if (NULL == s) { + return NEU_ERR_EINTERNAL; + } + if (0 != vector_push_back(plugin_names, &s)) { + return NEU_ERR_ENOMEM; + } + } + } + return 0; +} diff --git a/plugins/restful/license_handle.h b/plugins/restful/license_handle.h index 42727b09..00761df0 100644 --- a/plugins/restful/license_handle.h +++ b/plugins/restful/license_handle.h @@ -22,6 +22,7 @@ #include +void handle_get_license(nng_aio *aio); void handle_set_license(nng_aio *aio); #endif From 1d7f6970361d8fd960e3b65203193f2fb0df1a40 Mon Sep 17 00:00:00 2001 From: eeff <33566201+eeff@users.noreply.github.com> Date: Fri, 18 Mar 2022 14:10:37 +0800 Subject: [PATCH 6/7] Add get license endpoint in restful plugin --- plugins/restful/handle.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/restful/handle.c b/plugins/restful/handle.c index f6b8782c..19d30b82 100644 --- a/plugins/restful/handle.c +++ b/plugins/restful/handle.c @@ -297,6 +297,12 @@ struct neu_rest_handler api_handlers[] = { .url = "/api/v2/license", .value.handler = handle_set_license, }, + { + .method = NEU_REST_METHOD_GET, + .type = NEU_REST_HANDLER_FUNCTION, + .url = "/api/v2/license", + .value.handler = handle_get_license, + }, }; void neu_rest_web_handler(const struct neu_rest_handler **handlers, From dee23a7a15a4fab98fd4075eeaf88eee1d8fb5c9 Mon Sep 17 00:00:00 2001 From: eeff <33566201+eeff@users.noreply.github.com> Date: Fri, 18 Mar 2022 14:16:29 +0800 Subject: [PATCH 7/7] Add CORS handler for license --- plugins/restful/handle.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/restful/handle.c b/plugins/restful/handle.c index 19d30b82..4525415c 100644 --- a/plugins/restful/handle.c +++ b/plugins/restful/handle.c @@ -106,6 +106,9 @@ struct neu_rest_handler cors_handler[] = { { .url = "/api/v2/log", }, + { + .url = "/api/v2/license", + }, }; struct neu_rest_handler api_handlers[] = {