mirror of
https://github.com/emqx/neuron.git
synced 2026-10-17 04:40:42 +08:00
feat: ready
This commit is contained in:
@@ -48,6 +48,8 @@
|
||||
#define NEU_TAG_FLOAG_PRECISION_MAX 17
|
||||
#define NEU_USER_PASSWORD_MIN_LEN 4
|
||||
#define NEU_USER_PASSWORD_MAX_LEN 16
|
||||
#define NEU_USER_NAME_MIN_LEN 4
|
||||
#define NEU_USER_NAME_MAX_LEN 32
|
||||
#define NEU_LOG_LEVEL_LEN 9
|
||||
#define NEU_FILE_PATH_LEN 128
|
||||
#define NEU_MSG_MAX_SIZE 2048
|
||||
|
||||
@@ -49,6 +49,10 @@ typedef enum {
|
||||
NEU_ERR_IP_ADDRESS_IN_USE = 1016,
|
||||
NEU_ERR_BODY_TOO_BIG = 1017,
|
||||
NEU_ERR_INVALID_CID = 1018,
|
||||
NEU_ERR_USER_ALREADY_EXISTS = 1019,
|
||||
NEU_ERR_USER_NOT_EXISTS = 1020,
|
||||
NEU_ERR_INVALID_USER_LEN = 1021,
|
||||
NEU_ERR_USER_NO_PERMISSION = 1022,
|
||||
|
||||
NEU_ERR_NODE_EXIST = 2002,
|
||||
NEU_ERR_NODE_NOT_EXIST = 2003,
|
||||
|
||||
@@ -310,6 +310,14 @@ int neu_persister_load_node_setting(const char * node_name,
|
||||
*/
|
||||
int neu_persister_delete_node_setting(const char *node_name);
|
||||
|
||||
/**
|
||||
* Load all user infos.
|
||||
* @param[out] user_infos used to return pointer to heap allocated
|
||||
* vector of neu_persist_user_info_t.
|
||||
* @return 0 on success, non-zero otherwise
|
||||
*/
|
||||
int neu_persister_load_users(UT_array **user_infos);
|
||||
|
||||
/**
|
||||
* Save user info.
|
||||
* @param user user info
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
free(result_error); \
|
||||
return; \
|
||||
} else { \
|
||||
neu_jwt_decode_user(jwt, user); \
|
||||
neu_jwt_decode_user_after_valid(jwt, user); \
|
||||
} \
|
||||
}); \
|
||||
} \
|
||||
|
||||
@@ -29,7 +29,7 @@ int neu_jwt_init(const char *dir_path);
|
||||
int neu_jwt_new(char **token, const char *user);
|
||||
int neu_jwt_validate(char *b_token);
|
||||
void neu_jwt_destroy();
|
||||
int neu_jwt_decode_user(char *token, char *user);
|
||||
void neu_jwt_decode_user_after_valid(char *bearer, char *user);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -145,6 +145,9 @@ static struct neu_http_handler cors_handler[] = {
|
||||
{
|
||||
.url = "/api/v2/system/ctl",
|
||||
},
|
||||
{
|
||||
.url = "/api/v2/user",
|
||||
},
|
||||
};
|
||||
|
||||
static struct neu_http_handler rest_handlers[] = {
|
||||
@@ -467,6 +470,30 @@ static struct neu_http_handler rest_handlers[] = {
|
||||
.url = "/api/v2/system/ctl",
|
||||
.value.handler = handle_system_ctl,
|
||||
},
|
||||
{
|
||||
.method = NEU_HTTP_METHOD_GET,
|
||||
.type = NEU_HTTP_HANDLER_FUNCTION,
|
||||
.url = "/api/v2/user",
|
||||
.value.handler = handle_get_user,
|
||||
},
|
||||
{
|
||||
.method = NEU_HTTP_METHOD_POST,
|
||||
.type = NEU_HTTP_HANDLER_FUNCTION,
|
||||
.url = "/api/v2/user",
|
||||
.value.handler = handle_add_user,
|
||||
},
|
||||
{
|
||||
.method = NEU_HTTP_METHOD_PUT,
|
||||
.type = NEU_HTTP_HANDLER_FUNCTION,
|
||||
.url = "/api/v2/user",
|
||||
.value.handler = handle_update_user,
|
||||
},
|
||||
{
|
||||
.method = NEU_HTTP_METHOD_DELETE,
|
||||
.type = NEU_HTTP_HANDLER_FUNCTION,
|
||||
.url = "/api/v2/user",
|
||||
.value.handler = handle_delete_user,
|
||||
},
|
||||
};
|
||||
|
||||
void neu_rest_handler(const struct neu_http_handler **handlers, uint32_t *size)
|
||||
|
||||
+219
-39
@@ -99,74 +99,254 @@ void handle_login(nng_aio *aio)
|
||||
})
|
||||
}
|
||||
|
||||
void handle_get_user(nng_aio *aio)
|
||||
{
|
||||
char current_user[NEU_USER_NAME_MAX_LEN + 1] = { 0 };
|
||||
NEU_VALIDATE_JWT_WITH_USER(aio, current_user);
|
||||
|
||||
UT_icd icd = { sizeof(neu_json_user_resp_t), NULL, NULL, NULL };
|
||||
UT_array *user_list = NULL;
|
||||
utarray_new(user_list, &icd);
|
||||
|
||||
UT_array *user_infos = neu_user_list();
|
||||
utarray_foreach(user_infos, neu_persist_user_info_t *, p_info)
|
||||
{
|
||||
neu_json_user_resp_t resp = { 0 };
|
||||
strcpy(resp.name, p_info->name);
|
||||
utarray_push_back(user_list, &resp);
|
||||
}
|
||||
utarray_free(user_infos);
|
||||
|
||||
char *result = NULL;
|
||||
neu_json_encode_by_fn(user_list, neu_json_encode_user_list_resp, &result);
|
||||
neu_http_ok(aio, result);
|
||||
free(result);
|
||||
utarray_free(user_list);
|
||||
}
|
||||
|
||||
void handle_add_user(nng_aio *aio)
|
||||
{
|
||||
char current_user[USER_NAME_LEN] = { 0 };
|
||||
char current_user[NEU_USER_NAME_MAX_LEN + 1] = { 0 };
|
||||
NEU_VALIDATE_JWT_WITH_USER(aio, current_user);
|
||||
NEU_PROCESS_HTTP_REQUEST(
|
||||
aio, neu_json_login_req_t, neu_json_decode_login_req, {
|
||||
neu_json_login_resp_t login_resp = { 0 };
|
||||
neu_user_t * user = neu_load_user(req->name);
|
||||
int pass_len = strlen(req->pass);
|
||||
|
||||
if (0 == strlen(current_user)) {
|
||||
nlog_error("check current user failed");
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_USER_OR_PASSWORD, {
|
||||
aio, neu_json_add_user_req_t, neu_json_decode_add_user_req, {
|
||||
// user name length check
|
||||
int name_len = strlen(req->name);
|
||||
if (name_len < NEU_USER_NAME_MIN_LEN ||
|
||||
name_len > NEU_USER_NAME_MAX_LEN) {
|
||||
nlog_error("user name too short or too long");
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_USER_LEN, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (NULL == user) {
|
||||
nlog_error("could not find user `%s`", req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_USER_OR_PASSWORD, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
} else if (pass_len < NEU_USER_PASSWORD_MIN_LEN ||
|
||||
pass_len > NEU_USER_PASSWORD_MAX_LEN) {
|
||||
// user password length check
|
||||
int pass_len = strlen(req->pass);
|
||||
if (pass_len < NEU_USER_PASSWORD_MIN_LEN ||
|
||||
pass_len > NEU_USER_PASSWORD_MAX_LEN) {
|
||||
nlog_error("user `%s` password too short or too long",
|
||||
req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_PASSWORD_LEN, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
} else if (neu_user_check_password(user, req->pass)) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *token = NULL;
|
||||
char *result = NULL;
|
||||
// only admin can add user
|
||||
if (0 != strcmp(req->name, "admin")) {
|
||||
nlog_error("only admin can add user");
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_USER_NO_PERMISSION, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = neu_jwt_new(&token, req->name);
|
||||
if (ret != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_NEED_TOKEN, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
jwt_free_str(token);
|
||||
});
|
||||
}
|
||||
// user already exists
|
||||
neu_user_t *user = neu_load_user(req->name);
|
||||
if (NULL != user) {
|
||||
nlog_error("user `%s` already exists", req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_USER_ALREADY_EXISTS, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
|
||||
login_resp.token = token;
|
||||
neu_user_free(user);
|
||||
return;
|
||||
}
|
||||
|
||||
neu_json_encode_by_fn(&login_resp, neu_json_encode_login_resp,
|
||||
&result);
|
||||
neu_http_ok(aio, result);
|
||||
jwt_free_str(token);
|
||||
free(result);
|
||||
} else {
|
||||
nlog_error("user `%s` password check fail", req->name);
|
||||
// add user
|
||||
if (0 != neu_user_add(req->name, req->pass)) {
|
||||
nlog_error("add user `%s` fail", req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_SUCCESS, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
void handle_update_user(nng_aio *aio)
|
||||
{
|
||||
char current_user[NEU_USER_NAME_MAX_LEN + 1] = { 0 };
|
||||
NEU_VALIDATE_JWT_WITH_USER(aio, current_user);
|
||||
NEU_PROCESS_HTTP_REQUEST(
|
||||
aio, neu_json_password_req_t, neu_json_decode_update_user_req, {
|
||||
// user name length check
|
||||
int name_len = strlen(req->name);
|
||||
if (name_len < NEU_USER_NAME_MIN_LEN ||
|
||||
name_len > NEU_USER_NAME_MAX_LEN) {
|
||||
nlog_error("user name too short or too long");
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_USER_LEN, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// new password length check
|
||||
int new_pass_len = strlen(req->new_pass);
|
||||
if (new_pass_len < NEU_USER_PASSWORD_MIN_LEN ||
|
||||
new_pass_len > NEU_USER_PASSWORD_MAX_LEN) {
|
||||
nlog_error("user `%s` new password too short or too long",
|
||||
req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_PASSWORD_LEN, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// old password length check
|
||||
int old_pass_len = strlen(req->old_pass);
|
||||
if (old_pass_len < NEU_USER_PASSWORD_MIN_LEN ||
|
||||
old_pass_len > NEU_USER_PASSWORD_MAX_LEN) {
|
||||
nlog_error("user `%s` old password too short or too long",
|
||||
req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_PASSWORD_LEN, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// only admin & current user can update user
|
||||
if (0 != strcmp(req->name, "admin") &&
|
||||
0 != strcmp(req->name, current_user)) {
|
||||
nlog_error("only admin & current user can update user");
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_USER_NO_PERMISSION, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// user not exists
|
||||
neu_user_t *user = neu_load_user(req->name);
|
||||
if (NULL == user) {
|
||||
nlog_error("user `%s` not exists", req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_USER_NOT_EXISTS, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// check old password
|
||||
if (!neu_user_check_password(user, req->old_pass)) {
|
||||
nlog_error("user `%s` old password check fail", req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_USER_OR_PASSWORD, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
|
||||
neu_user_free(user);
|
||||
return;
|
||||
}
|
||||
|
||||
// update user password
|
||||
int rv = neu_user_update_password(user, req->new_pass);
|
||||
if (0 != rv) {
|
||||
nlog_error("update user `%s` fail", req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(rv, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
|
||||
neu_user_free(user);
|
||||
return;
|
||||
}
|
||||
|
||||
// save user
|
||||
rv = neu_save_user(user);
|
||||
if (0 != rv) {
|
||||
nlog_error("update user `%s` fail", req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(rv, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
|
||||
neu_user_free(user);
|
||||
return;
|
||||
}
|
||||
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_SUCCESS, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
|
||||
neu_user_free(user);
|
||||
})
|
||||
}
|
||||
|
||||
void handle_delete_user(nng_aio *aio)
|
||||
{
|
||||
(void) aio;
|
||||
}
|
||||
char current_user[NEU_USER_NAME_MAX_LEN + 1] = { 0 };
|
||||
NEU_VALIDATE_JWT_WITH_USER(aio, current_user);
|
||||
NEU_PROCESS_HTTP_REQUEST(
|
||||
aio, neu_json_delete_user_req_t, neu_json_decode_delete_user_req, {
|
||||
// user name length check
|
||||
int name_len = strlen(req->name);
|
||||
if (name_len < NEU_USER_NAME_MIN_LEN ||
|
||||
name_len > NEU_USER_NAME_MAX_LEN) {
|
||||
nlog_error("user name too short or too long");
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_USER_LEN, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_update_user(nng_aio *aio)
|
||||
{
|
||||
(void) aio;
|
||||
// only admin can delete user
|
||||
if (0 != strcmp(req->name, "admin")) {
|
||||
nlog_error("only admin can add user");
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_USER_NO_PERMISSION, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// user not exists
|
||||
neu_user_t *user = neu_load_user(req->name);
|
||||
if (NULL == user) {
|
||||
nlog_error("user `%s` not exists", req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_USER_NOT_EXISTS, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// delete user
|
||||
if (0 != neu_user_delete(req->name)) {
|
||||
nlog_error("delete user `%s` fail", req->name);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
|
||||
neu_user_free(user);
|
||||
return;
|
||||
}
|
||||
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_SUCCESS, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
|
||||
neu_user_free(user);
|
||||
})
|
||||
}
|
||||
|
||||
void handle_password(nng_aio *aio)
|
||||
|
||||
@@ -31,4 +31,9 @@ void handle_get_plugin_schema(nng_aio *aio);
|
||||
void handle_get_plugin_schema_resp(nng_aio *aio, neu_resp_check_schema_t *resp);
|
||||
void handle_status(nng_aio *aio);
|
||||
|
||||
#endif
|
||||
void handle_get_user(nng_aio *aio);
|
||||
void handle_add_user(nng_aio *aio);
|
||||
void handle_update_user(nng_aio *aio);
|
||||
void handle_delete_user(nng_aio *aio);
|
||||
|
||||
#endif
|
||||
|
||||
+17
-16
@@ -12,6 +12,10 @@
|
||||
#include "user.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
} neu_json_user_resp_t;
|
||||
|
||||
static const unsigned char cov_2char[64] = {
|
||||
0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
|
||||
0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
|
||||
@@ -372,16 +376,19 @@ void neu_user_free(neu_user_t *user)
|
||||
}
|
||||
}
|
||||
|
||||
int neu_user_list()
|
||||
UT_array *neu_user_list()
|
||||
{
|
||||
return 0;
|
||||
UT_array *user_infos = NULL;
|
||||
neu_persister_load_users(&user_infos);
|
||||
return user_infos;
|
||||
}
|
||||
|
||||
int neu_user_add(const char *name, const char *password)
|
||||
{
|
||||
neu_persist_user_info_t *info = NULL;
|
||||
if (0 != neu_persister_load_user(name, &info)) {
|
||||
return 1;
|
||||
if (0 == neu_persister_load_user(name, &info)) {
|
||||
free(info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
neu_user_t *user = neu_user_new(name, password);
|
||||
@@ -389,19 +396,13 @@ int neu_user_add(const char *name, const char *password)
|
||||
return -1;
|
||||
}
|
||||
|
||||
neu_save_user(user);
|
||||
return 0;
|
||||
}
|
||||
neu_persist_user_info_t info_new = {
|
||||
.name = user->name,
|
||||
.hash = user->hash,
|
||||
};
|
||||
|
||||
int neu_user_update(const char *name, const char *password)
|
||||
{
|
||||
neu_user_t *user = neu_load_user(name);
|
||||
if (NULL == user) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
neu_user_update_password(user, password);
|
||||
neu_save_user(user);
|
||||
neu_persister_store_user(&info_new);
|
||||
free(user);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@ extern "C" {
|
||||
|
||||
#include "persist/persist.h"
|
||||
|
||||
#define USER_NAME_LEN 32
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *hash;
|
||||
@@ -43,9 +41,9 @@ int neu_user_update_password(neu_user_t *user, const char *new_password);
|
||||
neu_user_t *neu_load_user(const char *name);
|
||||
int neu_save_user(neu_user_t *user);
|
||||
|
||||
int neu_user_list();
|
||||
int neu_user_add(const char *name, const char *password);
|
||||
int neu_user_delete(const char *name);
|
||||
UT_array *neu_user_list();
|
||||
int neu_user_add(const char *name, const char *password);
|
||||
int neu_user_delete(const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+81
-20
@@ -25,6 +25,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils/utarray.h"
|
||||
#include "utils/utextend.h"
|
||||
#include "json/json.h"
|
||||
|
||||
#include "neu_json_login.h"
|
||||
@@ -130,33 +132,29 @@ int neu_json_encode_login_resp(void *json_object, void *param)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_add_user_req(char *buf, neu_json_password_req_t **result)
|
||||
int neu_json_decode_add_user_req(char *buf, neu_json_add_user_req_t **result)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
neu_json_password_req_t *req = calloc(1, sizeof(neu_json_password_req_t));
|
||||
neu_json_add_user_req_t *req = calloc(1, sizeof(neu_json_add_user_req_t));
|
||||
neu_json_elem_t req_elems[] = {
|
||||
{
|
||||
.name = "name",
|
||||
.t = NEU_JSON_STR,
|
||||
},
|
||||
{
|
||||
.name = "old_pass",
|
||||
.t = NEU_JSON_STR,
|
||||
},
|
||||
{
|
||||
.name = "new_pass",
|
||||
.name = "pass",
|
||||
.t = NEU_JSON_STR,
|
||||
},
|
||||
|
||||
};
|
||||
ret = neu_json_decode(buf, NEU_JSON_ELEM_SIZE(req_elems), req_elems);
|
||||
if (ret != 0) {
|
||||
goto decode_fail;
|
||||
}
|
||||
|
||||
req->name = req_elems[0].v.val_str;
|
||||
req->old_pass = req_elems[1].v.val_str;
|
||||
req->new_pass = req_elems[2].v.val_str;
|
||||
req->name = req_elems[0].v.val_str;
|
||||
req->pass = req_elems[1].v.val_str;
|
||||
|
||||
*result = req;
|
||||
return ret;
|
||||
@@ -166,27 +164,90 @@ decode_fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void neu_json_decode_add_user_req_free(neu_json_password_req_t *req)
|
||||
void neu_json_decode_add_user_req_free(neu_json_add_user_req_t *req)
|
||||
{
|
||||
if (req) {
|
||||
free(req->name);
|
||||
free(req->old_pass);
|
||||
free(req->new_pass);
|
||||
|
||||
free(req->pass);
|
||||
free(req);
|
||||
}
|
||||
}
|
||||
|
||||
int neu_json_encode_add_user_resp(void *json_object, void *param)
|
||||
int neu_json_decode_update_user_req(char *buf, neu_json_password_req_t **result)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_login_resp_t *resp = (neu_json_login_resp_t *) param;
|
||||
return neu_json_decode_password_req(buf, result);
|
||||
}
|
||||
|
||||
void neu_json_decode_update_user_req_free(neu_json_password_req_t *req)
|
||||
{
|
||||
neu_json_decode_password_req_free(req);
|
||||
}
|
||||
|
||||
int neu_json_decode_delete_user_req(char * buf,
|
||||
neu_json_delete_user_req_t **result)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_delete_user_req_t *req =
|
||||
calloc(1, sizeof(neu_json_delete_user_req_t));
|
||||
neu_json_elem_t req_elems[] = {
|
||||
{
|
||||
.name = "name",
|
||||
.t = NEU_JSON_STR,
|
||||
},
|
||||
};
|
||||
ret = neu_json_decode(buf, NEU_JSON_ELEM_SIZE(req_elems), req_elems);
|
||||
if (ret != 0) {
|
||||
goto decode_fail;
|
||||
}
|
||||
|
||||
req->name = req_elems[0].v.val_str;
|
||||
|
||||
*result = req;
|
||||
return ret;
|
||||
|
||||
decode_fail:
|
||||
free(req);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void neu_json_decode_delete_user_req_free(neu_json_delete_user_req_t *req)
|
||||
{
|
||||
if (req) {
|
||||
free(req->name);
|
||||
free(req);
|
||||
}
|
||||
}
|
||||
|
||||
int neu_json_encode_user_list_resp(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
UT_array *user_list = (UT_array *) param;
|
||||
void * user_array = neu_json_array();
|
||||
|
||||
if (NULL != user_list) {
|
||||
utarray_foreach(user_list, neu_json_user_resp_t *, p_user)
|
||||
{
|
||||
if (NULL != p_user) {
|
||||
neu_json_elem_t user_elems[] = {
|
||||
{
|
||||
.name = "name",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = p_user->name,
|
||||
},
|
||||
};
|
||||
|
||||
neu_json_encode_array(user_array, user_elems,
|
||||
NEU_JSON_ELEM_SIZE(user_elems));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
neu_json_elem_t resp_elems[] = { {
|
||||
.name = "token",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = resp->token,
|
||||
.name = "users",
|
||||
.t = NEU_JSON_OBJECT,
|
||||
.v.val_object = user_array,
|
||||
} };
|
||||
|
||||
ret = neu_json_encode_field(json_object, resp_elems,
|
||||
NEU_JSON_ELEM_SIZE(resp_elems));
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef _NEU_JSON_API_NEU_JSON_LOGIN_H_
|
||||
#define _NEU_JSON_API_NEU_JSON_LOGIN_H_
|
||||
|
||||
#include "define.h"
|
||||
#include "json/json.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -48,17 +49,38 @@ typedef struct {
|
||||
int neu_json_decode_password_req(char *buf, neu_json_password_req_t **result);
|
||||
void neu_json_decode_password_req_free(neu_json_password_req_t *req);
|
||||
|
||||
typedef struct {
|
||||
char name[NEU_USER_NAME_MAX_LEN + 1];
|
||||
} neu_json_user_resp_t;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *pass;
|
||||
} neu_json_add_user_req_t;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
} neu_json_delete_user_req_t;
|
||||
|
||||
typedef struct {
|
||||
char *token;
|
||||
} neu_json_login_resp_t;
|
||||
|
||||
int neu_json_encode_login_resp(void *json_object, void *param);
|
||||
|
||||
int neu_json_decode_add_user_req(char *buf, neu_json_password_req_t **result);
|
||||
void neu_json_decode_add_user_req_free(neu_json_password_req_t *req);
|
||||
int neu_json_decode_add_user_req(char *buf, neu_json_add_user_req_t **result);
|
||||
void neu_json_decode_add_user_req_free(neu_json_add_user_req_t *req);
|
||||
int neu_json_decode_update_user_req(char * buf,
|
||||
neu_json_password_req_t **result);
|
||||
void neu_json_decode_update_user_req_free(neu_json_password_req_t *req);
|
||||
|
||||
int neu_json_decode_delete_user_req(char * buf,
|
||||
neu_json_delete_user_req_t **result);
|
||||
void neu_json_decode_delete_user_req_free(neu_json_delete_user_req_t *req);
|
||||
int neu_json_encode_user_list_resp(void *json_object, void *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -480,3 +480,8 @@ int neu_persister_delete_user(const char *user_name)
|
||||
{
|
||||
return g_impl->vtbl->delete_user(g_impl, user_name);
|
||||
}
|
||||
|
||||
int neu_persister_load_users(UT_array **user_infos)
|
||||
{
|
||||
return g_impl->vtbl->load_users(g_impl, user_infos);
|
||||
}
|
||||
|
||||
@@ -255,6 +255,14 @@ struct neu_persister_vtbl_s {
|
||||
int (*delete_group)(neu_persister_t *self, const char *driver_name,
|
||||
const char *group_name);
|
||||
|
||||
/**
|
||||
* Load all user infos.
|
||||
* @param[out] user_infos used to return pointer to heap allocated
|
||||
* vector of neu_persist_user_info_t.
|
||||
* @return 0 on success, non-zero otherwise
|
||||
*/
|
||||
int (*load_users)(neu_persister_t *self, UT_array **user_infos);
|
||||
|
||||
/**
|
||||
* Save user info.
|
||||
* @param user user info
|
||||
|
||||
@@ -433,6 +433,7 @@ static struct neu_persister_vtbl_s g_sqlite_persister_vtbl = {
|
||||
.store_node_setting = neu_sqlite_persister_store_node_setting,
|
||||
.load_node_setting = neu_sqlite_persister_load_node_setting,
|
||||
.delete_node_setting = neu_sqlite_persister_delete_node_setting,
|
||||
.load_users = neu_sqlite_persister_load_users,
|
||||
.store_user = neu_sqlite_persister_store_user,
|
||||
.update_user = neu_sqlite_persister_update_user,
|
||||
.load_user = neu_sqlite_persister_load_user,
|
||||
@@ -1155,6 +1156,71 @@ int neu_sqlite_persister_delete_node_setting(neu_persister_t *self,
|
||||
"DELETE FROM settings WHERE node_name=%Q", node_name);
|
||||
}
|
||||
|
||||
static UT_icd user_info_icd = {
|
||||
sizeof(neu_persist_user_info_t),
|
||||
NULL,
|
||||
NULL,
|
||||
(dtor_f *) neu_persist_user_info_fini,
|
||||
};
|
||||
|
||||
static int collect_user_info(sqlite3_stmt *stmt, UT_array **user_infos)
|
||||
{
|
||||
int step = sqlite3_step(stmt);
|
||||
while (SQLITE_ROW == step) {
|
||||
neu_persist_user_info_t info = {};
|
||||
char *name = strdup((char *) sqlite3_column_text(stmt, 0));
|
||||
if (NULL == name) {
|
||||
break;
|
||||
}
|
||||
|
||||
info.name = name;
|
||||
info.hash = strdup((char *) sqlite3_column_text(stmt, 1));
|
||||
if (NULL == info.hash) {
|
||||
break;
|
||||
}
|
||||
utarray_push_back(*user_infos, &info);
|
||||
|
||||
step = sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
if (SQLITE_DONE != step) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int neu_sqlite_persister_load_users(neu_persister_t *self,
|
||||
UT_array ** user_infos)
|
||||
{
|
||||
neu_sqlite_persister_t *persister = (neu_sqlite_persister_t *) self;
|
||||
|
||||
sqlite3_stmt *stmt = NULL;
|
||||
const char * query = "SELECT name, password FROM users";
|
||||
|
||||
utarray_new(*user_infos, &user_info_icd);
|
||||
|
||||
if (SQLITE_OK !=
|
||||
sqlite3_prepare_v2(persister->db, query, -1, &stmt, NULL)) {
|
||||
nlog_error("prepare `%s` fail: %s", query,
|
||||
sqlite3_errmsg(persister->db));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (0 != collect_user_info(stmt, user_infos)) {
|
||||
nlog_warn("query `%s` fail: %s", query, sqlite3_errmsg(persister->db));
|
||||
// do not set return code, return partial or empty result
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
utarray_free(*user_infos);
|
||||
*user_infos = NULL;
|
||||
return NEU_ERR_EINTERNAL;
|
||||
}
|
||||
|
||||
int neu_sqlite_persister_store_user(neu_persister_t * self,
|
||||
const neu_persist_user_info_t *user)
|
||||
{
|
||||
|
||||
@@ -110,6 +110,8 @@ int neu_sqlite_persister_load_node_setting(neu_persister_t * self,
|
||||
const char **const setting);
|
||||
int neu_sqlite_persister_delete_node_setting(neu_persister_t *self,
|
||||
const char * node_name);
|
||||
int neu_sqlite_persister_load_users(neu_persister_t *self,
|
||||
UT_array ** user_infos);
|
||||
int neu_sqlite_persister_store_user(neu_persister_t * self,
|
||||
const neu_persist_user_info_t *user);
|
||||
int neu_sqlite_persister_update_user(neu_persister_t * self,
|
||||
|
||||
@@ -330,6 +330,10 @@ int neu_http_response(nng_aio *aio, neu_err_code_e code, char *content)
|
||||
case NEU_ERR_LICENSE_MAX_TAGS:
|
||||
case NEU_ERR_LICENSE_BAD_CLOCK:
|
||||
case NEU_ERR_LICENSE_MODULE_INVALID:
|
||||
case NEU_ERR_USER_ALREADY_EXISTS:
|
||||
case NEU_ERR_USER_NOT_EXISTS:
|
||||
case NEU_ERR_USER_NO_PERMISSION:
|
||||
case NEU_ERR_INVALID_USER_LEN:
|
||||
status = NNG_HTTP_STATUS_BAD_REQUEST;
|
||||
break;
|
||||
case NEU_ERR_FILE_NOT_EXIST:
|
||||
|
||||
+20
-24
@@ -222,30 +222,6 @@ err_out:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int neu_jwt_decode_user(char *token, char *user)
|
||||
{
|
||||
jwt_t *jwt = NULL;
|
||||
int ret = -1;
|
||||
|
||||
ret = jwt_decode(&jwt, token, NULL, 0);
|
||||
if (ret != 0) {
|
||||
zlog_error(neuron, "jwt decode error: %d", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *user_grant = jwt_get_grant(jwt, "user");
|
||||
|
||||
if (NULL == user_grant) {
|
||||
zlog_error(neuron, "jwt get user grant error, the token is: %s", token);
|
||||
jwt_free(jwt);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(user, user_grant, strlen(user_grant));
|
||||
jwt_free(jwt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *neu_jwt_decode(char *token)
|
||||
{
|
||||
jwt_t * jwt = NULL;
|
||||
@@ -365,6 +341,26 @@ int neu_jwt_validate(char *b_token)
|
||||
return NEU_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
void neu_jwt_decode_user_after_valid(char *bearer, char *user)
|
||||
{
|
||||
char * token = &bearer[strlen("Bearar ")];
|
||||
jwt_t *jwt = NULL;
|
||||
if (0 != jwt_decode(&jwt, token, NULL, 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *user_grant = jwt_get_grant(jwt, "user");
|
||||
if (NULL == user_grant) {
|
||||
const char *admin = "admin";
|
||||
strncpy(user, admin, strlen(admin));
|
||||
jwt_free(jwt);
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(user, user_grant, strlen(user_grant));
|
||||
jwt_free(jwt);
|
||||
}
|
||||
|
||||
void neu_jwt_destroy()
|
||||
{
|
||||
// memset(token_local, 0, sizeof(token_local));
|
||||
|
||||
Reference in New Issue
Block a user