Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(backends): Check times of the backend servers #14012

Merged
merged 1 commit into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading