From 51d85eb2f84675f292279fc4d5977c958620e802 Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle <bjoern@schiessle.org>
Date: Fri, 28 Jul 2017 14:43:35 +0200
Subject: expire getShareadSecret job after 30 days

Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
---
 .../lib/BackgroundJob/GetSharedSecret.php          | 39 ++++++++++++++++++++--
 .../lib/Controller/OCSAuthAPIController.php        |  5 +++
 .../tests/Controller/OCSAuthAPIControllerTest.php  | 28 ++++++++++------
 3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/apps/federation/lib/BackgroundJob/GetSharedSecret.php b/apps/federation/lib/BackgroundJob/GetSharedSecret.php
index 8a8d475da61..761ad951e73 100644
--- a/apps/federation/lib/BackgroundJob/GetSharedSecret.php
+++ b/apps/federation/lib/BackgroundJob/GetSharedSecret.php
@@ -76,6 +76,9 @@ class GetSharedSecret extends Job{
 
 	private $defaultEndPoint = '/ocs/v2.php/apps/federation/api/v1/shared-secret';
 
+	/** @var  int  30 day = 2592000sec */
+	private $maxLifespan = 2592000;
+
 	/**
 	 * RequestSharedSecret constructor.
 	 *
@@ -130,8 +133,10 @@ class GetSharedSecret extends Job{
 			$this->parentExecute($jobList, $logger);
 		}
 
-		if (!$this->retainJob) {
-			$jobList->remove($this, $this->argument);
+		$jobList->remove($this, $this->argument);
+
+		if ($this->retainJob) {
+			$this->reAddJob($jobList, $this->argument);
 		}
 	}
 
@@ -147,10 +152,20 @@ class GetSharedSecret extends Job{
 
 	protected function run($argument) {
 		$target = $argument['url'];
+		$created = isset($argument['created']) ? (int)$argument['created'] : time();
+		$currentTime = time();
 		$source = $this->urlGenerator->getAbsoluteURL('/');
 		$source = rtrim($source, '/');
 		$token = $argument['token'];
 
+		// kill job after 30 days of trying
+		$deadline = $currentTime - $this->maxLifespan;
+		if ($created < $deadline) {
+			$this->retainJob = false;
+			$this->trustedServers->setServerStatus($target,TrustedServers::STATUS_FAILURE);
+			return;
+		}
+
 		$endPoints = $this->ocsDiscoveryService->discover($target, 'FEDERATED_SHARING');
 		$endPoint = isset($endPoints['shared-secret']) ? $endPoints['shared-secret'] : $this->defaultEndPoint;
 
@@ -215,4 +230,24 @@ class GetSharedSecret extends Job{
 		}
 
 	}
+
+	/**
+	 * re-add background job
+	 *
+	 * @param IJobList $jobList
+	 * @param array $argument
+	 */
+	protected function reAddJob(IJobList $jobList, array $argument) {
+		$url = $argument['url'];
+		$created = isset($argument['created']) ? (int)$argument['created'] : time();
+		$token = $argument['token'];
+		$this->jobList->add(
+			GetSharedSecret::class,
+			[
+				'url' => $url,
+				'token' => $token,
+				'created' => $created
+			]
+		);
+	}
 }
diff --git a/apps/federation/lib/Controller/OCSAuthAPIController.php b/apps/federation/lib/Controller/OCSAuthAPIController.php
index 594299a2d02..a2a608babac 100644
--- a/apps/federation/lib/Controller/OCSAuthAPIController.php
+++ b/apps/federation/lib/Controller/OCSAuthAPIController.php
@@ -163,6 +163,7 @@ class OCSAuthAPIController extends OCSController{
 			[
 				'url' => $url,
 				'token' => $token,
+				'created' => $this->getTimestamp()
 			]
 		);
 
@@ -211,4 +212,8 @@ class OCSAuthAPIController extends OCSController{
 		return hash_equals($storedToken, $token);
 	}
 
+	protected function getTimestamp() {
+		return time();
+	}
+
 }
diff --git a/apps/federation/tests/Controller/OCSAuthAPIControllerTest.php b/apps/federation/tests/Controller/OCSAuthAPIControllerTest.php
index 2b231b4fca0..41bfd70bfc5 100644
--- a/apps/federation/tests/Controller/OCSAuthAPIControllerTest.php
+++ b/apps/federation/tests/Controller/OCSAuthAPIControllerTest.php
@@ -59,6 +59,9 @@ class OCSAuthAPIControllerTest extends TestCase {
 	/** @var  OCSAuthAPIController */
 	private $ocsAuthApi;
 
+	/** @var int simulated timestamp */
+	private $currentTime = 1234567;
+
 	public function setUp() {
 		parent::setUp();
 
@@ -73,15 +76,20 @@ class OCSAuthAPIControllerTest extends TestCase {
 		$this->logger = $this->getMockBuilder('OCP\ILogger')
 			->disableOriginalConstructor()->getMock();
 
-		$this->ocsAuthApi = new OCSAuthAPIController(
-			'federation',
-			$this->request,
-			$this->secureRandom,
-			$this->jobList,
-			$this->trustedServers,
-			$this->dbHandler,
-			$this->logger
-		);
+		$this->ocsAuthApi = $this->getMockBuilder(OCSAuthAPIController::class)
+			->setConstructorArgs(
+				[
+					'federation',
+					$this->request,
+					$this->secureRandom,
+					$this->jobList,
+					$this->trustedServers,
+					$this->dbHandler,
+					$this->logger
+				]
+			)->setMethods(['getTimestamp'])->getMock();
+
+		$this->ocsAuthApi->expects($this->any())->method('getTimestamp')->willReturn($this->currentTime);
 
 	}
 
@@ -105,7 +113,7 @@ class OCSAuthAPIControllerTest extends TestCase {
 
 		if ($ok) {
 			$this->jobList->expects($this->once())->method('add')
-				->with('OCA\Federation\BackgroundJob\GetSharedSecret', ['url' => $url, 'token' => $token]);
+				->with('OCA\Federation\BackgroundJob\GetSharedSecret', ['url' => $url, 'token' => $token, 'created' => $this->currentTime]);
 			$this->jobList->expects($this->once())->method('remove')
 				->with('OCA\Federation\BackgroundJob\RequestSharedSecret', ['url' => $url, 'token' => $localToken]);
 		} else {
-- 
cgit v1.2.3