Added token update.

This commit is contained in:
Преподобный Ален
2022-11-01 00:57:06 +03:00
parent 94ffb25f8a
commit d99708838f
3 changed files with 122 additions and 22 deletions

View File

@@ -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);
if (Json.HasOwnProperty("error")) {
@@ -116,6 +116,10 @@ namespace Apostol {
throw Delphi::Exception::Exception(error["message"].AsString().c_str());
}
if (Json.HasOwnProperty("code")) {
Code = Json["code"].AsString();
}
if (Json.HasOwnProperty("data")) {
Key = Json["data"].AsString();
}
@@ -349,10 +353,15 @@ namespace Apostol {
Context.Session() = Json["session"].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);
Context.SetFixedDate(0);
Context.SetCheckDate(Now() + (CDateTime) (expires_in - 300) / SecsPerDay);
ModuleStatus(Context);
} else {
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) {
for (int i = 0; i < Context.Providers().Count(); i++) {
auto &Provider = Context.Providers()[i].Value();
@@ -400,7 +471,12 @@ namespace Apostol {
if (Provider.KeyStatus() != ksFetching) {
Provider.KeyStatusTime(Now);
Provider.KeyStatus(ksFetching);
const auto &module_token = Context.Tokens()["module_token"];
if (module_token.empty()) {
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");
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["access_token"]);
ARequest->AddHeader("Authorization", "Bearer " + Context.Tokens()["module_token"]);
if (!caModuleAddress.IsEmpty())
ARequest->AddHeader("Module-Address", caModuleAddress);
@@ -866,7 +942,7 @@ namespace Apostol {
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())
ARequest->AddHeader("Module-Address", caModuleAddress);
@@ -952,7 +1028,11 @@ namespace Apostol {
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"];
if (!caModuleAddress.IsEmpty())
@@ -972,20 +1052,24 @@ namespace Apostol {
DebugReply(pReply);
if (pReply->Status == CHTTPReply::ok) {
const CJSON Json(pReply->Content);
if (pReply->Status == CHTTPReply::ok) {
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);
} else {
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);

View File

@@ -98,6 +98,8 @@ namespace Apostol {
void CheckProviders(CContext &Context, CDateTime Now);
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 ModuleService(CContext &Context);
@@ -129,7 +131,7 @@ namespace Apostol {
virtual void Reload() abstract;
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);

View File

@@ -127,6 +127,16 @@ namespace Apostol {
}
pProxyConnection->SendReply(pProxyReply->Status, nullptr, true);
} 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;
pProxyConnection->SendStockReply(pProxyReply->Status, true);
}
@@ -1079,15 +1089,17 @@ namespace Apostol {
DebugReply(pReply);
CString Content;
CString Code;
CString Key;
try {
JsonStringToKey(pReply->Content, Content);
JsonStringToKey(pReply->Content, Code, Key);
if (Content.IsEmpty())
if (Key.IsEmpty())
throw Delphi::Exception::Exception("Not found.");
const auto &name = pClient->Data()["name"];
auto &Keys = Context.PGP();
int index = 0;
@@ -1096,17 +1108,19 @@ namespace Apostol {
}
if (index < Keys.Count()) {
auto &Key = Keys[index];
auto &PGP = Keys[index];
Key.Status = CKeyContext::ksSuccess;
Key.StatusTime = Now();
Key.Key = Content;
UpdateServerList(m_Servers, Content);
}
PGP.Status = CKeyContext::ksSuccess;
PGP.StatusTime = Now();
PGP.Key = Key;
if (Code == "PUBLIC") {
UpdateServerList(m_Servers, Key);
Context.SetStatus(csRunning);
}
}
} catch (Delphi::Exception::Exception &e) {
Context.SetStatus(Context::csAuthorized);
Log()->Error(APP_LOG_INFO, 0, "[FetchPGP] %s", e.what());
}