Added token update.
This commit is contained in:
@@ -107,7 +107,7 @@ namespace Apostol {
|
|||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
void CCustomModule::JsonStringToKey(const CString &String, CString& Key) {
|
void CCustomModule::JsonStringToKey(const CString &String, CString &Code, CString& Key) {
|
||||||
const CJSON Json(String);
|
const CJSON Json(String);
|
||||||
|
|
||||||
if (Json.HasOwnProperty("error")) {
|
if (Json.HasOwnProperty("error")) {
|
||||||
@@ -116,6 +116,10 @@ namespace Apostol {
|
|||||||
throw Delphi::Exception::Exception(error["message"].AsString().c_str());
|
throw Delphi::Exception::Exception(error["message"].AsString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Json.HasOwnProperty("code")) {
|
||||||
|
Code = Json["code"].AsString();
|
||||||
|
}
|
||||||
|
|
||||||
if (Json.HasOwnProperty("data")) {
|
if (Json.HasOwnProperty("data")) {
|
||||||
Key = Json["data"].AsString();
|
Key = Json["data"].AsString();
|
||||||
}
|
}
|
||||||
@@ -349,10 +353,15 @@ namespace Apostol {
|
|||||||
Context.Session() = Json["session"].AsString();
|
Context.Session() = Json["session"].AsString();
|
||||||
Context.Secret() = Json["secret"].AsString();
|
Context.Secret() = Json["secret"].AsString();
|
||||||
|
|
||||||
Context.Tokens().Values("access_token", Json["access_token"].AsString());
|
const auto expires_in = Json["expires_in"].AsInteger();
|
||||||
|
|
||||||
|
Context.Tokens().Values("module_token", Json["access_token"].AsString());
|
||||||
|
|
||||||
Provider.KeyStatus(ksSuccess);
|
Provider.KeyStatus(ksSuccess);
|
||||||
|
|
||||||
|
Context.SetFixedDate(0);
|
||||||
|
Context.SetCheckDate(Now() + (CDateTime) (expires_in - 300) / SecsPerDay);
|
||||||
|
|
||||||
ModuleStatus(Context);
|
ModuleStatus(Context);
|
||||||
} else {
|
} else {
|
||||||
Provider.KeyStatus(ksFailed);
|
Provider.KeyStatus(ksFailed);
|
||||||
@@ -391,6 +400,68 @@ namespace Apostol {
|
|||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CCustomModule::UpdateAccessToken(CContext &Context, CProvider &Provider, const CString &Application) {
|
||||||
|
|
||||||
|
auto OnDone = [this, &Context, &Provider](CTCPConnection *Sender) {
|
||||||
|
|
||||||
|
auto pConnection = dynamic_cast<CHTTPClientConnection *> (Sender);
|
||||||
|
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();
|
||||||
|
|
||||||
|
const auto expires_in = Json["expires_in"].AsInteger();
|
||||||
|
|
||||||
|
Context.Tokens().Values("module_token", Json["access_token"].AsString());
|
||||||
|
|
||||||
|
Provider.KeyStatus(ksSuccess);
|
||||||
|
|
||||||
|
Context.SetFixedDate(0);
|
||||||
|
Context.SetCheckDate(Now() + (CDateTime) (expires_in - 300) / SecsPerDay);
|
||||||
|
|
||||||
|
ModuleStatus(Context);
|
||||||
|
} else {
|
||||||
|
Provider.KeyStatus(ksFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto OnFail = [&Context, &Provider](CTCPConnection *Sender, const Delphi::Exception::Exception &E) {
|
||||||
|
Context.SetStatus(csInitialized);
|
||||||
|
|
||||||
|
auto pConnection = dynamic_cast<CHTTPClientConnection *> (Sender);
|
||||||
|
auto pClient = dynamic_cast<CHTTPClient *> (pConnection->Client());
|
||||||
|
|
||||||
|
Provider.KeyStatus(ksFailed);
|
||||||
|
|
||||||
|
DebugReply(pConnection->Reply());
|
||||||
|
|
||||||
|
Log()->Error(APP_LOG_ERR, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
|
||||||
|
};
|
||||||
|
|
||||||
|
auto OnHTTPClient = [this](const CLocation &URI) {
|
||||||
|
return GetClient(URI.hostname, URI.port);
|
||||||
|
};
|
||||||
|
//----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CString server_uri(Context.URL().Origin());
|
||||||
|
|
||||||
|
const auto &client_id = Provider.ClientId(Application);
|
||||||
|
const auto &secret = Provider.Secret(Application);
|
||||||
|
const auto &token_uri = Provider.TokenURI(Application);
|
||||||
|
|
||||||
|
if (!token_uri.IsEmpty()) {
|
||||||
|
CToken::ExchangeAccessToken(token_uri.front() == '/' ? server_uri + token_uri : token_uri, client_id, secret, Context.Tokens()["module_token"], OnHTTPClient, OnDone, OnFail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
void CCustomModule::CheckProviders(CContext &Context, CDateTime Now) {
|
void CCustomModule::CheckProviders(CContext &Context, CDateTime Now) {
|
||||||
for (int i = 0; i < Context.Providers().Count(); i++) {
|
for (int i = 0; i < Context.Providers().Count(); i++) {
|
||||||
auto &Provider = Context.Providers()[i].Value();
|
auto &Provider = Context.Providers()[i].Value();
|
||||||
@@ -400,7 +471,12 @@ namespace Apostol {
|
|||||||
if (Provider.KeyStatus() != ksFetching) {
|
if (Provider.KeyStatus() != ksFetching) {
|
||||||
Provider.KeyStatusTime(Now);
|
Provider.KeyStatusTime(Now);
|
||||||
Provider.KeyStatus(ksFetching);
|
Provider.KeyStatus(ksFetching);
|
||||||
|
const auto &module_token = Context.Tokens()["module_token"];
|
||||||
|
if (module_token.empty()) {
|
||||||
CreateAccessToken(Context, Provider, caApplication.String());
|
CreateAccessToken(Context, Provider, caApplication.String());
|
||||||
|
} else {
|
||||||
|
UpdateAccessToken(Context, Provider, caApplication.String());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -787,7 +863,7 @@ namespace Apostol {
|
|||||||
|
|
||||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/status");
|
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/status");
|
||||||
|
|
||||||
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["access_token"]);
|
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["module_token"]);
|
||||||
|
|
||||||
if (!caModuleAddress.IsEmpty())
|
if (!caModuleAddress.IsEmpty())
|
||||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||||
@@ -866,7 +942,7 @@ namespace Apostol {
|
|||||||
|
|
||||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/client/new");
|
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/client/new");
|
||||||
|
|
||||||
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["access_token"]);
|
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["module_token"]);
|
||||||
|
|
||||||
if (!caModuleAddress.IsEmpty())
|
if (!caModuleAddress.IsEmpty())
|
||||||
ARequest->AddHeader("Module-Address", caModuleAddress);
|
ARequest->AddHeader("Module-Address", caModuleAddress);
|
||||||
@@ -952,7 +1028,11 @@ namespace Apostol {
|
|||||||
|
|
||||||
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/authorize");
|
CHTTPRequest::Prepare(ARequest, "POST", "/api/v1/dm/authorize");
|
||||||
|
|
||||||
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["access_token"]);
|
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["module_token"]);
|
||||||
|
|
||||||
|
const auto &access_token = Context.Tokens()["access_token"];
|
||||||
|
if (!access_token.IsEmpty())
|
||||||
|
ARequest->AddHeader("Subject-Token", access_token);
|
||||||
|
|
||||||
const auto &caModuleAddress = m_Module["address"];
|
const auto &caModuleAddress = m_Module["address"];
|
||||||
if (!caModuleAddress.IsEmpty())
|
if (!caModuleAddress.IsEmpty())
|
||||||
@@ -972,20 +1052,24 @@ namespace Apostol {
|
|||||||
|
|
||||||
DebugReply(pReply);
|
DebugReply(pReply);
|
||||||
|
|
||||||
if (pReply->Status == CHTTPReply::ok) {
|
|
||||||
const CJSON Json(pReply->Content);
|
const CJSON Json(pReply->Content);
|
||||||
|
|
||||||
|
if (pReply->Status == CHTTPReply::ok) {
|
||||||
Context.Session() = Json["session"].AsString();
|
Context.Session() = Json["session"].AsString();
|
||||||
Context.Secret() = Json["secret"].AsString();
|
Context.Secret() = Json["secret"].AsString();
|
||||||
|
|
||||||
Context.Tokens().Values("access_token", Json["access_token"].AsString());
|
Context.Tokens().Values("access_token", Json["access_token"].AsString());
|
||||||
|
|
||||||
Context.SetFixedDate(0);
|
|
||||||
Context.SetCheckDate(Now() + (CDateTime) 55 / MinsPerDay); // 55 min
|
|
||||||
|
|
||||||
Context.SetStatus(csAuthorized);
|
Context.SetStatus(csAuthorized);
|
||||||
} else {
|
} else {
|
||||||
Context.SetCheckDate(Now() + (CDateTime) 5 / MinsPerDay); // 5 min
|
Context.SetCheckDate(Now() + (CDateTime) 5 / MinsPerDay); // 5 min
|
||||||
|
if (Json.HasOwnProperty("error")) {
|
||||||
|
const auto &error = Json["error"];
|
||||||
|
if (error.HasOwnProperty("message")) {
|
||||||
|
Log()->Error(APP_LOG_EMERG, 0, "[%s] [%s] %s", Context.Name().c_str(),
|
||||||
|
Context.URL().Origin().c_str(), error["message"].AsString().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pConnection->CloseConnection(true);
|
pConnection->CloseConnection(true);
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ namespace Apostol {
|
|||||||
void CheckProviders(CContext &Context, CDateTime Now);
|
void CheckProviders(CContext &Context, CDateTime Now);
|
||||||
|
|
||||||
void CreateAccessToken(CContext &Context, CProvider &Provider, const CString &Application);
|
void CreateAccessToken(CContext &Context, CProvider &Provider, const CString &Application);
|
||||||
|
void UpdateAccessToken(CContext &Context, CProvider &Provider, const CString &Application);
|
||||||
|
|
||||||
void ParsePGPKey(const CString &Key, CStringPairs &ServerList, CStringList &BTCKeys);
|
void ParsePGPKey(const CString &Key, CStringPairs &ServerList, CStringList &BTCKeys);
|
||||||
|
|
||||||
void ModuleService(CContext &Context);
|
void ModuleService(CContext &Context);
|
||||||
@@ -129,7 +131,7 @@ namespace Apostol {
|
|||||||
virtual void Reload() abstract;
|
virtual void Reload() abstract;
|
||||||
|
|
||||||
static CString ToString(unsigned long Value);
|
static CString ToString(unsigned long Value);
|
||||||
static void JsonStringToKey(const CString &String, CString &Key);
|
static void JsonStringToKey(const CString &String, CString &Code, CString &Key);
|
||||||
|
|
||||||
static void CheckKeyForNull(LPCTSTR Key, LPCTSTR Value);
|
static void CheckKeyForNull(LPCTSTR Key, LPCTSTR Value);
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,16 @@ namespace Apostol {
|
|||||||
}
|
}
|
||||||
pProxyConnection->SendReply(pProxyReply->Status, nullptr, true);
|
pProxyConnection->SendReply(pProxyReply->Status, nullptr, true);
|
||||||
} else {
|
} else {
|
||||||
|
if (pProxyReply->Status == CHTTPReply::forbidden) {
|
||||||
|
const auto &caServerParam = pServerRequest->Params["server"];
|
||||||
|
const auto index = CurrentContextIndex(caServerParam);
|
||||||
|
|
||||||
|
auto &Context = index == -1 ? m_CurrentServer : m_Servers[index].Value();
|
||||||
|
|
||||||
|
Context.SetCheckDate(0);
|
||||||
|
Context.SetStatus(Context::csInitialized);
|
||||||
|
}
|
||||||
|
|
||||||
pServerReply->Content = pProxyReply->Content;
|
pServerReply->Content = pProxyReply->Content;
|
||||||
pProxyConnection->SendStockReply(pProxyReply->Status, true);
|
pProxyConnection->SendStockReply(pProxyReply->Status, true);
|
||||||
}
|
}
|
||||||
@@ -1079,15 +1089,17 @@ namespace Apostol {
|
|||||||
|
|
||||||
DebugReply(pReply);
|
DebugReply(pReply);
|
||||||
|
|
||||||
CString Content;
|
CString Code;
|
||||||
|
CString Key;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JsonStringToKey(pReply->Content, Content);
|
JsonStringToKey(pReply->Content, Code, Key);
|
||||||
|
|
||||||
if (Content.IsEmpty())
|
if (Key.IsEmpty())
|
||||||
throw Delphi::Exception::Exception("Not found.");
|
throw Delphi::Exception::Exception("Not found.");
|
||||||
|
|
||||||
const auto &name = pClient->Data()["name"];
|
const auto &name = pClient->Data()["name"];
|
||||||
|
|
||||||
auto &Keys = Context.PGP();
|
auto &Keys = Context.PGP();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@@ -1096,17 +1108,19 @@ namespace Apostol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (index < Keys.Count()) {
|
if (index < Keys.Count()) {
|
||||||
auto &Key = Keys[index];
|
auto &PGP = Keys[index];
|
||||||
|
|
||||||
Key.Status = CKeyContext::ksSuccess;
|
PGP.Status = CKeyContext::ksSuccess;
|
||||||
Key.StatusTime = Now();
|
PGP.StatusTime = Now();
|
||||||
Key.Key = Content;
|
PGP.Key = Key;
|
||||||
|
|
||||||
UpdateServerList(m_Servers, Content);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (Code == "PUBLIC") {
|
||||||
|
UpdateServerList(m_Servers, Key);
|
||||||
Context.SetStatus(csRunning);
|
Context.SetStatus(csRunning);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Delphi::Exception::Exception &e) {
|
} catch (Delphi::Exception::Exception &e) {
|
||||||
|
Context.SetStatus(Context::csAuthorized);
|
||||||
Log()->Error(APP_LOG_INFO, 0, "[FetchPGP] %s", e.what());
|
Log()->Error(APP_LOG_INFO, 0, "[FetchPGP] %s", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user