|
5 | 5 | #include "SequenceAuthenticator.h" |
6 | 6 | #include "RequestHandler.h" |
7 | 7 | #include "ConfigFetcher.h" |
| 8 | +#include "HttpModule.h" |
8 | 9 | #include "Interfaces/IHttpResponse.h" |
9 | 10 | #include "Types/BinaryData.h" |
10 | 11 | #include "Misc/Base64.h" |
|
15 | 16 |
|
16 | 17 | template<typename T> FString USequenceRPCManager::GenerateIntent(T Data, TOptional<int64> CurrentTime) const |
17 | 18 | { |
18 | | - const int64 Issued = CurrentTime.IsSet() ? CurrentTime.GetValue() : FDateTime::UtcNow().ToUnixTimestamp() - 30; |
| 19 | + const int64 Issued = CurrentTime.IsSet() ? CurrentTime.GetValue() : (FDateTime::UtcNow() + TimeShift).ToUnixTimestamp() - 30; |
19 | 20 | const int64 Expires = Issued + 86400; |
20 | 21 | FGenericData * LocalDataPtr = &Data; |
21 | 22 | const FString Operation = LocalDataPtr->Operation; |
@@ -269,26 +270,36 @@ void USequenceRPCManager::UpdateWithStoredSessionWallet() |
269 | 270 |
|
270 | 271 | USequenceRPCManager* USequenceRPCManager::Make(const bool UseStoredSessionId) |
271 | 272 | { |
| 273 | + USequenceRPCManager* Manager = nullptr; |
| 274 | + |
272 | 275 | if (UseStoredSessionId) |
273 | 276 | { |
274 | | - const USequenceAuthenticator * Authenticator = NewObject<USequenceAuthenticator>(); |
| 277 | + const USequenceAuthenticator* Authenticator = NewObject<USequenceAuthenticator>(); |
275 | 278 | if (FStoredCredentials_BE StoredCredentials = Authenticator->GetStoredCredentials(); StoredCredentials.GetValid()) |
276 | 279 | { |
277 | | - return Make(StoredCredentials.GetCredentials().GetSessionWallet()); |
| 280 | + Manager = Make(StoredCredentials.GetCredentials().GetSessionWallet()); |
278 | 281 | } |
279 | 282 | } |
280 | | - return Make(UCryptoWallet::Make()); |
| 283 | + |
| 284 | + if (!Manager) |
| 285 | + { |
| 286 | + Manager = Make(UCryptoWallet::Make()); |
| 287 | + } |
| 288 | + |
| 289 | + return Manager; |
281 | 290 | } |
282 | 291 |
|
283 | 292 | USequenceRPCManager* USequenceRPCManager::Make(UCryptoWallet* SessionWalletIn) |
284 | 293 | { |
285 | | - USequenceRPCManager * SequenceRPCManager = NewObject<USequenceRPCManager>(); |
| 294 | + USequenceRPCManager* SequenceRPCManager = NewObject<USequenceRPCManager>(); |
286 | 295 | SequenceRPCManager->SessionWallet = SessionWalletIn; |
287 | 296 | SequenceRPCManager->Validator = NewObject<UResponseSignatureValidator>(); |
288 | 297 | FString ParsedJwt; |
289 | | - FBase64::Decode(UConfigFetcher::GetConfigVar(UConfigFetcher::WaaSConfigKey),ParsedJwt); |
| 298 | + FBase64::Decode(UConfigFetcher::GetConfigVar(UConfigFetcher::WaaSConfigKey), ParsedJwt); |
290 | 299 | SequenceRPCManager->WaaSSettings = USequenceSupport::JSONStringToStruct<FWaasJWT>(ParsedJwt); |
291 | 300 | SequenceRPCManager->Cached_ProjectAccessKey = UConfigFetcher::GetConfigVar(UConfigFetcher::ProjectAccessKey); |
| 301 | + |
| 302 | + SequenceRPCManager->InitializeTimeShift(); |
292 | 303 | return SequenceRPCManager; |
293 | 304 | } |
294 | 305 |
|
@@ -1088,3 +1099,50 @@ void USequenceRPCManager::FederateSessionInUse(const FString& WalletIn, const TF |
1088 | 1099 | return this->BuildFederateAccountIntent(FederateAccountData, CurrentTime); |
1089 | 1100 | }, OnFederateResponse, OnFailure); |
1090 | 1101 | } |
| 1102 | + |
| 1103 | +void USequenceRPCManager::InitializeTimeShift() |
| 1104 | +{ |
| 1105 | + const FString WaasUrl = this->WaaSSettings.GetRPCServer(); |
| 1106 | + const FString StatusUrl = WaasUrl.EndsWith(TEXT("/")) ? WaasUrl + TEXT("status") : WaasUrl + TEXT("/status"); |
| 1107 | + |
| 1108 | + TSharedRef<IHttpRequest, ESPMode::ThreadSafe> HttpRequest = FHttpModule::Get().CreateRequest(); |
| 1109 | + HttpRequest->SetVerb(TEXT("GET")); |
| 1110 | + HttpRequest->SetURL(StatusUrl); |
| 1111 | + |
| 1112 | + HttpRequest->OnProcessRequestComplete().BindLambda([this](FHttpRequestPtr Request, FHttpResponsePtr Response, bool bSuccess) |
| 1113 | + { |
| 1114 | + if (bSuccess && Response.IsValid()) |
| 1115 | + { |
| 1116 | + const FString DateHeader = Response->GetHeader(TEXT("date")); |
| 1117 | + if (!DateHeader.IsEmpty()) |
| 1118 | + { |
| 1119 | + TimeShift = GetTimeShiftFromResponse(DateHeader); |
| 1120 | + } |
| 1121 | + else |
| 1122 | + { |
| 1123 | + UE_LOG(LogTemp, Warning, TEXT("No date header in response from status endpoint")); |
| 1124 | + TimeShift = FTimespan::Zero(); |
| 1125 | + } |
| 1126 | + } |
| 1127 | + else |
| 1128 | + { |
| 1129 | + UE_LOG(LogTemp, Warning, TEXT("Failed to get server time for time shift calculation")); |
| 1130 | + TimeShift = FTimespan::Zero(); |
| 1131 | + } |
| 1132 | + }); |
| 1133 | + |
| 1134 | + HttpRequest->ProcessRequest(); |
| 1135 | +} |
| 1136 | + |
| 1137 | +FTimespan USequenceRPCManager::GetTimeShiftFromResponse(const FString& DateHeader) |
| 1138 | +{ |
| 1139 | + FDateTime ServerTime; |
| 1140 | + if (FDateTime::ParseHttpDate(DateHeader, ServerTime)) |
| 1141 | + { |
| 1142 | + const FDateTime LocalTime = FDateTime::UtcNow(); |
| 1143 | + return ServerTime - LocalTime; |
| 1144 | + } |
| 1145 | + |
| 1146 | + UE_LOG(LogTemp, Warning, TEXT("Failed to parse server time from date header: %s"), *DateHeader); |
| 1147 | + return FTimespan::Zero(); |
| 1148 | +} |
0 commit comments