mirror of
https://github.com/falk-werner/webfused
synced 2024-10-27 20:44:08 +00:00
added tests for userdb
This commit is contained in:
parent
35122136fd
commit
364d19bdea
@ -140,6 +140,7 @@ add_executable(alltests
|
||||
test/test_syslog_logger.cc
|
||||
test/test_daemon.cc
|
||||
test/test_change_user.cc
|
||||
test/test_userdb.cc
|
||||
)
|
||||
|
||||
target_include_directories(alltests PRIVATE
|
||||
|
@ -173,7 +173,7 @@ static int add_user(struct args * args)
|
||||
}
|
||||
|
||||
struct userdb * db = userdb_create(args->pepper);
|
||||
userdb_load(db, args->file);
|
||||
userdb_load_file(db, args->file);
|
||||
userdb_add(db, args->username, args->password);
|
||||
bool result = userdb_save(db, args->file);
|
||||
userdb_dispose(db);
|
||||
@ -191,7 +191,7 @@ static int remove_user(struct args * args)
|
||||
}
|
||||
|
||||
struct userdb * db = userdb_create(args->pepper);
|
||||
userdb_load(db, args->file);
|
||||
userdb_load_file(db, args->file);
|
||||
userdb_remove(db, args->username);
|
||||
bool result = userdb_save(db, args->file);
|
||||
userdb_dispose(db);
|
||||
@ -216,7 +216,7 @@ static int check_password(struct args * args)
|
||||
}
|
||||
|
||||
struct userdb * db = userdb_create(args->pepper);
|
||||
userdb_load(db, args->file);
|
||||
userdb_load_file(db, args->file);
|
||||
bool result = userdb_check(db, args->username, args->password);
|
||||
userdb_dispose(db);
|
||||
|
||||
|
@ -77,20 +77,17 @@ static char hex_char(unsigned char value)
|
||||
static char * to_hex(unsigned char const * value, size_t length)
|
||||
{
|
||||
char * result = malloc((2 * length) + 1);
|
||||
if (NULL != result)
|
||||
for (size_t i = 0, j = 0; i < length; i++, j+=2)
|
||||
{
|
||||
for (size_t i = 0, j = 0; i < length; i++, j+=2)
|
||||
{
|
||||
unsigned char high = (value[i] >> 4) & 0x0f;
|
||||
unsigned char low = value[i] & 0x0f;
|
||||
unsigned char high = (value[i] >> 4) & 0x0f;
|
||||
unsigned char low = value[i] & 0x0f;
|
||||
|
||||
result[j ] = hex_char(high);
|
||||
result[j + 1] = hex_char(low);
|
||||
}
|
||||
|
||||
result[2 * length] = '\0';
|
||||
result[j ] = hex_char(high);
|
||||
result[j + 1] = hex_char(low);
|
||||
}
|
||||
|
||||
result[2 * length] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -120,21 +117,46 @@ static char * compute_hash(
|
||||
}
|
||||
|
||||
char * result = NULL;
|
||||
EVP_MD_CTX * context = EVP_MD_CTX_new();
|
||||
EVP_DigestInit_ex(context, digest, NULL);
|
||||
EVP_DigestUpdate(context, password, strlen(password));
|
||||
EVP_DigestUpdate(context, salt, strlen(salt));
|
||||
EVP_DigestUpdate(context, db->pepper, strlen(db->pepper));
|
||||
|
||||
unsigned int hash_size = EVP_MD_size(digest);
|
||||
unsigned char * hash = malloc(hash_size);
|
||||
EVP_DigestFinal_ex(context, hash, &hash_size);
|
||||
EVP_MD_CTX_free(context);
|
||||
|
||||
if (NULL != hash)
|
||||
result = to_hex(hash, hash_size);
|
||||
free(hash);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool userdb_load(
|
||||
struct userdb * db,
|
||||
json_t * container)
|
||||
{
|
||||
bool result = false;
|
||||
if (NULL != container)
|
||||
{
|
||||
EVP_MD_CTX * context = EVP_MD_CTX_new();
|
||||
EVP_DigestInit_ex(context, digest, NULL);
|
||||
EVP_DigestUpdate(context, password, strlen(password));
|
||||
EVP_DigestUpdate(context, salt, strlen(salt));
|
||||
EVP_DigestUpdate(context, db->pepper, strlen(db->pepper));
|
||||
EVP_DigestFinal_ex(context, hash, &hash_size);
|
||||
EVP_MD_CTX_free(context);
|
||||
json_t * meta = json_object_get(container, "meta");
|
||||
json_t * users = json_object_get(container, "users");
|
||||
|
||||
result = to_hex(hash, hash_size);
|
||||
free(hash);
|
||||
if ((is_compatible(meta)) && (json_is_object(users))) {
|
||||
json_t * hash_algorithm = json_object_get(meta, "hash_algorithm");
|
||||
free(db->hash_algorithm);
|
||||
db->hash_algorithm = strdup(json_string_value(hash_algorithm));
|
||||
|
||||
json_decref(db->users);
|
||||
json_incref(users);
|
||||
db->users = users;
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
json_decref(container);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -144,12 +166,9 @@ struct userdb * userdb_create(
|
||||
char const * pepper)
|
||||
{
|
||||
struct userdb * db = malloc(sizeof(struct userdb));
|
||||
if (NULL != db)
|
||||
{
|
||||
db->users = json_object();
|
||||
db->pepper = strdup(pepper);
|
||||
db->hash_algorithm = strdup(USERDB_HASH_ALGORITHM);
|
||||
}
|
||||
db->users = json_object();
|
||||
db->pepper = strdup(pepper);
|
||||
db->hash_algorithm = strdup(USERDB_HASH_ALGORITHM);
|
||||
|
||||
return db;
|
||||
}
|
||||
@ -184,36 +203,23 @@ bool userdb_save(
|
||||
return (0 == result);
|
||||
}
|
||||
|
||||
|
||||
bool userdb_load(
|
||||
bool userdb_load_file(
|
||||
struct userdb * db,
|
||||
char const * filename)
|
||||
{
|
||||
bool result = false;
|
||||
json_t * container = json_load_file(filename, 0, NULL);
|
||||
if (NULL != container)
|
||||
{
|
||||
json_t * meta = json_object_get(container, "meta");
|
||||
json_t * users = json_object_get(container, "users");
|
||||
|
||||
if ((is_compatible(meta)) && (json_is_object(users))) {
|
||||
json_t * hash_algorithm = json_object_get(meta, "hash_algorithm");
|
||||
free(db->hash_algorithm);
|
||||
db->hash_algorithm = strdup(json_string_value(hash_algorithm));
|
||||
|
||||
json_decref(db->users);
|
||||
json_incref(users);
|
||||
db->users = users;
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
json_decref(container);
|
||||
}
|
||||
|
||||
return result;
|
||||
return userdb_load(db, container);
|
||||
}
|
||||
|
||||
bool userdb_load_string(
|
||||
struct userdb * db,
|
||||
char const * contents)
|
||||
{
|
||||
json_t * container = json_loads(contents, 0, NULL);
|
||||
return userdb_load(db, container);
|
||||
}
|
||||
|
||||
|
||||
void userdb_add(
|
||||
struct userdb * db,
|
||||
char const * username,
|
||||
@ -243,7 +249,7 @@ static char const * json_object_get_string(
|
||||
json_t * object,
|
||||
char const * key)
|
||||
{
|
||||
char const * result = NULL;
|
||||
char const * result = "";
|
||||
|
||||
json_t * string_holder = json_object_get(object, key);
|
||||
if (json_is_string(string_holder))
|
||||
|
@ -21,10 +21,14 @@ extern bool userdb_save(
|
||||
struct userdb * db,
|
||||
char const * filename);
|
||||
|
||||
extern bool userdb_load(
|
||||
extern bool userdb_load_file(
|
||||
struct userdb * db,
|
||||
char const * filename);
|
||||
|
||||
extern bool userdb_load_string(
|
||||
struct userdb * db,
|
||||
char const * contents);
|
||||
|
||||
extern void userdb_add(
|
||||
struct userdb * db,
|
||||
char const * username,
|
||||
|
@ -37,7 +37,7 @@ wfd_file_authenticator_authenticate(
|
||||
if ((NULL != username) && (NULL != password))
|
||||
{
|
||||
struct userdb * db = userdb_create("");
|
||||
result = userdb_load(db, authenticator->filename);
|
||||
result = userdb_load_file(db, authenticator->filename);
|
||||
if (result)
|
||||
{
|
||||
result = userdb_check(db, username, password);
|
||||
|
407
test/test_userdb.cc
Normal file
407
test/test_userdb.cc
Normal file
@ -0,0 +1,407 @@
|
||||
#include "userdb/userdb.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(userdb, load_file)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
|
||||
bool success = userdb_load_file(db, "test_passwd.json");
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "secret"));
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_file_failed_no_file)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
|
||||
bool success = userdb_load_file(db, "non_existing.json");
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, save)
|
||||
{
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
userdb_add(db, "bob", "secret");
|
||||
ASSERT_TRUE(userdb_save(db, "/tmp/webfused_test.json"));
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
ASSERT_TRUE(userdb_load_file(db, "/tmp/webfused_test.json"));
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "secret"));
|
||||
userdb_dispose(db);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(userdb, add)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
|
||||
userdb_add(db, "bob", "secret");
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "secret"));
|
||||
ASSERT_FALSE(userdb_check(db, "bob", "i_dont_know"));
|
||||
ASSERT_FALSE(userdb_check(db, "anna", "secret"));
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, remove)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
ASSERT_NE(nullptr, db);
|
||||
|
||||
userdb_add(db, "bob", "secret");
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "secret"));
|
||||
|
||||
userdb_remove(db, "bob");
|
||||
ASSERT_FALSE(userdb_check(db, "bob", "secret"));
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, update)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
ASSERT_NE(nullptr, db);
|
||||
|
||||
userdb_add(db, "bob", "secret");
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "secret"));
|
||||
|
||||
userdb_add(db, "bob", "new_secret");
|
||||
ASSERT_FALSE(userdb_check(db, "bob", "secret"));
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "new_secret"));
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_string)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_no_json)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] = "brummni";
|
||||
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_invalid_type)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"any-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_invalid_version)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 2,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_missing_type)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_type_not_string)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": 42,"
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_missing_major_version)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_major_version_not_int)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": false,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_missing_minor_version)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_minor_version_not_int)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": false,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_missing_hash_alg)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_hash_alg_not_string)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": 42"
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_missing_meta)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_unsupported_hash)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"brummni\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, fail_missing_user_salt)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
" \"bob\": {"
|
||||
" \"password_hash\": \"e51e27ce47054feead3d83068d47f2a07307d4877ac67da668ef43e0e466fe8c7b66651af14fdb8d48c51592ef5afa0c63f874d20861c6b9ef8e6513bfcaa330\""
|
||||
" }"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
ASSERT_FALSE(userdb_check(db, "bob", "secret"));
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, fail_missing_user_hash)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
" \"bob\": {"
|
||||
" \"salt\": \"b3be6979921edecfea88c50d0d1ec40b7f8c383831b2276c65969ead18e47c03\""
|
||||
" }"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
ASSERT_FALSE(userdb_check(db, "bob", "secret"));
|
||||
userdb_dispose(db);
|
||||
}
|
Loading…
Reference in New Issue
Block a user