Подписанная PGP ключом ДС Created сделка сначала должна отправляться по bitmessage, затем должна быть отдана МС.
This commit is contained in:
@@ -50,7 +50,6 @@ namespace Apostol {
|
||||
|
||||
CWebService::CWebService(CModuleProcess *AProcess): CApostolModule(AProcess, "web service", "module/WebService") {
|
||||
m_NexServerTime = 0;
|
||||
m_ServerIndex = -1;
|
||||
m_SyncPeriod = BPS_DEFAULT_SYNC_PERIOD;
|
||||
m_Status = psStopped;
|
||||
|
||||
@@ -122,125 +121,34 @@ namespace Apostol {
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebService::FetchOAuth2(CContext &Context) {
|
||||
|
||||
Log()->Debug(APP_LOG_DEBUG_CORE, "Trying to fetch a OAuth2 configuration file for module \"%s\" from: %s", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
|
||||
auto OnRequest = [this, &Context](CHTTPClient *Sender, CHTTPRequest *ARequest) {
|
||||
|
||||
ARequest->ContentType = CHTTPRequest::text;
|
||||
|
||||
Apostol::PGP::CleartextSignature(
|
||||
m_pgpPrivateKey,
|
||||
m_pgpPassphrase,
|
||||
BPS_PGP_HASH,
|
||||
Context.Name(),
|
||||
ARequest->Content);
|
||||
|
||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/service");
|
||||
|
||||
const auto& caModuleAddress = m_Module["address"];
|
||||
if (!caModuleAddress.IsEmpty())
|
||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||
|
||||
DebugRequest(ARequest);
|
||||
};
|
||||
|
||||
auto OnExecute = [this, &Context](CTCPConnection *AConnection) {
|
||||
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
|
||||
if (pConnection != nullptr) {
|
||||
auto pReply = pConnection->Reply();
|
||||
|
||||
DebugReply(pReply);
|
||||
|
||||
if (Context.Status() == Context::csPreparing) {
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
const CJSON Json(pReply->Content);
|
||||
Json.SaveToFile(m_OAuth2.c_str());
|
||||
UpdateOAuth2(m_OAuth2);
|
||||
} else {
|
||||
Context.SetStatus(Context::csInitialization);
|
||||
}
|
||||
}
|
||||
|
||||
pConnection->CloseConnection(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto OnException = [&Context](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
if (pConnection != nullptr) {
|
||||
auto pClient = dynamic_cast<CHTTPClient *> (pConnection->Client());
|
||||
if (pClient != nullptr) {
|
||||
Log()->Error(APP_LOG_EMERG, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
|
||||
}
|
||||
DebugReply(pConnection->Reply());
|
||||
}
|
||||
|
||||
Context.SetStatus(Context::csInitialization);
|
||||
};
|
||||
|
||||
Context.SetStatus(Context::csPreparing);
|
||||
|
||||
auto pClient = GetClient(Context.URL().hostname, Context.URL().port == 0 ? BPS_SERVER_PORT : Context.URL().port);
|
||||
|
||||
pClient->OnRequest(OnRequest);
|
||||
pClient->OnExecute(OnExecute);
|
||||
pClient->OnException(OnException);
|
||||
|
||||
pClient->AutoFree(true);
|
||||
pClient->Active(true);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebService::UpdateOAuth2(const CString &FileName) {
|
||||
for (int i = 0; i < m_Servers.Count(); i++) {
|
||||
auto &Context = m_Servers[i].Value();
|
||||
if (Context.Status() == Context::csInitialization || Context.Status() == Context::csPreparing) {
|
||||
if (LoadOAuth2(FileName, Context.Providers())) {
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
Context.SetCheckDate(0);
|
||||
} else {
|
||||
if (Context.Status() != Context::csPreparing) {
|
||||
FetchOAuth2(Context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool CWebService::LoadOAuth2(const CString &FileName, CProviders &Providers) {
|
||||
const auto &caProviderName = CString(SYSTEM_PROVIDER_NAME);
|
||||
const auto &caApplicationName = CString(SERVICE_APPLICATION_NAME);
|
||||
|
||||
if (FileExists(FileName.c_str())) {
|
||||
CJSONObject Json;
|
||||
Json.LoadFromFile(FileName.c_str());
|
||||
|
||||
int index = Providers.IndexOfName(caProviderName);
|
||||
if (index == -1)
|
||||
index = Providers.AddPair(caProviderName, CProvider(caProviderName));
|
||||
auto& Provider = Providers[index].Value();
|
||||
Provider.Applications().AddPair(caApplicationName, Json);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebService::CheckKeyForNull(LPCTSTR Key, LPCTSTR Value) {
|
||||
if (Value == nullptr)
|
||||
throw ExceptionFrm("Invalid format: key \"%s\" cannot be empty.", Key);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebService::UpdateOAuth2(CContext &Context, const CJSONObject &OAuth2) {
|
||||
if (OAuth2["type"].AsString() == "service_account") {
|
||||
UpdateProviders(Context.Providers(), OAuth2);
|
||||
|
||||
Context.SetCheckDate(0);
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebService::UpdateProviders(CProviders &Providers, const CJSONObject &Data) {
|
||||
const auto &caProviderName = CString(SYSTEM_PROVIDER_NAME);
|
||||
const auto &caApplicationName = CString(SERVICE_APPLICATION_NAME);
|
||||
|
||||
int index = Providers.IndexOfName(caProviderName);
|
||||
if (index == -1)
|
||||
index = Providers.AddPair(caProviderName, CProvider(caProviderName));
|
||||
auto& Provider = Providers[index].Value();
|
||||
Provider.Applications().AddPair(caApplicationName, Data);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool CWebService::FindURLInLine(const CString &Line, CStringList &List) {
|
||||
CString URL;
|
||||
|
||||
@@ -726,7 +634,7 @@ namespace Apostol {
|
||||
sPayload = caClearText.Text();
|
||||
} else {
|
||||
Apostol::PGP::CleartextSignature(
|
||||
m_pgpPrivateKey,
|
||||
m_pgpModuleKey,
|
||||
m_pgpPassphrase,
|
||||
BPS_PGP_HASH,
|
||||
caClearText.Text(),
|
||||
@@ -1174,7 +1082,7 @@ namespace Apostol {
|
||||
sPayload = caClearText;
|
||||
} else {
|
||||
Apostol::PGP::CleartextSignature(
|
||||
m_pgpPrivateKey,
|
||||
m_pgpModuleKey,
|
||||
m_pgpPassphrase,
|
||||
BPS_PGP_HASH,
|
||||
caClearText,
|
||||
@@ -1612,7 +1520,7 @@ namespace Apostol {
|
||||
|
||||
void CWebService::FetchPGP(CContext &Context) {
|
||||
|
||||
Log()->Debug(APP_LOG_DEBUG_CORE, "Trying to fetch a PGP key \"%s\" from: %s", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
Log()->Notice("[%s] [%s] Trying to fetch a PGP key.", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
|
||||
auto OnRequest = [&Context](CHTTPClient *Sender, CHTTPRequest *ARequest) {
|
||||
|
||||
@@ -1699,28 +1607,348 @@ namespace Apostol {
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebService::ModuleService(CContext &Context) {
|
||||
|
||||
Log()->Notice("[%s] [%s] Trying to fetch a OAuth2 configuration file.", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
|
||||
auto OnRequest = [this, &Context](CHTTPClient *Sender, CHTTPRequest *ARequest) {
|
||||
|
||||
Context.SetStatus(Context::csPreparing);
|
||||
|
||||
ARequest->ContentType = CHTTPRequest::text;
|
||||
|
||||
Apostol::PGP::CleartextSignature(
|
||||
m_pgpModuleKey,
|
||||
m_pgpPassphrase,
|
||||
BPS_PGP_HASH,
|
||||
Context.Name(),
|
||||
ARequest->Content);
|
||||
|
||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/service");
|
||||
|
||||
const auto &caModuleAddress = m_Module["address"];
|
||||
if (!caModuleAddress.IsEmpty())
|
||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||
|
||||
DebugRequest(ARequest);
|
||||
};
|
||||
|
||||
auto OnExecute = [&Context](CTCPConnection *AConnection) {
|
||||
|
||||
Context.SetStatus(Context::csInitialization);
|
||||
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
|
||||
if (pConnection != nullptr) {
|
||||
auto pReply = pConnection->Reply();
|
||||
|
||||
DebugReply(pReply);
|
||||
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
const CJSON OAuth2(pReply->Content);
|
||||
UpdateOAuth2(Context, OAuth2.Object());
|
||||
}
|
||||
|
||||
pConnection->CloseConnection(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto OnException = [&Context](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
if (pConnection != nullptr) {
|
||||
auto pClient = dynamic_cast<CHTTPClient *> (pConnection->Client());
|
||||
if (pClient != nullptr) {
|
||||
Log()->Error(APP_LOG_EMERG, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
|
||||
}
|
||||
DebugReply(pConnection->Reply());
|
||||
}
|
||||
|
||||
Context.SetStatus(Context::csInitialization);
|
||||
};
|
||||
|
||||
auto pClient = GetClient(Context.URL().hostname, Context.URL().port == 0 ? BPS_SERVER_PORT : Context.URL().port);
|
||||
|
||||
pClient->OnRequest(OnRequest);
|
||||
pClient->OnExecute(OnExecute);
|
||||
pClient->OnException(OnException);
|
||||
|
||||
pClient->AutoFree(true);
|
||||
pClient->Active(true);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebService::ModuleStatus(CContext &Context) {
|
||||
|
||||
Log()->Notice("[%s] [%s] Trying get module status.", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
|
||||
auto OnRequest = [this, &Context](CHTTPClient *Sender, CHTTPRequest *ARequest) {
|
||||
|
||||
Context.SetStatus(Context::csInProgress);
|
||||
|
||||
const auto &caModuleAddress = m_Module["address"];
|
||||
|
||||
ARequest->ContentType = CHTTPRequest::text;
|
||||
|
||||
ARequest->Content.Format(R"({"address": "%s"})", caModuleAddress.c_str());
|
||||
|
||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/status");
|
||||
|
||||
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["access_token"]);
|
||||
|
||||
if (!caModuleAddress.IsEmpty())
|
||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||
|
||||
DebugRequest(ARequest);
|
||||
};
|
||||
|
||||
auto OnExecute = [this, &Context](CTCPConnection *AConnection) {
|
||||
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
|
||||
if (pConnection != nullptr) {
|
||||
auto pReply = pConnection->Reply();
|
||||
|
||||
DebugReply(pReply);
|
||||
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
ModuleAuthorize(Context);
|
||||
} else {
|
||||
ModuleNew(Context);
|
||||
}
|
||||
|
||||
pConnection->CloseConnection(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto OnException = [&Context](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
if (pConnection != nullptr) {
|
||||
auto pClient = dynamic_cast<CHTTPClient *> (pConnection->Client());
|
||||
if (pClient != nullptr) {
|
||||
Log()->Error(APP_LOG_EMERG, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
|
||||
}
|
||||
DebugReply(pConnection->Reply());
|
||||
}
|
||||
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
};
|
||||
|
||||
auto pClient = GetClient(Context.URL().hostname, Context.URL().port == 0 ? BPS_SERVER_PORT : Context.URL().port);
|
||||
|
||||
pClient->OnRequest(OnRequest);
|
||||
pClient->OnExecute(OnExecute);
|
||||
pClient->OnException(OnException);
|
||||
|
||||
pClient->AutoFree(true);
|
||||
pClient->Active(true);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebService::ModuleNew(CContext &Context) {
|
||||
|
||||
Log()->Notice("[%s] [%s] Trying create new module.", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
|
||||
auto OnRequest = [this, &Context](CHTTPClient *Sender, CHTTPRequest *ARequest) {
|
||||
|
||||
Context.SetStatus(Context::csInProgress);
|
||||
|
||||
ARequest->ContentType = CHTTPRequest::json;
|
||||
|
||||
const auto &caModuleAddress = m_Module["address"];
|
||||
|
||||
CJSON Json(jvtObject);
|
||||
|
||||
Json.Object().AddPair("address", caModuleAddress);
|
||||
Json.Object().AddPair("bitmessage", Context.Name());
|
||||
|
||||
const OpenPGP::SecretKey pgpSecret(m_pgpModuleKey.c_str());
|
||||
const auto &public_key = pgpSecret.get_public();
|
||||
|
||||
Json.Object().AddPair("pgp", public_key.write(OpenPGP::PGP::Armored::YES));
|
||||
|
||||
ARequest->Content = Json.ToString();
|
||||
|
||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/client/new");
|
||||
|
||||
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["access_token"]);
|
||||
|
||||
if (!caModuleAddress.IsEmpty())
|
||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||
|
||||
DebugRequest(ARequest);
|
||||
};
|
||||
|
||||
auto OnExecute = [this, &Context](CTCPConnection *AConnection) {
|
||||
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
|
||||
if (pConnection != nullptr) {
|
||||
auto pReply = pConnection->Reply();
|
||||
|
||||
DebugReply(pReply);
|
||||
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
const CJSON Json(pReply->Content);
|
||||
|
||||
if (Json.HasOwnProperty("result")) {
|
||||
const auto &caResult = Json["result"];
|
||||
if (caResult.HasOwnProperty("success")) {
|
||||
if (caResult["success"].AsBoolean()) {
|
||||
ModuleAuthorize(Context);
|
||||
} else {
|
||||
if (caResult.HasOwnProperty("message")) {
|
||||
Log()->Error(APP_LOG_EMERG, 0, "[%s] [%s] %s", Context.Name().c_str(),
|
||||
Context.URL().Origin().c_str(), caResult["message"].AsString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pConnection->CloseConnection(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto OnException = [&Context](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
if (pConnection != nullptr) {
|
||||
auto pClient = dynamic_cast<CHTTPClient *> (pConnection->Client());
|
||||
if (pClient != nullptr) {
|
||||
Log()->Error(APP_LOG_EMERG, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
|
||||
}
|
||||
DebugReply(pConnection->Reply());
|
||||
}
|
||||
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
};
|
||||
|
||||
auto pClient = GetClient(Context.URL().hostname, Context.URL().port == 0 ? BPS_SERVER_PORT : Context.URL().port);
|
||||
|
||||
pClient->OnRequest(OnRequest);
|
||||
pClient->OnExecute(OnExecute);
|
||||
pClient->OnException(OnException);
|
||||
|
||||
pClient->AutoFree(true);
|
||||
pClient->Active(true);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebService::ModuleAuthorize(CContext &Context) {
|
||||
|
||||
Log()->Notice("[%s] [%s] Trying authorize module.", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
|
||||
auto OnRequest = [this, &Context](CHTTPClient *Sender, CHTTPRequest *ARequest) {
|
||||
|
||||
Context.SetStatus(Context::csAuthorization);
|
||||
|
||||
ARequest->ContentType = CHTTPRequest::text;
|
||||
|
||||
Apostol::PGP::CleartextSignature(
|
||||
m_pgpModuleKey,
|
||||
m_pgpPassphrase,
|
||||
BPS_PGP_HASH,
|
||||
Context.Name(),
|
||||
ARequest->Content);
|
||||
|
||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/authorize");
|
||||
|
||||
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["access_token"]);
|
||||
|
||||
const auto &caModuleAddress = m_Module["address"];
|
||||
if (!caModuleAddress.IsEmpty())
|
||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||
|
||||
DebugRequest(ARequest);
|
||||
};
|
||||
|
||||
auto OnExecute = [&Context](CTCPConnection *AConnection) {
|
||||
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
|
||||
if (pConnection != nullptr) {
|
||||
auto pReply = pConnection->Reply();
|
||||
|
||||
DebugReply(pReply);
|
||||
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
const CJSON Json(pReply->Content);
|
||||
|
||||
Context.Session() = Json["session"].AsString();
|
||||
Context.Secret() = Json["secret"].AsString();
|
||||
|
||||
Context.Tokens().Values("access_token", Json["access_token"].AsString());
|
||||
|
||||
Context.SetFixedDate(0);
|
||||
Context.SetCheckDate(Now() + (CDateTime) 55 / MinsPerDay); // 55 min
|
||||
|
||||
Context.SetStatus(csAuthorized);
|
||||
}
|
||||
|
||||
pConnection->CloseConnection(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto OnException = [&Context](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
if (pConnection != nullptr) {
|
||||
auto pClient = dynamic_cast<CHTTPClient *> (pConnection->Client());
|
||||
if (pClient != nullptr) {
|
||||
Log()->Error(APP_LOG_EMERG, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
|
||||
}
|
||||
DebugReply(pConnection->Reply());
|
||||
}
|
||||
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
};
|
||||
|
||||
auto pClient = GetClient(Context.URL().hostname, Context.URL().port == 0 ? BPS_SERVER_PORT : Context.URL().port);
|
||||
|
||||
pClient->OnRequest(OnRequest);
|
||||
pClient->OnExecute(OnExecute);
|
||||
pClient->OnException(OnException);
|
||||
|
||||
pClient->AutoFree(true);
|
||||
pClient->Active(true);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebService::Reload() {
|
||||
Config()->IniFile().ReadSectionValues("module", &m_Module);
|
||||
|
||||
m_OAuth2 = Config()->IniFile().ReadString(CONFIG_SECTION_NAME, "oauth2", "oauth2/service.json");
|
||||
if (!path_separator(m_OAuth2.front())) {
|
||||
m_OAuth2 = Config()->Prefix() + m_OAuth2;
|
||||
CString FileName;
|
||||
|
||||
FileName = Config()->IniFile().ReadString(CONFIG_SECTION_NAME, "oauth2", "oauth2/service.json");
|
||||
if (!path_separator(FileName.front())) {
|
||||
FileName = Config()->Prefix() + FileName;
|
||||
}
|
||||
|
||||
const auto& caPrivateKey = Config()->IniFile().ReadString("pgp", "private", "module.sec");
|
||||
const auto& caPublicKey = Config()->IniFile().ReadString("pgp", "public", "dm.pub");
|
||||
if (FileExists(FileName.c_str())) {
|
||||
m_OAuth2.LoadFromFile(FileName.c_str());
|
||||
}
|
||||
|
||||
const auto &caPrivateKey = Config()->IniFile().ReadString("pgp", "private", "module.sec");
|
||||
const auto &caPublicKey = Config()->IniFile().ReadString("pgp", "public", "dm.pub");
|
||||
|
||||
m_pgpPassphrase = Config()->IniFile().ReadString("pgp", "passphrase", "");
|
||||
|
||||
if (FileExists(caPrivateKey.c_str())) {
|
||||
m_pgpPrivateKey.LoadFromFile(caPrivateKey.c_str());
|
||||
m_pgpModuleKey.LoadFromFile(caPrivateKey.c_str());
|
||||
|
||||
if (FileExists(caPublicKey.c_str())) {
|
||||
CString Key;
|
||||
Key.LoadFromFile(caPublicKey.c_str());
|
||||
|
||||
UpdateServerList(Key);
|
||||
UpdateOAuth2(m_OAuth2);
|
||||
m_pgpPublicKey.LoadFromFile(caPublicKey.c_str());
|
||||
UpdateServerList(m_pgpPublicKey);
|
||||
} else {
|
||||
Log()->Error(APP_LOG_WARN, 0, APP_FILE_NOT_FOUND, caPublicKey.c_str());
|
||||
}
|
||||
@@ -1734,23 +1962,21 @@ namespace Apostol {
|
||||
for (int i = 0; i < m_Servers.Count(); i++) {
|
||||
auto &Context = m_Servers[i].Value();
|
||||
|
||||
if ((Now >= Context.CheckDate()) && (Context.Status() == Context::csInitialization)) {
|
||||
Context.SetCheckDate(Now + (CDateTime) 30 / SecsPerDay); // 30 sec
|
||||
FetchOAuth2(Context);
|
||||
}
|
||||
|
||||
if ((Now >= Context.CheckDate()) && (Context.Status() >= Context::csInitialized)) {
|
||||
if (Now >= Context.CheckDate()) {
|
||||
Context.SetCheckDate(Now + (CDateTime) 30 / SecsPerDay); // 30 sec
|
||||
|
||||
if (Context.Status() == Context::csInitialized)
|
||||
Context.SetStatus(Context::csAuthorization);
|
||||
if (Context.Status() == Context::csInitialization) {
|
||||
ModuleService(Context);
|
||||
}
|
||||
|
||||
CheckProviders(Now, Context);
|
||||
FetchProviders(Now, Context);
|
||||
if (Context.Status() >= Context::csInitialized) {
|
||||
CheckProviders(Now, Context);
|
||||
FetchProviders(Now, Context);
|
||||
}
|
||||
}
|
||||
|
||||
if (Context.Status() == Context::csAuthorized) {
|
||||
if (Now >= Context.FixedDate()) {
|
||||
if (Now >= Context.FixedDate()) {
|
||||
if (Context.Status() == Context::csAuthorized) {
|
||||
Context.SetFixedDate(Now + (CDateTime) 30 / SecsPerDay); // 30 sec
|
||||
Context.SetStatus(Context::csInProgress);
|
||||
|
||||
|
||||
@@ -42,11 +42,11 @@ namespace Apostol {
|
||||
|
||||
CStringList m_Module;
|
||||
|
||||
CString m_OAuth2;
|
||||
CString m_pgpPrivateKey;
|
||||
CString m_pgpPassphrase;
|
||||
CJSON m_OAuth2;
|
||||
|
||||
int m_ServerIndex;
|
||||
CString m_pgpModuleKey;
|
||||
CString m_pgpPublicKey;
|
||||
CString m_pgpPassphrase;
|
||||
|
||||
CProcessStatus m_Status;
|
||||
|
||||
@@ -65,17 +65,19 @@ namespace Apostol {
|
||||
|
||||
void InitServerList();
|
||||
void UpdateServerList(const CString &Key);
|
||||
void UpdateOAuth2(const CString &FileName);
|
||||
|
||||
void FetchProviders(CDateTime Now, CContext &Context);
|
||||
void CheckProviders(CDateTime Now, CContext &Context);
|
||||
|
||||
void CreateAccessToken(const CProvider &Provider, const CString &Application, CContext &Context);
|
||||
void ParsePGPKey(const CString& Key, CStringPairs& ServerList, CStringList& BTCKeys);
|
||||
|
||||
void FetchOAuth2(CContext &Context);
|
||||
void FetchPGP(CContext &Context);
|
||||
|
||||
void ModuleService(CContext &Context);
|
||||
void ModuleStatus(CContext &Context);
|
||||
void ModuleNew(CContext &Context);
|
||||
void ModuleAuthorize(CContext &Context);
|
||||
|
||||
protected:
|
||||
|
||||
CHTTPProxy *GetProxy(CHTTPServerConnection *AConnection);
|
||||
@@ -130,6 +132,8 @@ namespace Apostol {
|
||||
static int VerifyPGPSignature(const CString &ClearText, const CString &Key, CString &Message);
|
||||
|
||||
static bool FindURLInLine(const CString &Line, CStringList &List);
|
||||
static void UpdateOAuth2(CContext &Context, const CJSONObject &OAuth2);
|
||||
static void UpdateProviders(CProviders &Providers, const CJSONObject &Data);
|
||||
static bool LoadOAuth2(const CString &FileName, CProviders &Providers);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -125,29 +125,31 @@ namespace Apostol {
|
||||
Context.PGP().Name = "PUBLIC";
|
||||
Context.PGP().Key = Key;
|
||||
Context.BTCKeys() = Keys;
|
||||
|
||||
UpdateOAuth2(Context, m_OAuth2.Object());
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebSocketModule::FetchOAuth2(CContext &Context) {
|
||||
void CWebSocketModule::ModuleStatus(CContext &Context) {
|
||||
|
||||
Log()->Debug(APP_LOG_DEBUG_CORE, "Trying to fetch a OAuth2 configuration file for module \"%s\" from: %s", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
Log()->Notice("[%s] [%s] Trying get module status.", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
|
||||
auto OnRequest = [this, &Context](CHTTPClient *Sender, CHTTPRequest *ARequest) {
|
||||
|
||||
ARequest->ContentType = CHTTPRequest::text;
|
||||
|
||||
Apostol::PGP::CleartextSignature(
|
||||
m_pgpPrivateKey,
|
||||
m_pgpPassphrase,
|
||||
BPS_PGP_HASH,
|
||||
Context.Name(),
|
||||
ARequest->Content);
|
||||
|
||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/service");
|
||||
Context.SetStatus(Context::csInProgress);
|
||||
|
||||
const auto &caModuleAddress = m_Module["address"];
|
||||
|
||||
ARequest->ContentType = CHTTPRequest::text;
|
||||
|
||||
ARequest->Content.Format(R"({"address": "%s"})", caModuleAddress.c_str());
|
||||
|
||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/status");
|
||||
|
||||
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["access_token"]);
|
||||
|
||||
if (!caModuleAddress.IsEmpty())
|
||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||
|
||||
@@ -163,14 +165,82 @@ namespace Apostol {
|
||||
|
||||
DebugReply(pReply);
|
||||
|
||||
if (Context.Status() == Context::csPreparing) {
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
const CJSON Json(pReply->Content);
|
||||
Json.SaveToFile(m_OAuth2.c_str());
|
||||
UpdateOAuth2(m_OAuth2);
|
||||
} else {
|
||||
Context.SetStatus(Context::csInitialization);
|
||||
}
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
ModuleAuthorize(Context);
|
||||
} else {
|
||||
ModuleNew(Context);
|
||||
}
|
||||
|
||||
pConnection->CloseConnection(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto OnException = [&Context](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
if (pConnection != nullptr) {
|
||||
auto pClient = dynamic_cast<CHTTPClient *> (pConnection->Client());
|
||||
if (pClient != nullptr) {
|
||||
Log()->Error(APP_LOG_EMERG, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
|
||||
}
|
||||
DebugReply(pConnection->Reply());
|
||||
}
|
||||
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
};
|
||||
|
||||
auto pClient = GetClient(Context.URL().hostname, Context.URL().port == 0 ? BPS_SERVER_PORT : Context.URL().port);
|
||||
|
||||
pClient->OnRequest(OnRequest);
|
||||
pClient->OnExecute(OnExecute);
|
||||
pClient->OnException(OnException);
|
||||
|
||||
pClient->AutoFree(true);
|
||||
pClient->Active(true);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebSocketModule::ModuleService(CContext &Context) {
|
||||
|
||||
Log()->Notice("[%s] [%s] Trying to fetch a OAuth2 configuration file.", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
|
||||
auto OnRequest = [this, &Context](CHTTPClient *Sender, CHTTPRequest *ARequest) {
|
||||
|
||||
Context.SetStatus(Context::csPreparing);
|
||||
|
||||
ARequest->ContentType = CHTTPRequest::text;
|
||||
|
||||
Apostol::PGP::CleartextSignature(
|
||||
m_pgpModuleKey,
|
||||
m_pgpPassphrase,
|
||||
BPS_PGP_HASH,
|
||||
Context.Name(),
|
||||
ARequest->Content);
|
||||
|
||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/service");
|
||||
|
||||
const auto &caModuleAddress = m_Module["address"];
|
||||
if (!caModuleAddress.IsEmpty())
|
||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||
|
||||
DebugRequest(ARequest);
|
||||
};
|
||||
|
||||
auto OnExecute = [&Context](CTCPConnection *AConnection) {
|
||||
|
||||
Context.SetStatus(Context::csInitialization);
|
||||
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
|
||||
if (pConnection != nullptr) {
|
||||
auto pReply = pConnection->Reply();
|
||||
|
||||
DebugReply(pReply);
|
||||
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
const CJSON OAuth2(pReply->Content);
|
||||
UpdateOAuth2(Context, OAuth2.Object());
|
||||
}
|
||||
|
||||
pConnection->CloseConnection(true);
|
||||
@@ -192,7 +262,98 @@ namespace Apostol {
|
||||
Context.SetStatus(Context::csInitialization);
|
||||
};
|
||||
|
||||
Context.SetStatus(Context::csPreparing);
|
||||
auto pClient = GetClient(Context.URL().hostname, Context.URL().port == 0 ? BPS_SERVER_PORT : Context.URL().port);
|
||||
|
||||
pClient->OnRequest(OnRequest);
|
||||
pClient->OnExecute(OnExecute);
|
||||
pClient->OnException(OnException);
|
||||
|
||||
pClient->AutoFree(true);
|
||||
pClient->Active(true);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebSocketModule::ModuleNew(CContext &Context) {
|
||||
|
||||
Log()->Notice("[%s] [%s] Trying create new module.", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
|
||||
auto OnRequest = [this, &Context](CHTTPClient *Sender, CHTTPRequest *ARequest) {
|
||||
|
||||
Context.SetStatus(Context::csInProgress);
|
||||
|
||||
ARequest->ContentType = CHTTPRequest::json;
|
||||
|
||||
const auto &caModuleAddress = m_Module["address"];
|
||||
|
||||
CJSON Json(jvtObject);
|
||||
|
||||
Json.Object().AddPair("address", caModuleAddress);
|
||||
Json.Object().AddPair("bitmessage", Context.Name());
|
||||
|
||||
const OpenPGP::SecretKey pgpSecret(m_pgpModuleKey.c_str());
|
||||
const auto &public_key = pgpSecret.get_public();
|
||||
|
||||
Json.Object().AddPair("pgp", public_key.write(OpenPGP::PGP::Armored::YES));
|
||||
|
||||
ARequest->Content = Json.ToString();
|
||||
|
||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/client/new");
|
||||
|
||||
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["access_token"]);
|
||||
|
||||
if (!caModuleAddress.IsEmpty())
|
||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||
|
||||
DebugRequest(ARequest);
|
||||
};
|
||||
|
||||
auto OnExecute = [this, &Context](CTCPConnection *AConnection) {
|
||||
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
|
||||
if (pConnection != nullptr) {
|
||||
auto pReply = pConnection->Reply();
|
||||
|
||||
DebugReply(pReply);
|
||||
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
const CJSON Json(pReply->Content);
|
||||
|
||||
if (Json.HasOwnProperty("result")) {
|
||||
const auto &caResult = Json["result"];
|
||||
if (caResult.HasOwnProperty("success")) {
|
||||
if (caResult["success"].AsBoolean()) {
|
||||
ModuleAuthorize(Context);
|
||||
} else {
|
||||
if (caResult.HasOwnProperty("message")) {
|
||||
Log()->Error(APP_LOG_EMERG, 0, "[%s] [%s] %s", Context.Name().c_str(),
|
||||
Context.URL().Origin().c_str(), caResult["message"].AsString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pConnection->CloseConnection(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto OnException = [&Context](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
if (pConnection != nullptr) {
|
||||
auto pClient = dynamic_cast<CHTTPClient *> (pConnection->Client());
|
||||
if (pClient != nullptr) {
|
||||
Log()->Error(APP_LOG_EMERG, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
|
||||
}
|
||||
DebugReply(pConnection->Reply());
|
||||
}
|
||||
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
};
|
||||
|
||||
auto pClient = GetClient(Context.URL().hostname, Context.URL().port == 0 ? BPS_SERVER_PORT : Context.URL().port);
|
||||
|
||||
@@ -205,41 +366,108 @@ namespace Apostol {
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebSocketModule::UpdateOAuth2(const CString &FileName) {
|
||||
for (int i = 0; i < m_Servers.Count(); i++) {
|
||||
auto &Context = m_Servers[i].Value();
|
||||
if (Context.Status() == Context::csInitialization || Context.Status() == Context::csPreparing) {
|
||||
if (LoadOAuth2(FileName, Context.Providers())) {
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
Context.SetCheckDate(0);
|
||||
} else {
|
||||
if (Context.Status() != Context::csPreparing) {
|
||||
FetchOAuth2(Context);
|
||||
}
|
||||
void CWebSocketModule::ModuleAuthorize(CContext &Context) {
|
||||
|
||||
Log()->Notice("[%s] [%s] Trying authorize module.", Context.Name().c_str(), Context.URL().Origin().c_str());
|
||||
|
||||
auto OnRequest = [this, &Context](CHTTPClient *Sender, CHTTPRequest *ARequest) {
|
||||
|
||||
Context.SetStatus(Context::csAuthorization);
|
||||
|
||||
ARequest->ContentType = CHTTPRequest::text;
|
||||
|
||||
Apostol::PGP::CleartextSignature(
|
||||
m_pgpModuleKey,
|
||||
m_pgpPassphrase,
|
||||
BPS_PGP_HASH,
|
||||
Context.Name(),
|
||||
ARequest->Content);
|
||||
|
||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/authorize");
|
||||
|
||||
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["access_token"]);
|
||||
|
||||
const auto &caModuleAddress = m_Module["address"];
|
||||
if (!caModuleAddress.IsEmpty())
|
||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||
|
||||
DebugRequest(ARequest);
|
||||
};
|
||||
|
||||
auto OnExecute = [&Context](CTCPConnection *AConnection) {
|
||||
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
|
||||
if (pConnection != nullptr) {
|
||||
auto pReply = pConnection->Reply();
|
||||
|
||||
DebugReply(pReply);
|
||||
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
const CJSON Json(pReply->Content);
|
||||
|
||||
Context.Session() = Json["session"].AsString();
|
||||
Context.Secret() = Json["secret"].AsString();
|
||||
|
||||
Context.Tokens().Values("access_token", Json["access_token"].AsString());
|
||||
|
||||
Context.SetFixedDate(0);
|
||||
Context.SetCheckDate(Now() + (CDateTime) 55 / MinsPerDay); // 55 min
|
||||
|
||||
Context.SetStatus(csAuthorized);
|
||||
}
|
||||
|
||||
pConnection->CloseConnection(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto OnException = [&Context](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
|
||||
if (pConnection != nullptr) {
|
||||
auto pClient = dynamic_cast<CHTTPClient *> (pConnection->Client());
|
||||
if (pClient != nullptr) {
|
||||
Log()->Error(APP_LOG_EMERG, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
|
||||
}
|
||||
DebugReply(pConnection->Reply());
|
||||
}
|
||||
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
};
|
||||
|
||||
auto pClient = GetClient(Context.URL().hostname, Context.URL().port == 0 ? BPS_SERVER_PORT : Context.URL().port);
|
||||
|
||||
pClient->OnRequest(OnRequest);
|
||||
pClient->OnExecute(OnExecute);
|
||||
pClient->OnException(OnException);
|
||||
|
||||
pClient->AutoFree(true);
|
||||
pClient->Active(true);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebSocketModule::UpdateOAuth2(CContext &Context, const CJSONObject &OAuth2) {
|
||||
if (OAuth2["type"].AsString() == "service_account") {
|
||||
UpdateProviders(Context.Providers(), OAuth2);
|
||||
|
||||
Context.SetCheckDate(0);
|
||||
Context.SetStatus(Context::csInitialized);
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool CWebSocketModule::LoadOAuth2(const CString &FileName, CProviders &Providers) {
|
||||
void CWebSocketModule::UpdateProviders(CProviders &Providers, const CJSONObject &Data) {
|
||||
const auto &caProviderName = CString(SYSTEM_PROVIDER_NAME);
|
||||
const auto &caApplicationName = CString(SERVICE_APPLICATION_NAME);
|
||||
|
||||
if (FileExists(FileName.c_str())) {
|
||||
CJSONObject Json;
|
||||
Json.LoadFromFile(FileName.c_str());
|
||||
|
||||
int index = Providers.IndexOfName(caProviderName);
|
||||
if (index == -1)
|
||||
index = Providers.AddPair(caProviderName, CProvider(caProviderName));
|
||||
auto& Provider = Providers[index].Value();
|
||||
Provider.Applications().AddPair(caApplicationName, Json);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
int index = Providers.IndexOfName(caProviderName);
|
||||
if (index == -1)
|
||||
index = Providers.AddPair(caProviderName, CProvider(caProviderName));
|
||||
auto& Provider = Providers[index].Value();
|
||||
Provider.Applications().AddPair(caApplicationName, Data);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -355,9 +583,7 @@ namespace Apostol {
|
||||
pClient->Active(true);
|
||||
|
||||
Context.SetFixedDate(0);
|
||||
|
||||
if (Context.Status() == Context::csInProgress)
|
||||
Context.SetStatus(csRunning);
|
||||
Context.SetStatus(csRunning);
|
||||
} catch (std::exception &e) {
|
||||
Log()->Error(APP_LOG_ERR, 0, e.what());
|
||||
}
|
||||
@@ -425,7 +651,7 @@ namespace Apostol {
|
||||
|
||||
void CWebSocketModule::CreateAccessToken(const CProvider &Provider, const CString &Application, CClientContext &Context) {
|
||||
|
||||
auto OnDone = [&Context](CTCPConnection *Sender) {
|
||||
auto OnDone = [this, &Context](CTCPConnection *Sender) {
|
||||
|
||||
auto pConnection = dynamic_cast<CHTTPClientConnection *> (Sender);
|
||||
auto pReply = pConnection->Reply();
|
||||
@@ -435,14 +661,12 @@ namespace Apostol {
|
||||
if (pReply->Status == CHTTPReply::ok) {
|
||||
const CJSON Json(pReply->Content);
|
||||
|
||||
if (Context.Status() == Context::csAuthorization)
|
||||
Context.SetStatus(csAuthorized);
|
||||
|
||||
Context.Session() = Json["session"].AsString();
|
||||
Context.Secret() = Json["secret"].AsString();
|
||||
|
||||
Context.SetFixedDate(0);
|
||||
Context.SetCheckDate(Now() + (CDateTime) 55 / MinsPerDay); // 55 min
|
||||
Context.Tokens().Values("access_token", Json["access_token"].AsString());
|
||||
|
||||
ModuleStatus(Context);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -639,7 +863,6 @@ namespace Apostol {
|
||||
|
||||
if (Response.Payload.HasOwnProperty("data")) {
|
||||
UpdateServerList(Response.Payload["data"].AsString());
|
||||
UpdateOAuth2(m_OAuth2);
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
@@ -863,7 +1086,7 @@ namespace Apostol {
|
||||
sPayload = caClearText.Text();
|
||||
} else {
|
||||
Apostol::PGP::CleartextSignature(
|
||||
m_pgpPrivateKey,
|
||||
m_pgpModuleKey,
|
||||
m_pgpPassphrase,
|
||||
BPS_PGP_HASH,
|
||||
caClearText.Text(),
|
||||
@@ -1260,7 +1483,7 @@ namespace Apostol {
|
||||
sPayload = caClearText;
|
||||
} else {
|
||||
Apostol::PGP::CleartextSignature(
|
||||
m_pgpPrivateKey,
|
||||
m_pgpModuleKey,
|
||||
m_pgpPassphrase,
|
||||
BPS_PGP_HASH,
|
||||
caClearText,
|
||||
@@ -1517,34 +1740,27 @@ namespace Apostol {
|
||||
for (int i = 0; i < m_Servers.Count(); i++) {
|
||||
auto &Context = m_Servers[i].Value();
|
||||
|
||||
if ((Now >= Context.CheckDate()) && (Context.Status() == Context::csInitialization)) {
|
||||
Context.SetCheckDate(Now + (CDateTime) 30 / SecsPerDay); // 30 sec
|
||||
FetchOAuth2(Context);
|
||||
}
|
||||
|
||||
if ((Now >= Context.CheckDate()) && (Context.Status() >= Context::csInitialized)) {
|
||||
if (Now >= Context.CheckDate()) {
|
||||
Context.SetCheckDate(Now + (CDateTime) 30 / SecsPerDay); // 30 sec
|
||||
|
||||
if (Context.Status() == Context::csInitialized)
|
||||
Context.SetStatus(Context::csAuthorization);
|
||||
if (Context.Status() == Context::csInitialization) {
|
||||
ModuleService(Context);
|
||||
}
|
||||
|
||||
CheckProviders(Now, Context);
|
||||
FetchProviders(Now, Context);
|
||||
}
|
||||
|
||||
if (Context.Status() == Context::csAuthorized) {
|
||||
if (Now >= Context.FixedDate()) {
|
||||
Context.SetFixedDate(Now + (CDateTime) 30 / SecsPerDay); // 30 sec
|
||||
Context.SetStatus(Context::csInProgress);
|
||||
|
||||
CreateWebSocketClient(Context);
|
||||
if (Context.Status() >= Context::csInitialized) {
|
||||
CheckProviders(Now, Context);
|
||||
FetchProviders(Now, Context);
|
||||
}
|
||||
}
|
||||
|
||||
if (Context.Status() == Context::csRunning) {
|
||||
if (Now >= Context.FixedDate()) {
|
||||
Context.SetFixedDate(Now + (CDateTime) 30 / SecsPerDay); // 30 sec
|
||||
if (Now >= Context.FixedDate()) {
|
||||
Context.SetFixedDate(Now + (CDateTime) 30 / SecsPerDay); // 30 sec
|
||||
|
||||
if (Context.Status() == Context::csAuthorized) {
|
||||
CreateWebSocketClient(Context);
|
||||
}
|
||||
|
||||
if (Context.Status() == Context::csRunning) {
|
||||
for (int j = 0; j < Context.ClientManager().Count(); ++j) {
|
||||
auto pClient = Context.ClientManager()[j];
|
||||
|
||||
@@ -1552,7 +1768,10 @@ namespace Apostol {
|
||||
pClient->Active(true);
|
||||
|
||||
if (!pClient->Connected() && !pClient->Session().IsEmpty()) {
|
||||
Log()->Notice(_T("[%s] Trying connect to %s."), pClient->Session().c_str(), pClient->URI().href().c_str());
|
||||
Log()->Notice(_T("[%s] [%s] [%s] Trying to establish a connection."),
|
||||
Context.Name().c_str(),
|
||||
Context.URL().Origin().c_str(),
|
||||
pClient->Session().c_str());
|
||||
pClient->ConnectStart();
|
||||
}
|
||||
}
|
||||
@@ -1565,9 +1784,15 @@ namespace Apostol {
|
||||
void CWebSocketModule::Reload() {
|
||||
Config()->IniFile().ReadSectionValues("module", &m_Module);
|
||||
|
||||
m_OAuth2 = Config()->IniFile().ReadString(CONFIG_SECTION_NAME, "oauth2", "oauth2/service.json");
|
||||
if (!path_separator(m_OAuth2.front())) {
|
||||
m_OAuth2 = Config()->Prefix() + m_OAuth2;
|
||||
CString FileName;
|
||||
|
||||
FileName = Config()->IniFile().ReadString(CONFIG_SECTION_NAME, "oauth2", "oauth2/service.json");
|
||||
if (!path_separator(FileName.front())) {
|
||||
FileName = Config()->Prefix() + FileName;
|
||||
}
|
||||
|
||||
if (FileExists(FileName.c_str())) {
|
||||
m_OAuth2.LoadFromFile(FileName.c_str());
|
||||
}
|
||||
|
||||
const auto &caPrivateKey = Config()->IniFile().ReadString("pgp", "private", "module.sec");
|
||||
@@ -1576,14 +1801,11 @@ namespace Apostol {
|
||||
m_pgpPassphrase = Config()->IniFile().ReadString("pgp", "passphrase", "");
|
||||
|
||||
if (FileExists(caPrivateKey.c_str())) {
|
||||
m_pgpPrivateKey.LoadFromFile(caPrivateKey.c_str());
|
||||
m_pgpModuleKey.LoadFromFile(caPrivateKey.c_str());
|
||||
|
||||
if (FileExists(caPublicKey.c_str())) {
|
||||
CString Key;
|
||||
Key.LoadFromFile(caPublicKey.c_str());
|
||||
|
||||
UpdateServerList(Key);
|
||||
UpdateOAuth2(m_OAuth2);
|
||||
m_pgpPublicKey.LoadFromFile(caPublicKey.c_str());
|
||||
UpdateServerList(m_pgpPublicKey);
|
||||
} else {
|
||||
Log()->Error(APP_LOG_WARN, 0, APP_FILE_NOT_FOUND, caPublicKey.c_str());
|
||||
}
|
||||
|
||||
@@ -69,8 +69,10 @@ namespace Apostol {
|
||||
|
||||
CStringList m_Module;
|
||||
|
||||
CString m_OAuth2;
|
||||
CString m_pgpPrivateKey;
|
||||
CJSON m_OAuth2;
|
||||
|
||||
CString m_pgpModuleKey;
|
||||
CString m_pgpPublicKey;
|
||||
CString m_pgpPassphrase;
|
||||
|
||||
int m_SyncPeriod;
|
||||
@@ -83,7 +85,6 @@ namespace Apostol {
|
||||
|
||||
void InitServerList();
|
||||
void UpdateServerList(const CString &Key);
|
||||
void UpdateOAuth2(const CString &FileName);
|
||||
|
||||
void FetchProviders(CDateTime Now, CClientContext &Context);
|
||||
void CheckProviders(CDateTime Now, CClientContext &Context);
|
||||
@@ -94,7 +95,10 @@ namespace Apostol {
|
||||
CWebSocketClient *GetWebSocketClient(CClientContext &Context);
|
||||
void CreateWebSocketClient(CClientContext &Context);
|
||||
|
||||
void FetchOAuth2(CContext &Context);
|
||||
void ModuleService(CContext &Context);
|
||||
void ModuleStatus(CContext &Context);
|
||||
void ModuleNew(CContext &Context);
|
||||
void ModuleAuthorize(CContext &Context);
|
||||
|
||||
static CWebSocketClient *GetConnectedClient(const CClientContext &Context);
|
||||
|
||||
@@ -147,12 +151,14 @@ namespace Apostol {
|
||||
void Reload();
|
||||
|
||||
static CString ToString(unsigned long Value);
|
||||
|
||||
static int CheckFee(const CString& Fee);
|
||||
static void CheckDeal(const CDeal& Deal);
|
||||
static void CheckKeyForNull(LPCTSTR key, const CString& Value);
|
||||
|
||||
static bool FindURLInLine(const CString &Line, CStringList &List);
|
||||
static bool LoadOAuth2(const CString &FileName, CProviders &Providers);
|
||||
static void UpdateOAuth2(CContext &Context, const CJSONObject &OAuth2);
|
||||
static void UpdateProviders(CProviders &Providers, const CJSONObject &Data);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user