Merge pull request 'develop' (#3) from develop into main
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Make (push) Successful in 9s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-CMake (push) Successful in 12s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Meson (push) Successful in 11s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Make-Without-sqlite3 (push) Successful in 10s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-CMake-Without-sqlite3 (push) Successful in 14s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Meson-Without-sqlite3 (push) Successful in 12s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Make (push) Successful in 9s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-CMake (push) Successful in 12s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Meson (push) Successful in 11s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Make-Without-sqlite3 (push) Successful in 10s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-CMake-Without-sqlite3 (push) Successful in 14s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Meson-Without-sqlite3 (push) Successful in 12s
Reviewed-on: https://gitea.home.com:3000/TolaMironcenko/auth_service_c/pulls/3
This commit was merged in pull request #3.
This commit is contained in:
commit
7f68d60863
46 files changed
+742
-184
No files matched your search
@@ -9,7 +9,7 @@ jobs:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- name: Building binary with make
|
||||
run: make -j$(nproc)
|
||||
run: make USE_SQLITE3=1 -j$(nproc)
|
||||
- name: Testing binary
|
||||
run: make test
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
run: |
|
||||
mkdir build && \
|
||||
cd build && \
|
||||
cmake .. && \
|
||||
cmake -DUSE_SQLITE3=ON .. && \
|
||||
make -j$(nproc)
|
||||
- name: Testing binary
|
||||
run: |
|
||||
@@ -41,7 +41,51 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
- name: Building binary with meson
|
||||
run: |
|
||||
meson setup build && \
|
||||
meson setup build -Duse_sqlite3=true && \
|
||||
ninja -C build
|
||||
- name: Testing binary
|
||||
run: |
|
||||
cp -v build/auth_service . && ./tests.sh
|
||||
|
||||
Prepare-Build-Testing-With-Make-Without-sqlite3:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- name: Building binary with make
|
||||
run: make USE_SQLITE3=0 -j$(nproc)
|
||||
- name: Testing binary
|
||||
run: make test
|
||||
|
||||
Prepare-Build-Testing-With-CMake-Without-sqlite3:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: prepare-container
|
||||
run: |
|
||||
apt install -y cmake
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- name: Building binary with CMake
|
||||
run: |
|
||||
mkdir build && \
|
||||
cd build && \
|
||||
cmake -DUSE_SQLITE3=OFF .. && \
|
||||
make -j$(nproc)
|
||||
- name: Testing binary
|
||||
run: |
|
||||
cp -v build/auth_service . && ./tests.sh
|
||||
|
||||
Prepare-Build-Testing-With-Meson-Without-sqlite3:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: prepare-container
|
||||
run: |
|
||||
apt install -y meson
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- name: Building binary with meson
|
||||
run: |
|
||||
meson setup build -Duse_sqlite3=false && \
|
||||
ninja -C build
|
||||
- name: Testing binary
|
||||
run: |
|
||||
|
||||
@@ -6,6 +6,7 @@ build
|
||||
builddir
|
||||
auth_service
|
||||
users.db
|
||||
users_db.json
|
||||
*.swp
|
||||
*.log
|
||||
.proxy.sh
|
||||
|
||||
+18
-2
@@ -3,16 +3,32 @@ project(auth_service LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 23)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(CMAKE_C_FLAGS "-ffunction-sections -fdata-sections")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections")
|
||||
|
||||
include_directories(./src/lib/ ${SQLite3_INCLUDE_DIRS})
|
||||
|
||||
FILE(GLOB_RECURSE SOURCES src/*.c)
|
||||
|
||||
find_package(SQLite3 REQUIRED)
|
||||
option(USE_SQLITE3 "Enable SQLite3 support" OFF)
|
||||
option(USE_WERROR "Enable SQLite3 support" OFF)
|
||||
|
||||
if(USE_SQLITE3)
|
||||
find_package(SQLite3 REQUIRED)
|
||||
add_definitions(-DUSE_SQLITE3)
|
||||
endif()
|
||||
|
||||
if(USE_WERROR)
|
||||
add_definitions(-Werror)
|
||||
endif()
|
||||
|
||||
add_executable(
|
||||
auth_service
|
||||
${SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(auth_service ssl crypto sqlite3 pthread)
|
||||
if(USE_SQLITE3)
|
||||
target_link_libraries(auth_service ssl crypto sqlite3 pthread)
|
||||
else()
|
||||
target_link_libraries(auth_service ssl crypto pthread)
|
||||
endif()
|
||||
@@ -1,13 +1,24 @@
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -g -std=gnu2x -DMG_TLS=MG_TLS_OPENSSL
|
||||
LDFLAGS =
|
||||
LIBS = -lpthread -lcrypto -lssl -lsqlite3
|
||||
CFLAGS = -Wall -g -std=gnu2x -DMG_TLS=MG_TLS_OPENSSL -ffunction-sections -fdata-sections
|
||||
LDFLAGS = -Wl,--gc-sections
|
||||
INCLUDES = -I./src/lib -I./src
|
||||
SRCS = $(wildcard src/*.c src/lib/*.c)
|
||||
SRCS = $(wildcard src/*/*.c src/*.c)
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
TARGET = auth_service
|
||||
BUILD_DIR=./build
|
||||
CROSS_COMPILE =
|
||||
LIBS = -lpthread -lcrypto -lssl
|
||||
USE_SQLITE3 ?= 0
|
||||
WERROR ?= 0
|
||||
|
||||
ifeq ($(USE_SQLITE3), 1)
|
||||
CFLAGS += -DUSE_SQLITE3
|
||||
LIBS += -lsqlite3
|
||||
endif
|
||||
|
||||
ifeq ($(WERROR), 1)
|
||||
CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
@@ -18,7 +29,7 @@ $(TARGET): $(OBJS)
|
||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(TARGET) $(shell find . -type f -name '*.log') users.db
|
||||
rm -f $(OBJS) $(TARGET) $(shell find . -type f -name '*.log') users.db users_db.json
|
||||
|
||||
test: $(TARGET)
|
||||
bash ./tests.sh
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"database": "users.db",
|
||||
"address": "localhost:8222",
|
||||
"tls_address": "localhost:8223",
|
||||
"address": "0.0.0.0:8222",
|
||||
"tls_address": "0.0.0.0:8223",
|
||||
"default_users_file": "users.json",
|
||||
"web": "./web",
|
||||
"tls_enabled": true,
|
||||
|
||||
+22
-1
@@ -1,6 +1,25 @@
|
||||
project('auth_service', 'c', default_options: ['c_std=gnu2x'])
|
||||
include_dirs = include_directories('src', 'src/lib')
|
||||
deps = [dependency('openssl'), dependency('sqlite3')]
|
||||
deps = [dependency('openssl')]
|
||||
extra_c_args = ['-ffunction-sections', '-fdata-sections']
|
||||
extra_c_link_args = ['-Wl,--gc-sections']
|
||||
|
||||
sqlite3_dep = dependency('sqlite3', required: false)
|
||||
use_sqlite3 = get_option('use_sqlite3')
|
||||
use_werror = get_option('use_werror')
|
||||
|
||||
if use_sqlite3
|
||||
if not sqlite3_dep.found()
|
||||
error('SQLite3 requested but not found')
|
||||
endif
|
||||
deps += sqlite3_dep
|
||||
add_project_arguments('-DUSE_SQLITE3', language: 'c')
|
||||
endif
|
||||
|
||||
if use_werror
|
||||
add_project_arguments('-Werror', language: 'c')
|
||||
endif
|
||||
|
||||
executable(
|
||||
'auth_service',
|
||||
'src/main.c',
|
||||
@@ -35,4 +54,6 @@ executable(
|
||||
'src/db_update_user_field.c',
|
||||
include_directories: include_dirs,
|
||||
dependencies: deps,
|
||||
c_args: extra_c_args,
|
||||
link_args: extra_c_link_args,
|
||||
)
|
||||
@@ -0,0 +1,2 @@
|
||||
option('use_sqlite3', type: 'boolean', value: false, description: 'Enable SQLite3 support')
|
||||
option('use_werror', type: 'boolean', value: false, description: 'Build with warning as errors')
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "ConfigManager.h"
|
||||
|
||||
#include <cJSON.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "file.h"
|
||||
|
||||
typedef struct ConfigManager {
|
||||
|
||||
+3
-5
@@ -33,10 +33,9 @@ void add_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
return;
|
||||
}
|
||||
const bool user_is_superuser = is_superuser->valueint ? true : false;
|
||||
User *new_db_user = db_insert_user(
|
||||
username->valuestring, email->valuestring, password->valuestring,
|
||||
group->valuestring,
|
||||
&user_is_superuser);
|
||||
User *new_db_user = db_insert_user(username->valuestring, email->valuestring,
|
||||
password->valuestring, group->valuestring,
|
||||
&user_is_superuser);
|
||||
if (!new_db_user) {
|
||||
mg_http_reply(c, 500, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("failed to create user"));
|
||||
@@ -50,7 +49,6 @@ void add_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
username->valuestring, email->valuestring, group->valuestring,
|
||||
is_superuser->valueint ? "true" : "false");
|
||||
|
||||
|
||||
mg_http_reply(c, 200, HTTP_HEADERS, responsedata);
|
||||
cJSON_Delete(payload);
|
||||
}
|
||||
+1
-1
@@ -3,5 +3,5 @@
|
||||
ConfigManager *config = nullptr;
|
||||
|
||||
void init_config(const char *filename) {
|
||||
config = cm_new_config_from_file(filename);
|
||||
config = cm_new_config_from_file(filename);
|
||||
}
|
||||
+6
-1
@@ -1,5 +1,10 @@
|
||||
#include "cors.h"
|
||||
|
||||
void set_cors_headers(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
mg_http_reply(c, 200, "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Methods: GET,POST,OPTIONS,PUT,DELETE\r\nAccess-Control-Allow-Headers: Authorization,X-Custom,Content-Type", "");
|
||||
mg_http_reply(
|
||||
c, 200,
|
||||
"Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Methods: "
|
||||
"GET,POST,OPTIONS,PUT,DELETE\r\nAccess-Control-Allow-Headers: "
|
||||
"Authorization,X-Custom,Content-Type",
|
||||
"");
|
||||
}
|
||||
+71
-33
@@ -1,22 +1,36 @@
|
||||
#include "database.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "sql.h"
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
|
||||
sqlite3* db = nullptr;
|
||||
#ifdef USE_SQLITE3
|
||||
#include "config.h"
|
||||
#include "sql.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
sqlite3 *db = nullptr;
|
||||
pthread_mutex_t db_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#else
|
||||
pthread_mutex_t users_file_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
void init_db() {
|
||||
if (sqlite3_open(cm_get_parameter_as_string(config, "database"), &db) != SQLITE_OK) {
|
||||
#ifdef USE_SQLITE3
|
||||
if (sqlite3_open(cm_get_parameter_as_string(config, "database"), &db) !=
|
||||
SQLITE_OK) {
|
||||
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
void migrate_db() {
|
||||
#ifdef USE_SQLITE3
|
||||
char *err_msg = 0;
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (sqlite3_exec(db, CREATE_TABLE_USERS, nullptr, nullptr, &err_msg) !=
|
||||
@@ -27,37 +41,61 @@ void migrate_db() {
|
||||
exit(1);
|
||||
}
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Вспомогательная функция для экранирования специальных символов в JSON
|
||||
char* json_escape(const char* str) {
|
||||
if (!str) return NULL;
|
||||
|
||||
size_t len = strlen(str);
|
||||
// Выделяем память с запасом (каждый символ может быть экранирован)
|
||||
char* escaped = malloc(len * 6 + 1);
|
||||
if (!escaped) return NULL;
|
||||
|
||||
char* p = escaped;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
switch (str[i]) {
|
||||
case '\"': strcpy(p, "\\\""); p += 2; break;
|
||||
case '\\': strcpy(p, "\\\\"); p += 2; break;
|
||||
case '\b': strcpy(p, "\\b"); p += 2; break;
|
||||
case '\f': strcpy(p, "\\f"); p += 2; break;
|
||||
case '\n': strcpy(p, "\\n"); p += 2; break;
|
||||
case '\r': strcpy(p, "\\r"); p += 2; break;
|
||||
case '\t': strcpy(p, "\\t"); p += 2; break;
|
||||
default:
|
||||
if (str[i] < 0x20) {
|
||||
sprintf(p, "\\u%04x", (unsigned char)str[i]);
|
||||
p += 6;
|
||||
} else {
|
||||
*p++ = str[i];
|
||||
}
|
||||
char *json_escape(const char *str) {
|
||||
if (!str) return NULL;
|
||||
|
||||
size_t len = strlen(str);
|
||||
// Выделяем память с запасом (каждый символ может быть экранирован)
|
||||
char *escaped = malloc(len * 6 + 1);
|
||||
if (!escaped) return NULL;
|
||||
|
||||
char *p = escaped;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
switch (str[i]) {
|
||||
case '\"':
|
||||
strcpy(p, "\\\"");
|
||||
p += 2;
|
||||
break;
|
||||
case '\\':
|
||||
strcpy(p, "\\\\");
|
||||
p += 2;
|
||||
break;
|
||||
case '\b':
|
||||
strcpy(p, "\\b");
|
||||
p += 2;
|
||||
break;
|
||||
case '\f':
|
||||
strcpy(p, "\\f");
|
||||
p += 2;
|
||||
break;
|
||||
case '\n':
|
||||
strcpy(p, "\\n");
|
||||
p += 2;
|
||||
break;
|
||||
case '\r':
|
||||
strcpy(p, "\\r");
|
||||
p += 2;
|
||||
break;
|
||||
case '\t':
|
||||
strcpy(p, "\\t");
|
||||
p += 2;
|
||||
break;
|
||||
default:
|
||||
if (str[i] < 0x20) {
|
||||
sprintf(p, "\\u%04x", (unsigned char) str[i]);
|
||||
p += 6;
|
||||
} else {
|
||||
*p++ = str[i];
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return escaped;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return escaped;
|
||||
}
|
||||
+6
-2
@@ -1,11 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include <sqlite3.h>
|
||||
extern sqlite3 *db;
|
||||
extern pthread_mutex_t db_mutex;
|
||||
#else
|
||||
extern pthread_mutex_t users_file_mutex;
|
||||
#endif
|
||||
|
||||
void init_db();
|
||||
void migrate_db();
|
||||
char* json_escape(const char* str);
|
||||
char *json_escape(const char *str);
|
||||
+35
-1
@@ -1,8 +1,14 @@
|
||||
#include "database.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include "sql.h"
|
||||
#else
|
||||
#include "file.h"
|
||||
#endif
|
||||
|
||||
bool db_delete_user(const int id) {
|
||||
#ifdef USE_SQLITE3
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db) {
|
||||
fprintf(stderr, "Database not initialized\n");
|
||||
@@ -42,4 +48,32 @@ bool db_delete_user(const int id) {
|
||||
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return true;
|
||||
#else
|
||||
pthread_mutex_lock(&users_file_mutex);
|
||||
char *data = read_file("users_db.json");
|
||||
cJSON *users = cJSON_Parse(data);
|
||||
cJSON *user = nullptr;
|
||||
int index = 0;
|
||||
bool found = false;
|
||||
cJSON_ArrayForEach(user, users) {
|
||||
cJSON *user_id = cJSON_GetObjectItem(user, "id");
|
||||
if (user_id->valueint == id) {
|
||||
cJSON_DeleteItemFromArray(users, index);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if (!found) {
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
return false;
|
||||
}
|
||||
char *new_data = cJSON_Print(users);
|
||||
write_file("users_db.json", new_data);
|
||||
free(new_data);
|
||||
free(data);
|
||||
cJSON_Delete(users);
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
+14
-3
@@ -1,9 +1,14 @@
|
||||
#include "database.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include "sql.h"
|
||||
#else
|
||||
#include "file.h"
|
||||
#endif
|
||||
|
||||
char *db_get_all_users() {
|
||||
#ifdef USE_SQLITE3
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db) {
|
||||
fprintf(stderr, "Database not initialized\n");
|
||||
@@ -96,4 +101,10 @@ char *db_get_all_users() {
|
||||
sqlite3_finalize(stmt);
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
pthread_mutex_lock(&users_file_mutex);
|
||||
char *data = read_file("users_db.json");
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
return data;
|
||||
#endif
|
||||
}
|
||||
+41
-1
@@ -1,8 +1,15 @@
|
||||
#include "database.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include "sql.h"
|
||||
#else
|
||||
#include "cJSON.h"
|
||||
#include "file.h"
|
||||
#endif
|
||||
|
||||
User *db_get_user_by_id(const int id) {
|
||||
#ifdef USE_SQLITE3
|
||||
User *user = nullptr;
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db) {
|
||||
@@ -41,4 +48,37 @@ User *db_get_user_by_id(const int id) {
|
||||
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return user;
|
||||
#else
|
||||
pthread_mutex_lock(&users_file_mutex);
|
||||
char *data = read_file("users_db.json");
|
||||
cJSON *users = cJSON_Parse(data);
|
||||
cJSON *user = nullptr;
|
||||
User *found = nullptr;
|
||||
cJSON_ArrayForEach(user, users) {
|
||||
cJSON *user_id = cJSON_GetObjectItem(user, "id");
|
||||
cJSON *user_username = cJSON_GetObjectItem(user, "username");
|
||||
cJSON *user_password = cJSON_GetObjectItem(user, "password");
|
||||
cJSON *user_email = cJSON_GetObjectItem(user, "email");
|
||||
cJSON *user_group = cJSON_GetObjectItem(user, "group");
|
||||
cJSON *user_is_superuser = cJSON_GetObjectItem(user, "is_superuser");
|
||||
if (user_id->valueint == id) {
|
||||
found = new_user(user_id->valueint, user_username->valuestring,
|
||||
user_password->valuestring, user_email->valuestring,
|
||||
user_group->valuestring, user_is_superuser->valueint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == nullptr) {
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
// if (user != nullptr) cJSON_Delete(user);
|
||||
cJSON_Delete(users);
|
||||
free(data);
|
||||
return nullptr;
|
||||
}
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
// if (user != nullptr) cJSON_Delete(user);
|
||||
cJSON_Delete(users);
|
||||
free(data);
|
||||
return found;
|
||||
#endif
|
||||
}
|
||||
@@ -1,8 +1,15 @@
|
||||
#include "database.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include "sql.h"
|
||||
#else
|
||||
#include "cJSON.h"
|
||||
#include "file.h"
|
||||
#endif
|
||||
|
||||
User *db_get_user_by_username(const char *username) {
|
||||
#ifdef USE_SQLITE3
|
||||
User *user = nullptr;
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db) {
|
||||
@@ -41,4 +48,37 @@ User *db_get_user_by_username(const char *username) {
|
||||
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return user;
|
||||
#else
|
||||
pthread_mutex_lock(&users_file_mutex);
|
||||
char *data = read_file("users_db.json");
|
||||
cJSON *users = cJSON_Parse(data);
|
||||
cJSON *user = nullptr;
|
||||
User *found = nullptr;
|
||||
cJSON_ArrayForEach(user, users) {
|
||||
cJSON *user_id = cJSON_GetObjectItem(user, "id");
|
||||
cJSON *user_username = cJSON_GetObjectItem(user, "username");
|
||||
cJSON *user_password = cJSON_GetObjectItem(user, "password");
|
||||
cJSON *user_email = cJSON_GetObjectItem(user, "email");
|
||||
cJSON *user_group = cJSON_GetObjectItem(user, "group");
|
||||
cJSON *user_is_superuser = cJSON_GetObjectItem(user, "is_superuser");
|
||||
if (!strcmp(user_username->valuestring, username)) {
|
||||
found = new_user(user_id->valueint, user_username->valuestring,
|
||||
user_password->valuestring, user_email->valuestring,
|
||||
user_group->valuestring, user_is_superuser->valueint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == nullptr) {
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
// if (user != nullptr) cJSON_Delete(user);
|
||||
cJSON_Delete(users);
|
||||
free(data);
|
||||
return nullptr;
|
||||
}
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
// if (user != nullptr) cJSON_Delete(user);
|
||||
cJSON_Delete(users);
|
||||
free(data);
|
||||
return found;
|
||||
#endif
|
||||
}
|
||||
@@ -1,9 +1,15 @@
|
||||
#include <pthread.h>
|
||||
#include "database.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include "sql.h"
|
||||
#else
|
||||
#include "file.h"
|
||||
#endif
|
||||
|
||||
char *db_get_user_field_by_id(const int id, const char *field) {
|
||||
#ifdef USE_SQLITE3
|
||||
char *password = nullptr;
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db) {
|
||||
@@ -42,4 +48,37 @@ char *db_get_user_field_by_id(const int id, const char *field) {
|
||||
}
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return password;
|
||||
#else
|
||||
pthread_mutex_lock(&users_file_mutex);
|
||||
char *data = read_file("users_db.json");
|
||||
cJSON *users = cJSON_Parse(data);
|
||||
cJSON *user = nullptr;
|
||||
User *found = nullptr;
|
||||
cJSON_ArrayForEach(user, users) {
|
||||
cJSON *user_id = cJSON_GetObjectItem(user, "id");
|
||||
cJSON *user_username = cJSON_GetObjectItem(user, "username");
|
||||
cJSON *user_password = cJSON_GetObjectItem(user, "password");
|
||||
cJSON *user_email = cJSON_GetObjectItem(user, "email");
|
||||
cJSON *user_group = cJSON_GetObjectItem(user, "group");
|
||||
cJSON *user_is_superuser = cJSON_GetObjectItem(user, "is_superuser");
|
||||
if (user_id->valueint == id) {
|
||||
found = new_user(user_id->valueint, user_username->valuestring,
|
||||
user_password->valuestring, user_email->valuestring,
|
||||
user_group->valuestring, user_is_superuser->valueint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == nullptr) {
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
// if (user != nullptr) cJSON_Delete(user);
|
||||
cJSON_Delete(users);
|
||||
free(data);
|
||||
return nullptr;
|
||||
}
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
// if (user != nullptr) cJSON_Delete(user);
|
||||
cJSON_Delete(users);
|
||||
free(data);
|
||||
return found->password;
|
||||
#endif
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <cJSON.h>
|
||||
#include <sqlite3.h>
|
||||
#include "file.h"
|
||||
#include "user.h"
|
||||
|
||||
|
||||
+57
-1
@@ -1,10 +1,17 @@
|
||||
#include "database.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include "sql.h"
|
||||
#else
|
||||
#include "cJSON.h"
|
||||
#include "file.h"
|
||||
#endif
|
||||
|
||||
User *db_insert_user(const char *username, const char *email,
|
||||
const char *password, const char *group,
|
||||
const bool *is_superuser) {
|
||||
#ifdef USE_SQLITE3
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db) {
|
||||
fprintf(stderr, "Databse not initialized\n");
|
||||
@@ -60,4 +67,53 @@ User *db_insert_user(const char *username, const char *email,
|
||||
User *new_db_user =
|
||||
new_user(inserted_id, username, email, password, group, is_superuser);
|
||||
return new_db_user;
|
||||
#else
|
||||
pthread_mutex_lock(&users_file_mutex);
|
||||
char *data = read_file("users_db.json");
|
||||
cJSON *users = cJSON_Parse(data);
|
||||
cJSON *user = nullptr;
|
||||
int users_size = 0;
|
||||
bool found = false;
|
||||
cJSON_ArrayForEach(user, users) {
|
||||
cJSON *user_username = cJSON_GetObjectItem(user, "username");
|
||||
cJSON *user_password = cJSON_GetObjectItem(user, "password");
|
||||
cJSON *user_email = cJSON_GetObjectItem(user, "email");
|
||||
cJSON *user_group = cJSON_GetObjectItem(user, "group");
|
||||
if (!strcmp(user_username->valuestring, username) &&
|
||||
!strcmp(user_password->valuestring, password) &&
|
||||
!strcmp(user_email->valuestring, email) &&
|
||||
!strcmp(user_group->valuestring, group)) {
|
||||
found = true;
|
||||
}
|
||||
users_size++;
|
||||
}
|
||||
if (found == true) {
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
return nullptr;
|
||||
}
|
||||
cJSON *new_user_data = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(new_user_data, "id", users_size);
|
||||
cJSON_AddStringToObject(new_user_data, "username", username);
|
||||
cJSON_AddStringToObject(new_user_data, "password", password);
|
||||
cJSON_AddStringToObject(new_user_data, "email", email);
|
||||
cJSON_AddStringToObject(new_user_data, "group", group);
|
||||
cJSON_AddBoolToObject(new_user_data, "is_superuser", *is_superuser);
|
||||
char *new_user_data_string = cJSON_Print(new_user_data);
|
||||
if (users_size == 0) {
|
||||
users = cJSON_CreateArray();
|
||||
}
|
||||
cJSON_AddItemToArray(users, new_user_data);
|
||||
char *new_data = cJSON_Print(users);
|
||||
write_file("users_db.json", new_data);
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
User *return_user =
|
||||
new_user(users_size, username, email, password, group, is_superuser);
|
||||
free(new_data);
|
||||
free(data);
|
||||
free(new_user_data_string);
|
||||
// cJSON_Delete(new_user_data);
|
||||
cJSON_Delete(users);
|
||||
if (user != nullptr) cJSON_Delete(user);
|
||||
return return_user;
|
||||
#endif
|
||||
}
|
||||
+43
-1
@@ -1,10 +1,18 @@
|
||||
#include <pthread.h>
|
||||
#include "database.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include "sql.h"
|
||||
#else
|
||||
#include "cJSON.h"
|
||||
#include "file.h"
|
||||
#endif
|
||||
|
||||
User *db_update_user(const int userid, const char *username, const char *email,
|
||||
const char *password, const char *group,
|
||||
const bool *is_superuser) {
|
||||
#ifdef USE_SQLITE3
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db) {
|
||||
fprintf(stderr, "Databse not initialized\n");
|
||||
@@ -52,4 +60,38 @@ User *db_update_user(const int userid, const char *username, const char *email,
|
||||
}
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return new_user(userid, username, email, password, group, is_superuser);
|
||||
#else
|
||||
pthread_mutex_lock(&users_file_mutex);
|
||||
char *data = read_file("users_db.json");
|
||||
cJSON *users = cJSON_Parse(data);
|
||||
cJSON *user = nullptr;
|
||||
cJSON_ArrayForEach(user, users) {
|
||||
cJSON *user_id = cJSON_GetObjectItem(user, "id");
|
||||
if (user_id->valueint == userid) {
|
||||
cJSON *user_username = cJSON_GetObjectItem(user, "username");
|
||||
cJSON *user_password = cJSON_GetObjectItem(user, "password");
|
||||
cJSON *user_email = cJSON_GetObjectItem(user, "email");
|
||||
cJSON *user_group = cJSON_GetObjectItem(user, "group");
|
||||
cJSON_SetValuestring(user_username, username);
|
||||
cJSON_SetValuestring(user_password, password);
|
||||
cJSON_SetValuestring(user_email, email);
|
||||
cJSON_SetValuestring(user_group, group);
|
||||
cJSON_DeleteItemFromObject(user, "is_superuser");
|
||||
cJSON_AddBoolToObject(user, "is_superuser", *is_superuser);
|
||||
char *new_data = cJSON_Print(users);
|
||||
write_file("users_db.json", new_data);
|
||||
free(new_data);
|
||||
free(data);
|
||||
cJSON_Delete(users);
|
||||
User *ret =
|
||||
new_user(userid, username, password, email, group, is_superuser);
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
free(data);
|
||||
cJSON_Delete(users);
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
@@ -1,8 +1,15 @@
|
||||
#include "database.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include "sql.h"
|
||||
#else
|
||||
#include "cJSON.h"
|
||||
#include "file.h"
|
||||
#endif
|
||||
|
||||
bool db_update_user_field(const int id, const char *field, const char *value) {
|
||||
#ifdef USE_SQLITE3
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db || !field || !value) {
|
||||
fprintf(stderr, "invalid parameters\n");
|
||||
@@ -26,10 +33,43 @@ bool db_update_user_field(const int id, const char *field, const char *value) {
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
if (rc != SQLITE_DONE) {
|
||||
fprintf(stderr, "execution failed: %s\n", sqlite3_errmsg(db));
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return false;
|
||||
fprintf(stderr, "execution failed: %s\n", sqlite3_errmsg(db));
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return false;
|
||||
}
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return sqlite3_changes(db) > 0;
|
||||
#else
|
||||
pthread_mutex_lock(&users_file_mutex);
|
||||
char *data = read_file("users_db.json");
|
||||
cJSON *users = cJSON_Parse(data);
|
||||
cJSON *user = nullptr;
|
||||
cJSON_ArrayForEach(user, users) {
|
||||
cJSON *user_id = cJSON_GetObjectItem(user, "id");
|
||||
if (user_id->valueint == id) {
|
||||
cJSON *user_field = cJSON_GetObjectItem(user, field);
|
||||
if (cJSON_IsNumber(user_field)) {
|
||||
// cJSON_SetNumberValue(user_field, value);
|
||||
return false;
|
||||
} else if (cJSON_IsBool(user_field)) {
|
||||
// cJSON_DeleteItemFromObject(user, field);
|
||||
// cJSON_AddBoolToObject(user, field, value);
|
||||
return false;
|
||||
} else if (cJSON_IsString(user_field)) {
|
||||
cJSON_SetValuestring(user_field, value);
|
||||
}
|
||||
char *new_data = cJSON_Print(users);
|
||||
write_file("users_db.json", new_data);
|
||||
free(new_data);
|
||||
free(data);
|
||||
cJSON_Delete(users);
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
free(data);
|
||||
cJSON_Delete(users);
|
||||
pthread_mutex_unlock(&users_file_mutex);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
+8
-8
@@ -4,20 +4,20 @@
|
||||
|
||||
void delete_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
if (hm->body.len == 0) {
|
||||
mg_http_reply(c, 400, HTTP_HEADERS, "{%m:%m}",
|
||||
MG_ESC("error"), MG_ESC("must have token"));
|
||||
mg_http_reply(c, 400, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("must have token"));
|
||||
return;
|
||||
}
|
||||
request_with_token *requestdata = check_body(hm);
|
||||
if (requestdata->error != NULL) {
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}",
|
||||
MG_ESC("error"), MG_ESC(requestdata->error));
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC(requestdata->error));
|
||||
return;
|
||||
}
|
||||
const bool valid = jwt_verifyJWT(requestdata->token, JWT_DEFAULT_SECRET);
|
||||
if (!valid) {
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}",
|
||||
MG_ESC("error"), MG_ESC("invalid token"));
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("invalid token"));
|
||||
free_request_with_token(requestdata);
|
||||
return;
|
||||
}
|
||||
@@ -38,8 +38,8 @@ void delete_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
}
|
||||
bool is_superuser = cJSON_GetObjectItem(payload, "is_superuser")->valueint;
|
||||
if (!is_superuser) {
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}",
|
||||
MG_ESC("error"), MG_ESC("user is not superuser"));
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("user is not superuser"));
|
||||
return;
|
||||
}
|
||||
bool user_deleted = db_delete_user(useridfromjson->valueint);
|
||||
|
||||
+43
-1
@@ -1,8 +1,13 @@
|
||||
#include "file.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
char *read_file(const char *path) {
|
||||
create_file_if_not_exists(path);
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (fp == NULL) {
|
||||
perror("Error opening file");
|
||||
@@ -31,4 +36,41 @@ char *read_file(const char *path) {
|
||||
buffer[file_size] = '\0';
|
||||
fclose(fp);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
char *write_file(const char *path, const char *data) {
|
||||
create_file_if_not_exists(path);
|
||||
FILE *fp = fopen(path, "w");
|
||||
if (fp == NULL) {
|
||||
printf("%s\n", path);
|
||||
perror("Error opening file");
|
||||
return nullptr;
|
||||
}
|
||||
if (fprintf(fp, "%s", data) < 0) {
|
||||
perror("Error write file");
|
||||
return nullptr;
|
||||
}
|
||||
fclose(fp);
|
||||
char *ret = strdup(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int create_file_if_not_exists(const char *filename) {
|
||||
if (!check_file_exists(filename)) {
|
||||
return 0;
|
||||
}
|
||||
FILE *file = fopen(filename, "w");
|
||||
if (file == nullptr) {
|
||||
perror("Error creating file");
|
||||
return -1;
|
||||
}
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int check_file_exists(const char *filename) {
|
||||
if (access(filename, F_OK) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
+4
-1
@@ -1,3 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
char *read_file(const char *path);
|
||||
char *read_file(const char *path);
|
||||
char *write_file(const char *path, const char *data);
|
||||
int create_file_if_not_exists(const char *filename);
|
||||
int check_file_exists(const char *filename);
|
||||
+2
-1
@@ -5,7 +5,8 @@
|
||||
void get_all_users(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
request_with_token *data = check_body(hm);
|
||||
if (data->error != NULL) {
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"), MG_ESC(data->error));
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC(data->error));
|
||||
return;
|
||||
}
|
||||
if (!jwt_verifyJWT(data->token, JWT_DEFAULT_SECRET)) {
|
||||
|
||||
+4
-2
@@ -13,7 +13,8 @@ void get_token(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
if (username == NULL || password == NULL) {
|
||||
const char *error_ptr = cJSON_GetErrorPtr();
|
||||
if (error_ptr != NULL) {
|
||||
mg_http_reply(c, 400, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"), MG_ESC(error_ptr));
|
||||
mg_http_reply(c, 400, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC(error_ptr));
|
||||
return;
|
||||
}
|
||||
mg_http_reply(c, 400, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
@@ -41,7 +42,8 @@ void get_token(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
db_user->id, db_user->username, db_user->email, db_user->group,
|
||||
db_user->is_superuser ? "true" : "false");
|
||||
char *token = jwt_createJWT(header, payload, JWT_DEFAULT_SECRET);
|
||||
mg_http_reply(c, 200, HTTP_HEADERS, "{%m:%m}", MG_ESC("token"), MG_ESC(token));
|
||||
mg_http_reply(c, 200, HTTP_HEADERS, "{%m:%m}", MG_ESC("token"),
|
||||
MG_ESC(token));
|
||||
free_user(db_user);
|
||||
free(token);
|
||||
}
|
||||
+2
-1
@@ -10,7 +10,8 @@ void get_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
}
|
||||
request_with_token *requestdata = check_body(hm);
|
||||
if (requestdata->error != NULL) {
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"), MG_ESC(requestdata->error));
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC(requestdata->error));
|
||||
return;
|
||||
}
|
||||
if (!jwt_verifyJWT(requestdata->token, JWT_DEFAULT_SECRET)) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "jwt.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/evp.h>
|
||||
@@ -57,7 +58,7 @@ char *jwt_base64url_encode(const unsigned char *input, const int length) {
|
||||
BUF_MEM *bufferPtr;
|
||||
BIO_get_mem_ptr(bio, &bufferPtr);
|
||||
|
||||
const auto result = (char *) malloc(bufferPtr->length + 1);
|
||||
const auto result = (char *)malloc(bufferPtr->length + 1);
|
||||
memcpy(result, bufferPtr->data, bufferPtr->length);
|
||||
result[bufferPtr->length] = '\0';
|
||||
|
||||
@@ -73,7 +74,7 @@ unsigned char *jwt_base64url_decode(const char *input, int input_len,
|
||||
if (input_len == 0) input_len = strlen(input);
|
||||
|
||||
// Создаем копию для преобразования
|
||||
const auto input_copy = (char *) malloc(input_len + 1);
|
||||
const auto input_copy = (char *)malloc(input_len + 1);
|
||||
strncpy(input_copy, input, input_len);
|
||||
input_copy[input_len] = '\0';
|
||||
|
||||
@@ -85,7 +86,7 @@ unsigned char *jwt_base64url_decode(const char *input, int input_len,
|
||||
|
||||
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
|
||||
|
||||
const auto buffer = (unsigned char *) malloc(input_len);
|
||||
const auto buffer = (unsigned char *)malloc(input_len);
|
||||
const int len = BIO_read(bio, buffer, input_len);
|
||||
|
||||
BIO_free_all(bio);
|
||||
@@ -104,13 +105,13 @@ unsigned char *jwt_base64url_decode(const char *input, int input_len,
|
||||
// Создание JWT токена
|
||||
char *jwt_createJWT(const char *header_json, const char *payload_json,
|
||||
const char *secret) {
|
||||
char *encodedHeader = jwt_base64url_encode(
|
||||
(const unsigned char *) header_json, strlen(header_json));
|
||||
char *encodedHeader = jwt_base64url_encode((const unsigned char *)header_json,
|
||||
strlen(header_json));
|
||||
char *encodedPayload = jwt_base64url_encode(
|
||||
(const unsigned char *) payload_json, strlen(payload_json));
|
||||
(const unsigned char *)payload_json, strlen(payload_json));
|
||||
|
||||
char *unsignedToken =
|
||||
(char *) malloc(strlen(encodedHeader) + strlen(encodedPayload) + 2);
|
||||
(char *)malloc(strlen(encodedHeader) + strlen(encodedPayload) + 2);
|
||||
sprintf(unsignedToken, "%s.%s", encodedHeader, encodedPayload);
|
||||
|
||||
unsigned int digest_len;
|
||||
@@ -119,7 +120,7 @@ char *jwt_createJWT(const char *header_json, const char *payload_json,
|
||||
char *encodedSignature = jwt_base64url_encode(digest, digest_len);
|
||||
|
||||
char *jwt =
|
||||
(char *) malloc(strlen(unsignedToken) + strlen(encodedSignature) + 2);
|
||||
(char *)malloc(strlen(unsignedToken) + strlen(encodedSignature) + 2);
|
||||
sprintf(jwt, "%s.%s", unsignedToken, encodedSignature);
|
||||
|
||||
free(encodedHeader);
|
||||
@@ -134,8 +135,8 @@ char *jwt_createJWT(const char *header_json, const char *payload_json,
|
||||
// Генерация HMAC-SHA256
|
||||
unsigned char *jwt_hmac_sha256(const char *key, int key_len, const char *data,
|
||||
int data_len, unsigned int *digest_len) {
|
||||
unsigned char *digest = (unsigned char *) malloc(EVP_MAX_MD_SIZE);
|
||||
HMAC(EVP_sha256(), key, key_len, (const unsigned char *) data, data_len,
|
||||
unsigned char *digest = (unsigned char *)malloc(EVP_MAX_MD_SIZE);
|
||||
HMAC(EVP_sha256(), key, key_len, (const unsigned char *)data, data_len,
|
||||
digest, digest_len);
|
||||
return digest;
|
||||
}
|
||||
@@ -150,17 +151,17 @@ bool jwt_verifyJWT(const char *token, const char *secret) {
|
||||
size_t payload_len = dot2 - dot1 - 1;
|
||||
size_t sig_len = strlen(dot2 + 1);
|
||||
|
||||
char *header = (char *) malloc(header_len + 1);
|
||||
char *header = (char *)malloc(header_len + 1);
|
||||
strncpy(header, token, header_len);
|
||||
header[header_len] = '\0';
|
||||
|
||||
char *payload = (char *) malloc(payload_len + 1);
|
||||
char *payload = (char *)malloc(payload_len + 1);
|
||||
strncpy(payload, dot1 + 1, payload_len);
|
||||
payload[payload_len] = '\0';
|
||||
|
||||
char *signature = strndup(dot2 + 1, sig_len);
|
||||
|
||||
char *signing_input = (char *) malloc(header_len + payload_len + 2);
|
||||
char *signing_input = (char *)malloc(header_len + payload_len + 2);
|
||||
sprintf(signing_input, "%s.%s", header, payload);
|
||||
|
||||
int expected_sig_len;
|
||||
@@ -181,7 +182,7 @@ bool jwt_verifyJWT(const char *token, const char *secret) {
|
||||
int payload_bin_len;
|
||||
unsigned char *payload_bin =
|
||||
jwt_base64url_decode(payload, payload_len, &payload_bin_len);
|
||||
char *payload_str = (char *) malloc(payload_bin_len + 1);
|
||||
char *payload_str = (char *)malloc(payload_bin_len + 1);
|
||||
memcpy(payload_str, payload_bin, payload_bin_len);
|
||||
payload_str[payload_bin_len] = '\0';
|
||||
|
||||
@@ -190,7 +191,7 @@ bool jwt_verifyJWT(const char *token, const char *secret) {
|
||||
cJSON *exp = cJSON_GetObjectItemCaseSensitive(json_payload, "exp");
|
||||
if (cJSON_IsNumber(exp)) {
|
||||
time_t now = time(nullptr);
|
||||
if (now >= (time_t) exp->valuedouble) {
|
||||
if (now >= (time_t)exp->valuedouble) {
|
||||
exp_valid = false;
|
||||
}
|
||||
}
|
||||
@@ -217,14 +218,14 @@ cJSON *jwt_get_payload(const char *token) {
|
||||
if (!dot1 || !dot2) return nullptr;
|
||||
|
||||
size_t payload_len = dot2 - dot1 - 1;
|
||||
char *payload = (char *) malloc(payload_len + 1);
|
||||
char *payload = (char *)malloc(payload_len + 1);
|
||||
strncpy(payload, dot1 + 1, payload_len);
|
||||
payload[payload_len] = '\0';
|
||||
|
||||
int payload_bin_len;
|
||||
unsigned char *payload_bin =
|
||||
jwt_base64url_decode(payload, payload_len, &payload_bin_len);
|
||||
char *payload_str = (char *) malloc(payload_bin_len + 1);
|
||||
char *payload_str = (char *)malloc(payload_bin_len + 1);
|
||||
memcpy(payload_str, payload_bin, payload_bin_len);
|
||||
payload_str[payload_bin_len] = '\0';
|
||||
|
||||
@@ -243,14 +244,14 @@ cJSON *jwt_get_header(const char *token) {
|
||||
if (!dot1) return nullptr;
|
||||
|
||||
size_t header_len = dot1 - token;
|
||||
char *header = (char *) malloc(header_len + 1);
|
||||
char *header = (char *)malloc(header_len + 1);
|
||||
strncpy(header, token, header_len);
|
||||
header[header_len] = '\0';
|
||||
|
||||
int header_bin_len;
|
||||
unsigned char *header_bin =
|
||||
jwt_base64url_decode(header, header_len, &header_bin_len);
|
||||
char *header_str = (char *) malloc(header_bin_len + 1);
|
||||
char *header_str = (char *)malloc(header_bin_len + 1);
|
||||
memcpy(header_str, header_bin, header_bin_len);
|
||||
header_str[header_bin_len] = '\0';
|
||||
|
||||
|
||||
+10
-5
@@ -1,6 +1,10 @@
|
||||
#include <colors.h>
|
||||
#include <mongoose.h>
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include <sqlite3.h>
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "cors.h"
|
||||
#include "database.h"
|
||||
@@ -25,7 +29,7 @@ static const struct route routes[] = {
|
||||
|
||||
void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||
if (ev == MG_EV_ERROR) {
|
||||
MG_LOG(MG_LL_ERROR, ("Ошибка соединения: %s", (char *) ev_data));
|
||||
MG_LOG(MG_LL_ERROR, ("Ошибка соединения: %s", (char *)ev_data));
|
||||
}
|
||||
const bool tls_enabled = cm_get_parameter_as_bool(config, "tls_enabled");
|
||||
if (tls_enabled) {
|
||||
@@ -40,7 +44,7 @@ void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||
}
|
||||
}
|
||||
if (ev == MG_EV_HTTP_MSG) {
|
||||
const auto hm = (struct mg_http_message *) ev_data;
|
||||
const auto hm = (struct mg_http_message *)ev_data;
|
||||
bool route_found = false;
|
||||
|
||||
for (int i = 0; routes[i].path != nullptr; i++) {
|
||||
@@ -66,7 +70,7 @@ int main(void) {
|
||||
migrate_db();
|
||||
const char *default_users_filename =
|
||||
cm_get_parameter_as_string(config, "default_users_file");
|
||||
if (default_users_filename) db_get_users_from_file("users.json");
|
||||
if (default_users_filename) db_get_users_from_file(default_users_filename);
|
||||
|
||||
struct mg_mgr mgr;
|
||||
mg_log_set(MG_LL_DEBUG);
|
||||
@@ -80,8 +84,9 @@ int main(void) {
|
||||
const char *tls_address = cm_get_parameter_as_string(config, "tls_address");
|
||||
char https_address[64];
|
||||
snprintf(https_address, sizeof(https_address), "https://%s", tls_address);
|
||||
tls_address ? mg_http_listen(&mgr, https_address, ev_handler, nullptr)
|
||||
: mg_http_listen(&mgr, "https://0.0.0.0:8223", ev_handler, nullptr);
|
||||
tls_address
|
||||
? mg_http_listen(&mgr, https_address, ev_handler, nullptr)
|
||||
: mg_http_listen(&mgr, "https://0.0.0.0:8223", ev_handler, nullptr);
|
||||
}
|
||||
for (;;) {
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
|
||||
+10
-21
@@ -2,12 +2,9 @@
|
||||
|
||||
void register_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
if (hm->body.len == 0) {
|
||||
mg_http_reply(
|
||||
c, 400,
|
||||
HTTP_HEADERS,
|
||||
"{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("must have <username>, <password>, <email>, <group, "
|
||||
"optional>, <is_superuser, optional>"));
|
||||
mg_http_reply(c, 400, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("must have <username>, <password>, <email>, <group, "
|
||||
"optional>, <is_superuser, optional>"));
|
||||
return;
|
||||
}
|
||||
cJSON *jsonbody = cJSON_Parse(hm->body.buf);
|
||||
@@ -17,12 +14,9 @@ void register_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
cJSON *group = cJSON_GetObjectItem(jsonbody, "group");
|
||||
cJSON *is_superuser = cJSON_GetObjectItem(jsonbody, "is_superuser");
|
||||
if (username == nullptr || password == nullptr || email == nullptr) {
|
||||
mg_http_reply(
|
||||
c, 400,
|
||||
HTTP_HEADERS,
|
||||
"{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("must have <username>, <password>, <email>, <group, "
|
||||
"optional>, <is_superuser, optional>"));
|
||||
mg_http_reply(c, 400, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("must have <username>, <password>, <email>, <group, "
|
||||
"optional>, <is_superuser, optional>"));
|
||||
return;
|
||||
}
|
||||
if (group == nullptr) {
|
||||
@@ -34,12 +28,10 @@ void register_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
const bool is_superuser_value = is_superuser->valueint ? true : false;
|
||||
User *new_user_data = db_insert_user(
|
||||
username->valuestring, email->valuestring, password->valuestring,
|
||||
group->valuestring, (const bool *) is_superuser_value);
|
||||
group->valuestring, &is_superuser_value);
|
||||
if (new_user_data == nullptr) {
|
||||
mg_http_reply(
|
||||
c, 500,
|
||||
HTTP_HEADERS,
|
||||
"{%m:%m}", MG_ESC("error"), MG_ESC("failed to create user"));
|
||||
mg_http_reply(c, 500, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("failed to create user"));
|
||||
return;
|
||||
}
|
||||
char responsedata[2048] = {0};
|
||||
@@ -49,9 +41,6 @@ void register_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
new_user_data->id, new_user_data->username, new_user_data->email,
|
||||
new_user_data->group, new_user_data->is_superuser);
|
||||
|
||||
mg_http_reply(
|
||||
c, 200,
|
||||
HTTP_HEADERS,
|
||||
responsedata);
|
||||
mg_http_reply(c, 200, HTTP_HEADERS, responsedata);
|
||||
free_user(new_user_data);
|
||||
}
|
||||
+3
-1
@@ -1,7 +1,9 @@
|
||||
#include "static.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void root_handler(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
struct mg_http_serve_opts opts = {.root_dir = cm_get_parameter_as_string(config, "web")};
|
||||
struct mg_http_serve_opts opts = {
|
||||
.root_dir = cm_get_parameter_as_string(config, "web")};
|
||||
mg_http_serve_dir(c, hm, &opts);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "user.h"
|
||||
|
||||
#include <cJSON.h>
|
||||
#include <mongoose.h>
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
#include <cJSON.h>
|
||||
#include <mongoose.h>
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include <sqlite3.h>
|
||||
#endif
|
||||
|
||||
#define HTTP_HEADERS \
|
||||
"Content-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n"
|
||||
|
||||
+5
-3
@@ -1,11 +1,13 @@
|
||||
#include "utils.h"
|
||||
|
||||
#include <cJSON.h>
|
||||
#include <mongoose.h>
|
||||
|
||||
#include "user.h"
|
||||
|
||||
request_with_token *check_body(const struct mg_http_message *hm) {
|
||||
if (hm->body.len == 0) {
|
||||
return new_request_with_token(nullptr, nullptr, (char *) "must have token");
|
||||
return new_request_with_token(nullptr, nullptr, (char *)"must have token");
|
||||
}
|
||||
|
||||
cJSON *json_body = cJSON_Parse(hm->body.buf);
|
||||
@@ -13,9 +15,9 @@ request_with_token *check_body(const struct mg_http_message *hm) {
|
||||
if (token == NULL) {
|
||||
const char *error_ptr = cJSON_GetErrorPtr();
|
||||
if (error_ptr != NULL) {
|
||||
return new_request_with_token(nullptr, nullptr, (char *) error_ptr);
|
||||
return new_request_with_token(nullptr, nullptr, (char *)error_ptr);
|
||||
}
|
||||
return new_request_with_token(nullptr, nullptr, (char *) "must have token");
|
||||
return new_request_with_token(nullptr, nullptr, (char *)"must have token");
|
||||
}
|
||||
return new_request_with_token(strdup(token->valuestring), json_body, nullptr);
|
||||
}
|
||||
+24
-4
@@ -3,16 +3,36 @@
|
||||
#include "utils.h"
|
||||
|
||||
void verify_token(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
const request_with_token *data = check_body(hm);
|
||||
request_with_token *data = check_body(hm);
|
||||
if (data->error != nullptr) {
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"), MG_ESC(data->error));
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:false}", MG_ESC("valid"));
|
||||
return;
|
||||
}
|
||||
const bool valid = jwt_verifyJWT(data->token, JWT_DEFAULT_SECRET);
|
||||
if (!valid) {
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("invalid token"));
|
||||
mg_http_reply(c, 403, HTTP_HEADERS, "{%m:false}", MG_ESC("valid"));
|
||||
free_request_with_token(data);
|
||||
return;
|
||||
}
|
||||
cJSON *payload = jwt_get_payload(data->token);
|
||||
char *username =
|
||||
strdup(cJSON_GetObjectItem(payload, "username")->valuestring);
|
||||
if (!username) {
|
||||
free_request_with_token(data);
|
||||
cJSON_Delete(payload);
|
||||
mg_http_reply(c, 500, HTTP_HEADERS, "{%m:false}", MG_ESC("valid"));
|
||||
return;
|
||||
}
|
||||
User *user = db_get_user_by_username(username);
|
||||
if (!user) {
|
||||
free_request_with_token(data);
|
||||
cJSON_Delete(payload);
|
||||
free(username);
|
||||
mg_http_reply(c, 404, HTTP_HEADERS, "{%m:false}", MG_ESC("valid"));
|
||||
return;
|
||||
}
|
||||
mg_http_reply(c, 200, HTTP_HEADERS, "{%m:true}", MG_ESC("valid"));
|
||||
free_request_with_token(data);
|
||||
free(username);
|
||||
free_user(user);
|
||||
}
|
||||
@@ -7,6 +7,8 @@ GREEN="\033[0;32m"
|
||||
RED="\033[0;31m"
|
||||
YELLOW="\033[1;33m"
|
||||
CYAN="\033[0;36m"
|
||||
HOST="localhost"
|
||||
PORT="8222"
|
||||
|
||||
./auth_service &> auth_service.log &
|
||||
sleep 0.1
|
||||
@@ -19,7 +21,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '{"username":"tola","password":"e0c7bfa5b8e4ae0cecfc1f14093a71e05c27abd93a3850fc35f008c3baf866b4"}' \
|
||||
localhost:8222/api/token &> api_token_test.log
|
||||
$HOST:$PORT/api/token &> api_token_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_token_test.log)
|
||||
if [[ "$res" == *"token"* ]]; then
|
||||
@@ -36,7 +38,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '{"username":"tola","password":"288"}' \
|
||||
localhost:8222/api/token &> api_token_wrong_password_test.log
|
||||
$HOST:$PORT/api/token &> api_token_wrong_password_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_token_wrong_password_test.log)
|
||||
if [[ "$res" == *"{\"error\":\"wrong password\"}"* ]]; then
|
||||
@@ -53,7 +55,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '{"username":"toa","password":"2808"}' \
|
||||
localhost:8222/api/token &> api_token_wrong_username_test.log
|
||||
$HOST:$PORT/api/token &> api_token_wrong_username_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_token_wrong_username_test.log)
|
||||
if [[ "$res" == *"{\"error\":\"couldn't find user\"}"* ]]; then
|
||||
@@ -70,7 +72,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '' \
|
||||
localhost:8222/api/token &> api_token_no_data_test.log
|
||||
$HOST:$PORT/api/token &> api_token_no_data_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_token_no_data_test.log)
|
||||
if [[ "$res" == *"{\"error\":\"must have username and password\"}"* ]]; then
|
||||
@@ -87,7 +89,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '{{asdf}}}asdfasdfasdf""asdf' \
|
||||
localhost:8222/api/token &> api_token_not_valid_json_test.log
|
||||
$HOST:$PORT/api/token &> api_token_not_valid_json_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_token_not_valid_json_test.log)
|
||||
if [[ "$res" == *"error"* ]]; then
|
||||
@@ -104,7 +106,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d $(cat api_token_test.log) \
|
||||
localhost:8222/api/token/verify &> api_token_verify_test.log
|
||||
$HOST:$PORT/api/token/verify &> api_token_verify_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_token_verify_test.log)
|
||||
if [[ "$res" == *'{"valid":true}'* ]]; then
|
||||
@@ -121,10 +123,10 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '' \
|
||||
localhost:8222/api/token/verify &> api_token_verify_no_data_test.log
|
||||
$HOST:$PORT/api/token/verify &> api_token_verify_no_data_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_token_verify_no_data_test.log)
|
||||
if [[ "$res" == *'{"error":"must have token"}'* ]]; then
|
||||
if [[ "$res" == *'{"valid":false}'* ]]; then
|
||||
printf "[$GREEN OK $RESET]\n"
|
||||
success=$(($success+1))
|
||||
else
|
||||
@@ -138,10 +140,10 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '{"token":"asdf"}' \
|
||||
localhost:8222/api/token/verify &> api_token_verify_wrong_token_test.log
|
||||
$HOST:$PORT/api/token/verify &> api_token_verify_wrong_token_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_token_verify_wrong_token_test.log)
|
||||
if [[ "$res" == *'{"error":"invalid token"}'* ]]; then
|
||||
if [[ "$res" == *'{"valid":false}'* ]]; then
|
||||
printf "[$GREEN OK $RESET]\n"
|
||||
success=$(($success+1))
|
||||
else
|
||||
@@ -155,10 +157,10 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d 'asdf[apsdfqopwjf[9qfm93qq89n]]' \
|
||||
localhost:8222/api/token/verify &> api_token_verify_wrong_json_test.log
|
||||
$HOST:$PORT/api/token/verify &> api_token_verify_wrong_json_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_token_verify_wrong_json_test.log)
|
||||
if [[ "$res" == *'error'* ]]; then
|
||||
if [[ "$res" == *'{"valid":false}'* ]]; then
|
||||
printf "[$GREEN OK $RESET]\n"
|
||||
success=$(($success+1))
|
||||
else
|
||||
@@ -172,7 +174,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d $(cat api_token_test.log) \
|
||||
localhost:8222/api/users &> api_users_test.log
|
||||
$HOST:$PORT/api/users &> api_users_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_test.log)
|
||||
if [[ "$res" == *'username'* ]]; then
|
||||
@@ -189,7 +191,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '{"token":"asdf"}' \
|
||||
localhost:8222/api/users &> api_users_wrong_token_test.log
|
||||
$HOST:$PORT/api/users &> api_users_wrong_token_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_wrong_token_test.log)
|
||||
if [[ "$res" == *'{"error":"invalid token"}'* ]]; then
|
||||
@@ -206,7 +208,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '' \
|
||||
localhost:8222/api/users &> api_users_no_data_test.log
|
||||
$HOST:$PORT/api/users &> api_users_no_data_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_no_data_test.log)
|
||||
if [[ "$res" == *'{"error":"must have token"}'* ]]; then
|
||||
@@ -223,7 +225,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d 'ahsdlfhjalighafina[a[][apofj OFFW[Efflja]]]' \
|
||||
localhost:8222/api/users &> api_users_wrong_json_test.log
|
||||
$HOST:$PORT/api/users &> api_users_wrong_json_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_wrong_json_test.log)
|
||||
if [[ "$res" == *'error'* ]]; then
|
||||
@@ -240,7 +242,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d $(cat api_token_test.log) \
|
||||
localhost:8222/api/users/user &> api_users_user_test.log
|
||||
$HOST:$PORT/api/users/user &> api_users_user_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_user_test.log)
|
||||
if [[ "$res" == *'username'* ]]; then
|
||||
@@ -257,7 +259,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '{"token":"asdf"}' \
|
||||
localhost:8222/api/users/user &> api_users_user_wrong_token_test.log
|
||||
$HOST:$PORT/api/users/user &> api_users_user_wrong_token_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_user_wrong_token_test.log)
|
||||
if [[ "$res" == *'{"error":"invalid token"}'* ]]; then
|
||||
@@ -274,7 +276,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '' \
|
||||
localhost:8222/api/users/user &> api_users_user_no_data_test.log
|
||||
$HOST:$PORT/api/users/user &> api_users_user_no_data_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_user_no_data_test.log)
|
||||
if [[ "$res" == *'{"error":"must have token"}'* ]]; then
|
||||
@@ -291,7 +293,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d 'alskodjfqjvoq3vn[q90\audv0q j89fvn 2vp]' \
|
||||
localhost:8222/api/users/user &> api_users_user_wrong_json_test.log
|
||||
$HOST:$PORT/api/users/user &> api_users_user_wrong_json_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_user_wrong_json_test.log)
|
||||
if [[ "$res" == *'error'* ]]; then
|
||||
@@ -315,7 +317,7 @@ curl \
|
||||
"is_superuser":false,
|
||||
"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IDEsInVzZXJuYW1lIjogInRvbGEiLCJlbWFpbCI6ICJtYWlsQGV4YW1wbGUuY29tIiwiZ3JvdXAiOiAicm9vdCIsImlzX3N1cGVydXNlciI6IHRydWV9.QGUnCWPmp5hWAtGFTGDMw2SugZqLsYfMboeFU4UQLXQ"
|
||||
}' \
|
||||
localhost:8222/api/users/add &> api_users_add_test.log
|
||||
$HOST:$PORT/api/users/add &> api_users_add_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_add_test.log)
|
||||
if [[ "$res" == *'username'* ]]; then
|
||||
@@ -332,13 +334,13 @@ reqdata=$(curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '{"username":"asdff","password":"asdf"}' \
|
||||
localhost:8222/api/token)
|
||||
$HOST:$PORT/api/token)
|
||||
sleep 0.1
|
||||
curl \
|
||||
--silent \
|
||||
-X DELETE \
|
||||
-d $reqdata \
|
||||
localhost:8222/api/users &> delete_api_users_test.log
|
||||
$HOST:$PORT/api/users &> delete_api_users_test.log
|
||||
sleep 0.1
|
||||
res=$(cat delete_api_users_test.log)
|
||||
if [[ "$res" == *'{"success": true}'* ]]; then
|
||||
@@ -356,7 +358,7 @@ curl \
|
||||
--silent \
|
||||
-X DELETE \
|
||||
-d $reqdata \
|
||||
localhost:8222/api/users &> delete_api_users_second_delete_test.log
|
||||
$HOST:$PORT/api/users &> delete_api_users_second_delete_test.log
|
||||
sleep 0.1
|
||||
res=$(cat delete_api_users_second_delete_test.log)
|
||||
if [[ "$res" == *'{"success": false}'* ]]; then
|
||||
@@ -373,7 +375,7 @@ curl \
|
||||
--silent \
|
||||
-X DELETE \
|
||||
-d '$reqdata' \
|
||||
localhost:8222/api/users &> delete_api_users_wrong_json_test.log
|
||||
$HOST:$PORT/api/users &> delete_api_users_wrong_json_test.log
|
||||
sleep 0.1
|
||||
res=$(cat delete_api_users_wrong_json_test.log)
|
||||
if [[ "$res" == *'error'* ]]; then
|
||||
@@ -390,7 +392,7 @@ curl \
|
||||
--silent \
|
||||
-X DELETE \
|
||||
-d '{"token":"asdf"}' \
|
||||
localhost:8222/api/users &> delete_api_users_wrong_token_test.log
|
||||
$HOST:$PORT/api/users &> delete_api_users_wrong_token_test.log
|
||||
sleep 0.1
|
||||
res=$(cat delete_api_users_wrong_token_test.log)
|
||||
if [[ "$res" == *'{"error":"invalid token"}'* ]]; then
|
||||
@@ -407,7 +409,7 @@ curl \
|
||||
--silent \
|
||||
-X DELETE \
|
||||
-d '' \
|
||||
localhost:8222/api/users &> delete_api_users_no_data_test.log
|
||||
$HOST:$PORT/api/users &> delete_api_users_no_data_test.log
|
||||
sleep 0.1
|
||||
res=$(cat delete_api_users_no_data_test.log)
|
||||
if [[ "$res" == *'{"error":"must have token"}'* ]]; then
|
||||
@@ -425,7 +427,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d "{\"old_password\":\"e0c7bfa5b8e4ae0cecfc1f14093a71e05c27abd93a3850fc35f008c3baf866b4\",\"new_password\":\"1234\",$reqtoken}" \
|
||||
localhost:8222/api/users/password &> api_users_password_test.log
|
||||
$HOST:$PORT/api/users/password &> api_users_password_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_password_test.log)
|
||||
if [[ "$res" == *'{"success": true}'* ]]; then
|
||||
@@ -442,7 +444,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d "" \
|
||||
localhost:8222/api/users/password &> api_users_password_no_data_test.log
|
||||
$HOST:$PORT/api/users/password &> api_users_password_no_data_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_password_no_data_test.log)
|
||||
if [[ "$res" == *'{"error":"must have token, old_password, new_password"}'* ]]; then
|
||||
@@ -459,7 +461,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d "ijansd fu9q303ghq9" \
|
||||
localhost:8222/api/users/password &> api_users_password_wrong_json_test.log
|
||||
$HOST:$PORT/api/users/password &> api_users_password_wrong_json_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_users_password_wrong_json_test.log)
|
||||
if [[ "$res" == *'error'* ]]; then
|
||||
@@ -482,7 +484,7 @@ curl \
|
||||
\"group\":\"admin\",
|
||||
\"is_superuser\":true,
|
||||
$reqtoken}" \
|
||||
localhost:8222/api/users &> put_api_users_test.log
|
||||
$HOST:$PORT/api/users &> put_api_users_test.log
|
||||
sleep 0.1
|
||||
res=$(cat put_api_users_test.log)
|
||||
if [[ "$res" == *'username'* ]]; then
|
||||
@@ -499,7 +501,7 @@ curl \
|
||||
--silent \
|
||||
-X PUT \
|
||||
-d "" \
|
||||
localhost:8222/api/users &> put_api_users_no_data_test.log
|
||||
$HOST:$PORT/api/users &> put_api_users_no_data_test.log
|
||||
sleep 0.1
|
||||
res=$(cat put_api_users_no_data_test.log)
|
||||
if [[ "$res" == *'{"error":"must have token, new_user_data"}'* ]]; then
|
||||
@@ -516,7 +518,7 @@ curl \
|
||||
--silent \
|
||||
-X PUT \
|
||||
-d "hiusdf 7qyt0 y qy40" \
|
||||
localhost:8222/api/users &> put_api_users_wrong_json_test.log
|
||||
$HOST:$PORT/api/users &> put_api_users_wrong_json_test.log
|
||||
sleep 0.1
|
||||
res=$(cat put_api_users_wrong_json_test.log)
|
||||
if [[ "$res" == *'error'* ]]; then
|
||||
@@ -539,7 +541,7 @@ curl \
|
||||
"group":"users",
|
||||
"is_superuser":false
|
||||
}' \
|
||||
localhost:8222/api/register &> api_register_test.log
|
||||
$HOST:$PORT/api/register &> api_register_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_register_test.log)
|
||||
if [[ "$res" == *'username'* ]]; then
|
||||
@@ -561,7 +563,7 @@ curl \
|
||||
"group":"users",
|
||||
"is_superuser":false
|
||||
}' \
|
||||
localhost:8222/api/register &> api_register_without_username_test.log
|
||||
$HOST:$PORT/api/register &> api_register_without_username_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_register_without_username_test.log)
|
||||
if [[ "$res" == *'{"error":"must have <username>, <password>, <email>, <group, optional>, <is_superuser, optional>"}'* ]]; then
|
||||
@@ -583,7 +585,7 @@ curl \
|
||||
"group":"users",
|
||||
"is_superuser":false
|
||||
}' \
|
||||
localhost:8222/api/register &> api_register_without_email_test.log
|
||||
$HOST:$PORT/api/register &> api_register_without_email_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_register_without_email_test.log)
|
||||
if [[ "$res" == *'{"error":"must have <username>, <password>, <email>, <group, optional>, <is_superuser, optional>"}'* ]]; then
|
||||
@@ -605,7 +607,7 @@ curl \
|
||||
"group":"users",
|
||||
"is_superuser":false
|
||||
}' \
|
||||
localhost:8222/api/register &> api_register_without_password_test.log
|
||||
$HOST:$PORT/api/register &> api_register_without_password_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_register_without_password_test.log)
|
||||
if [[ "$res" == *'{"error":"must have <username>, <password>, <email>, <group, optional>, <is_superuser, optional>"}'* ]]; then
|
||||
@@ -627,7 +629,7 @@ curl \
|
||||
"password":"qwer",
|
||||
"is_superuser":false
|
||||
}' \
|
||||
localhost:8222/api/register &> api_register_without_group_test.log
|
||||
$HOST:$PORT/api/register &> api_register_without_group_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_register_without_group_test.log)
|
||||
if [[ "$res" == *'username'* ]]; then
|
||||
@@ -649,7 +651,7 @@ curl \
|
||||
"password":"zxcv",
|
||||
"group":"users"
|
||||
}' \
|
||||
localhost:8222/api/register &> api_register_without_is_superuser_test.log
|
||||
$HOST:$PORT/api/register &> api_register_without_is_superuser_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_register_without_is_superuser_test.log)
|
||||
if [[ "$res" == *'username'* ]]; then
|
||||
@@ -671,7 +673,7 @@ curl \
|
||||
"password":"zxcv",
|
||||
"group":"users"
|
||||
}' \
|
||||
localhost:8222/api/register &> api_register_second_register_test.log
|
||||
$HOST:$PORT/api/register &> api_register_second_register_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_register_second_register_test.log)
|
||||
if [[ "$res" == *'{"error":"failed to create user"}'* ]]; then
|
||||
@@ -688,7 +690,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d 'najsnvpnvq234890vn9qq234vqui3v' \
|
||||
localhost:8222/api/register &> api_register_wrong_json_test.log
|
||||
$HOST:$PORT/api/register &> api_register_wrong_json_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_register_wrong_json_test.log)
|
||||
if [[ "$res" == *'error'* ]]; then
|
||||
@@ -705,7 +707,7 @@ curl \
|
||||
--silent \
|
||||
-X POST \
|
||||
-d '' \
|
||||
localhost:8222/api/register &> api_register_no_data_test.log
|
||||
$HOST:$PORT/api/register &> api_register_no_data_test.log
|
||||
sleep 0.1
|
||||
res=$(cat api_register_no_data_test.log)
|
||||
if [[ "$res" == *'{"error":"must have <username>, <password>, <email>, <group, optional>, <is_superuser, optional>"}'* ]]; then
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
set(CMAKE_C_COMPILER aarch64-buildroot-linux-uclibc-gcc)
|
||||
@@ -0,0 +1,11 @@
|
||||
[binaries]
|
||||
c = 'aarch64-buildroot-linux-uclibc-gcc'
|
||||
ar = 'aarch64-buildroot-linux-uclibc-ar'
|
||||
strip = 'aarch64-buildroot-linux-uclibc-strip'
|
||||
ld = 'aarch64-buildroot-linux-uclibc-ld'
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
@@ -0,0 +1 @@
|
||||
set(CMAKE_C_COMPILER arm-buildroot-linux-uclibcgnueabihf-gcc)
|
||||
@@ -0,0 +1,11 @@
|
||||
[binaries]
|
||||
c = 'arm-buildroot-linux-uclibcgnueabihf-gcc'
|
||||
ar = 'arm-buildroot-linux-uclibcgnueabihf-ar'
|
||||
strip = 'arm-buildroot-linux-uclibcgnueabihf-strip'
|
||||
ld = 'arm-buildroot-linux-uclibcgnueabihf-ld'
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
@@ -0,0 +1 @@
|
||||
set(CMAKE_C_COMPILER x86_64-buildroot-linux-uclibc-gcc)
|
||||
@@ -0,0 +1,11 @@
|
||||
[binaries]
|
||||
c = 'x86_64-buildroot-linux-uclibc-gcc'
|
||||
ar = 'x86_64-buildroot-linux-uclibc-ar'
|
||||
strip = 'x86_64-buildroot-linux-uclibc-strip'
|
||||
ld = 'x86_64-buildroot-linux-uclibc-ld'
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
@@ -215,6 +215,7 @@
|
||||
<tbody id="alluserstablebody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script src="/js/crypto-js.min.js"></script>
|
||||
<script src="/js/security.js"></script>
|
||||
<script src="/js/message.js"></script>
|
||||
<script src="/js/routes.js"></script>
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
!function(t,e){"object"==typeof exports?module.exports=exports=e():"function"==typeof define&&define.amd?define([],e):t.CryptoJS=e()}(this,function(){var n,o,s,a,h,t,e,l,r,i,c,f,d,u,p,S,x,b,A,H,z,_,v,g,y,B,w,k,m,C,D,E,R,M,F,P,W,O,I,U=U||function(h){var i;if("undefined"!=typeof window&&window.crypto&&(i=window.crypto),"undefined"!=typeof self&&self.crypto&&(i=self.crypto),!(i=!(i=!(i="undefined"!=typeof globalThis&&globalThis.crypto?globalThis.crypto:i)&&"undefined"!=typeof window&&window.msCrypto?window.msCrypto:i)&&"undefined"!=typeof global&&global.crypto?global.crypto:i)&&"function"==typeof require)try{i=require("crypto")}catch(t){}var r=Object.create||function(t){return e.prototype=t,t=new e,e.prototype=null,t};function e(){}var t={},n=t.lib={},o=n.Base={extend:function(t){var e=r(this);return t&&e.mixIn(t),e.hasOwnProperty("init")&&this.init!==e.init||(e.init=function(){e.$super.init.apply(this,arguments)}),(e.init.prototype=e).$super=this,e},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);t.hasOwnProperty("toString")&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}},l=n.WordArray=o.extend({init:function(t,e){t=this.words=t||[],this.sigBytes=null!=e?e:4*t.length},toString:function(t){return(t||c).stringify(this)},concat:function(t){var e=this.words,r=t.words,i=this.sigBytes,n=t.sigBytes;if(this.clamp(),i%4)for(var o=0;o<n;o++){var s=r[o>>>2]>>>24-o%4*8&255;e[i+o>>>2]|=s<<24-(i+o)%4*8}else for(var c=0;c<n;c+=4)e[i+c>>>2]=r[c>>>2];return this.sigBytes+=n,this},clamp:function(){var t=this.words,e=this.sigBytes;t[e>>>2]&=4294967295<<32-e%4*8,t.length=h.ceil(e/4)},clone:function(){var t=o.clone.call(this);return t.words=this.words.slice(0),t},random:function(t){for(var e=[],r=0;r<t;r+=4)e.push(function(){if(i){if("function"==typeof i.getRandomValues)try{return i.getRandomValues(new Uint32Array(1))[0]}catch(t){}if("function"==typeof i.randomBytes)try{return i.randomBytes(4).readInt32LE()}catch(t){}}throw new Error("Native crypto module could not be used to get secure random number.")}());return new l.init(e,t)}}),s=t.enc={},c=s.Hex={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=[],n=0;n<r;n++){var o=e[n>>>2]>>>24-n%4*8&255;i.push((o>>>4).toString(16)),i.push((15&o).toString(16))}return i.join("")},parse:function(t){for(var e=t.length,r=[],i=0;i<e;i+=2)r[i>>>3]|=parseInt(t.substr(i,2),16)<<24-i%8*4;return new l.init(r,e/2)}},a=s.Latin1={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=[],n=0;n<r;n++){var o=e[n>>>2]>>>24-n%4*8&255;i.push(String.fromCharCode(o))}return i.join("")},parse:function(t){for(var e=t.length,r=[],i=0;i<e;i++)r[i>>>2]|=(255&t.charCodeAt(i))<<24-i%4*8;return new l.init(r,e)}},f=s.Utf8={stringify:function(t){try{return decodeURIComponent(escape(a.stringify(t)))}catch(t){throw new Error("Malformed UTF-8 data")}},parse:function(t){return a.parse(unescape(encodeURIComponent(t)))}},d=n.BufferedBlockAlgorithm=o.extend({reset:function(){this._data=new l.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=f.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(t){var e,r=this._data,i=r.words,n=r.sigBytes,o=this.blockSize,s=n/(4*o),c=(s=t?h.ceil(s):h.max((0|s)-this._minBufferSize,0))*o,n=h.min(4*c,n);if(c){for(var a=0;a<c;a+=o)this._doProcessBlock(i,a);e=i.splice(0,c),r.sigBytes-=n}return new l.init(e,n)},clone:function(){var t=o.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),u=(n.Hasher=d.extend({cfg:o.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){d.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){return t&&this._append(t),this._doFinalize()},blockSize:16,_createHelper:function(r){return function(t,e){return new r.init(e).finalize(t)}},_createHmacHelper:function(r){return function(t,e){return new u.HMAC.init(r,e).finalize(t)}}}),t.algo={});return t}(Math);function K(t,e,r){return t&e|~t&r}function X(t,e,r){return t&r|e&~r}function L(t,e){return t<<e|t>>>32-e}function j(t,e,r,i){var n,o=this._iv;o?(n=o.slice(0),this._iv=void 0):n=this._prevBlock,i.encryptBlock(n,0);for(var s=0;s<r;s++)t[e+s]^=n[s]}function T(t){var e,r,i;return 255==(t>>24&255)?(r=t>>8&255,i=255&t,255===(e=t>>16&255)?(e=0,255===r?(r=0,255===i?i=0:++i):++r):++e,t=0,t+=e<<16,t+=r<<8,t+=i):t+=1<<24,t}function N(){for(var t=this._X,e=this._C,r=0;r<8;r++)E[r]=e[r];e[0]=e[0]+1295307597+this._b|0,e[1]=e[1]+3545052371+(e[0]>>>0<E[0]>>>0?1:0)|0,e[2]=e[2]+886263092+(e[1]>>>0<E[1]>>>0?1:0)|0,e[3]=e[3]+1295307597+(e[2]>>>0<E[2]>>>0?1:0)|0,e[4]=e[4]+3545052371+(e[3]>>>0<E[3]>>>0?1:0)|0,e[5]=e[5]+886263092+(e[4]>>>0<E[4]>>>0?1:0)|0,e[6]=e[6]+1295307597+(e[5]>>>0<E[5]>>>0?1:0)|0,e[7]=e[7]+3545052371+(e[6]>>>0<E[6]>>>0?1:0)|0,this._b=e[7]>>>0<E[7]>>>0?1:0;for(r=0;r<8;r++){var i=t[r]+e[r],n=65535&i,o=i>>>16;R[Line truncated
|
||||
+9
-6
@@ -1,8 +1,11 @@
|
||||
const hashPassword = async (password) => {
|
||||
const encoder = new TextEncoder()
|
||||
const data = encoder.encode(password)
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', data)
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer))
|
||||
const hashHex = hashArray.map(b=>('00' + b.toString(16)).slice(-2)).join('')
|
||||
return hashHex
|
||||
if (crypto && crypto.subtle) {
|
||||
const encoder = new TextEncoder()
|
||||
const data = encoder.encode(password)
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', data)
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer))
|
||||
const hashHex = hashArray.map(b=>('00' + b.toString(16)).slice(-2)).join('')
|
||||
return hashHex
|
||||
}
|
||||
return CryptoJS.SHA256(password).toString()
|
||||
}
|
||||
Reference in new issue
Block a user