Skip to content

Commit

Permalink
Merge pull request #14012 from nextcloud/bugfix/noid/check-server-times
Browse files Browse the repository at this point in the history
fix(backends): Check times of the backend servers
  • Loading branch information
nickvergessen authored Dec 18, 2024
2 parents 0008f68 + ef632ef commit bab0241
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use OCP\Security\ISecureRandom;

class Config {
public const ALLOWED_BACKEND_TIMEOFFSET = 45;
public const SIGNALING_INTERNAL = 'internal';
public const SIGNALING_EXTERNAL = 'external';
public const SIGNALING_CLUSTER_CONVERSATION = 'conversation_cluster';
Expand Down
12 changes: 12 additions & 0 deletions lib/Controller/RecordingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use OCP\AppFramework\Http\Attribute\OpenAPI;
use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Http\Client\IClientService;
use OCP\IRequest;
use Psr\Log\LoggerInterface;
Expand All @@ -44,6 +45,7 @@ public function __construct(
private ParticipantService $participantService,
private RecordingService $recordingService,
private RoomService $roomService,
private ITimeFactory $timeFactory,
private LoggerInterface $logger,
) {
parent::__construct($appName, $request);
Expand Down Expand Up @@ -81,19 +83,29 @@ public function getWelcomeMessage(int $serverId): DataResponse {

$client = $this->clientService->newClient();
try {
$timeBefore = $this->timeFactory->getTime();
$response = $client->get($url . '/api/v1/welcome', [
'verify' => $verifyServer,
'nextcloud' => [
'allow_local_address' => true,
],
]);
$timeAfter = $this->timeFactory->getTime();

if ($response->getHeader(\OCA\Talk\Signaling\Manager::FEATURE_HEADER)) {
return new DataResponse([
'error' => 'IS_SIGNALING_SERVER',
], Http::STATUS_INTERNAL_SERVER_ERROR);
}

$responseTime = $this->timeFactory->getDateTime($response->getHeader('date'))->getTimestamp();
if (($timeBefore - Config::ALLOWED_BACKEND_TIMEOFFSET) > $responseTime
|| ($timeAfter + Config::ALLOWED_BACKEND_TIMEOFFSET) < $responseTime) {
return new DataResponse([
'error' => 'TIME_OUT_OF_SYNC',
], Http::STATUS_INTERNAL_SERVER_ERROR);
}

$body = $response->getBody();
$data = json_decode($body, true);

Expand Down
10 changes: 10 additions & 0 deletions lib/Controller/SignalingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,14 @@ public function getWelcomeMessage(int $serverId): DataResponse {

$client = $this->clientService->newClient();
try {
$timeBefore = $this->timeFactory->getTime();
$response = $client->get($url . '/api/v1/welcome', [
'verify' => $verifyServer,
'nextcloud' => [
'allow_local_address' => true,
],
]);
$timeAfter = $this->timeFactory->getTime();

$body = $response->getBody();
$data = json_decode($body, true);
Expand All @@ -330,6 +332,14 @@ public function getWelcomeMessage(int $serverId): DataResponse {
], Http::STATUS_INTERNAL_SERVER_ERROR);
}

$responseTime = $this->timeFactory->getDateTime($response->getHeader('date'))->getTimestamp();
if (($timeBefore - Config::ALLOWED_BACKEND_TIMEOFFSET) > $responseTime
|| ($timeAfter + Config::ALLOWED_BACKEND_TIMEOFFSET) < $responseTime) {
return new DataResponse([
'error' => 'TIME_OUT_OF_SYNC',
], Http::STATUS_INTERNAL_SERVER_ERROR);
}

$missingFeatures = $this->signalingManager->getSignalingServerMissingFeatures($response);
if (!empty($missingFeatures)) {
return new DataResponse([
Expand Down
2 changes: 2 additions & 0 deletions src/components/AdminSettings/RecordingServer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ export default {
this.errorMessage = t('spreed', 'Error: Server did not respond with proper JSON')
} else if (error === 'CERTIFICATE_EXPIRED') {
this.errorMessage = t('spreed', 'Error: Certificate expired')
} else if (error === 'TIME_OUT_OF_SYNC') {
this.errorMessage = t('spreed', 'Error: System times of Nextcloud server and Recording backend server are out of sync. Please make sure that both servers are connected to a time-server or manually synchronize their time.')
} else if (error) {
this.errorMessage = t('spreed', 'Error: Server responded with: {error}', data)
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/components/AdminSettings/SignalingServer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ export default {
this.errorMessage = t('spreed', 'Error: Server did not respond with proper JSON')
} else if (error === 'CERTIFICATE_EXPIRED') {
this.errorMessage = t('spreed', 'Error: Certificate expired')
} else if (error === 'TIME_OUT_OF_SYNC') {
this.errorMessage = t('spreed', 'Error: System times of Nextcloud server and High-performance backend server are out of sync. Please make sure that both servers are connected to a time-server or manually synchronize their time.')
} else if (error === 'UPDATE_REQUIRED') {
this.versionFound = data.version || t('spreed', 'Could not get version')
this.errorMessage = t('spreed', 'Error: Running version: {version}; Server needs to be updated to be compatible with this version of Talk', {
Expand Down

0 comments on commit bab0241

Please sign in to comment.