1
0
mirror of https://github.com/falk-werner/webfused synced 2024-10-27 20:44:08 +00:00

add authenticator to server config

This commit is contained in:
Falk Werner 2020-03-17 16:49:17 +01:00
parent d90afed1b2
commit 7e7cbd5d42
9 changed files with 268 additions and 96 deletions

View File

@ -113,6 +113,7 @@ add_executable(alltests
test/mock_config_builder.cc test/mock_config_builder.cc
test/mock_logger.cc test/mock_logger.cc
test/mock_credentials.cc test/mock_credentials.cc
test/mock_auth_settings.cc
test/test_config_factory.cc test/test_config_factory.cc
test/test_config.cc test/test_config.cc
test/test_auth_settings.cc test/test_auth_settings.cc
@ -132,6 +133,8 @@ target_compile_options(alltests PRIVATE ${GMOCK_CFLAGS} ${GTEST_CFLAGS} "-pthrea
target_link_libraries(alltests PRIVATE target_link_libraries(alltests PRIVATE
-Wl,--wrap=wf_credentials_type -Wl,--wrap=wf_credentials_type
-Wl,--wrap=wf_credentials_get -Wl,--wrap=wf_credentials_get
-Wl,--wrap=wfd_auth_settings_get_provider
-Wl,--wrap=wfd_auth_settings_get
webfused-static webfused-static
userdb userdb
${LIBCONFIG_LIBRARIES} ${LIBCONFIG_LIBRARIES}

View File

@ -16,3 +16,9 @@ wfd_authenticator_authenticate(
credentials, authenticator.data); credentials, authenticator.data);
} }
char const *
wfd_authenticator_get_type(
struct wfd_authenticator authenticator)
{
return authenticator.vtable->get_type(authenticator.data);
}

View File

@ -12,10 +12,15 @@ typedef void
wfd_authenticator_dispose_fn( wfd_authenticator_dispose_fn(
void * data); void * data);
typedef char const *
wfd_authenticator_get_type_fn(
void * data);
struct wfd_authenticator_vtable struct wfd_authenticator_vtable
{ {
wfd_authenticator_dispose_fn * dispose; wfd_authenticator_dispose_fn * dispose;
wf_authenticate_fn * authenticate; wf_authenticate_fn * authenticate;
wfd_authenticator_get_type_fn * get_type;
}; };
struct wfd_authenticator struct wfd_authenticator
@ -33,6 +38,10 @@ wfd_authenticator_authenticate(
struct wfd_authenticator authenticator, struct wfd_authenticator authenticator,
struct wf_credentials * credentials); struct wf_credentials * credentials);
extern char const *
wfd_authenticator_get_type(
struct wfd_authenticator authenticator);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -48,11 +48,20 @@ wfd_file_authenticator_authenticate(
return result; return result;
} }
static char const *
wfd_file_authenticator_get_type(
void * data)
{
(void) data;
return "username";
}
static struct wfd_authenticator_vtable static struct wfd_authenticator_vtable
wfd_file_authenticator_vtable = wfd_file_authenticator_vtable =
{ {
.dispose = &wfd_file_authenticator_dispose, .dispose = &wfd_file_authenticator_dispose,
.authenticate = &wfd_file_authenticator_authenticate .authenticate = &wfd_file_authenticator_authenticate,
.get_type = &wfd_file_authenticator_get_type
}; };
bool bool

View File

@ -1,5 +1,7 @@
#include "webfused/config/config.h" #include "webfused/config/config.h"
#include "webfuse/adapter/server_config.h" #include "webfuse/adapter/server_config.h"
#include "webfused/auth/factory.h"
#include "webfused/auth/authenticator.h"
#include <stdlib.h> #include <stdlib.h>
@ -9,6 +11,8 @@
struct wfd_config struct wfd_config
{ {
struct wf_server_config * server; struct wf_server_config * server;
bool has_authenticator;
struct wfd_authenticator authenticator;
}; };
static void static void
@ -56,6 +60,33 @@ wfd_config_set_server_document_root(
wf_server_config_set_documentroot(config->server, document_root); wf_server_config_set_documentroot(config->server, document_root);
} }
static bool
wfd_config_add_auth_provider(
void * data,
struct wfd_auth_settings * settings)
{
bool result = false;
struct wfd_config * config = data;
if (!config->has_authenticator)
{
result = wfd_authenticator_create(settings, &config->authenticator);
if (result)
{
wf_server_config_add_authenticator(
config->server,
wfd_authenticator_get_type(config->authenticator),
config->authenticator.vtable->authenticate,
config->authenticator.data);
config->has_authenticator = true;
}
}
return result;
}
static const struct wfd_config_builder_vtable static const struct wfd_config_builder_vtable
wfd_config_vtable_config_builder = wfd_config_vtable_config_builder =
{ {
@ -63,17 +94,21 @@ wfd_config_vtable_config_builder =
.set_server_port = &wfd_config_set_server_port, .set_server_port = &wfd_config_set_server_port,
.set_server_key = &wfd_config_set_server_key, .set_server_key = &wfd_config_set_server_key,
.set_server_cert = &wfd_config_set_server_cert, .set_server_cert = &wfd_config_set_server_cert,
.set_server_document_root = &wfd_config_set_server_document_root .set_server_document_root = &wfd_config_set_server_document_root,
.add_auth_provider = &wfd_config_add_auth_provider
}; };
struct wfd_config * struct wfd_config *
wfd_config_create(void) wfd_config_create(void)
{ {
struct wfd_config * config = malloc(sizeof(struct wfd_config)); struct wfd_config * config = malloc(sizeof(struct wfd_config));
config->server = wf_server_config_create(); config->server = wf_server_config_create();
wf_server_config_set_vhostname(config->server, WFD_CONFIG_DEFAULT_VHOSTNAME); wf_server_config_set_vhostname(config->server, WFD_CONFIG_DEFAULT_VHOSTNAME);
wf_server_config_set_port(config->server, WFD_CONFIG_DEFAULT_PORT); wf_server_config_set_port(config->server, WFD_CONFIG_DEFAULT_PORT);
config->has_authenticator = false;
return config; return config;
} }
@ -82,6 +117,11 @@ wfd_config_dispose(
struct wfd_config * config) struct wfd_config * config)
{ {
wf_server_config_dispose(config->server); wf_server_config_dispose(config->server);
if (config->has_authenticator)
{
wfd_authenticator_dispose(config->authenticator);
}
free(config); free(config);
} }

View File

@ -0,0 +1,63 @@
#include "mock_auth_settings.hpp"
extern "C"
{
using webfused_test::IAuthSettings;
static IAuthSettings * wfd_mock_auth_settings = nullptr;
extern char const *
__real_wfd_auth_settings_get_provider(
struct wfd_auth_settings * settings);
extern char const *
__real_wfd_auth_settings_get(
struct wfd_auth_settings * settings,
char const * key);
char const *
__wrap_wfd_auth_settings_get_provider(
struct wfd_auth_settings * settings)
{
if (nullptr == wfd_mock_auth_settings)
{
return __real_wfd_auth_settings_get_provider(settings);
}
else
{
return wfd_mock_auth_settings->getProvider();
}
}
char const *
__wrap_wfd_auth_settings_get(
struct wfd_auth_settings * settings,
char const * key)
{
if (nullptr == wfd_mock_auth_settings)
{
return __real_wfd_auth_settings_get(settings, key);
}
else
{
return wfd_mock_auth_settings->get(key);
}
}
}
namespace webfused_test
{
MockAuthSettings::MockAuthSettings()
{
wfd_mock_auth_settings = this;
}
MockAuthSettings::~MockAuthSettings()
{
wfd_mock_auth_settings = nullptr;
}
}

View File

@ -0,0 +1,31 @@
#ifndef WFD_MOCK_AUTH_SETTINGS_HPP
#define WFD_MOCK_AUTH_SETTINGS_HPP
#include <gmock/gmock.h>
#include "webfused/auth/settings.h"
namespace webfused_test
{
class IAuthSettings
{
public:
virtual ~IAuthSettings() = default;
virtual char const * getProvider() = 0;
virtual char const * get(char const * key) = 0;
};
class MockAuthSettings: public IAuthSettings
{
public:
MockAuthSettings();
~MockAuthSettings() override;
MOCK_METHOD0(getProvider, char const * ());
MOCK_METHOD1(get, char const * (char const * key));
};
}
#endif

View File

@ -1,5 +1,10 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "webfused/config/config.h" #include "webfused/config/config.h"
#include "mock_auth_settings.hpp"
using ::webfused_test::MockAuthSettings;
using ::testing::Return;
using ::testing::StrEq;
TEST(config, server_config) TEST(config, server_config)
{ {
@ -18,3 +23,56 @@ TEST(config, server_config)
wfd_config_dispose(config); wfd_config_dispose(config);
} }
TEST(config, auth_config)
{
wfd_config * config = wfd_config_create();
ASSERT_NE(nullptr, config);
wfd_config_builder builder = wfd_config_get_builder(config);
MockAuthSettings settings;
EXPECT_CALL(settings, getProvider()).Times(1).WillOnce(Return("file"));
EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return("/any/path"));
bool success = wfd_config_builder_add_auth_provider(builder, nullptr);
ASSERT_TRUE(success);
wfd_config_dispose(config);
}
TEST(config, auth_config_failed_to_add_second_provider)
{
wfd_config * config = wfd_config_create();
ASSERT_NE(nullptr, config);
wfd_config_builder builder = wfd_config_get_builder(config);
MockAuthSettings settings;
EXPECT_CALL(settings, getProvider()).Times(1).WillOnce(Return("file"));
EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return("/any/path"));
bool success = wfd_config_builder_add_auth_provider(builder, nullptr);
ASSERT_TRUE(success);
success = wfd_config_builder_add_auth_provider(builder, nullptr);
ASSERT_FALSE(success);
wfd_config_dispose(config);
}
TEST(config, auth_config_failed_to_add_unknown_provider)
{
wfd_config * config = wfd_config_create();
ASSERT_NE(nullptr, config);
wfd_config_builder builder = wfd_config_get_builder(config);
MockAuthSettings settings;
EXPECT_CALL(settings, getProvider()).Times(1).WillOnce(Return("unknown"));
bool success = wfd_config_builder_add_auth_provider(builder, nullptr);
ASSERT_FALSE(success);
wfd_config_dispose(config);
}

View File

@ -4,86 +4,59 @@
#include "webfused/auth/factory.h" #include "webfused/auth/factory.h"
#include "mock_credentials.hpp" #include "mock_credentials.hpp"
#include "mock_auth_settings.hpp"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <libconfig.h> #include <libconfig.h>
using ::webfused_test::MockAuthSettings;
using ::webfused_test::MockCredentials; using ::webfused_test::MockCredentials;
using ::testing::Return; using ::testing::Return;
using ::testing::StrEq; using ::testing::StrEq;
TEST(file_authenticator, create) TEST(file_authenticator, create)
{ {
char const config_text[] = MockAuthSettings settings;
"file = \"/tmp/webfuse_passwd.json\"\n" EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
;
config_t config;
config_init(&config);
config_read_string(&config, config_text);
config_setting_t * settings = config_root_setting(&config);
wfd_auth_settings * auth_settings = wfd_auth_settings_create("file", settings);
wfd_authenticator authenticator; wfd_authenticator authenticator;
bool success = wfd_file_authenticator_create(auth_settings, &authenticator); bool success = wfd_file_authenticator_create(nullptr, &authenticator);
ASSERT_TRUE(success); ASSERT_TRUE(success);
wfd_auth_settings_dispose(auth_settings);
wfd_authenticator_dispose(authenticator); wfd_authenticator_dispose(authenticator);
config_destroy(&config);
} }
TEST(file_authenticator, create_fail_missing_file) TEST(file_authenticator, create_fail_missing_file)
{ {
config_t config; MockAuthSettings settings;
config_init(&config); EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return(nullptr));
config_setting_t * settings = config_root_setting(&config);
wfd_auth_settings * auth_settings = wfd_auth_settings_create("file", settings);
wfd_authenticator authenticator; wfd_authenticator authenticator;
bool success = wfd_file_authenticator_create(auth_settings, &authenticator); bool success = wfd_file_authenticator_create(nullptr, &authenticator);
ASSERT_FALSE(success); ASSERT_FALSE(success);
wfd_auth_settings_dispose(auth_settings);
config_destroy(&config);
} }
TEST(file_authenticator, create_via_factory) TEST(file_authenticator, create_via_factory)
{ {
char const config_text[] = MockAuthSettings settings;
"file = \"/tmp/webfuse_passwd.json\"\n" EXPECT_CALL(settings, getProvider()).Times(1).WillOnce(Return("file"));
; EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
config_t config;
config_init(&config);
config_read_string(&config, config_text);
config_setting_t * settings = config_root_setting(&config);
wfd_auth_settings * auth_settings = wfd_auth_settings_create("file", settings);
wfd_authenticator authenticator; wfd_authenticator authenticator;
bool success = wfd_authenticator_create(auth_settings, &authenticator); bool success = wfd_authenticator_create(nullptr, &authenticator);
ASSERT_TRUE(success); ASSERT_TRUE(success);
wfd_auth_settings_dispose(auth_settings);
wfd_authenticator_dispose(authenticator); wfd_authenticator_dispose(authenticator);
config_destroy(&config);
} }
TEST(file_authenticator, authenticate) TEST(file_authenticator, authenticate)
{ {
char const config_text[] = MockAuthSettings settings;
"file = \"test_passwd.json\"\n" EXPECT_CALL(settings, getProvider()).Times(1).WillOnce(Return("file"));
; EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
config_t config;
config_init(&config);
config_read_string(&config, config_text);
config_setting_t * settings = config_root_setting(&config);
wfd_auth_settings * auth_settings = wfd_auth_settings_create("file", settings);
wfd_authenticator authenticator; wfd_authenticator authenticator;
bool success = wfd_authenticator_create(auth_settings, &authenticator); bool success = wfd_authenticator_create(nullptr, &authenticator);
ASSERT_TRUE(success); ASSERT_TRUE(success);
MockCredentials creds; MockCredentials creds;
@ -93,25 +66,17 @@ TEST(file_authenticator, authenticate)
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr); bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
ASSERT_TRUE(is_authenticated); ASSERT_TRUE(is_authenticated);
wfd_auth_settings_dispose(auth_settings);
wfd_authenticator_dispose(authenticator); wfd_authenticator_dispose(authenticator);
config_destroy(&config);
} }
TEST(file_authenticator, authenticate_fail_wrong_passwd) TEST(file_authenticator, authenticate_fail_wrong_passwd)
{ {
char const config_text[] = MockAuthSettings settings;
"file = \"test_passwd.json\"\n" EXPECT_CALL(settings, getProvider()).Times(1).WillOnce(Return("file"));
; EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
config_t config;
config_init(&config);
config_read_string(&config, config_text);
config_setting_t * settings = config_root_setting(&config);
wfd_auth_settings * auth_settings = wfd_auth_settings_create("file", settings);
wfd_authenticator authenticator; wfd_authenticator authenticator;
bool success = wfd_authenticator_create(auth_settings, &authenticator); bool success = wfd_authenticator_create(nullptr, &authenticator);
ASSERT_TRUE(success); ASSERT_TRUE(success);
MockCredentials creds; MockCredentials creds;
@ -121,25 +86,17 @@ TEST(file_authenticator, authenticate_fail_wrong_passwd)
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr); bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
ASSERT_FALSE(is_authenticated); ASSERT_FALSE(is_authenticated);
wfd_auth_settings_dispose(auth_settings);
wfd_authenticator_dispose(authenticator); wfd_authenticator_dispose(authenticator);
config_destroy(&config);
} }
TEST(file_authenticator, authenticate_fail_no_passwd_file) TEST(file_authenticator, authenticate_fail_no_passwd_file)
{ {
char const config_text[] = MockAuthSettings settings;
"file = \"non_existing_passwd.json\"\n" EXPECT_CALL(settings, getProvider()).Times(1).WillOnce(Return("file"));
; EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return("unknown_passwd.json"));
config_t config;
config_init(&config);
config_read_string(&config, config_text);
config_setting_t * settings = config_root_setting(&config);
wfd_auth_settings * auth_settings = wfd_auth_settings_create("file", settings);
wfd_authenticator authenticator; wfd_authenticator authenticator;
bool success = wfd_authenticator_create(auth_settings, &authenticator); bool success = wfd_authenticator_create(nullptr, &authenticator);
ASSERT_TRUE(success); ASSERT_TRUE(success);
MockCredentials creds; MockCredentials creds;
@ -149,25 +106,17 @@ TEST(file_authenticator, authenticate_fail_no_passwd_file)
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr); bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
ASSERT_FALSE(is_authenticated); ASSERT_FALSE(is_authenticated);
wfd_auth_settings_dispose(auth_settings);
wfd_authenticator_dispose(authenticator); wfd_authenticator_dispose(authenticator);
config_destroy(&config);
} }
TEST(file_authenticator, authenticate_fail_missing_username) TEST(file_authenticator, authenticate_fail_missing_username)
{ {
char const config_text[] = MockAuthSettings settings;
"file = \"test_passwd.json\"\n" EXPECT_CALL(settings, getProvider()).Times(1).WillOnce(Return("file"));
; EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
config_t config;
config_init(&config);
config_read_string(&config, config_text);
config_setting_t * settings = config_root_setting(&config);
wfd_auth_settings * auth_settings = wfd_auth_settings_create("file", settings);
wfd_authenticator authenticator; wfd_authenticator authenticator;
bool success = wfd_authenticator_create(auth_settings, &authenticator); bool success = wfd_authenticator_create(nullptr, &authenticator);
ASSERT_TRUE(success); ASSERT_TRUE(success);
MockCredentials creds; MockCredentials creds;
@ -177,25 +126,17 @@ TEST(file_authenticator, authenticate_fail_missing_username)
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr); bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
ASSERT_FALSE(is_authenticated); ASSERT_FALSE(is_authenticated);
wfd_auth_settings_dispose(auth_settings);
wfd_authenticator_dispose(authenticator); wfd_authenticator_dispose(authenticator);
config_destroy(&config);
} }
TEST(file_authenticator, authenticate_fail_missing_password) TEST(file_authenticator, authenticate_fail_missing_password)
{ {
char const config_text[] = MockAuthSettings settings;
"file = \"test_passwd.json\"\n" EXPECT_CALL(settings, getProvider()).Times(1).WillOnce(Return("file"));
; EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
config_t config;
config_init(&config);
config_read_string(&config, config_text);
config_setting_t * settings = config_root_setting(&config);
wfd_auth_settings * auth_settings = wfd_auth_settings_create("file", settings);
wfd_authenticator authenticator; wfd_authenticator authenticator;
bool success = wfd_authenticator_create(auth_settings, &authenticator); bool success = wfd_authenticator_create(nullptr, &authenticator);
ASSERT_TRUE(success); ASSERT_TRUE(success);
MockCredentials creds; MockCredentials creds;
@ -205,7 +146,19 @@ TEST(file_authenticator, authenticate_fail_missing_password)
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr); bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
ASSERT_FALSE(is_authenticated); ASSERT_FALSE(is_authenticated);
wfd_auth_settings_dispose(auth_settings);
wfd_authenticator_dispose(authenticator); wfd_authenticator_dispose(authenticator);
config_destroy(&config); }
TEST(file_authenticator, get_type)
{
MockAuthSettings settings;
EXPECT_CALL(settings, get(StrEq("file"))).Times(1).WillOnce(Return("/any/path"));
wfd_authenticator authenticator;
bool success = wfd_file_authenticator_create(nullptr, &authenticator);
ASSERT_TRUE(success);
ASSERT_STREQ("username", wfd_authenticator_get_type(authenticator));
wfd_authenticator_dispose(authenticator);
} }