Refactoring namespace for OpenWifi.

This commit is contained in:
stephb9959
2021-08-31 11:30:40 -07:00
parent 7054894ccc
commit 5f6f101395
26 changed files with 443 additions and 154 deletions

4
CLI.md
View File

@@ -1,9 +1,9 @@
# Security Service CLI Documentation
## Before using the CLI
You must set the environment variable `UCENTRALSEC`. You must specify the host and port for the security service. Here is an example
You must set the environment variable `OWSEC`. You must specify the host and port for the security service. Here is an example
```csh
export UCENTRALSEC=mysecurityservice,example.com:16001
export OWSEC=mysecurityservice,example.com:16001
```
Once set, you can start using the `CLI`.

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(ucentralsec VERSION 2.1.0)
project(owsec VERSION 2.2.0)
set(CMAKE_CXX_STANDARD 17)
@@ -47,7 +47,7 @@ find_package(PostgreSQL REQUIRED)
find_package(MySQL REQUIRED)
find_package(Poco REQUIRED COMPONENTS JSON Crypto JWT Net Util NetSSL Data DataSQLite DataPostgreSQL DataMySQL)
add_executable( ucentralsec
add_executable( owsec
build
src/Daemon.h src/Daemon.cpp
src/MicroService.cpp src/MicroService.h
@@ -76,11 +76,11 @@ add_executable( ucentralsec
src/OpenWifiTypes.h )
if(NOT SMALL_BUILD)
target_link_libraries(ucentralsec PUBLIC
target_link_libraries(owsec PUBLIC
${Poco_LIBRARIES} ${Boost_LIBRARIES} ${MySQL_LIBRARIES} ${ZLIB_LIBRARIES}
CppKafka::cppkafka
)
if(UNIX AND NOT APPLE)
target_link_libraries(ucentralsec PUBLIC PocoJSON)
target_link_libraries(owsec PUBLIC PocoJSON)
endif()
endif()

View File

@@ -21,7 +21,7 @@ The entire uCentral systems uses several MicroServices. In order for the whole s
access
- Security
- Properties file: ucentralsec.properties
- Properties file: owsec.properties
- Ports
- Public: 16001
- Private: 17001
@@ -42,7 +42,7 @@ access
- ALB: 16104
## Security Configuration
The service relies on a properties configuration file called `ucentralsec.properties`. In this file, you should configure several entries. Many values are optional
The service relies on a properties configuration file called `owsec.properties`. In this file, you should configure several entries. Many values are optional
and you can rely on the defaults. Here are some values of note:
### `authentication.default.password`
@@ -52,7 +52,7 @@ Set the hash of the default username and password. Please look below on how to d
Set the default username to use to login.
### Default username and password
The default username and password are set in `ucentralsec.properties` file. The following entries manage the username and password
The default username and password are set in `owsec.properties` file. The following entries manage the username and password
```text
authentication.default.username = tip@ucentral.com
authentication.default.password = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -97,19 +97,19 @@ This security service uses Kafka to coordinate security with other services that
in order to use this. You can find several examples of Kafka services available with Docker. Here are the values you need to configure.
```asm
ucentral.kafka.group.id = security
ucentral.kafka.client.id = security1
ucentral.kafka.enable = true
ucentral.kafka.brokerlist = my.kafkaserver.arilia.com:9092
ucentral.kafka.auto.commit = false
ucentral.kafka.queue.buffering.max.ms = 50
openwifi.kafka.group.id = security
openwifi.kafka.client.id = security1
openwifi.kafka.enable = true
openwifi.kafka.brokerlist = my.kafkaserver.arilia.com:9092
openwifi.kafka.auto.commit = false
openwifi.kafka.queue.buffering.max.ms = 50
```
#### `ucentral.kafka.brokerlist`
#### `openwifi.kafka.brokerlist`
This is the list of your kafka brokers. This is a comma separated list. You should use IP addresses or FQDNs and the relevant ports, usually 9092 is the
default.
#### `ucentral.kafka.group.id`
#### `openwifi.kafka.group.id`
Every service on the Kafka bux must have a unique value (at least in our case). This should be a string. We suggest using a name corresponding to the
function provided. In this case, security.
@@ -124,17 +124,17 @@ Here are the parameters for the public interface. The important files are:
- `restapi-ca.pem` : the CA of your certificate
- `restapi-cert.pem` : the certificate for the public interface
- `restapi-key.pem` : the key associated with this certificate
- `ucentral.restapi.host.0.key.password` : if you key is password protected, you may supply that password here.
- `openwifi.restapi.host.0.key.password` : if you key is password protected, you may supply that password here.
```asm
ucentral.restapi.host.0.backlog = 100
ucentral.restapi.host.0.security = relaxed
ucentral.restapi.host.0.rootca = $UCENTRALSEC_ROOT/certs/restapi-ca.pem
ucentral.restapi.host.0.address = *
ucentral.restapi.host.0.port = 16001
ucentral.restapi.host.0.cert = $UCENTRALSEC_ROOT/certs/restapi-cert.pem
ucentral.restapi.host.0.key = $UCENTRALSEC_ROOT/certs/restapi-key.pem
ucentral.restapi.host.0.key.password = mypassword
openwifi.restapi.host.0.backlog = 100
openwifi.restapi.host.0.security = relaxed
openwifi.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem
openwifi.restapi.host.0.address = *
openwifi.restapi.host.0.port = 16001
openwifi.restapi.host.0.cert = $OWSEC_ROOT/certs/restapi-cert.pem
openwifi.restapi.host.0.key = $OWSEC_ROOT/certs/restapi-key.pem
openwifi.restapi.host.0.key.password = mypassword
```
#### The private interface
@@ -142,14 +142,14 @@ The private interface is used for service-to-service communication. You can use
to the filenames used in the previous section.
```asm
ucentral.internal.restapi.host.0.backlog = 100
ucentral.internal.restapi.host.0.security = relaxed
ucentral.internal.restapi.host.0.rootca = $UCENTRALSEC_ROOT/certs/restapi-ca.pem
ucentral.internal.restapi.host.0.address = *
ucentral.internal.restapi.host.0.port = 17001
ucentral.internal.restapi.host.0.cert = $UCENTRALSEC_ROOT/certs/restapi-cert.pem
ucentral.internal.restapi.host.0.key = $UCENTRALSEC_ROOT/certs/restapi-key.pem
ucentral.internal.restapi.host.0.key.password = mypassword
openwifi.internal.restapi.host.0.backlog = 100
openwifi.internal.restapi.host.0.security = relaxed
openwifi.internal.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem
openwifi.internal.restapi.host.0.address = *
openwifi.internal.restapi.host.0.port = 17001
openwifi.internal.restapi.host.0.cert = $OWSEC_ROOT/certs/restapi-cert.pem
openwifi.internal.restapi.host.0.key = $OWSEC_ROOT/certs/restapi-key.pem
openwifi.internal.restapi.host.0.key.password = mypassword
```
### Other important values
@@ -157,19 +157,19 @@ Here are other important values you must set.
```asm
ucentral.system.data = $UCENTRALSEC_ROOT/data
ucentral.system.uri.private = https://localhost:17001
ucentral.system.uri.public = https://ucentral.dpaas.arilia.com:16001
ucentral.system.commandchannel = /tmp/app.ucentralsec
ucentral.service.key = $UCENTRALSEC_ROOT/certs/restapi-key.pem
openwifi.system.data = $OWSEC_ROOT/data
openwifi.system.uri.private = https://localhost:17001
openwifi.system.uri.public = https://openwifi.dpaas.arilia.com:16001
openwifi.system.commandchannel = /tmp/app.ucentralsec
openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem
```
#### `ucentral.system.data`
#### `openwifi.system.data`
The location of some important data files including the user name database.
#### `ucentral.system.uri.private`
#### `openwifi.system.uri.private`
This is the FQDN used internally between services.
#### `ucentral.system.uri.public`
#### `openwifi.system.uri.public`
This is the FQDN used externally serving the OpenAPI interface.

2
build
View File

@@ -1 +1 @@
11
2

148
new.properties Normal file
View File

@@ -0,0 +1,148 @@
#
# uCentral protocol server for devices. This is where you point
# all your devices. You can replace the * for address by the specific
# address of one of your interfaces
#
#
# REST API access
#
openwifi.restapi.host.0.backlog = 100
openwifi.restapi.host.0.security = relaxed
openwifi.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem
openwifi.restapi.host.0.address = *
openwifi.restapi.host.0.port = 16001
openwifi.restapi.host.0.cert = $OWSEC_ROOT/certs/restapi-cert.pem
openwifi.restapi.host.0.key = $OWSEC_ROOT/certs/restapi-key.pem
openwifi.restapi.host.0.key.password = mypassword
openwifi.restapi.wwwassets = $OWSEC_ROOT/wwwassets
openwifi.internal.restapi.host.0.backlog = 100
openwifi.internal.restapi.host.0.security = relaxed
openwifi.internal.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem
openwifi.internal.restapi.host.0.address = *
openwifi.internal.restapi.host.0.port = 17001
openwifi.internal.restapi.host.0.cert = $OWSEC_ROOT/certs/restapi-cert.pem
openwifi.internal.restapi.host.0.key = $OWSEC_ROOT/certs/restapi-key.pem
openwifi.internal.restapi.host.0.key.password = mypassword
#
# Generic section that all microservices must have
#
authentication.enabled = true
authentication.default.username = tip@ucentral.com
authentication.default.password = 13268b7daa751240369d125e79c873bd8dd3bef7981bdfd38ea03dbb1fbe7dcf
openwifi.system.data = $OWSEC_ROOT/data
openwifi.system.uri.private = https://localhost:17001
openwifi.system.uri.public = https://local.dpaas.arilia.com:16001
openwifi.system.uri.ui = https://ucentral-ui.arilia.com
openwifi.system.commandchannel = /tmp/app.ucentralsec
openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem
openwifi.service.key.password = mypassword
#
# Security Microservice Specific Section
#
mailer.hostname = smtp.gmail.com
mailer.username = ************************
mailer.password = ************************
mailer.loginmethod = login
mailer.port = 587
mailer.templates = $OWSEC_ROOT/templates
#############################
# Generic information for all micro services
#############################
#
# NLB Support
#
alb.enable = true
alb.port = 16101
#
# Kafka
#
openwifi.kafka.group.id = security
openwifi.kafka.client.id = security1
openwifi.kafka.enable = true
openwifi.kafka.brokerlist = a1.arilia.com:9092
openwifi.kafka.auto.commit = false
openwifi.kafka.queue.buffering.max.ms = 50
openwifi.document.policy.access = /wwwassets/access_policy.html
openwifi.document.policy.password = /wwwassets/password_policy.html
openwifi.avatar.maxsize = 2000000
#
# This section select which form of persistence you need
# Only one selected at a time. If you select multiple, this service will die if a horrible
# death and might make your beer flat.
#
storage.type = sqlite
#storage.type = postgresql
#storage.type = mysql
#storage.type = odbc
storage.type.sqlite.db = security.db
storage.type.sqlite.idletime = 120
storage.type.sqlite.maxsessions = 128
storage.type.postgresql.maxsessions = 64
storage.type.postgresql.idletime = 60
storage.type.postgresql.host = localhost
storage.type.postgresql.username = stephb
storage.type.postgresql.password = snoopy99
storage.type.postgresql.database = ucentral
storage.type.postgresql.port = 5432
storage.type.postgresql.connectiontimeout = 60
storage.type.mysql.maxsessions = 64
storage.type.mysql.idletime = 60
storage.type.mysql.host = localhost
storage.type.mysql.username = stephb
storage.type.mysql.password = snoopy99
storage.type.mysql.database = ucentral
storage.type.mysql.port = 3306
storage.type.mysql.connectiontimeout = 60
########################################################################
########################################################################
#
# Logging: please leave as is for now.
#
########################################################################
logging.formatters.f1.class = PatternFormatter
logging.formatters.f1.pattern = %s: [%p] %t
logging.formatters.f1.times = UTC
logging.channels.c1.class = ConsoleChannel
logging.channels.c1.formatter = f1
# This is where the logs will be written. This path MUST exist
logging.channels.c2.class = FileChannel
logging.channels.c2.path = $OWSEC_ROOT/logs/log
logging.channels.c2.formatter.class = PatternFormatter
logging.channels.c2.formatter.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
logging.channels.c2.rotation = 20 M
logging.channels.c2.archive = timestamp
logging.channels.c2.purgeCount = 20
logging.channels.c3.class = ConsoleChannel
logging.channels.c3.pattern = %s: [%p] %t
# External Channel
logging.loggers.root.channel = c2
logging.loggers.root.level = debug
# Inline Channel with PatternFormatter
# logging.loggers.l1.name = logger1
# logging.loggers.l1.channel.class = ConsoleChannel
# logging.loggers.l1.channel.pattern = %s: [%p] %t
# logging.loggers.l1.level = information
# SplitterChannel
# logging.channels.splitter.class = SplitterChannel
# logging.channels.splitter.channels = l1,l2
# logging.loggers.l2.name = logger2
# logging.loggers.l2.channel = splitter

22
new.service Normal file
View File

@@ -0,0 +1,22 @@
[Unit]
Description=OpenWiFi Security Service
After=network-online.target docker.service
Wants=network-online.target
[Service]
Type=simple
Environment="UCENTRALSEC_ROOT=/home/admin/dev/wlan-cloud-ucentralsec"
ExecStart=/home/admin/dev/wlan-cloud-ucentralsec/cmake-build/owsec
WorkingDirectory=/home/admin/dev/wlan-cloud-ucentralsec
# ExecReload=/bin/kill -s HUP $MAINPID
User=admin
# TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
# KillMode=process
LimitNOFILE=500000
LimitNPROC=500000
[Install]
WantedBy=multi-user.target

View File

@@ -1,4 +1,4 @@
#!/bin/bash
export UCENTRALSEC_CONFIG=`pwd`
export UCENTRALSEC_ROOT=`pwd`
export OWSEC_CONFIG=`pwd`
export OWSEC_ROOT=`pwd`

View File

@@ -1,5 +1,9 @@
//
// Created by stephane bourque on 2021-06-04.
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#ifndef UCENTRALGW_ALBHEALTHCHECKSERVER_H
@@ -26,12 +30,12 @@ namespace OpenWifi {
/// Return a HTML document with the current date and time.
{
public:
ALBRequestHandler(Poco::Logger & L)
explicit ALBRequestHandler(Poco::Logger & L)
: Logger_(L)
{
}
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response)
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override
{
Logger_.information(Poco::format("ALB-REQUEST(%s): New ALB request.",Request.clientAddress().toString()));
Response.setChunkedTransferEncoding(true);
@@ -83,7 +87,7 @@ namespace OpenWifi {
return instance_;
}
int Start() {
int Start() override {
if(Daemon()->ConfigGetBool("alb.enable",false)) {
Port_ = (int)Daemon()->ConfigGetInt("alb.port",15015);
Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_);
@@ -95,7 +99,7 @@ namespace OpenWifi {
return 0;
}
void Stop() {
void Stop() override {
if(Server_)
Server_->stop();
}

View File

@@ -26,7 +26,7 @@
namespace OpenWifi {
static const char * vDAEMON_PROPERTIES_FILENAME = "ucentralsec.properties";
static const char * vDAEMON_PROPERTIES_FILENAME = "owsec.properties";
static const char * vDAEMON_ROOT_ENV_VAR = "UCENTRALSEC_ROOT";
static const char * vDAEMON_CONFIG_ENV_VAR = "UCENTRALSEC_CONFIG";
static const char * vDAEMON_APP_NAME = uSERVICE_SECURITY.c_str();
@@ -34,15 +34,15 @@ namespace OpenWifi {
class Daemon : public MicroService {
public:
explicit Daemon(std::string PropFile,
std::string RootEnv,
std::string ConfigEnv,
std::string AppName,
explicit Daemon(const std::string & PropFile,
const std::string & RootEnv,
const std::string & ConfigEnv,
const std::string & AppName,
uint64_t BusTimer,
Types::SubSystemVec SubSystems) :
const Types::SubSystemVec & SubSystems) :
MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {};
void initialize(Poco::Util::Application &self);
void initialize(Poco::Util::Application &self) override;
static Daemon *instance();
private:
static Daemon *instance_;

View File

@@ -17,13 +17,13 @@ namespace OpenWifi {
class KafkaManager *KafkaManager::instance_ = nullptr;
KafkaManager::KafkaManager() noexcept:
SubSystemServer("KafkaManager", "KAFKA-SVR", "ucentral.kafka")
SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka")
{
}
void KafkaManager::initialize(Poco::Util::Application & self) {
SubSystemServer::initialize(self);
KafkaEnabled_ = Daemon()->ConfigGetBool("ucentral.kafka.enable",false);
KafkaEnabled_ = Daemon()->ConfigGetBool("openwifi.kafka.enable",false);
}
#ifdef SMALL_BUILD
@@ -55,8 +55,8 @@ namespace OpenWifi {
void KafkaManager::ProducerThr() {
cppkafka::Configuration Config({
{ "client.id", Daemon()->ConfigGetString("ucentral.kafka.client.id") },
{ "metadata.broker.list", Daemon()->ConfigGetString("ucentral.kafka.brokerlist") }
{ "client.id", Daemon()->ConfigGetString("openwifi.kafka.client.id") },
{ "metadata.broker.list", Daemon()->ConfigGetString("openwifi.kafka.brokerlist") }
});
SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" +
std::to_string(Daemon()->ID()) +
@@ -96,10 +96,10 @@ namespace OpenWifi {
void KafkaManager::ConsumerThr() {
cppkafka::Configuration Config({
{ "client.id", Daemon()->ConfigGetString("ucentral.kafka.client.id") },
{ "metadata.broker.list", Daemon()->ConfigGetString("ucentral.kafka.brokerlist") },
{ "group.id", Daemon()->ConfigGetString("ucentral.kafka.group.id") },
{ "enable.auto.commit", Daemon()->ConfigGetBool("ucentral.kafka.auto.commit",false) },
{ "client.id", Daemon()->ConfigGetString("openwifi.kafka.client.id") },
{ "metadata.broker.list", Daemon()->ConfigGetString("openwifi.kafka.brokerlist") },
{ "group.id", Daemon()->ConfigGetString("openwifi.kafka.group.id") },
{ "enable.auto.commit", Daemon()->ConfigGetBool("openwifi.kafka.auto.commit",false) },
{ "auto.offset.reset", "latest" } ,
{ "enable.partition.eof", false }
});
@@ -125,8 +125,8 @@ namespace OpenWifi {
}
});
bool AutoCommit = Daemon()->ConfigGetBool("ucentral.kafka.auto.commit",false);
auto BatchSize = Daemon()->ConfigGetInt("ucentral.kafka.consumer.batchsize",20);
bool AutoCommit = Daemon()->ConfigGetBool("openwifi.kafka.auto.commit",false);
auto BatchSize = Daemon()->ConfigGetInt("openwifi.kafka.consumer.batchsize",20);
Types::StringVec Topics;
for(const auto &i:Notifiers_)
@@ -174,7 +174,7 @@ namespace OpenWifi {
return std::move( SystemInfoWrapper_ + PayLoad + "}");
}
void KafkaManager::PostMessage(std::string topic, std::string key, std::string PayLoad, bool WrapMessage ) {
void KafkaManager::PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage ) {
if(KafkaEnabled_) {
SubMutexGuard G(Mutex_);
KMessage M{

View File

@@ -41,7 +41,7 @@ namespace OpenWifi {
int Start() override;
void Stop() override;
void PostMessage(std::string topic, std::string key, std::string payload, bool WrapMessage = true);
void PostMessage(const std::string &topic, const std::string & key, const std::string &payload, bool WrapMessage = true);
[[nodiscard]] std::string WrapSystemId(const std::string & PayLoad);
[[nodiscard]] bool Enabled() { return KafkaEnabled_; }
int RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction & F);

View File

@@ -1,6 +1,11 @@
//
// Created by stephane bourque on 2021-06-22.
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#include <cstdlib>
#include <boost/algorithm/string.hpp>
@@ -182,7 +187,7 @@ namespace OpenWifi {
} else {
config().setString(LogFilePathKey, LogDir_);
}
Poco::File DataDir(ConfigPath("ucentral.system.data"));
Poco::File DataDir(ConfigPath("openwifi.system.data"));
DataDir_ = DataDir.path();
if(!DataDir.exists()) {
try {
@@ -191,16 +196,16 @@ namespace OpenWifi {
logger().log(E);
}
}
std::string KeyFile = ConfigPath("ucentral.service.key");
std::string KeyFilePassword = ConfigPath("ucentral.service.key.password" , "" );
std::string KeyFile = ConfigPath("openwifi.service.key");
std::string KeyFilePassword = ConfigPath("openwifi.service.key.password" , "" );
AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
Cipher_ = CipherFactory_.createCipher(*AppKey_);
ID_ = Utils::GetSystemId();
if(!DebugMode_)
DebugMode_ = ConfigGetBool("ucentral.system.debug",false);
MyPrivateEndPoint_ = ConfigGetString("ucentral.system.uri.private");
MyPublicEndPoint_ = ConfigGetString("ucentral.system.uri.public");
UIURI_ = ConfigGetString("ucentral.system.uri.ui");
DebugMode_ = ConfigGetBool("openwifi.system.debug",false);
MyPrivateEndPoint_ = ConfigGetString("openwifi.system.uri.private");
MyPublicEndPoint_ = ConfigGetString("openwifi.system.uri.public");
UIURI_ = ConfigGetString("openwifi.system.uri.ui");
MyHash_ = CreateHash(MyPublicEndPoint_);
InitializeSubSystemServers();
ServerApplication::initialize(self);
@@ -427,7 +432,7 @@ namespace OpenWifi {
Poco::Thread::trySleep((unsigned long)Daemon()->DaemonBusTimer());
if(!Running_)
break;
auto Msg = Daemon()->MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE);
Msg = Daemon()->MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false);
}
Msg = Daemon()->MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE);

View File

@@ -1,5 +1,9 @@
//
// Created by stephane bourque on 2021-06-22.
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#ifndef UCENTRALGW_MICROSERVICE_H
@@ -34,6 +38,7 @@ namespace OpenWifi {
static const std::string uSERVICE_FIRMWARE{ "ucentralfms"};
static const std::string uSERVICE_TOPOLOGY{ "owtopo"};
static const std::string uSERVICE_PROVISIONING{ "owprov"};
static const std::string uSERVICE_OWLS{ "owls"};
class MyErrorHandler : public Poco::ErrorHandler {
public:
@@ -82,9 +87,6 @@ namespace OpenWifi {
DAEMON_APP_NAME(std::move(AppName)),
DAEMON_BUS_TIMER(BusTimer),
SubSystems_(std::move(Subsystems)) {
std::string V{APP_VERSION};
std::string B{BUILD_NUMBER};
Version_ = V + "(" + B + ")";
}
int main(const ArgVec &args) override;
@@ -136,9 +138,9 @@ namespace OpenWifi {
[[nodiscard]] MicroServiceMetaVec GetServices();
[[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request);
void SavePID();
inline uint64_t GetPID() { return Poco::Process::id(); };
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() const { return MyPublicEndPoint_ + "/api/v1"; };
static void SavePID();
static inline uint64_t GetPID() { return Poco::Process::id(); };
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; };
[[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;};
private:
@@ -159,7 +161,7 @@ namespace OpenWifi {
std::string MyPrivateEndPoint_;
std::string MyPublicEndPoint_;
std::string UIURI_;
std::string Version_;
std::string Version_{std::string(APP_VERSION) + "("+ BUILD_NUMBER + ")"};
BusEventManager BusEventManager_;
SubMutex InfraMutex_;

View File

@@ -1,17 +1,20 @@
//
// Created by stephane bourque on 2021-07-01.
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
//
#include <iostream>
#include "OpenAPIRequest.h"
#include "Poco/Net/HTTPSClientSession.h"
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/StreamCopier.h>
#include <Poco/JSON/Parser.h>
#include <Poco/Path.h>
#include <Poco/URI.h>
#include <Poco/Exception.h>
#include "Utils.h"
@@ -19,12 +22,12 @@
namespace OpenWifi {
OpenAPIRequestGet::OpenAPIRequestGet( const std::string & ServiceType,
const std::string & EndPoint,
OpenAPIRequestGet::OpenAPIRequestGet( std::string ServiceType,
std::string EndPoint,
Types::StringPairVec & QueryData,
uint64_t msTimeout):
Type_(ServiceType),
EndPoint_(EndPoint),
Type_(std::move(ServiceType)),
EndPoint_(std::move(EndPoint)),
QueryData_(QueryData),
msTimeout_(msTimeout) {

View File

@@ -1,5 +1,9 @@
//
// Created by stephane bourque on 2021-07-01.
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#ifndef UCENTRALGW_OPENAPIREQUEST_H
@@ -13,8 +17,8 @@ namespace OpenWifi {
class OpenAPIRequestGet {
public:
explicit OpenAPIRequestGet( const std::string & Type,
const std::string & EndPoint,
explicit OpenAPIRequestGet( std::string Type,
std::string EndPoint,
Types::StringPairVec & QueryData,
uint64_t msTimeout);
int Do(Poco::JSON::Object::Ptr &ResponseObject);

View File

@@ -1,5 +1,9 @@
//
// Created by stephane bourque on 2021-06-13.
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#ifndef UCENTRALGW_UCENTRALTYPES_H
@@ -16,6 +20,8 @@
#include <queue>
#include "Poco/StringTokenizer.h"
#include "Poco/JSON/Parser.h"
#include "Poco/JSON/Stringifier.h"
namespace OpenWifi::Types {
typedef std::pair<std::string,std::string> StringPair;
@@ -42,26 +48,58 @@ namespace OpenWifi::Types {
}
inline std::string to_string( const StringVec &V) {
std::string Result;
bool first=true;
Poco::JSON::Array O;
for(const auto &i:V) {
if(first) {
Result += i;
first = false;
} else {
Result += ",";
Result += i;
}
O.add(i);
}
std::stringstream SS;
Poco::JSON::Stringifier::stringify(O,SS);
return SS.str();
}
inline std::string to_string( const StringPairVec &V) {
Poco::JSON::Array O;
for(const auto &i:V) {
Poco::JSON::Array OO;
OO.add(i.first);
OO.add(i.second);
O.add(OO);
}
std::stringstream SS;
Poco::JSON::Stringifier::stringify(O,SS);
return SS.str();
}
inline void from_string(const std::string &S, StringPairVec &V) {
try {
Poco::JSON::Parser P;
auto O = P.parse(S).extract<Poco::JSON::Array::Ptr>();
for(const auto &i:*O) {
auto Inner = i.extract<Poco::JSON::Array::Ptr>();
for(const auto &j:*Inner) {
auto S1 = i[0].toString();
auto S2 = i[1].toString();
V.push_back(std::make_pair(S1,S2));
}
}
} catch (...) {
}
return Result;
}
inline void from_string(const std::string &S, StringVec &V) {
Poco::StringTokenizer Tokens(S,",",Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY);
try {
Poco::JSON::Parser P;
auto O = P.parse(S).extract<Poco::JSON::Array::Ptr>();
for(auto const &i:Tokens)
V.emplace_back(i);
for(auto const &i:*O) {
V.push_back(i.toString());
}
} catch (...) {
}
}
};

View File

@@ -19,7 +19,7 @@ namespace OpenWifi {
class RESTAPI_InternalServer *RESTAPI_InternalServer::instance_ = nullptr;
RESTAPI_InternalServer::RESTAPI_InternalServer() noexcept:
SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "ucentral.internal.restapi")
SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "openwifi.internal.restapi")
{
}

View File

@@ -160,7 +160,7 @@ namespace OpenWifi::SecurityObjects {
typedef std::vector<ProfileAction> ProfileActionVec;
struct SecurityProfile {
uint64_t id;
uint64_t id=0;
std::string name;
std::string description;
ProfileActionVec policy;

View File

@@ -65,7 +65,7 @@ namespace OpenWifi {
Poco::Net::HTMLForm form(Request, Request.stream(), partHandler);
Poco::JSON::Object Answer;
if (!partHandler.Name().empty() && partHandler.Length()<Daemon()->ConfigGetInt("ucentral.avatar.maxsize",2000000)) {
if (!partHandler.Name().empty() && partHandler.Length()<Daemon()->ConfigGetInt("openwifi.avatar.maxsize",2000000)) {
Answer.set(RESTAPI::Protocol::AVATARID, Id);
Answer.set(RESTAPI::Protocol::ERRORCODE, 0);
Logger_.information(Poco::format("Uploaded avatar: %s Type: %s", partHandler.Name(), partHandler.ContentType()));

View File

@@ -64,9 +64,9 @@ namespace OpenWifi {
}
void RESTAPIHandler::ParseParameters(Poco::Net::HTTPServerRequest &request) {
Poco::URI uri(request.getURI());
Parameters_ = uri.getQueryParameters();
InitQueryBlock();
}
static bool is_number(const std::string &s) {
@@ -111,6 +111,26 @@ namespace OpenWifi {
return Default;
}
bool RESTAPIHandler::HasParameter(const std::string &Name, std::string &Value) {
for (const auto &i : Parameters_) {
if (i.first == Name) {
Value = i.second;
return true;
}
}
return false;
}
bool RESTAPIHandler::HasParameter(const std::string &Name, uint64_t & Value) {
for (const auto &i : Parameters_) {
if (i.first == Name) {
Value = std::stoi(i.second);
return true;
}
}
return false;
}
const std::string &RESTAPIHandler::GetBinding(const std::string &Name, const std::string &Default) {
auto E = Bindings_.find(Poco::toLower(Name));
if (E == Bindings_.end())
@@ -130,6 +150,22 @@ namespace OpenWifi {
return Return;
}
bool RESTAPIHandler::AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, std::string &Value) {
if(O->has(Field)) {
Value = O->get(Field).toString();
return true;
}
return false;
}
bool RESTAPIHandler::AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, uint64_t &Value) {
if(O->has(Field)) {
Value = O->get(Field);
return true;
}
return false;
}
void RESTAPIHandler::AddCORS(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) {
auto Origin = Request.find("Origin");
@@ -364,7 +400,17 @@ namespace OpenWifi {
Poco::JSON::Stringifier::stringify(Object, Answer);
}
void RESTAPIHandler::ReturnCountOnly(Poco::Net::HTTPServerRequest &Request, uint64_t Count,
Poco::Net::HTTPServerResponse &Response) {
Poco::JSON::Object Answer;
Answer.set("count", Count);
ReturnObject(Request,Answer,Response);
}
bool RESTAPIHandler::InitQueryBlock() {
if(QueryBlockInitialized_)
return true;
QueryBlockInitialized_=true;
QB_.SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
QB_.StartDate = GetParameter(RESTAPI::Protocol::STARTDATE, 0);
QB_.EndDate = GetParameter(RESTAPI::Protocol::ENDDATE, 0);
@@ -376,8 +422,10 @@ namespace OpenWifi {
QB_.LogType = GetParameter(RESTAPI::Protocol::LOGTYPE,0);
QB_.LastOnly = GetBoolParameter(RESTAPI::Protocol::LASTONLY,false);
QB_.Newest = GetBoolParameter(RESTAPI::Protocol::NEWEST,false);
QB_.CountOnly = GetBoolParameter(RESTAPI::Protocol::COUNTONLY,false);
if(QB_.Offset<1) return false;
if(QB_.Offset<1)
QB_.Offset=1;
return true;
}

View File

@@ -25,6 +25,7 @@
#include "Poco/NullStream.h"
#include "RESTAPI_SecurityObjects.h"
#include "RESTAPI_utils.h"
namespace OpenWifi {
@@ -86,7 +87,7 @@ namespace OpenWifi {
struct QueryBlock {
uint64_t StartDate = 0 , EndDate = 0 , Offset = 0 , Limit = 0, LogType = 0 ;
std::string SerialNumber, Filter, Select;
bool Lifetime=false, LastOnly=false, Newest=false;
bool Lifetime=false, LastOnly=false, Newest=false, CountOnly=false;
};
typedef std::map<std::string, std::string> BindingMap;
@@ -142,10 +143,25 @@ namespace OpenWifi {
const std::string &GetBinding(const std::string &Name, const std::string &Default);
bool InitQueryBlock();
void ReturnCountOnly(Poco::Net::HTTPServerRequest &Request, uint64_t Count,
Poco::Net::HTTPServerResponse &Response);
[[nodiscard]] static uint64_t Get(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, uint64_t Default=0);
[[nodiscard]] static std::string GetS(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, const std::string & Default="");
[[nodiscard]] static bool GetB(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, bool Default=false);
[[nodiscard]] static uint64_t GetWhen(const Poco::JSON::Object::Ptr &Obj);
bool HasParameter(const std::string &QueryParameter, std::string &Value);
bool HasParameter(const std::string &QueryParameter, uint64_t & Value);
bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, std::string &Value);
bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, uint64_t &Value);
template<typename T> void ReturnObject( Poco::Net::HTTPServerRequest &Request, const char *Name, const std::vector<T> & Objects,
Poco::Net::HTTPServerResponse &Response) {
Poco::JSON::Object Answer;
RESTAPI_utils::field_to_json(Answer,Name,Objects);
ReturnObject(Request, Answer, Response);
}
protected:
BindingMap Bindings_;
@@ -156,6 +172,7 @@ namespace OpenWifi {
std::vector<std::string> Methods_;
QueryBlock QB_;
bool Internal_=false;
bool QueryBlockInitialized_=false;
};
class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {

View File

@@ -30,9 +30,9 @@ namespace OpenWifi {
int RESTAPI_Server::Start() {
Logger_.information("Starting.");
AsserDir_ = Daemon()->ConfigPath("ucentral.restapi.wwwassets");
AccessPolicy_ = Daemon()->ConfigGetString("ucentral.document.policy.access", "/wwwassets/access_policy.html");
PasswordPolicy_ = Daemon()->ConfigGetString("ucentral.document.policy.password", "/wwwassets/possword_policy.html");
AsserDir_ = Daemon()->ConfigPath("openwifi.restapi.wwwassets");
AccessPolicy_ = Daemon()->ConfigGetString("openwifi.document.policy.access", "/wwwassets/access_policy.html");
PasswordPolicy_ = Daemon()->ConfigGetString("openwifi.document.policy.password", "/wwwassets/possword_policy.html");
for(const auto & Svr: ConfigServersList_) {
Logger_.information(Poco::format("Starting: %s:%s Keyfile:%s CertFile: %s", Svr.Address(), std::to_string(Svr.Port()),

View File

@@ -42,7 +42,7 @@ namespace OpenWifi {
std::string AccessPolicy_;
RESTAPI_Server() noexcept:
SubSystemServer("RESTAPIServer", "REST-SRV", "ucentral.restapi")
SubSystemServer("RESTAPIServer", "REST-SRV", "openwifi.restapi")
{
}
};

View File

@@ -15,11 +15,6 @@ namespace OpenWifi {
class Storage *Storage::instance_ = nullptr;
Storage::Storage() noexcept:
SubSystemServer("Storage", "STORAGE-SVR", "storage")
{
}
std::string Storage::ConvertParams(const std::string & S) const {
std::string R;

View File

@@ -177,7 +177,6 @@ namespace OpenWifi {
int Create_UserTable();
int Create_AvatarTable();
int Setup_SQLite();
[[nodiscard]] std::string ConvertParams(const std::string &S) const;
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
if(dbType_==sqlite) {
@@ -190,11 +189,15 @@ namespace OpenWifi {
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
}
#ifndef SMALL_BUILD
Storage() noexcept:
SubSystemServer("Storage", "STORAGE-SVR", "storage")
{
}
int Setup_SQLite();
int Setup_MySQL();
int Setup_PostgreSQL();
#endif
Storage() noexcept;
};
inline Storage * Storage() { return Storage::instance(); };

View File

@@ -20,10 +20,10 @@ then
exit 1
fi
if [[ "${UCENTRALSEC}" == "" ]]
if [[ "${OWSEC}" == "" ]]
then
echo "You must set the variable UCENTRALSEC in order to use this script. Something like"
echo "UCENTRALSEC=myauthgateway.isp.com:16001"
echo "You must set the variable OWSEC in order to use this script. Something like"
echo "OWSEC=myauthgateway.isp.com:16001"
exit 1
fi
@@ -43,7 +43,7 @@ browser=""
login() {
payload="{ \"userId\" : \"$username\" , \"password\" : \"$password\" }"
token=$(curl ${FLAGS} -X POST -H "Content-Type: application/json" -d "$payload" "https://${UCENTRALSEC}/api/v1/oauth2" | jq -r '.access_token')
token=$(curl ${FLAGS} -X POST -H "Content-Type: application/json" -d "$payload" "https://${OWSEC}/api/v1/oauth2" | jq -r '.access_token')
if [[ "${token}" == "" ]]
then
@@ -55,7 +55,7 @@ login() {
testlogin() {
payload="{ \"userId\" : \"$1\" , \"password\" : \"$2\" }"
curl ${FLAGS} -X POST "https://${UCENTRALSEC}/api/v1/oauth2" \
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/oauth2" \
-H "Content-Type: application/json" \
-d "$payload" > ${result_file}
userMustChangePassword=$(cat ${result_file} | jq -r '.userMustChangePassword')
@@ -68,14 +68,14 @@ testlogin() {
exit 1
fi
payload="{ \"userId\" : \"$1\" , \"password\" : \"$2\", \"newPassword\" : \"$3\" }"
curl ${FLAGS} -X POST "https://${UCENTRALSEC}/api/v1/oauth2" \
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/oauth2" \
-H "Content-Type: application/json" \
-d "$payload" > ${result_file}
jq < ${result_file}
elif [[ "$3" != "" ]]
then
payload="{ \"userId\" : \"$1\" , \"password\" : \"$2\", \"newPassword\" : \"$3\" }"
curl ${FLAGS} -X POST "https://${UCENTRALSEC}/api/v1/oauth2" \
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/oauth2" \
-H "Content-Type: application/json" \
-d "$payload" > ${result_file}
jq < ${result_file}
@@ -85,7 +85,7 @@ testlogin() {
emailtest() {
payload="{ \"userId\" : \"$1\" }"
curl ${FLAGS} -X POST "https://${UCENTRALSEC}/api/v1/oauth2?forgotPassword=true" \
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/oauth2?forgotPassword=true" \
-H "Content-Type: application/json" \
-d "$payload" > ${result_file}
jq < ${result_file}
@@ -114,18 +114,18 @@ findbrowser() {
logout() {
curl ${FLAGS} -X DELETE -H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
"https://${UCENTRALSEC}/api/v1/oauth2/${token}"
"https://${OWSEC}/api/v1/oauth2/${token}"
rm -rf token.json
}
me() {
curl ${FLAGS} -X GET -H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
"https://${UCENTRALSEC}/api/v1/oauth2?me=true"
"https://${OWSEC}/api/v1/oauth2?me=true"
}
listendpoints() {
curl ${FLAGS} -X GET "https://${UCENTRALSEC}/api/v1/systemEndpoints" \
curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/systemEndpoints" \
-H "accept: application/json" \
-H "Authorization: Bearer ${token}" > ${result_file}
jq < ${result_file}
@@ -161,12 +161,12 @@ listendpoints() {
}
getlogo() {
curl ${FLAGS} -X GET "https://${UCENTRALSEC}/wwwassets/open-wifi.svg"
curl ${FLAGS} -X GET "https://${OWSEC}/wwwassets/open-wifi.svg"
}
createuser() {
payload="{ \"id\": \"0\", \"email\" : \"$1\", \"currentPassword\" : \"$2\", \"changePassword\" : true}"
curl ${FLAGS} -X POST "https://${UCENTRALSEC}/api/v1/user/0" \
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/user/0" \
-H "accept: application/json" \
-H "Authorization: Bearer ${token}" \
-d "$payload" > ${result_file}
@@ -175,7 +175,7 @@ createuser() {
createuser_v() {
payload="{ \"id\": \"0\", \"email\" : \"$1\", \"currentPassword\" : \"$2\", \"changePassword\" : true}"
curl ${FLAGS} -X POST "https://${UCENTRALSEC}/api/v1/user/0?email_verification=true" \
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/user/0?email_verification=true" \
-H "accept: application/json" \
-H "Authorization: Bearer ${token}" \
-d "$payload" > ${result_file}
@@ -183,7 +183,7 @@ createuser_v() {
}
deleteuser() {
curl ${FLAGS} -X DELETE "https://${UCENTRALSEC}/api/v1/user/$1" \
curl ${FLAGS} -X DELETE "https://${OWSEC}/api/v1/user/$1" \
-H "accept: application/json" \
-H "Authorization: Bearer ${token}" \
-d "$payload" > ${result_file}
@@ -191,7 +191,7 @@ deleteuser() {
}
getuser() {
curl ${FLAGS} -X GET "https://${UCENTRALSEC}/api/v1/user/$1" \
curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/user/$1" \
-H "accept: application/json" \
-H "Authorization: Bearer ${token}" \
-d "$payload" > ${result_file}
@@ -199,7 +199,7 @@ getuser() {
}
listusers() {
curl ${FLAGS} -X GET "https://${UCENTRALSEC}/api/v1/users" \
curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/users" \
-H "accept: application/json" \
-H "Authorization: Bearer ${token}" \
-d "$payload" > ${result_file}
@@ -208,41 +208,41 @@ listusers() {
policies() {
payload="{}"
curl ${FLAGS} -X POST "https://${UCENTRALSEC}/api/v1/oauth2?requirements=true" \
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/oauth2?requirements=true" \
-H "Content-Type: application/json" \
-d "$payload" > ${result_file}
jq < ${result_file}
}
setavatar() {
curl ${FLAGS} -F 'data=@open-wifi.svg' "https://${UCENTRALSEC}/api/v1/avatar/$1" \
curl ${FLAGS} -F 'data=@open-wifi.svg' "https://${OWSEC}/api/v1/avatar/$1" \
-H "Authorization: Bearer ${token}" > ${result_file};
jq < ${result_file}
}
getavatar() {
curl ${FLAGS} -X GET "https://${UCENTRALSEC}/api/v1/avatar/$1" \
curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/avatar/$1" \
-H "accept: application/octet-stream" \
-H "Authorization: Bearer ${token}" \
-o "user.svg"
}
deleteavatar() {
curl ${FLAGS} -X DELETE "https://${UCENTRALSEC}/api/v1/avatar/$1" \
curl ${FLAGS} -X DELETE "https://${OWSEC}/api/v1/avatar/$1" \
-H "Authorization: Bearer ${token}" \
-H "Content-Type: application/json" > ${result_file}
jq < ${result_file}
}
secversion() {
curl ${FLAGS} -X GET "https://${UCENTRALSEC}/api/v1/system?command=version" \
curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/system?command=version" \
-H "accept: application/json" \
-H "Authorization: Bearer ${token}" > ${result_file}
jq < ${result_file}
}
sectimes() {
curl ${FLAGS} -X GET "https://${UCENTRALSEC}/api/v1/system?command=times" \
curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/system?command=times" \
-H "accept: application/json" \
-H "Authorization: Bearer ${token}" > ${result_file}
jq < ${result_file}