mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 05:55:28 +00:00
[#1304] Added config/parse
This commit is contained in:
@@ -10,6 +10,17 @@
|
||||
|
||||
"http-host": "127.0.0.1",
|
||||
"http-port": 8000,
|
||||
"basic-authentication-realm": "kea-control-agent",
|
||||
|
||||
// In basoc HTTP authentication
|
||||
"basic-authentications":
|
||||
[
|
||||
{
|
||||
"comment": "admin is authorized",
|
||||
"user": "admin",
|
||||
"password": "1234"
|
||||
}
|
||||
],
|
||||
|
||||
// In control socket
|
||||
"control-sockets":
|
||||
|
@@ -11,6 +11,28 @@
|
||||
// Another mandatory parameter is the HTTP port.
|
||||
"http-port": 8000,
|
||||
|
||||
// An optional parameter is the basic HTTP authentication realm.
|
||||
// Its default is "kea-control-agent".
|
||||
"basic-authentication-realm": "kea-control-agent",
|
||||
|
||||
// This list specifies the user ids and passwords to use for
|
||||
// basic HTTP authentication. If empty or not present any client
|
||||
// is authorized.
|
||||
"basic-authentications":
|
||||
[
|
||||
// This specifies an authorized client.
|
||||
{
|
||||
"comment": "admin is authorized",
|
||||
|
||||
// The user id must not be empty or contain the ':' character.
|
||||
// It is a mandatory parameter.
|
||||
"user": "admin",
|
||||
|
||||
// If password is not specified an empty password is used.
|
||||
"password": "1234"
|
||||
}
|
||||
],
|
||||
|
||||
// This map specifies where control channel of each server is configured
|
||||
// to listen on. See 'control-socket' object in the respective
|
||||
// servers. At this time the only supported socket type is "unix".
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2016-2020 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@@ -21,7 +21,7 @@ namespace isc {
|
||||
namespace agent {
|
||||
|
||||
CtrlAgentCfgContext::CtrlAgentCfgContext()
|
||||
:http_host_(""), http_port_(0) {
|
||||
: http_host_(""), http_port_(0), basic_auth_realm_("") {
|
||||
}
|
||||
|
||||
CtrlAgentCfgContext::CtrlAgentCfgContext(const CtrlAgentCfgContext& orig)
|
||||
@@ -50,6 +50,8 @@ CtrlAgentCfgMgr::getConfigSummary(const uint32_t /*selection*/) {
|
||||
// Then print the control-sockets
|
||||
s << ctx->getControlSocketInfoSummary();
|
||||
|
||||
// @todo: add something if authentication is required
|
||||
|
||||
// Finally, print the hook libraries names
|
||||
const isc::hooks::HookLibsCollection libs = ctx->getHooksConfig().get();
|
||||
s << ", " << libs.size() << " lib(s):";
|
||||
@@ -152,6 +154,8 @@ CtrlAgentCfgContext::toElement() const {
|
||||
ca->set("http-host", Element::create(http_host_));
|
||||
// Set http-port
|
||||
ca->set("http-port", Element::create(static_cast<int64_t>(http_port_)));
|
||||
// Set basic-authentication-realm
|
||||
ca->set("basic-authentication-realm", Element::create(basic_auth_realm_));
|
||||
// Set hooks-libraries
|
||||
ca->set("hooks-libraries", hooks_config_.toElement());
|
||||
// Set control-sockets
|
||||
@@ -161,6 +165,7 @@ CtrlAgentCfgContext::toElement() const {
|
||||
control_sockets->set(si->first, socket);
|
||||
}
|
||||
ca->set("control-sockets", control_sockets);
|
||||
// @todo: Set authentication.
|
||||
// Set Control-agent
|
||||
ElementPtr result = Element::createMap();
|
||||
result->set("Control-agent", ca);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2016-2020 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@@ -98,6 +98,20 @@ public:
|
||||
return (http_port_);
|
||||
}
|
||||
|
||||
/// @brief Sets basic-authentication-realm parameter
|
||||
///
|
||||
/// @param real Basic HTTP authentication realm
|
||||
void setBasicAuthRealm(const std::string& realm) {
|
||||
basic_auth_realm_ = realm;
|
||||
}
|
||||
|
||||
/// @brief Returns basic-authentication-realm parameter
|
||||
///
|
||||
/// @return Basic HTTP authentication realm.
|
||||
std::string getBasicAuthRealm() const {
|
||||
return (basic_auth_realm_);
|
||||
}
|
||||
|
||||
/// @brief Returns non-const reference to configured hooks libraries.
|
||||
///
|
||||
/// @return non-const reference to configured hooks libraries.
|
||||
@@ -147,6 +161,9 @@ private:
|
||||
/// TCP port the CA should listen on.
|
||||
uint16_t http_port_;
|
||||
|
||||
/// Basic HTTP authentication realm.
|
||||
std::string basic_auth_realm_;
|
||||
|
||||
/// @brief Configured hooks libraries.
|
||||
isc::hooks::HooksConfig hooks_config_;
|
||||
};
|
||||
|
@@ -36,8 +36,9 @@ namespace agent {
|
||||
///
|
||||
/// These are global Control Agent parameters.
|
||||
const SimpleDefaults AgentSimpleParser::AGENT_DEFAULTS = {
|
||||
{ "http-host", Element::string, "127.0.0.1"},
|
||||
{ "http-port", Element::integer, "8000"}
|
||||
{ "http-host", Element::string, "127.0.0.1" },
|
||||
{ "http-port", Element::integer, "8000" },
|
||||
{ "basic-authentication-realm", Element::string, "kea-control-agent" }
|
||||
};
|
||||
|
||||
/// @brief This table defines default values for control sockets.
|
||||
@@ -88,6 +89,8 @@ AgentSimpleParser::parse(const CtrlAgentCfgContextPtr& ctx,
|
||||
// Let's get the HTTP parameters first.
|
||||
ctx->setHttpHost(SimpleParser::getString(config, "http-host"));
|
||||
ctx->setHttpPort(SimpleParser::getIntType<uint16_t>(config, "http-port"));
|
||||
ctx->setBasicAuthRealm(SimpleParser::getString(config,
|
||||
"basic-authentication-realm"));
|
||||
|
||||
// Control sockets are second.
|
||||
ConstElementPtr ctrl_sockets = config->get("control-sockets");
|
||||
@@ -98,6 +101,8 @@ AgentSimpleParser::parse(const CtrlAgentCfgContextPtr& ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Basic HTTP authentications are third.
|
||||
|
||||
// User context can be done at anytime.
|
||||
ConstElementPtr user_context = config->get("user-context");
|
||||
if (user_context) {
|
||||
|
@@ -40,6 +40,7 @@ libkea_http_la_SOURCES += response_creator_factory.h
|
||||
libkea_http_la_SOURCES += response_json.cc response_json.h
|
||||
libkea_http_la_SOURCES += url.cc url.h
|
||||
libkea_http_la_SOURCES += basic_auth.cc basic_auth.h
|
||||
libkea_http_la_SOURCES += basic_auth_config.cc basic_auth_config.h
|
||||
|
||||
libkea_http_la_CXXFLAGS = $(AM_CXXFLAGS)
|
||||
libkea_http_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
@@ -90,6 +91,8 @@ endif
|
||||
# Specify the headers for copying into the installation directory tree.
|
||||
libkea_http_includedir = $(pkgincludedir)/http
|
||||
libkea_http_include_HEADERS = \
|
||||
basic_auth.h \
|
||||
basic_auth_config.h \
|
||||
client.h \
|
||||
connection.h \
|
||||
connection_pool.h \
|
||||
@@ -112,6 +115,7 @@ libkea_http_include_HEADERS = \
|
||||
response.h \
|
||||
response_context.h \
|
||||
response_creator.h \
|
||||
response_creator_auth.h \
|
||||
response_creator_factory.h \
|
||||
response_json.h \
|
||||
response_parser.h \
|
||||
|
137
src/lib/http/basic_auth_config.cc
Normal file
137
src/lib/http/basic_auth_config.cc
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright (C) 2020 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <http/basic_auth_config.h>
|
||||
|
||||
using namespace isc;
|
||||
using namespace isc::data;
|
||||
using namespace isc::dhcp;
|
||||
using namespace std;
|
||||
|
||||
namespace isc {
|
||||
namespace http {
|
||||
|
||||
BasicHttpAuthClient::BasicHttpAuthClient(const std::string& user,
|
||||
const std::string& password,
|
||||
const isc::data::ConstElementPtr& user_context)
|
||||
: user_(user), password_(password) {
|
||||
if (user_context) {
|
||||
setContext(user_context);
|
||||
}
|
||||
}
|
||||
|
||||
ElementPtr
|
||||
BasicHttpAuthClient::toElement() const {
|
||||
ElementPtr result = Element::createMap();
|
||||
|
||||
// Set user-context
|
||||
contextToElement(result);
|
||||
|
||||
// Set user
|
||||
result->set("user", Element::create(user_));
|
||||
|
||||
// Set password
|
||||
result->set("password", Element::create(password_));
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
BasicHttpAuthConfig::add(const std::string& user,
|
||||
const std::string& password,
|
||||
const ConstElementPtr& user_context) {
|
||||
BasicHttpAuth basic_auth(user, password);
|
||||
list_.push_back(BasicHttpAuthClient(user, password, user_context));
|
||||
map_[basic_auth.getCredential()] = user;
|
||||
}
|
||||
|
||||
void
|
||||
BasicHttpAuthConfig::clear() {
|
||||
list_.clear();
|
||||
map_.clear();
|
||||
}
|
||||
|
||||
ElementPtr
|
||||
BasicHttpAuthConfig::toElement() const {
|
||||
ElementPtr result = Element::createList();
|
||||
|
||||
for (auto client : list_) {
|
||||
result->add(client.toElement());
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
BasicHttpAuthConfig::parse(const ConstElementPtr& config) {
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
if (config->getType() != Element::list) {
|
||||
isc_throw(DhcpConfigError, "basic-authentications must be a list ("
|
||||
<< config->getPosition() << ")");
|
||||
}
|
||||
for (auto client : config->listValue()) {
|
||||
if (client->getType() != Element::map) {
|
||||
isc_throw(DhcpConfigError, "basic-authentications items must be "
|
||||
<< "maps (" << client->getPosition() << ")");
|
||||
}
|
||||
|
||||
// user
|
||||
ConstElementPtr user_cfg = client->get("user");
|
||||
if (!user_cfg) {
|
||||
isc_throw(DhcpConfigError, "user is required in "
|
||||
<< "basic-authentications items ("
|
||||
<< client->getPosition() << ")");
|
||||
}
|
||||
if (user_cfg->getType() != Element::string) {
|
||||
isc_throw(DhcpConfigError, "user must be a string ("
|
||||
<< user_cfg->getPosition() << ")");
|
||||
}
|
||||
string user = user_cfg->stringValue();
|
||||
if (user.empty()) {
|
||||
isc_throw(DhcpConfigError, "user must be not be empty ("
|
||||
<< user_cfg->getPosition() << ")");
|
||||
}
|
||||
if (user.find(':') != string::npos) {
|
||||
isc_throw(DhcpConfigError, "user must not contain a ':': '"
|
||||
<< user << "' (" << user_cfg->getPosition() << ")");
|
||||
}
|
||||
|
||||
// password
|
||||
string password;
|
||||
ConstElementPtr password_cfg = client->get("password");
|
||||
if (password_cfg) {
|
||||
if (password_cfg->getType() != Element::string) {
|
||||
isc_throw(DhcpConfigError, "password must be a string ("
|
||||
<< password_cfg->getPosition() << ")");
|
||||
}
|
||||
password = password_cfg->stringValue();
|
||||
}
|
||||
|
||||
// user context
|
||||
ConstElementPtr user_context = client->get("user-context");
|
||||
if (user_context) {
|
||||
if (user_context->getType() != Element::map) {
|
||||
isc_throw(DhcpConfigError, "user-context must be a map ("
|
||||
<< user_context->getPosition() << ")");
|
||||
}
|
||||
}
|
||||
|
||||
// add it.
|
||||
try {
|
||||
add(user, password, user_context);
|
||||
} catch (const std::exception& ex) {
|
||||
isc_throw(DhcpConfigError, ex.what() << " ("
|
||||
<< client->getPosition() << ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace isc::http
|
||||
} // end of namespace isc
|
120
src/lib/http/basic_auth_config.h
Normal file
120
src/lib/http/basic_auth_config.h
Normal file
@@ -0,0 +1,120 @@
|
||||
// Copyright (C) 2020 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef HTTP_BASIC_AUTH_CONFIG_H
|
||||
#define HTTP_BASIC_AUTH_CONFIG_H
|
||||
|
||||
#include <cc/cfg_to_element.h>
|
||||
#include <cc/data.h>
|
||||
#include <cc/simple_parser.h>
|
||||
#include <cc/user_context.h>
|
||||
#include <http/basic_auth.h>
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace isc {
|
||||
namespace http {
|
||||
|
||||
/// @brief Type of basic HTTP authentication credential and user id map.
|
||||
typedef std::unordered_map<std::string, std::string> BasicHttpAuthMap;
|
||||
|
||||
/// @brief Basic HTTP authentication client configuration.
|
||||
class BasicHttpAuthClient : public isc::data::UserContext,
|
||||
public isc::data::CfgToElement {
|
||||
public:
|
||||
|
||||
/// @brief Constructor.
|
||||
///
|
||||
/// @param user User id
|
||||
/// @param password Password
|
||||
/// @param user_context Optional user context
|
||||
BasicHttpAuthClient(const std::string& user,
|
||||
const std::string& password,
|
||||
const isc::data::ConstElementPtr& user_context);
|
||||
|
||||
/// @brief Returns the user id.
|
||||
const std::string& getUser() const {
|
||||
return (user_);
|
||||
}
|
||||
|
||||
/// @brief Returns the password.
|
||||
const std::string& getPassword() const {
|
||||
return (password_);
|
||||
}
|
||||
|
||||
/// @brief Unparses basic HTTP authentication client configuration.
|
||||
///
|
||||
/// @return A pointer to unparsed client configuration.
|
||||
virtual isc::data::ElementPtr toElement() const;
|
||||
|
||||
private:
|
||||
|
||||
/// @brief The user id.
|
||||
std::string user_;
|
||||
|
||||
/// @brief The password.
|
||||
std::string password_;
|
||||
};
|
||||
|
||||
/// @brief Type of basic HTTP authentication client configuration list.
|
||||
typedef std::list<BasicHttpAuthClient> BasicHttpAuthClientList;
|
||||
|
||||
/// @brief Basic HTTP authentication configuration.
|
||||
class BasicHttpAuthConfig : public isc::data::CfgToElement {
|
||||
public:
|
||||
|
||||
/// @brief Add a client configuration.
|
||||
///
|
||||
/// @param user User id
|
||||
/// @param password Password
|
||||
/// @param user_context Optional user context
|
||||
/// @throw BadValue if the user id contains the ':' character.
|
||||
void add(const std::string& user,
|
||||
const std::string& password,
|
||||
const isc::data::ConstElementPtr& user_context = isc::data::ConstElementPtr());
|
||||
|
||||
/// @brief Clear configuration.
|
||||
void clear();
|
||||
|
||||
/// @brief Returns the list of client configuration.
|
||||
///
|
||||
/// @return List of basic HTTP authentication client configuration.
|
||||
const BasicHttpAuthClientList& getClientList() const {
|
||||
return (list_);
|
||||
}
|
||||
|
||||
/// @brief Returns the credential and user id map.
|
||||
///
|
||||
/// @return The basic HTTP authentication credential and user id map.
|
||||
const BasicHttpAuthMap& getCredentialMap() const {
|
||||
return (map_);
|
||||
}
|
||||
|
||||
/// @brief Parses basic HTTP authentication configuration.
|
||||
///
|
||||
/// @param config Element holding the basic HTTP authentication
|
||||
/// configuration to be parsed.
|
||||
/// @throw DhcpConfigError when the configuration is invalid.
|
||||
void parse(const isc::data::ConstElementPtr& config);
|
||||
|
||||
/// @brief Unparses basic HTTP authentication configuration.
|
||||
///
|
||||
/// @return A pointer to unparsed basic HTTP authentication configuration.
|
||||
virtual isc::data::ElementPtr toElement() const;
|
||||
|
||||
private:
|
||||
|
||||
/// @brief The list of basic HTTP authentication client configuration.
|
||||
BasicHttpAuthClientList list_;
|
||||
|
||||
/// @brief The basic HTTP authentication credential and user id map.
|
||||
BasicHttpAuthMap map_;
|
||||
};
|
||||
|
||||
} // end of namespace isc::http
|
||||
} // end of namespace isc
|
||||
|
||||
#endif // endif HTTP_BASIC_AUTH_CONFIG_H
|
@@ -7,6 +7,7 @@
|
||||
#ifndef HTTP_RESPONSE_CREATOR_AUTH_H
|
||||
#define HTTP_RESPONSE_CREATOR_AUTH_H
|
||||
|
||||
#include <http/basic_auth_config.h>
|
||||
#include <http/response_creator.h>
|
||||
#include <string.h>
|
||||
#include <unordered_map>
|
||||
@@ -14,9 +15,6 @@
|
||||
namespace isc {
|
||||
namespace http {
|
||||
|
||||
/// @brief Type of basic HTTP authentication credential and user id map.
|
||||
typedef std::unordered_map<std::string, std::string> BasicHttpAuthMap;
|
||||
|
||||
/// @brief Validate basic HTTP authentication.
|
||||
///
|
||||
/// @param creator The HTTP response creator.
|
||||
|
@@ -21,6 +21,7 @@ if HAVE_GTEST
|
||||
TESTS += libhttp_unittests
|
||||
|
||||
libhttp_unittests_SOURCES = basic_auth_unittests.cc
|
||||
libhttp_unittests_SOURCES += basic_auth_config_unittests.cc
|
||||
libhttp_unittests_SOURCES += connection_pool_unittests.cc
|
||||
libhttp_unittests_SOURCES += date_time_unittests.cc
|
||||
libhttp_unittests_SOURCES += http_header_unittests.cc
|
||||
|
218
src/lib/http/tests/basic_auth_config_unittests.cc
Normal file
218
src/lib/http/tests/basic_auth_config_unittests.cc
Normal file
@@ -0,0 +1,218 @@
|
||||
// Copyright (C) 2020 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <config.h>
|
||||
#include <http/basic_auth_config.h>
|
||||
#include <testutils/gtest_utils.h>
|
||||
#include <testutils/test_to_element.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace isc;
|
||||
using namespace isc::data;
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::http;
|
||||
using namespace isc::test;
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
|
||||
// Test that basic auth client works as expected.
|
||||
TEST(BasicHttpAuthClientTest, basic) {
|
||||
// Create a client.
|
||||
ConstElementPtr ctx = Element::fromJSON("{ \"foo\": \"bar\" }");
|
||||
BasicHttpAuthClient client("foo", "bar", ctx);
|
||||
|
||||
// Check it.
|
||||
EXPECT_EQ("foo", client.getUser());
|
||||
EXPECT_EQ("bar", client.getPassword());
|
||||
EXPECT_TRUE(ctx->equals(*client.getContext()));
|
||||
|
||||
// Check toElement.
|
||||
ElementPtr expected = Element::createMap();
|
||||
expected->set("user", Element::create(string("foo")));
|
||||
expected->set("password", Element::create(string("bar")));
|
||||
expected->set("user-context", ctx);
|
||||
runToElementTest<BasicHttpAuthClient>(expected, client);
|
||||
}
|
||||
|
||||
// Test that basic auth configuration works as expected.
|
||||
TEST(BasicHttpAuthConfigTest, basic) {
|
||||
// Create a configuration.
|
||||
BasicHttpAuthConfig config;
|
||||
|
||||
// Initial configuration is empty.
|
||||
EXPECT_TRUE(config.getClientList().empty());
|
||||
EXPECT_TRUE(config.getCredentialMap().empty());
|
||||
|
||||
// Add rejects user id with embedded ':'.
|
||||
EXPECT_THROW(config.add("foo:", "bar"), BadValue);
|
||||
|
||||
// Add a client.
|
||||
ConstElementPtr ctx = Element::fromJSON("{ \"foo\": \"bar\" }");
|
||||
EXPECT_NO_THROW(config.add("foo", "bar", ctx));
|
||||
|
||||
// Check the client.
|
||||
ASSERT_EQ(1, config.getClientList().size());
|
||||
const BasicHttpAuthClient& client = config.getClientList().front();
|
||||
EXPECT_EQ("foo", client.getUser());
|
||||
EXPECT_EQ("bar", client.getPassword());
|
||||
EXPECT_TRUE(ctx->equals(*client.getContext()));
|
||||
|
||||
// Check the credential.
|
||||
ASSERT_NE(0, config.getCredentialMap().count("Zm9vOmJhcg=="));
|
||||
string user;
|
||||
EXPECT_NO_THROW(user = config.getCredentialMap().at("Zm9vOmJhcg=="));
|
||||
EXPECT_EQ("foo", user);
|
||||
|
||||
// Check toElement.
|
||||
ElementPtr expected = Element::createList();
|
||||
ElementPtr elem = Element::createMap();
|
||||
elem->set("user", Element::create(string("foo")));
|
||||
elem->set("password", Element::create(string("bar")));
|
||||
elem->set("user-context", ctx);
|
||||
expected->add(elem);
|
||||
runToElementTest<BasicHttpAuthConfig>(expected, config);
|
||||
|
||||
// Add a second client and test it.
|
||||
EXPECT_NO_THROW(config.add("test", "123\xa3"));
|
||||
ASSERT_EQ(2, config.getClientList().size());
|
||||
EXPECT_EQ("foo", config.getClientList().front().getUser());
|
||||
EXPECT_EQ("test", config.getClientList().back().getUser());
|
||||
ASSERT_NE(0, config.getCredentialMap().count("dGVzdDoxMjPCow=="));
|
||||
|
||||
// Check clear.
|
||||
config.clear();
|
||||
expected = Element::createList();
|
||||
runToElementTest<BasicHttpAuthConfig>(expected, config);
|
||||
|
||||
// Add clients again.
|
||||
EXPECT_NO_THROW(config.add("test", "123\xa3"));
|
||||
EXPECT_NO_THROW(config.add("foo", "bar", ctx));
|
||||
|
||||
// Check that toElement keeps add order.
|
||||
ElementPtr elem0 = Element::createMap();
|
||||
elem0->set("user", Element::create(string("test")));
|
||||
elem0->set("password", Element::create(string("123\xa3")));
|
||||
expected->add(elem0);
|
||||
expected->add(elem);
|
||||
runToElementTest<BasicHttpAuthConfig>(expected, config);
|
||||
}
|
||||
|
||||
// Test that basic auth configuration parses.
|
||||
TEST(BasicHttpAuthConfigTest, parse) {
|
||||
BasicHttpAuthConfig config;
|
||||
ElementPtr cfg;
|
||||
|
||||
// No config is accepted.
|
||||
EXPECT_NO_THROW(config.parse(cfg));
|
||||
EXPECT_TRUE(config.getClientList().empty());
|
||||
EXPECT_TRUE(config.getCredentialMap().empty());
|
||||
runToElementTest<BasicHttpAuthConfig>(Element::createList(), config);
|
||||
|
||||
// The config must be a list.
|
||||
cfg = Element::createMap();
|
||||
EXPECT_THROW_MSG(config.parse(cfg), DhcpConfigError,
|
||||
"basic-authentications must be a list (:0:0)");
|
||||
|
||||
// The client config must be a map.
|
||||
cfg = Element::createList();
|
||||
ElementPtr client_cfg = Element::createList();
|
||||
cfg->add(client_cfg);
|
||||
EXPECT_THROW_MSG(config.parse(cfg), DhcpConfigError,
|
||||
"basic-authentications items must be maps (:0:0)");
|
||||
|
||||
// The user parameter is mandatory in client config.
|
||||
client_cfg = Element::createMap();
|
||||
cfg = Element::createList();
|
||||
cfg->add(client_cfg);
|
||||
EXPECT_THROW_MSG(config.parse(cfg), DhcpConfigError,
|
||||
"user is required in basic-authentications items (:0:0)");
|
||||
|
||||
// The user parameter must be a string.
|
||||
ElementPtr user_cfg = Element::create(1);
|
||||
client_cfg = Element::createMap();
|
||||
client_cfg->set("user", user_cfg);
|
||||
cfg = Element::createList();
|
||||
cfg->add(client_cfg);
|
||||
EXPECT_THROW_MSG(config.parse(cfg), DhcpConfigError,
|
||||
"user must be a string (:0:0)");
|
||||
|
||||
// The user parameter must not be empty.
|
||||
user_cfg = Element::create(string(""));
|
||||
client_cfg = Element::createMap();
|
||||
client_cfg->set("user", user_cfg);
|
||||
cfg = Element::createList();
|
||||
cfg->add(client_cfg);
|
||||
EXPECT_THROW_MSG(config.parse(cfg), DhcpConfigError,
|
||||
"user must be not be empty (:0:0)");
|
||||
|
||||
// The user parameter must not contain ':'.
|
||||
user_cfg = Element::create(string("foo:bar"));
|
||||
client_cfg = Element::createMap();
|
||||
client_cfg->set("user", user_cfg);
|
||||
cfg = Element::createList();
|
||||
cfg->add(client_cfg);
|
||||
EXPECT_THROW_MSG(config.parse(cfg), DhcpConfigError,
|
||||
"user must not contain a ':': 'foo:bar' (:0:0)");
|
||||
|
||||
// Password is not required.
|
||||
user_cfg = Element::create(string("foo"));
|
||||
client_cfg = Element::createMap();
|
||||
client_cfg->set("user", user_cfg);
|
||||
cfg = Element::createList();
|
||||
cfg->add(client_cfg);
|
||||
EXPECT_NO_THROW(config.parse(cfg));
|
||||
ASSERT_EQ(1, config.getClientList().size());
|
||||
EXPECT_EQ("", config.getClientList().front().getPassword());
|
||||
config.clear();
|
||||
|
||||
// The password parameter must be a string.
|
||||
ElementPtr password_cfg = Element::create(1);
|
||||
client_cfg = Element::createMap();
|
||||
client_cfg->set("user", user_cfg);
|
||||
client_cfg->set("password", password_cfg);
|
||||
cfg = Element::createList();
|
||||
cfg->add(client_cfg);
|
||||
EXPECT_THROW_MSG(config.parse(cfg), DhcpConfigError,
|
||||
"password must be a string (:0:0)");
|
||||
|
||||
// Empty password is accepted.
|
||||
password_cfg = Element::create(string(""));
|
||||
client_cfg = Element::createMap();
|
||||
client_cfg->set("user", user_cfg);
|
||||
client_cfg->set("password", password_cfg);
|
||||
cfg = Element::createList();
|
||||
cfg->add(client_cfg);
|
||||
EXPECT_NO_THROW(config.parse(cfg));
|
||||
ASSERT_EQ(1, config.getClientList().size());
|
||||
EXPECT_EQ("", config.getClientList().front().getPassword());
|
||||
config.clear();
|
||||
|
||||
// User context must be a map.
|
||||
password_cfg = Element::create(string("bar"));
|
||||
ElementPtr ctx = Element::createList();
|
||||
client_cfg = Element::createMap();
|
||||
client_cfg->set("user", user_cfg);
|
||||
client_cfg->set("password", password_cfg);
|
||||
client_cfg->set("user-context", ctx);
|
||||
cfg = Element::createList();
|
||||
cfg->add(client_cfg);
|
||||
EXPECT_THROW_MSG(config.parse(cfg), DhcpConfigError,
|
||||
"user-context must be a map (:0:0)");
|
||||
|
||||
// Check a working not empty config.
|
||||
ctx = Element::fromJSON("{ \"foo\": \"bar\" }");
|
||||
client_cfg = Element::createMap();
|
||||
client_cfg->set("user", user_cfg);
|
||||
client_cfg->set("password", password_cfg);
|
||||
client_cfg->set("user-context", ctx);
|
||||
cfg = Element::createList();
|
||||
cfg->add(client_cfg);
|
||||
EXPECT_NO_THROW(config.parse(cfg));
|
||||
runToElementTest<BasicHttpAuthConfig>(cfg, config);
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
Reference in New Issue
Block a user