mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
synced 2025-10-30 02:12:32 +00:00
New router and simplifiedrest handler
This commit is contained in:
@@ -54,7 +54,6 @@ add_executable( ucentralsec
|
||||
src/Daemon.h src/Daemon.cpp
|
||||
src/MicroService.cpp src/MicroService.h
|
||||
src/SubSystemServer.cpp src/SubSystemServer.h
|
||||
src/RESTAPI_unknownRequestHandler.h src/RESTAPI_unknownRequestHandler.cpp
|
||||
src/RESTAPI_oauth2Handler.h src/RESTAPI_oauth2Handler.cpp
|
||||
src/RESTAPI_handler.h src/RESTAPI_handler.cpp
|
||||
src/RESTAPI_server.cpp src/RESTAPI_server.h
|
||||
@@ -70,7 +69,8 @@ add_executable( ucentralsec
|
||||
src/storage_tables.cpp src/SMTPMailerService.cpp src/SMTPMailerService.h
|
||||
src/RESTAPI_users_handler.cpp src/RESTAPI_users_handler.h
|
||||
src/RESTAPI_user_handler.cpp src/RESTAPI_user_handler.h
|
||||
src/RESTAPI_action_links.cpp src/RESTAPI_action_links.h)
|
||||
src/RESTAPI_action_links.cpp src/RESTAPI_action_links.h src/storage_users.cpp
|
||||
src/RESTAPI_systemServices_handler.cpp src/RESTAPI_systemServices_handler.h)
|
||||
|
||||
target_link_libraries(ucentralsec PUBLIC
|
||||
${Poco_LIBRARIES} ${Boost_LIBRARIES} ${ZLIB_LIBRARIES} ${AWSSDK_LINK_LIBRARIES} CppKafka::cppkafka )
|
||||
|
||||
@@ -308,6 +308,11 @@ components:
|
||||
- instagram
|
||||
oauthUserInfo:
|
||||
type: string
|
||||
securityPolicy:
|
||||
type: string
|
||||
securityPolicyChange:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
UserList:
|
||||
type: object
|
||||
@@ -417,6 +422,29 @@ components:
|
||||
items:
|
||||
$ref: '#/components/schemas/SecurityProfile'
|
||||
|
||||
InternalServiceInfo:
|
||||
type: object
|
||||
properties:
|
||||
privateURI:
|
||||
type: string
|
||||
publicURI:
|
||||
type: string
|
||||
auth:
|
||||
type: string
|
||||
|
||||
|
||||
InternalSystemServices:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
version:
|
||||
type: integer
|
||||
services:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/InternalServiceInfo'
|
||||
|
||||
#########################################################################################
|
||||
##
|
||||
## End of uCentral system wide values
|
||||
@@ -741,6 +769,24 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
#########################################################################################
|
||||
## The following calls are restricted to the private system side APIs
|
||||
#########################################################################################
|
||||
/systemServices:
|
||||
get:
|
||||
tags:
|
||||
- Security
|
||||
summary: Retrieve the basic system information. This information is used between services only.
|
||||
operationId: getSystemServices
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/InternalSystemServices'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
|
||||
#########################################################################################
|
||||
##
|
||||
## These are endpoints that all services in the uCentral stack must provide
|
||||
|
||||
4
set_env.sh
Executable file
4
set_env.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
export UCENTRALSEC_CONFIG=`pwd`
|
||||
export UCENTRALSEC_ROOT=`pwd`
|
||||
@@ -38,9 +38,7 @@ namespace uCentral {
|
||||
Types::SubSystemVec{
|
||||
Storage(),
|
||||
RESTAPI_Server(),
|
||||
KafkaManager(),
|
||||
SMTPMailerService(),
|
||||
ALBHealthCheckServer()
|
||||
SMTPMailerService()
|
||||
});
|
||||
}
|
||||
return instance_;
|
||||
@@ -49,7 +47,6 @@ namespace uCentral {
|
||||
void Daemon::initialize(Poco::Util::Application &self) {
|
||||
MicroService::initialize(*this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
@@ -39,14 +39,10 @@ namespace uCentral {
|
||||
Types::SubSystemVec SubSystems) :
|
||||
MicroService( PropFile, RootEnv, ConfigEnv, AppName, SubSystems) {};
|
||||
|
||||
bool AutoProvisioning() const { return AutoProvisioning_ ; }
|
||||
[[nodiscard]] std::string IdentifyDevice(const std::string & Compatible) const;
|
||||
void initialize(Poco::Util::Application &self);
|
||||
static Daemon *instance();
|
||||
private:
|
||||
static Daemon *instance_;
|
||||
bool AutoProvisioning_ = false;
|
||||
Types::StringMapStringSet DeviceTypeIdentifications_;
|
||||
};
|
||||
|
||||
inline Daemon * Daemon() { return Daemon::instance(); }
|
||||
|
||||
@@ -38,93 +38,104 @@ namespace uCentral {
|
||||
int KafkaManager::Start() {
|
||||
if(!KafkaEnabled_)
|
||||
return 0;
|
||||
Running_ = true;
|
||||
ProducerThr_ = std::make_unique<std::thread>(Producer,this);
|
||||
ProducerThr_->detach();
|
||||
ConsumerThr_ = std::make_unique<std::thread>(Consumer,this);
|
||||
ConsumerThr_->detach();
|
||||
ProducerThr_ = std::make_unique<std::thread>([this]() { this->Producer(); });
|
||||
ConsumerThr_ = std::make_unique<std::thread>([this]() { this->Consumer(); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KafkaManager::Stop() {
|
||||
if(KafkaEnabled_) {
|
||||
Running_ = false;
|
||||
ConsumerThr_->join();
|
||||
ProducerRunning_ = ConsumerRunning_ = false;
|
||||
ProducerThr_->join();
|
||||
ConsumerThr_->join();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaManager::Producer(KafkaManager *Mgr) {
|
||||
void KafkaManager::Producer() {
|
||||
cppkafka::Configuration Config({
|
||||
{ "metadata.broker.list", Daemon()->ConfigGetString("ucentral.kafka.brokerlist") } ,
|
||||
{ "enable.auto.commit", Daemon()->ConfigGetBool("ucentral.kafka.auto.commit", false)}
|
||||
{ "metadata.broker.list", Daemon()->ConfigGetString("ucentral.kafka.brokerlist") }
|
||||
});
|
||||
Mgr->SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" +
|
||||
std::to_string(Daemon()->ConfigGetInt("ucentral.system.id")) +
|
||||
R"lit( , "host" : ")lit" + Daemon()->ConfigGetString("ucentral.system.uri") +
|
||||
SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" +
|
||||
std::to_string(Daemon()->ID()) +
|
||||
R"lit( , "host" : ")lit" + Daemon()->PrivateEndPoint() +
|
||||
R"lit(" } , "payload" : ")lit" ;
|
||||
|
||||
cppkafka::Producer Producer(Config);
|
||||
|
||||
while(Mgr->Running_) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
|
||||
if(!Mgr->Running_)
|
||||
break;
|
||||
ProducerRunning_ = true;
|
||||
while(ProducerRunning_) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
try
|
||||
{
|
||||
SubMutexGuard G(Mgr->ProducerMutex_);
|
||||
while (!Mgr->Queue_.empty() && Mgr->Running_) {
|
||||
const auto M = Mgr->Queue_.front();
|
||||
// std::cout << "Producing Topic: " << M.Topic << " Key: " << M.Key <<std::endl;
|
||||
SubMutexGuard G(ProducerMutex_);
|
||||
while (!Queue_.empty()) {
|
||||
const auto M = Queue_.front();
|
||||
Producer.produce(
|
||||
cppkafka::MessageBuilder(M.Topic).key(M.Key).payload(M.PayLoad));
|
||||
Mgr->Queue_.pop();
|
||||
Queue_.pop();
|
||||
}
|
||||
// Producer_->flush();
|
||||
|
||||
Producer.flush();
|
||||
} catch (const cppkafka::HandleException &E ) {
|
||||
Logger_.warning(Poco::format("Caught a Kafka exception (producer): %s",std::string{E.what()}));
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaManager::Consumer(KafkaManager *Mgr ) {
|
||||
void KafkaManager::Consumer() {
|
||||
cppkafka::Configuration Config({
|
||||
{ "group.id", 1 },
|
||||
{ "group.id", Daemon()->ConfigGetString("ucentral.kafka.group.id") },
|
||||
{ "enable.auto.commit", Daemon()->ConfigGetBool("ucentral.kafka.auto.commit",false) },
|
||||
{ "metadata.broker.list", Daemon()->ConfigGetString("ucentral.kafka.brokerlist") }
|
||||
{ "metadata.broker.list", Daemon()->ConfigGetString("ucentral.kafka.brokerlist") },
|
||||
{ "auto.offset.reset", "earliest" } ,
|
||||
{ "enable.partition.eof", false }
|
||||
});
|
||||
|
||||
cppkafka::Consumer Consumer(Config);
|
||||
|
||||
Consumer.set_assignment_callback([Mgr](const cppkafka::TopicPartitionList& partitions) {
|
||||
Mgr->Logger_.information(Poco::format("Got assigned: %Lu...",(uint64_t )partitions.front().get_partition()));
|
||||
Consumer.set_assignment_callback([=](const cppkafka::TopicPartitionList& partitions) {
|
||||
std::cout << "Partition assigned: " << partitions.front().get_partition() << std::endl;
|
||||
Logger_.information(Poco::format("Got assigned: %Lu...",(uint64_t )partitions.front().get_partition()));
|
||||
});
|
||||
Consumer.set_revocation_callback([Mgr](const cppkafka::TopicPartitionList& partitions) {
|
||||
Mgr->Logger_.information(Poco::format("Got revoked: %Lu...",(uint64_t )partitions.front().get_partition()));
|
||||
Consumer.set_revocation_callback([this](const cppkafka::TopicPartitionList& partitions) {
|
||||
std::cout << "Partition revocation: " << partitions.front().get_partition() << std::endl;
|
||||
Logger_.information(Poco::format("Got revoked: %Lu...",(uint64_t )partitions.front().get_partition()));
|
||||
});
|
||||
|
||||
std::vector<std::string> Topics;
|
||||
for(const auto &i:Mgr->Notifiers_)
|
||||
Types::StringVec Topics;
|
||||
for(const auto &i:Notifiers_)
|
||||
Topics.push_back(i.first);
|
||||
|
||||
Consumer.subscribe(Topics);
|
||||
while(Mgr->Running_) {
|
||||
cppkafka::Message Msg = Consumer.poll(std::chrono::milliseconds(2000));
|
||||
if (Msg) {
|
||||
|
||||
ConsumerRunning_ = true;
|
||||
while(ConsumerRunning_) {
|
||||
try {
|
||||
cppkafka::Message Msg = Consumer.poll(std::chrono::milliseconds(200));
|
||||
if (!Msg)
|
||||
continue;;
|
||||
if (Msg.get_error()) {
|
||||
if (!Msg.is_eof()) {
|
||||
Mgr->Logger_.error(
|
||||
Poco::format("Error: %s", Msg.get_error().to_string()));
|
||||
}
|
||||
} else {
|
||||
SubMutexGuard G(Mgr->ConsumerMutex_);
|
||||
auto It = Mgr->Notifiers_.find(Msg.get_topic());
|
||||
if (It != Mgr->Notifiers_.end()) {
|
||||
Types::TopicNotifyFunctionList &FL = It->second;
|
||||
for (auto &F : FL)
|
||||
F.first(Msg.get_key(), Msg.get_payload());
|
||||
Logger_.error(Poco::format("Error: %s", Msg.get_error().to_string()));
|
||||
}
|
||||
Consumer.commit(Msg);
|
||||
continue;
|
||||
}
|
||||
SubMutexGuard G(ConsumerMutex_);
|
||||
auto It = Notifiers_.find(Msg.get_topic());
|
||||
if (It != Notifiers_.end()) {
|
||||
Types::TopicNotifyFunctionList &FL = It->second;
|
||||
for (auto &F : FL) {
|
||||
std::string Key{Msg.get_key()};
|
||||
std::string Payload{Msg.get_payload()};
|
||||
std::thread T(F.first, Key, Payload);
|
||||
T.detach();
|
||||
}
|
||||
}
|
||||
Consumer.commit(Msg);
|
||||
} catch (const cppkafka::HandleException &E) {
|
||||
Logger_.warning(Poco::format("Caught a Kafka exception (consumer): %s",std::string{E.what()}));
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,19 +144,19 @@ namespace uCentral {
|
||||
return std::move( SystemInfoWrapper_ + PayLoad + "}");
|
||||
}
|
||||
|
||||
void KafkaManager::PostMessage(std::string topic, std::string key, std::string PayLoad) {
|
||||
if(KafkaEnabled_ && Running_) {
|
||||
void KafkaManager::PostMessage(std::string topic, std::string key, std::string PayLoad, bool WrapMessage ) {
|
||||
if(KafkaEnabled_) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
|
||||
KMessage M{
|
||||
.Topic = std::move(topic), .Key = std::move(key), .PayLoad = std::move(WrapSystemId(PayLoad))};
|
||||
// std::cout << "Posting Topic: " << M.Topic << " Key: " << M.Key << " Payload: " << M.PayLoad << std::endl;
|
||||
.Topic = std::move(topic),
|
||||
.Key = std::move(key),
|
||||
.PayLoad = std::move(WrapMessage ? WrapSystemId(PayLoad) : PayLoad )};
|
||||
Queue_.push(std::move(M));
|
||||
}
|
||||
}
|
||||
|
||||
int KafkaManager::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
|
||||
if(!Running_) {
|
||||
if(KafkaEnabled_) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
auto It = Notifiers_.find(Topic);
|
||||
if(It == Notifiers_.end()) {
|
||||
@@ -162,7 +173,7 @@ namespace uCentral {
|
||||
}
|
||||
|
||||
void KafkaManager::UnregisterTopicWatcher(const std::string &Topic, int Id) {
|
||||
if(!Running_) {
|
||||
if(KafkaEnabled_) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
auto It = Notifiers_.find(Topic);
|
||||
if(It != Notifiers_.end()) {
|
||||
|
||||
@@ -35,24 +35,26 @@ namespace uCentral {
|
||||
return instance_;
|
||||
}
|
||||
|
||||
static void Producer(KafkaManager *);
|
||||
static void Consumer(KafkaManager *);
|
||||
void Producer();
|
||||
void Consumer();
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
|
||||
void PostMessage(std::string topic, std::string key, std::string payload);
|
||||
void PostMessage(std::string topic, std::string key, std::string payload, bool WrapMessage = true);
|
||||
[[nodiscard]] std::string WrapSystemId(const std::string & PayLoad);
|
||||
[[nodiscard]] bool Enabled() { return Running_ && KafkaEnabled_; }
|
||||
[[nodiscard]] bool Enabled() { return KafkaEnabled_; }
|
||||
int RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction & F);
|
||||
void UnregisterTopicWatcher(const std::string &Topic, int FunctionId);
|
||||
void WakeUp();
|
||||
|
||||
private:
|
||||
static KafkaManager *instance_;
|
||||
SubMutex ProducerMutex_;
|
||||
SubMutex ConsumerMutex_;
|
||||
bool KafkaEnabled_ = false;
|
||||
std::atomic_bool Running_ = false;
|
||||
std::atomic_bool ProducerRunning_ = false;
|
||||
std::atomic_bool ConsumerRunning_ = false;
|
||||
std::queue<KMessage> Queue_;
|
||||
std::string SystemInfoWrapper_;
|
||||
std::unique_ptr<std::thread> ConsumerThr_;
|
||||
|
||||
17
src/Kafka_topics.h
Normal file
17
src/Kafka_topics.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-07.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_KAFKA_TOPICS_H
|
||||
#define UCENTRALGW_KAFKA_TOPICS_H
|
||||
|
||||
namespace uCentral::KafkaTopics {
|
||||
static const std::string HEALTHCHECK{"healthcheck"};
|
||||
static const std::string STATE{"state"};
|
||||
static const std::string CONNECTION{"connection"};
|
||||
static const std::string WIFISCAN{"wifiscan"};
|
||||
static const std::string ALERTS{"alerts"};
|
||||
static const std::string COMMAND{"command"};
|
||||
static const std::string SERVICE_EVENTS{"service_events"};
|
||||
}
|
||||
#endif // UCENTRALGW_KAFKA_TOPICS_H
|
||||
@@ -17,10 +17,22 @@
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
|
||||
#include "ALBHealthCheckServer.h"
|
||||
#ifndef SMALL_BUILD
|
||||
#include "KafkaManager.h"
|
||||
#endif
|
||||
#include "Kafka_topics.h"
|
||||
|
||||
#include "MicroService.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#undef DBGLINE
|
||||
#define DBGLINE
|
||||
|
||||
namespace uCentral {
|
||||
|
||||
void MyErrorHandler::exception(const Poco::Exception & E) {
|
||||
@@ -43,7 +55,84 @@ namespace uCentral {
|
||||
std::exit(Reason);
|
||||
}
|
||||
|
||||
void MicroService::BusMessageReceived(std::string Key, std::string Message) {
|
||||
SubMutexGuard G(InfraMutex_);
|
||||
// std::cout << "Message arrived:" << Key << " ," << Message << std::endl;
|
||||
try {
|
||||
Poco::JSON::Parser P;
|
||||
auto Object = P.parse(Message).extract<Poco::JSON::Object::Ptr>();
|
||||
if(Object->has("id")) {
|
||||
uint64_t ID = Object->get("id");
|
||||
if(ID!=ID_) {
|
||||
if( Object->has("event") &&
|
||||
Object->has("type") &&
|
||||
Object->has("publicEndPoint") &&
|
||||
Object->has("privateEndPoint") &&
|
||||
Object->has("version") &&
|
||||
Object->has("key")) {
|
||||
auto Event = Object->get("event").toString();
|
||||
|
||||
if(Event == "keep-alive" && Services_.find(ID)!=Services_.end()) {
|
||||
std::cout << "Keep-alive from " << ID << std::endl;
|
||||
Services_[ID].LastUpdate = std::time(nullptr);
|
||||
} else if (Event=="leave") {
|
||||
Services_.erase(ID);
|
||||
std::cout << "Leave from " << ID << std::endl;
|
||||
} else if (Event== "join" || Event=="keep_alive") {
|
||||
std::cout << "Join from " << ID << std::endl;
|
||||
Services_[ID] = MicroServiceMeta{
|
||||
.Id = ID,
|
||||
.Type = Poco::toLower(Object->get("type").toString()),
|
||||
.PrivateEndPoint = Object->get("privateEndPoint").toString(),
|
||||
.PublicEndPoint = Object->get("publicEndPoint").toString(),
|
||||
.AccessKey = Object->get("key").toString(),
|
||||
.Version = Object->get("version").toString(),
|
||||
.LastUpdate = (uint64_t )std::time(nullptr) };
|
||||
for(const auto &[Id,Svc]:Services_)
|
||||
std::cout << "ID:" << Id << " Type:" << Svc.Type << " EndPoint:" << Svc.PublicEndPoint << std::endl;
|
||||
} else {
|
||||
std::cout << "Bad packet 2 ..." << std::endl;
|
||||
logger().error(Poco::format("Malformed event from device %Lu, event=%s", ID, Event));
|
||||
}
|
||||
} else {
|
||||
std::cout << "Bad packet 1 ..." << std::endl;
|
||||
logger().error(Poco::format("Malformed event from device %Lu", ID));
|
||||
}
|
||||
|
||||
} else {
|
||||
std::cout << "Ignoring my own messages..." << std::endl;
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
DBGLINE
|
||||
logger().log(E);
|
||||
DBGLINE
|
||||
}
|
||||
DBGLINE
|
||||
}
|
||||
|
||||
MicroServiceMetaVec MicroService::GetServices(const std::string & Type) {
|
||||
SubMutexGuard G(InfraMutex_);
|
||||
|
||||
auto T = Poco::toLower(Type);
|
||||
MicroServiceMetaVec Res;
|
||||
for(const auto &[Id,ServiceRec]:Services_) {
|
||||
if(ServiceRec.Type==T)
|
||||
Res.push_back(ServiceRec);
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
void MicroService::initialize(Poco::Util::Application &self) {
|
||||
|
||||
std::string V{APP_VERSION};
|
||||
std::string B{BUILD_NUMBER};
|
||||
Version_ = V + "(" + B + ")";
|
||||
|
||||
// add the default services
|
||||
SubSystems_.push_back(KafkaManager());
|
||||
SubSystems_.push_back(ALBHealthCheckServer());
|
||||
|
||||
Poco::Net::initializeSSL();
|
||||
Poco::Net::HTTPStreamFactory::registerFactory();
|
||||
Poco::Net::HTTPSStreamFactory::registerFactory();
|
||||
@@ -87,9 +176,14 @@ namespace uCentral {
|
||||
ID_ = Utils::GetSystemId();
|
||||
if(!DebugMode_)
|
||||
DebugMode_ = ConfigGetBool("ucentral.system.debug",false);
|
||||
|
||||
MyPrivateEndPoint_ = ConfigGetString("ucentral.system.uri.private");
|
||||
MyPublicEndPoint_ = ConfigGetString("ucentral.system.uri.public");
|
||||
MyHash_ = CreateHash(MyPrivateEndPoint_);
|
||||
InitializeSubSystemServers();
|
||||
ServerApplication::initialize(self);
|
||||
|
||||
Types::TopicNotifyFunction F = [this](std::string s1,std::string s2) { this->BusMessageReceived(s1,s2); };
|
||||
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
|
||||
}
|
||||
|
||||
void MicroService::uninitialize() {
|
||||
@@ -139,12 +233,6 @@ namespace uCentral {
|
||||
|
||||
}
|
||||
|
||||
std::string MicroService::Version() {
|
||||
std::string V = APP_VERSION;
|
||||
std::string B = BUILD_NUMBER;
|
||||
return V + "(" + B + ")";
|
||||
}
|
||||
|
||||
void MicroService::handleHelp(const std::string &name, const std::string &value) {
|
||||
HelpRequested_ = true;
|
||||
displayHelp();
|
||||
@@ -186,9 +274,11 @@ namespace uCentral {
|
||||
void MicroService::StartSubSystemServers() {
|
||||
for(auto i:SubSystems_)
|
||||
i->Start();
|
||||
BusEventManager_.Start();
|
||||
}
|
||||
|
||||
void MicroService::StopSubSystemServers() {
|
||||
BusEventManager_.Stop();
|
||||
for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i)
|
||||
(*i)->Stop();
|
||||
}
|
||||
@@ -286,6 +376,58 @@ namespace uCentral {
|
||||
return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
|
||||
}
|
||||
|
||||
std::string MicroService::CreateHash(const std::string &S) {
|
||||
SHA2_.update(S);
|
||||
return Utils::ToHex(SHA2_.digest());
|
||||
}
|
||||
|
||||
std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const {
|
||||
Poco::JSON::Object Obj;
|
||||
Obj.set("event",Type);
|
||||
Obj.set("id",ID_);
|
||||
Obj.set("type",Poco::toLower(DAEMON_APP_NAME));
|
||||
Obj.set("publicEndPoint",MyPublicEndPoint_);
|
||||
Obj.set("privateEndPoint",MyPrivateEndPoint_);
|
||||
Obj.set("key",MyHash_);
|
||||
Obj.set("version",Version_);
|
||||
std::stringstream ResultText;
|
||||
Poco::JSON::Stringifier::stringify(Obj, ResultText);
|
||||
return ResultText.str();
|
||||
}
|
||||
|
||||
void BusEventManager::run() {
|
||||
|
||||
Running_ = true;
|
||||
|
||||
auto Msg = Daemon()->MakeSystemEventMessage("join");
|
||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false);
|
||||
|
||||
while(Running_) {
|
||||
Poco::Thread::trySleep(60000);
|
||||
if(!Running_)
|
||||
break;
|
||||
auto Msg = Daemon()->MakeSystemEventMessage("keep-alive");
|
||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false);
|
||||
}
|
||||
|
||||
Msg = Daemon()->MakeSystemEventMessage("leave");
|
||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false);
|
||||
};
|
||||
|
||||
void BusEventManager::Start() {
|
||||
if(KafkaManager()->Enabled()) {
|
||||
Thread_.start(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void BusEventManager::Stop() {
|
||||
if(KafkaManager()->Enabled()) {
|
||||
Running_ = false;
|
||||
Thread_.wakeUp();
|
||||
Thread_.join();
|
||||
}
|
||||
}
|
||||
|
||||
int MicroService::main(const ArgVec &args) {
|
||||
|
||||
MyErrorHandler ErrorHandler(*this);
|
||||
@@ -313,7 +455,4 @@ namespace uCentral {
|
||||
|
||||
return Application::EXIT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "Poco/Crypto/RSAKey.h"
|
||||
#include "Poco/Crypto/CipherFactory.h"
|
||||
#include "Poco/Crypto/Cipher.h"
|
||||
#include "Poco/SHA2Engine.h"
|
||||
|
||||
#include "uCentralTypes.h"
|
||||
#include "SubSystemServer.h"
|
||||
@@ -36,6 +37,29 @@ namespace uCentral {
|
||||
Poco::Util::Application &App_;
|
||||
};
|
||||
|
||||
class BusEventManager : public Poco::Runnable {
|
||||
public:
|
||||
void run() override;
|
||||
void Start();
|
||||
void Stop();
|
||||
private:
|
||||
std::atomic_bool Running_ = false;
|
||||
Poco::Thread Thread_;
|
||||
};
|
||||
|
||||
struct MicroServiceMeta {
|
||||
uint64_t Id=0;
|
||||
std::string Type;
|
||||
std::string PrivateEndPoint;
|
||||
std::string PublicEndPoint;
|
||||
std::string AccessKey;
|
||||
std::string Version;
|
||||
uint64_t LastUpdate=0;
|
||||
};
|
||||
|
||||
typedef std::map<uint64_t, MicroServiceMeta> MicroServiceMetaMap;
|
||||
typedef std::vector<MicroServiceMeta> MicroServiceMetaVec;
|
||||
|
||||
class MicroService : public Poco::Util::ServerApplication {
|
||||
public:
|
||||
explicit MicroService( std::string PropFile,
|
||||
@@ -66,7 +90,7 @@ namespace uCentral {
|
||||
void StopSubSystemServers();
|
||||
void Exit(int Reason);
|
||||
bool SetSubsystemLogLevel(const std::string & SubSystem, const std::string & Level);
|
||||
[[nodiscard]] static std::string Version();
|
||||
[[nodiscard]] std::string Version() { return Version_; }
|
||||
[[nodiscard]] const Poco::SharedPtr<Poco::Crypto::RSAKey> & Key() { return AppKey_; }
|
||||
[[nodiscard]] inline const std::string & DataDir() { return DataDir_; }
|
||||
[[nodiscard]] std::string CreateUUID();
|
||||
@@ -85,6 +109,15 @@ namespace uCentral {
|
||||
[[nodiscard]] uint64_t ConfigGetBool(const std::string &Key);
|
||||
[[nodiscard]] std::string Encrypt(const std::string &S);
|
||||
[[nodiscard]] std::string Decrypt(const std::string &S);
|
||||
[[nodiscard]] std::string CreateHash(const std::string &S);
|
||||
[[nodiscard]] std::string Hash() const { return MyHash_; };
|
||||
[[nodiscard]] std::string ServiceType() const { return DAEMON_APP_NAME; };
|
||||
[[nodiscard]] std::string PrivateEndPoint() const { return MyPrivateEndPoint_; };
|
||||
[[nodiscard]] std::string PublicEndPoint() const { return MyPublicEndPoint_; };
|
||||
[[nodiscard]] std::string MakeSystemEventMessage( const std::string & Type ) const ;
|
||||
|
||||
void BusMessageReceived( std::string Key, std::string Message);
|
||||
[[nodiscard]] MicroServiceMetaVec GetServices(const std::string & type);
|
||||
|
||||
private:
|
||||
bool HelpRequested_ = false;
|
||||
@@ -98,6 +131,14 @@ namespace uCentral {
|
||||
Types::SubSystemVec SubSystems_;
|
||||
Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
|
||||
Poco::Crypto::Cipher * Cipher_ = nullptr;
|
||||
Poco::SHA2Engine SHA2_;
|
||||
MicroServiceMetaMap Services_;
|
||||
std::string MyHash_;
|
||||
std::string MyPrivateEndPoint_;
|
||||
std::string MyPublicEndPoint_;
|
||||
std::string Version_;
|
||||
BusEventManager BusEventManager_;
|
||||
SubMutex InfraMutex_;
|
||||
|
||||
std::string DAEMON_PROPERTIES_FILENAME;
|
||||
std::string DAEMON_ROOT_ENV_VAR;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace uCentral {
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/actions"}; };
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -11,40 +11,46 @@
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <future>
|
||||
#include <numeric>
|
||||
#include <chrono>
|
||||
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/DateTimeParser.h"
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "AuthService.h"
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#define DBG std::cout << __LINE__ << " " __FILE__ << std::endl;
|
||||
|
||||
namespace uCentral {
|
||||
bool RESTAPIHandler::ParseBindings(const std::string & Request, const std::string & Path, BindingMap &bindings) {
|
||||
|
||||
bool RESTAPIHandler::ParseBindings(const std::string & Request, const std::list<const char *> & EndPoints, BindingMap &bindings) {
|
||||
std::string Param, Value;
|
||||
|
||||
bindings.clear();
|
||||
std::vector<std::string> PathItems = uCentral::Utils::Split(Path,'/');
|
||||
std::vector<std::string> ParamItems = uCentral::Utils::Split(Request,'/');
|
||||
std::vector<std::string> PathItems = uCentral::Utils::Split(Request, '/');
|
||||
|
||||
if(PathItems.size()!=ParamItems.size())
|
||||
return false;
|
||||
for(const auto &EndPoint:EndPoints) {
|
||||
std::vector<std::string> ParamItems = uCentral::Utils::Split(EndPoint, '/');
|
||||
if (PathItems.size() != ParamItems.size())
|
||||
continue;
|
||||
|
||||
for(auto i=0;i!=PathItems.size();i++) {
|
||||
if (PathItems[i] != ParamItems[i]) {
|
||||
if (PathItems[i][0] == '{') {
|
||||
auto ParamName = PathItems[i].substr(1, PathItems[i].size() - 2);
|
||||
bindings[ParamName] = ParamItems[i];
|
||||
} else
|
||||
return false;
|
||||
bool Matched = true;
|
||||
for (auto i = 0; i != PathItems.size() && Matched; i++) {
|
||||
// std::cout << "PATH:" << PathItems[i] << " ENDPOINT:" << ParamItems[i] << std::endl;
|
||||
if (PathItems[i] != ParamItems[i]) {
|
||||
if (ParamItems[i][0] == '{') {
|
||||
auto ParamName = ParamItems[i].substr(1, ParamItems[i].size() - 2);
|
||||
bindings[ParamName] = PathItems[i];
|
||||
} else {
|
||||
Matched = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(Matched)
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void RESTAPIHandler::PrintBindings() {
|
||||
@@ -242,7 +248,7 @@ namespace uCentral {
|
||||
|
||||
bool RESTAPIHandler::IsAuthorized(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (AuthService()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
|
||||
if (uCentral::AuthService()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
|
||||
return true;
|
||||
} else {
|
||||
UnAuthorized(Request, Response);
|
||||
@@ -253,7 +259,7 @@ namespace uCentral {
|
||||
bool RESTAPIHandler::IsAuthorized(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response, std::string &UserName) {
|
||||
|
||||
if (AuthService()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
|
||||
if (uCentral::AuthService()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
|
||||
UserName = UserInfo_.username_;
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -19,25 +19,24 @@
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
#include "RESTAPI_objects.h"
|
||||
#include "AuthService.h"
|
||||
#include "RESTAPI_objects.h"
|
||||
|
||||
namespace uCentral {
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
class RESTAPIHandler : public Poco::Net::HTTPRequestHandler {
|
||||
public:
|
||||
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;
|
||||
};
|
||||
typedef std::map<std::string, std::string> BindingMap;
|
||||
|
||||
RESTAPIHandler(BindingMap map, Poco::Logger &l, std::vector<std::string> Methods)
|
||||
: Bindings_(std::move(map)), Logger_(l), Methods_(std::move(Methods)) {}
|
||||
|
||||
static bool ParseBindings(const std::string & Path, const std::string & Request, BindingMap &Keys);
|
||||
static bool ParseBindings(const std::string & Request, const std::list<const char *> & EndPoints, BindingMap &Keys);
|
||||
void PrintBindings();
|
||||
void ParseParameters(Poco::Net::HTTPServerRequest &request);
|
||||
|
||||
@@ -94,14 +93,52 @@ namespace uCentral {
|
||||
[[nodiscard]] static uint64_t GetWhen(const Poco::JSON::Object::Ptr &Obj);
|
||||
|
||||
protected:
|
||||
BindingMap Bindings_;
|
||||
Poco::URI::QueryParameters Parameters_;
|
||||
BindingMap Bindings_;
|
||||
Poco::URI::QueryParameters Parameters_;
|
||||
Poco::Logger &Logger_;
|
||||
std::string SessionToken_;
|
||||
struct uCentral::Objects::WebToken UserInfo_;
|
||||
std::vector<std::string> Methods_;
|
||||
QueryBlock QB_;
|
||||
};
|
||||
|
||||
class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_UnknownRequestHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
|
||||
: RESTAPIHandler(bindings, L, std::vector<std::string>{}) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) override {
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
constexpr auto test_has_PathName_method(T*)
|
||||
-> decltype( T::PathName() , std::true_type{} )
|
||||
{
|
||||
return std::true_type{};
|
||||
}
|
||||
constexpr auto test_has_PathName_method(...) -> std::false_type
|
||||
{
|
||||
return std::false_type{};
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
RESTAPIHandler * RESTAPI_Router(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings, Poco::Logger & Logger) {
|
||||
static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method.");
|
||||
if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) {
|
||||
return new T(Bindings, Logger);
|
||||
}
|
||||
|
||||
if constexpr (sizeof...(Args) == 0) {
|
||||
return new RESTAPI_UnknownRequestHandler(Bindings,Logger);
|
||||
} else {
|
||||
return RESTAPI_Router<Args...>(RequestedPath, Bindings, Logger);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //UCENTRAL_RESTAPI_HANDLER_H
|
||||
|
||||
@@ -8,55 +8,57 @@
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "AuthService.h"
|
||||
#include "RESTAPI_oauth2Handler.h"
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "AuthService.h"
|
||||
|
||||
namespace uCentral {
|
||||
void RESTAPI_oauth2Handler::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
void RESTAPI_oauth2Handler::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
try {
|
||||
if (Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
|
||||
// Extract the info for login...
|
||||
Poco::JSON::Parser parser;
|
||||
Poco::JSON::Object::Ptr Obj = parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
try {
|
||||
if (Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
|
||||
auto userId = GetS(uCentral::RESTAPI::Protocol::USERID, Obj);
|
||||
auto password = GetS(uCentral::RESTAPI::Protocol::PASSWORD, Obj);
|
||||
// Extract the info for login...
|
||||
Poco::JSON::Parser parser;
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
Poco::toLowerInPlace(userId);
|
||||
uCentral::Objects::WebToken Token;
|
||||
auto userId = GetS(uCentral::RESTAPI::Protocol::USERID, Obj);
|
||||
auto password = GetS(uCentral::RESTAPI::Protocol::PASSWORD, Obj);
|
||||
|
||||
if (AuthService()->Authorize(userId, password, Token)) {
|
||||
Poco::JSON::Object ReturnObj;
|
||||
Token.to_json(ReturnObj);
|
||||
ReturnObject(Request, ReturnObj, Response);
|
||||
} else {
|
||||
UnAuthorized(Request, Response);
|
||||
}
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_DELETE) {
|
||||
if (!IsAuthorized(Request, Response)) {
|
||||
return;
|
||||
}
|
||||
auto Token = GetBinding(uCentral::RESTAPI::Protocol::TOKEN, "...");
|
||||
if (Token == SessionToken_) {
|
||||
AuthService()->Logout(Token);
|
||||
ReturnStatus(Request, Response, Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
|
||||
} else {
|
||||
NotFound(Request, Response);
|
||||
}
|
||||
} else {
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch (const Poco::Exception &E) {
|
||||
Logger_.warning(Poco::format("%s: Failed with: %s", std::string(__func__), E.displayText()));
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
Poco::toLowerInPlace(userId);
|
||||
uCentral::Objects::WebToken Token;
|
||||
|
||||
if (AuthService()->Authorize(userId, password, Token)) {
|
||||
Poco::JSON::Object ReturnObj;
|
||||
Token.to_json(ReturnObj);
|
||||
ReturnObject(Request, ReturnObj, Response);
|
||||
} else {
|
||||
UnAuthorized(Request, Response);
|
||||
}
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_DELETE) {
|
||||
if (!IsAuthorized(Request, Response)) {
|
||||
return;
|
||||
}
|
||||
auto Token = GetBinding(uCentral::RESTAPI::Protocol::TOKEN, "...");
|
||||
if (Token == SessionToken_) {
|
||||
AuthService()->Logout(Token);
|
||||
ReturnStatus(Request, Response, Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
|
||||
} else {
|
||||
NotFound(Request, Response);
|
||||
}
|
||||
} else {
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.warning(
|
||||
Poco::format("%s: Failed with: %s", std::string(__func__), E.displayText()));
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
}
|
||||
@@ -12,17 +12,16 @@
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
class RESTAPI_oauth2Handler : public uCentral::RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_oauth2Handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>
|
||||
{Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
|
||||
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response) override;
|
||||
};
|
||||
class RESTAPI_oauth2Handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_oauth2Handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; };
|
||||
};
|
||||
}
|
||||
|
||||
#endif //UCENTRAL_RESTAPI_OAUTH2HANDLER_H
|
||||
|
||||
@@ -8,11 +8,7 @@
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
|
||||
#include "Daemon.h"
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "RESTAPI_objects.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral::Objects {
|
||||
|
||||
@@ -44,5 +40,94 @@ namespace uCentral::Objects {
|
||||
Obj.set("username",username_);
|
||||
Obj.set("aclTemplate",AclTemplateObj);
|
||||
}
|
||||
|
||||
void UserInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
Obj.set("Id",Id);
|
||||
Obj.set("name",name);
|
||||
Obj.set("description", description);
|
||||
Obj.set("avatar", avatar);
|
||||
Obj.set("email", email);
|
||||
Obj.set("validated", validated);
|
||||
Obj.set("validationEmail", validationEmail);
|
||||
Obj.set("validationDate", validationDate);
|
||||
Obj.set("creationDate", creationDate);
|
||||
Obj.set("validationURI", validationURI);
|
||||
Obj.set("changePassword", changePassword);
|
||||
Obj.set("lastLogin", lastLogin);
|
||||
Obj.set("currentLoginURI", currentLoginURI);
|
||||
Obj.set("lastPasswordChange", lastPasswordChange);
|
||||
Obj.set("lastEmailCheck", lastEmailCheck);
|
||||
Obj.set("waitingForEmailCheck", waitingForEmailCheck);
|
||||
Obj.set("locale", locale);
|
||||
Obj.set("notes", notes);
|
||||
Obj.set("location", location);
|
||||
Obj.set("owner", owner);
|
||||
Obj.set("suspended", suspended);
|
||||
Obj.set("blackListed", blackListed);
|
||||
Obj.set("userRole", userRole);
|
||||
Obj.set("userTypeProprietaryInfo", userTypeProprietaryInfo);
|
||||
Obj.set("securityPolicy", securityPolicy);
|
||||
Obj.set("securityPolicyChange", securityPolicyChange);
|
||||
};
|
||||
|
||||
bool UserInfo::from_json(Poco::JSON::Object::Ptr Obj) {
|
||||
try {
|
||||
if(Obj->has("Id"))
|
||||
Id = Obj->get("Id");
|
||||
if(Obj->has("name"))
|
||||
name = Obj->get("name").toString();
|
||||
if(Obj->has("description"))
|
||||
description = Obj->get("description").toString();
|
||||
if(Obj->has("avatar"))
|
||||
avatar = Obj->get("avatar").toString();
|
||||
if(Obj->has("email"))
|
||||
email = Obj->get("email").toString();
|
||||
if(Obj->has("validationEmail"))
|
||||
validationEmail = Obj->get("validationEmail").toString();
|
||||
if(Obj->has("validationURI"))
|
||||
validationURI = Obj->get("validationURI").toString();
|
||||
if(Obj->has("currentLoginURI"))
|
||||
currentLoginURI = Obj->get("currentLoginURI").toString();
|
||||
if(Obj->has("locale"))
|
||||
locale = Obj->get("locale").toString();
|
||||
if(Obj->has("notes"))
|
||||
notes = Obj->get("notes").toString();
|
||||
if(Obj->has("userRole"))
|
||||
userRole = Obj->get("userRole").toString();
|
||||
if(Obj->has("securityPolicy"))
|
||||
securityPolicy = Obj->get("securityPolicy").toString();
|
||||
if(Obj->has("userTypeProprietaryInfo"))
|
||||
description = Obj->get("userTypeProprietaryInfo").toString();
|
||||
if(Obj->has("description"))
|
||||
description = Obj->get("description").toString();
|
||||
if(Obj->has("validationDate"))
|
||||
validationDate = Obj->get("validationDate");
|
||||
if(Obj->has("creationDate"))
|
||||
creationDate = Obj->get("creationDate");
|
||||
if(Obj->has("lastLogin"))
|
||||
lastLogin = Obj->get("lastLogin");
|
||||
if(Obj->has("lastPasswordChange"))
|
||||
lastPasswordChange = Obj->get("lastPasswordChange");
|
||||
if(Obj->has("lastEmailCheck"))
|
||||
lastEmailCheck = Obj->get("lastEmailCheck");
|
||||
if(Obj->has("securityPolicyChange"))
|
||||
securityPolicyChange = Obj->get("securityPolicyChange");
|
||||
if(Obj->has("validated"))
|
||||
validated = (Obj->get("validated").toString() == "true");
|
||||
if(Obj->has("changePassword"))
|
||||
changePassword = (Obj->get("changePassword").toString() == "true");
|
||||
if(Obj->has("waitingForEmailCheck"))
|
||||
waitingForEmailCheck = (Obj->get("waitingForEmailCheck").toString() == "true");
|
||||
if(Obj->has("suspended"))
|
||||
suspended = (Obj->get("suspended").toString() == "true");
|
||||
if(Obj->has("blackListed"))
|
||||
blackListed = (Obj->get("blackListed").toString() == "true");
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -13,27 +13,61 @@
|
||||
|
||||
namespace uCentral::Objects {
|
||||
|
||||
struct AclTemplate {
|
||||
bool Read_ = true ;
|
||||
bool ReadWrite_ = true ;
|
||||
bool ReadWriteCreate_ = true ;
|
||||
bool Delete_ = true ;
|
||||
bool PortalLogin_ = true ;
|
||||
void to_json(Poco::JSON::Object &Obj) const ;
|
||||
};
|
||||
struct AclTemplate {
|
||||
bool Read_ = true;
|
||||
bool ReadWrite_ = true;
|
||||
bool ReadWriteCreate_ = true;
|
||||
bool Delete_ = true;
|
||||
bool PortalLogin_ = true;
|
||||
|
||||
struct WebToken {
|
||||
std::string access_token_;
|
||||
std::string refresh_token_;
|
||||
std::string id_token_;
|
||||
std::string token_type_;
|
||||
std::string username_;
|
||||
unsigned int expires_in_;
|
||||
unsigned int idle_timeout_;
|
||||
AclTemplate acl_template_;
|
||||
uint64_t created_;
|
||||
void to_json(Poco::JSON::Object &Obj) const ;
|
||||
};
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct WebToken {
|
||||
std::string access_token_;
|
||||
std::string refresh_token_;
|
||||
std::string id_token_;
|
||||
std::string token_type_;
|
||||
std::string username_;
|
||||
unsigned int expires_in_;
|
||||
unsigned int idle_timeout_;
|
||||
AclTemplate acl_template_;
|
||||
uint64_t created_;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct UserInfo {
|
||||
uint64_t Id = 0;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string avatar;
|
||||
std::string email;
|
||||
bool validated = false;
|
||||
std::string validationEmail;
|
||||
uint64_t validationDate = 0;
|
||||
uint64_t creationDate = 0;
|
||||
std::string validationURI;
|
||||
bool changePassword = true;
|
||||
uint64_t lastLogin = 0;
|
||||
std::string currentLoginURI;
|
||||
uint64_t lastPasswordChange = 0;
|
||||
uint64_t lastEmailCheck = 0;
|
||||
bool waitingForEmailCheck = false;
|
||||
std::string locale;
|
||||
std::string notes;
|
||||
std::string location;
|
||||
std::string owner;
|
||||
bool suspended = false;
|
||||
bool blackListed = false;
|
||||
std::string userRole;
|
||||
std::string userTypeProprietaryInfo;
|
||||
std::string securityPolicy;
|
||||
uint64_t securityPolicyChange;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr Obj);
|
||||
};
|
||||
}
|
||||
|
||||
#endif //UCENTRAL_RESTAPI_OBJECTS_H
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "RESTAPI_server.h"
|
||||
#include "RESTAPI_oauth2Handler.h"
|
||||
#include "RESTAPI_unknownRequestHandler.h"
|
||||
#include "RESTAPI_system_command.h"
|
||||
#include "RESTAPI_user_handler.h"
|
||||
#include "RESTAPI_users_handler.h"
|
||||
@@ -58,24 +57,15 @@ namespace uCentral {
|
||||
|
||||
Poco::URI uri(Request.getURI());
|
||||
const auto & Path = uri.getPath();
|
||||
RESTAPIHandler::BindingMap bindings;
|
||||
RESTAPIHandler::BindingMap Bindings;
|
||||
|
||||
if (RESTAPIHandler::ParseBindings(Path, "/api/v1/oauth2/{token}", bindings)) {
|
||||
return new RESTAPI_oauth2Handler(bindings, Logger_);
|
||||
} else if (RESTAPIHandler::ParseBindings(Path, "/api/v1/oauth2", bindings)) {
|
||||
return new RESTAPI_oauth2Handler(bindings, Logger_);
|
||||
} else if (RESTAPIHandler::ParseBindings(Path, "/api/v1/users", bindings)) {
|
||||
return new RESTAPI_users_handler(bindings, Logger_);
|
||||
} else if (RESTAPIHandler::ParseBindings(Path, "/api/v1/user", bindings)) {
|
||||
return new RESTAPI_user_handler(bindings, Logger_);
|
||||
} else if (RESTAPIHandler::ParseBindings(Path, "/api/v1/system", bindings)) {
|
||||
return new RESTAPI_system_command(bindings, Logger_);
|
||||
} else if (RESTAPIHandler::ParseBindings(Path, "/api/v1/actions", bindings)) {
|
||||
return new RESTAPI_action_links(bindings, Logger_);
|
||||
}
|
||||
|
||||
Logger_.error(Poco::format("INVALID-API-ENDPOINT: %s",Path));
|
||||
return new RESTAPI_UnknownRequestHandler(bindings,Logger_);
|
||||
return RESTAPI_Router<
|
||||
RESTAPI_oauth2Handler,
|
||||
RESTAPI_users_handler,
|
||||
RESTAPI_user_handler,
|
||||
RESTAPI_system_command,
|
||||
RESTAPI_action_links
|
||||
>(Path,Bindings,Logger_);
|
||||
}
|
||||
|
||||
void RESTAPI_Server::Stop() {
|
||||
|
||||
11
src/RESTAPI_systemServices_handler.cpp
Normal file
11
src/RESTAPI_systemServices_handler.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-28.
|
||||
//
|
||||
|
||||
#include "RESTAPI_systemServices_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
void RESTAPI_systemServices_handler::handleRequest(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
}
|
||||
}
|
||||
27
src/RESTAPI_systemServices_handler.h
Normal file
27
src/RESTAPI_systemServices_handler.h
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-28.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALSEC_RESTAPI_SYSTEMSERVICES_HANDLER_H
|
||||
#define UCENTRALSEC_RESTAPI_SYSTEMSERVICES_HANDLER_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
class RESTAPI_systemServices_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_systemServices_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>
|
||||
{Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) override;
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //UCENTRALSEC_RESTAPI_SYSTEMSERVICES_HANDLER_H
|
||||
@@ -20,6 +20,7 @@ class RESTAPI_system_command : public RESTAPIHandler {
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/system"}; };
|
||||
};
|
||||
}
|
||||
#endif // UCENTRALGW_RESTAPI_SYSTEM_COMMAND_H
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
//
|
||||
// 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 "RESTAPI_unknownRequestHandler.h"
|
||||
|
||||
void RESTAPI_UnknownRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response)
|
||||
{
|
||||
if(!IsAuthorized(Request,Response))
|
||||
return;
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
//
|
||||
// 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 UCENTRAL_RESTAPI_UNKNOWNREQUESTHANDLER_H
|
||||
#define UCENTRAL_RESTAPI_UNKNOWNREQUESTHANDLER_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
class RESTAPI_UnknownRequestHandler: public uCentral::RESTAPIHandler
|
||||
{
|
||||
public:
|
||||
RESTAPI_UnknownRequestHandler(const RESTAPIHandler::BindingMap & bindings,Poco::Logger & L)
|
||||
: RESTAPIHandler(bindings,L,
|
||||
std::vector<std::string>{}) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //UCENTRAL_RESTAPI_UNKNOWNREQUESTHANDLER_H
|
||||
@@ -19,6 +19,8 @@ namespace uCentral {
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/user/{id}"}; };
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
@@ -16,8 +16,7 @@ namespace uCentral {
|
||||
{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) override;
|
||||
private:
|
||||
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/users"}; };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -45,6 +45,39 @@ namespace uCentral {
|
||||
PASSWORD_INVALID
|
||||
};
|
||||
|
||||
enum USER_TYPE {
|
||||
UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, SPECIAL
|
||||
};
|
||||
|
||||
static USER_TYPE to_userType(const std::string &U) {
|
||||
if (U=="root")
|
||||
return ROOT;
|
||||
else if (U=="admin")
|
||||
return ADMIN;
|
||||
else if (U=="subscriber")
|
||||
return SUBSCRIBER;
|
||||
else if (U=="csr")
|
||||
return CSR;
|
||||
else if (U=="system")
|
||||
return SYSTEM;
|
||||
else if (U=="SPECIAL")
|
||||
return SPECIAL;
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
static const std::string from_userType(USER_TYPE U) {
|
||||
switch(U) {
|
||||
case ROOT: return "root";
|
||||
case ADMIN: return "admin";
|
||||
case SUBSCRIBER: return "subscriber";
|
||||
case CSR: return "csr";
|
||||
case SYSTEM: return "system";
|
||||
case SPECIAL: return "special";
|
||||
case UNKNOWN:
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static Storage *instance() {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new Storage;
|
||||
@@ -55,9 +88,25 @@ namespace uCentral {
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
|
||||
int CreateUser(const std::string & Admin, const std::string &UserName, const std::string &Password);
|
||||
bool DeleteUser(const std::string & Admin, const std::string &UserName);
|
||||
bool ChangePassword(const std::string & Admin, const std::string &UserName, const std::string &OldPassword, const std::string &NewPassword);
|
||||
// all passwords passed here are all plaintext
|
||||
bool CreateUser(const std::string & Admin, uCentral::Objects::UserInfo & NewUser);
|
||||
bool DeleteUser(const std::string & Admin, uint64_t Id);
|
||||
bool SetOwner(const std::string & Admin, uint64_t Id, const std::string &Owner);
|
||||
bool SetLocation(const std::string & Admin, uint64_t Id, const std::string &Location);
|
||||
AUTH_ERROR ChangePassword(const std::string & Admin, uint64_t Id, const std::string &OldPassword, const std::string &NewPassword);
|
||||
bool AddNotes(const std::string & Admin, uint64_t Id, const std::string &Notes);
|
||||
bool SetPolicyChange(const std::string & Admin, const std::string &NewPolicy);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool IdentityExists(std::string & Identity, AuthService::ACCESS_TYPE Type);
|
||||
bool AddIdentity(std::string & Identity, std::string & Password, AuthService::ACCESS_TYPE Type, uCentral::Objects::AclTemplate & ACL);
|
||||
|
||||
@@ -360,12 +360,13 @@ namespace uCentral::Utils {
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t InitializeSystemId() {
|
||||
uint64_t R = ~ std::rand();
|
||||
auto S = GetDefaultMacAsInt64() ^ R;
|
||||
SaveSystemId(S);
|
||||
return S;
|
||||
}
|
||||
uint64_t InitializeSystemId() {
|
||||
std::srand(std::time(nullptr));
|
||||
auto S = GetDefaultMacAsInt64() ^ std::rand();
|
||||
SaveSystemId(S);
|
||||
std::cout << "ID: " << S << std::endl;
|
||||
return S;
|
||||
}
|
||||
|
||||
uint64_t GetSystemId() {
|
||||
uint64_t ID=0;
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "Poco/Net/NetworkInterface.h"
|
||||
|
||||
#define DBGLINE { std::cout << __FILE__ << ":" << __func__ << ":" << __LINE__ << std::endl; };
|
||||
|
||||
namespace uCentral::Utils {
|
||||
|
||||
[[nodiscard]] std::vector<std::string> Split(const std::string &List, char Delimiter=',');
|
||||
|
||||
@@ -41,7 +41,9 @@ namespace uCentral {
|
||||
"owner varchar, "
|
||||
"suspended int, "
|
||||
"blackListed int, "
|
||||
"userType varchar, "
|
||||
"userRole varchar, "
|
||||
"securityPolicy text, "
|
||||
"securityPolicyChange bigint, "
|
||||
"userTypeProprietaryInfo text"
|
||||
" ,INDEX emailindex (email ASC)"
|
||||
" ,INDEX nameindex (name ASC))",
|
||||
@@ -72,7 +74,9 @@ namespace uCentral {
|
||||
"owner varchar, "
|
||||
"suspended int, "
|
||||
"blackListed int, "
|
||||
"userType varchar, "
|
||||
"userRole varchar, "
|
||||
"securityPolicy text, "
|
||||
"securityPolicyChange bigint, "
|
||||
"userTypeProprietaryInfo text"
|
||||
")",
|
||||
Poco::Data::Keywords::now;
|
||||
|
||||
38
src/storage_users.cpp
Normal file
38
src/storage_users.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-25.
|
||||
//
|
||||
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace uCentral {
|
||||
|
||||
bool Storage::CreateUser(const std::string & Admin, uCentral::Objects::UserInfo & NewUser) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Storage::DeleteUser(const std::string & Admin, uint64_t Id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Storage::SetOwner(const std::string & Admin, uint64_t Id, const std::string &Owner) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Storage::SetLocation(const std::string & Admin, uint64_t Id, const std::string &Location) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Storage::AUTH_ERROR Storage::ChangePassword(const std::string & Admin, uint64_t Id, const std::string &OldPassword, const std::string &NewPassword) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
bool Storage::AddNotes(const std::string & Admin, uint64_t Id, const std::string &Notes) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Storage::SetPolicyChange(const std::string & Admin, const std::string &NewPolicy) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace uCentral::Types {
|
||||
typedef std::vector<std::string> StringVec;
|
||||
typedef std::vector<SubSystemServer*> SubSystemVec;
|
||||
typedef std::map<std::string,std::set<std::string>> StringMapStringSet;
|
||||
typedef std::function<void(std::string,std::string)> TopicNotifyFunction;
|
||||
typedef std::function<void(std::string, std::string)> TopicNotifyFunction;
|
||||
typedef std::list<std::pair<TopicNotifyFunction,int>> TopicNotifyFunctionList;
|
||||
typedef std::map<std::string, TopicNotifyFunctionList> NotifyTable;
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ 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.port = 16002
|
||||
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
|
||||
@@ -27,14 +27,12 @@ authentication.default.username = tip@ucentral.com
|
||||
authentication.default.password = openwifi
|
||||
authentication.default.access = master
|
||||
authentication.service.type = internal
|
||||
firmware.autoupdate.policy.default = auto
|
||||
system.directory.data = $UCENTRALSEC_ROOT/data
|
||||
|
||||
ucentral.service.key = $UCENTRALSEC_ROOT/certs/restapi-key.pem
|
||||
ucentral.system.debug = true
|
||||
ucentral.system.uri = https://localhost:16001
|
||||
ucentral.system.id = 1
|
||||
ucentral.system.commandchannel = /tmp/app.ucentralgw
|
||||
ucentral.system.uri = https://localhost:16002
|
||||
ucentral.system.commandchannel = /tmp/app.ucentralsec
|
||||
|
||||
mailer.hostname = smtp.gmail.com
|
||||
mailer.username = no-reply@arilia.com
|
||||
@@ -45,8 +43,9 @@ mailer.port = 587
|
||||
#
|
||||
# Kafka
|
||||
#
|
||||
ucentral.kafka.enable = false
|
||||
ucentral.kafka.brokerlist = 127.0.0.1:9092
|
||||
ucentral.kafka.group.id = 3
|
||||
ucentral.kafka.enable = true
|
||||
ucentral.kafka.brokerlist = a1.arilia.com:9092
|
||||
ucentral.kafka.auto.commit = false
|
||||
ucentral.kafka.queue.buffering.max.ms = 50
|
||||
|
||||
@@ -60,7 +59,7 @@ storage.type = sqlite
|
||||
#storage.type = mysql
|
||||
#storage.type = odbc
|
||||
|
||||
storage.type.sqlite.db = $UCENTRALSEC_ROOT/security.db
|
||||
storage.type.sqlite.db = security.db
|
||||
storage.type.sqlite.idletime = 120
|
||||
storage.type.sqlite.maxsessions = 128
|
||||
|
||||
@@ -91,11 +90,11 @@ authentication.default.password = 13268b7daa751240369d125e79c873bd8dd3bef7981bdf
|
||||
authentication.default.access = master
|
||||
authentication.service.type = internal
|
||||
|
||||
system.directory.data = $UCENTRALSEC_ROOT/data
|
||||
|
||||
ucentral.system.data = $UCENTRALSEC_ROOT/data
|
||||
ucentral.system.debug = true
|
||||
ucentral.system.uri = https://localhost:16001
|
||||
ucentral.system.commandchannel = /tmp/app.ucentralgw
|
||||
ucentral.system.uri.private = https://localhost:16002
|
||||
ucentral.system.uri.public = https://local.dpaas.arilia.com:16002
|
||||
ucentral.system.commandchannel = /tmp/app.ucentralsec
|
||||
|
||||
# email.includeonly = mydomain.com
|
||||
# email.exclude = gmail.com
|
||||
|
||||
Reference in New Issue
Block a user