diff --git a/include/db/auth.h b/include/db/auth.h index eb60a47..7157bd2 100644 --- a/include/db/auth.h +++ b/include/db/auth.h @@ -24,11 +24,11 @@ extern "C" int set_user_permission(const char* user_id, int permission); - int set_admin_password_hash(const char* hash); + int set_admin_password(const char* password); int admin_login(const char* password, int* result); - int has_admin_password_hash(int* result); + int has_admin_password(int* result); #ifdef __cplusplus } diff --git a/src/server/auth/admin.c b/src/server/auth/admin.c index 21def19..f69588c 100644 --- a/src/server/auth/admin.c +++ b/src/server/auth/admin.c @@ -1,5 +1,6 @@ #include "server/auth.h" #include "server/response.h" +#include "server/types.h" #include "server/util.h" #include "db/auth.h" @@ -16,12 +17,24 @@ typedef struct { + char* action; char* password; + char* token; + char* user_id; + char* raw_passwd; + char* new_passwd; + char* permission; } admin_form_t; static void admin_form_dtor(admin_form_t* form) { + if (form->action) free(form->action); if (form->password) free(form->password); + if (form->token) free(form->token); + if (form->user_id) free(form->user_id); + if (form->raw_passwd) free(form->raw_passwd); + if (form->new_passwd) free(form->new_passwd); + if (form->permission) free(form->permission); } static int field_found(const char* key, const char* filename, char* path, size_t pathlen, void* user_data) @@ -32,13 +45,117 @@ static int field_found(const char* key, const char* filename, char* path, size_t static int field_get(const char* key, const char* value, size_t valuelen, void* user_data) { admin_form_t* form = (admin_form_t*)user_data; - if (strcmp(key, "password") == 0) { + if (strcmp(key, "action") == 0) { + form->action = kqm_strndup(value, valuelen); + } else if (strcmp(key, "password") == 0) { form->password = kqm_strndup(value, valuelen); - return MG_FORM_FIELD_HANDLE_ABORT; + } else if (strcmp(key, "token") == 0) { + form->token = kqm_strndup(value, valuelen); + } else if (strcmp(key, "user_id") == 0) { + form->user_id = kqm_strndup(value, valuelen); + } else if (strcmp(key, "raw_passwd") == 0) { + form->raw_passwd = kqm_strndup(value, valuelen); + } else if (strcmp(key, "permission") == 0) { + form->permission = kqm_strndup(value, valuelen); } return MG_FORM_FIELD_HANDLE_GET; } +static void impl_login(mg_connection* conn, admin_form_t* form) +{ + if (!form->password) { + res_need_password(conn); + return; + } + + int result; + int flag = admin_login(form->password, &result); + if (!flag) { + res_login_fail(conn); + } else if (!result) { + res_incorrect(conn); + } else { + if (admin_session) free(admin_session); + admin_session = kqm_random_password(32); + res_login(conn, admin_session); + } +} + +static void impl_repasswd(mg_connection* conn, admin_form_t* form) +{ + if (!form->raw_passwd || !form->new_passwd) { + res_need_password(conn); + return; + } + + int result; + if (!admin_login(form->password, &result)) { + res_auth_fail(conn); + } else if (!result) { + res_incorrect(conn); + } + + if (!set_admin_password(form->new_passwd)) { + res_repasswd_fail(conn); + } else { + res_repasswd(conn); + } +} + +static void impl_repasswd2(mg_connection* conn, admin_form_t* form) +{ + if (!form->user_id) { + res_need_user_id(conn); + return; + } + if (!form->new_passwd) { + res_need_password(conn); + return; + } + + int flag = set_user_password(form->user_id, form->new_passwd); + if (!flag) { + res_repasswd_fail(conn); + } else { + res_repasswd(conn); + } +} + +static void impl_permission(mg_connection* conn, admin_form_t* form) +{ + if (!form->user_id) { + res_need_user_id(conn); + return; + } + if (!form->permission) { + res_need_xxx(conn, "permission"); + return; + } + + int flag = set_user_permission(form->user_id, atoi(form->permission)); + if (!flag) { + res_repermission_fail(conn); + } else { + res_repermission(conn); + } +} + +static void impl_delete(mg_connection* conn, admin_form_t* form) +{ + if (!form->user_id) { + res_need_user_id(conn); + return; + } + + int flag = delete_user(form->user_id); + if (!flag) { + res_delete_account_fail(conn); + } else { + res_delete_account(conn); + } +} + + int admin_handler(mg_connection* conn, void* cbdata) { const mg_request_info* post_body = mg_get_request_info(conn); @@ -53,7 +170,7 @@ int admin_handler(mg_connection* conn, void* cbdata) return 1; } - admin_form_t form = {NULL}; + admin_form_t form = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; mg_form_data_handler admin_callback = { .field_found = field_found, @@ -64,22 +181,31 @@ int admin_handler(mg_connection* conn, void* cbdata) mg_handle_form_request(conn, &admin_callback); - if (!form.password) { - res_need_password(conn); - admin_form_dtor(&form); - return 1; + if (!strcmp(form.action, "login")) { + form.token = strdup(""); + admin_session = strdup(""); } - int result; - int flag = admin_login(form.password, &result); - if (!flag) { - res_login_fail(conn); - } else if (!result) { - res_incorrect(conn); + if (!form.action) { + res_need_action(conn); + } else if (!form.token) { + res_need_token(conn); + } else if (!admin_session || strcmp(form.token, admin_session)) { + res_permission_denied(conn); } else { - if (admin_session) free(admin_session); - admin_session = kqm_random_password(16); - res_login(conn, admin_session); + if (!strcmp(form.action, "login")) { + impl_login(conn, &form); + } else if (!strcmp(form.action, "repasswd")) { + impl_repasswd(conn, &form); + } else if (!strcmp(form.action, "repasswd2")) { + impl_repasswd2(conn, &form); + } else if (!strcmp(form.action, "permission")) { + impl_permission(conn, &form); + } else if (!strcmp(form.action, "delete")) { + impl_delete(conn, &form); + } else { + res_bad_action(conn); + } } admin_form_dtor(&form); diff --git a/src/server/auth/permission.c b/src/server/auth/permission.c new file mode 100644 index 0000000..ed6630c --- /dev/null +++ b/src/server/auth/permission.c @@ -0,0 +1,83 @@ +#include "server/auth.h" +#include "server/response.h" +#include "server/util.h" + +#include "db/auth.h" + +#include "jwt/jwt.h" + +#include + +#include + +#include +#include +#include + +typedef struct +{ + char* user_id; +} permission_form_t; + +static void permission_form_dtor(permission_form_t* form) +{ + if (form->user_id) free(form->user_id); +} + +static int field_found(const char* key, const char* filename, char* path, size_t pathlen, void* user_data) +{ + return MG_FORM_FIELD_HANDLE_GET; +} + +static int field_get(const char* key, const char* value, size_t valuelen, void* user_data) +{ + permission_form_t* form = (permission_form_t*)user_data; + if (strcmp(key, "user_id") == 0) { + form->user_id = kqm_strndup(value, valuelen); + return MG_FORM_FIELD_HANDLE_ABORT; + } + return MG_FORM_FIELD_HANDLE_GET; +} + +int user_permission_handler(mg_connection* conn, void* cbdata) +{ + const mg_request_info* post_body = mg_get_request_info(conn); + + if (post_body == NULL) { + res_null_req(conn); + return 1; + } + + if (strcmp(post_body->request_method, "POST")) { + res_must_post(conn); + return 1; + } + + permission_form_t form = {NULL}; + + mg_form_data_handler permission_callback = { + .field_found = field_found, + .field_get = field_get, + .field_store = NULL, + .user_data = &form, + }; + + mg_handle_form_request(conn, &permission_callback); + + if (!form.user_id) { + res_need_user_id(conn); + permission_form_dtor(&form); + return 1; + } + + int perm; + int flag = get_user_permission(form.user_id, &perm); + if (!flag) { + res_check_permission_fail(conn); + } else { + res_permission(conn, perm); + } + + permission_form_dtor(&form); + return 1; +} diff --git a/src/server/auth/repasswd.c b/src/server/auth/repasswd.c index acab2c8..2ef5e0b 100644 --- a/src/server/auth/repasswd.c +++ b/src/server/auth/repasswd.c @@ -27,6 +27,8 @@ static void repasswd_form_dtor(repasswd_form_t* form) { if (form->token) free(form->token); if (form->user_id) free(form->user_id); + if (form->raw_passwd) free(form->raw_passwd); + if (form->new_passwd) free(form->new_passwd); } static int field_found(const char* key, const char* filename, char* path, size_t pathlen, void* user_data) diff --git a/ui/src/components/users/LoginForm.vue b/ui/src/components/users/LoginForm.vue index e2a5554..8fdd71c 100644 --- a/ui/src/components/users/LoginForm.vue +++ b/ui/src/components/users/LoginForm.vue @@ -21,7 +21,7 @@ + @click="dialog('忘记密码', '请联系老师或管理员重置密码。')"> 忘记密码