summaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/AppFramework/OCS/BaseResponse.php58
-rw-r--r--lib/private/Authentication/Exceptions/ExpiredTokenException.php41
-rw-r--r--lib/private/Authentication/Token/DefaultToken.php116
-rw-r--r--lib/private/Authentication/Token/DefaultTokenMapper.php27
-rw-r--r--lib/private/Authentication/Token/DefaultTokenProvider.php77
-rw-r--r--lib/private/Authentication/Token/IProvider.php41
-rw-r--r--lib/private/Authentication/Token/IToken.php51
-rw-r--r--lib/private/Files/AppData/AppData.php16
-rw-r--r--lib/private/Files/AppData/Factory.php3
-rw-r--r--lib/private/Preview/BackgroundCleanupJob.php91
-rw-r--r--lib/private/Preview/Watcher.php48
-rw-r--r--lib/private/Preview/WatcherConnector.php11
-rw-r--r--lib/private/Repair.php4
-rw-r--r--lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php48
-rw-r--r--lib/private/Setup.php2
15 files changed, 480 insertions, 154 deletions
diff --git a/lib/private/AppFramework/OCS/BaseResponse.php b/lib/private/AppFramework/OCS/BaseResponse.php
index 59b8660a382..b27784cfcf2 100644
--- a/lib/private/AppFramework/OCS/BaseResponse.php
+++ b/lib/private/AppFramework/OCS/BaseResponse.php
@@ -22,6 +22,7 @@
*/
namespace OC\AppFramework\OCS;
+use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\EmptyContentSecurityPolicy;
use OCP\AppFramework\Http\Response;
@@ -85,9 +86,60 @@ abstract class BaseResponse extends Response {
* @param string[] $meta
* @return string
*/
- protected function renderResult($meta) {
- // TODO rewrite functions
- return \OC_API::renderResult($this->format, $meta, $this->data);
+ protected function renderResult(array $meta): string {
+ $status = $this->getStatus();
+ if ($status === Http::STATUS_NO_CONTENT ||
+ $status === Http::STATUS_NOT_MODIFIED ||
+ ($status >= 100 && $status <= 199)) {
+ // Those status codes are not supposed to have a body:
+ // https://stackoverflow.com/q/8628725
+ return '';
+ }
+
+ $response = [
+ 'ocs' => [
+ 'meta' => $meta,
+ 'data' => $this->data,
+ ],
+ ];
+
+ if ($this->format === 'json') {
+ return json_encode($response, JSON_HEX_TAG);
+ }
+
+ $writer = new \XMLWriter();
+ $writer->openMemory();
+ $writer->setIndent(true);
+ $writer->startDocument();
+ $this->toXML($response, $writer);
+ $writer->endDocument();
+ return $writer->outputMemory(true);
+
+ }
+
+ /**
+ * @param array $array
+ * @param \XMLWriter $writer
+ */
+ protected function toXML(array $array, \XMLWriter $writer) {
+ foreach ($array as $k => $v) {
+ if ($k[0] === '@') {
+ $writer->writeAttribute(substr($k, 1), $v);
+ continue;
+ }
+
+ if (\is_numeric($k)) {
+ $k = 'element';
+ }
+
+ if (\is_array($v)) {
+ $writer->startElement($k);
+ $this->toXML($v, $writer);
+ $writer->endElement();
+ } else {
+ $writer->writeElement($k, $v);
+ }
+ }
}
public function getOCSStatus() {
diff --git a/lib/private/Authentication/Exceptions/ExpiredTokenException.php b/lib/private/Authentication/Exceptions/ExpiredTokenException.php
new file mode 100644
index 00000000000..a45ca5b6955
--- /dev/null
+++ b/lib/private/Authentication/Exceptions/ExpiredTokenException.php
@@ -0,0 +1,41 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OC\Authentication\Token;
+
+use OC\Authentication\Exceptions\InvalidTokenException;
+
+class ExpiredTokenException extends InvalidTokenException {
+ /** @var IToken */
+ private $token;
+
+ public function __construct(IToken $token) {
+ parent::__construct();
+
+ $this->token = $token;
+ }
+
+ public function getToken(): IToken {
+ return $this->token;
+ }
+}
diff --git a/lib/private/Authentication/Token/DefaultToken.php b/lib/private/Authentication/Token/DefaultToken.php
index e06803d0bfc..67aa89ea66b 100644
--- a/lib/private/Authentication/Token/DefaultToken.php
+++ b/lib/private/Authentication/Token/DefaultToken.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -28,82 +29,69 @@ use OCP\AppFramework\Db\Entity;
/**
* @method void setId(int $id)
* @method void setUid(string $uid);
- * @method void setLoginName(string $loginName)
- * @method void setPassword(string $password)
+ * @method void setLoginName(string $loginname)
* @method void setName(string $name)
- * @method string getName()
- * @method void setToken(string $token)
* @method string getToken()
- * @method void setType(string $type)
+ * @method void setType(int $type)
* @method int getType()
* @method void setRemember(int $remember)
- * @method int getRemember()
- * @method void setLastActivity(int $lastActivity)
+ * @method void setLastActivity(int $lastactivity)
* @method int getLastActivity()
*/
class DefaultToken extends Entity implements IToken {
- /**
- * @var string user UID
- */
+ /** @var string user UID */
protected $uid;
- /**
- * @var string login name used for generating the token
- */
+ /** @var string login name used for generating the token */
protected $loginName;
- /**
- * @var string encrypted user password
- */
+ /** @var string encrypted user password */
protected $password;
- /**
- * @var string token name (e.g. browser/OS)
- */
+ /** @var string token name (e.g. browser/OS) */
protected $name;
- /**
- * @var string
- */
+ /** @var string */
protected $token;
- /**
- * @var int
- */
+ /** @var int */
protected $type;
- /**
- * @var int
- */
+ /** @var int */
protected $remember;
- /**
- * @var int
- */
+ /** @var int */
protected $lastActivity;
- /**
- * @var int
- */
+ /** @var int */
protected $lastCheck;
- /**
- * @var string
- */
+ /** @var string */
protected $scope;
+ /** @var int */
+ protected $expires;
+
public function __construct() {
+ $this->addType('uid', 'string');
+ $this->addType('loginName', 'string');
+ $this->addType('password', 'string');
+ $this->addType('name', 'string');
+ $this->addType('token', 'string');
$this->addType('type', 'int');
+ $this->addType('remember', 'int');
$this->addType('lastActivity', 'int');
$this->addType('lastCheck', 'int');
+ $this->addType('scope', 'string');
+ $this->addType('expires', 'int');
}
- public function getId() {
+ public function getId(): int {
return $this->id;
}
- public function getUID() {
+ public function getUID(): string {
return $this->uid;
}
@@ -112,14 +100,14 @@ class DefaultToken extends Entity implements IToken {
*
* @return string
*/
- public function getLoginName() {
+ public function getLoginName(): string {
return parent::getLoginName();
}
/**
* Get the (encrypted) login password
*
- * @return string
+ * @return string|null
*/
public function getPassword() {
return parent::getPassword();
@@ -140,7 +128,7 @@ class DefaultToken extends Entity implements IToken {
*
* @return int
*/
- public function getLastCheck() {
+ public function getLastCheck(): int {
return parent::getLastCheck();
}
@@ -149,15 +137,20 @@ class DefaultToken extends Entity implements IToken {
*
* @param int $time
*/
- public function setLastCheck($time) {
- return parent::setLastCheck($time);
+ public function setLastCheck(int $time) {
+ parent::setLastCheck($time);
}
- public function getScope() {
- return parent::getScope();
+ public function getScope(): string {
+ $scope = parent::getScope();
+ if ($scope === null) {
+ return '';
+ }
+
+ return $scope;
}
- public function getScopeAsArray() {
+ public function getScopeAsArray(): array {
$scope = json_decode($this->getScope(), true);
if (!$scope) {
return [
@@ -168,10 +161,37 @@ class DefaultToken extends Entity implements IToken {
}
public function setScope($scope) {
- if (is_array($scope)) {
+ if (\is_array($scope)) {
parent::setScope(json_encode($scope));
} else {
parent::setScope((string)$scope);
}
}
+
+ public function getName(): string {
+ return parent::getName();
+ }
+
+ public function getRemember(): int {
+ return parent::getRemember();
+ }
+
+ public function setToken(string $token) {
+ parent::setToken($token);
+ }
+
+ public function setPassword(string $password = null) {
+ parent::setPassword($password);
+ }
+
+ public function setExpires($expires) {
+ parent::setExpires($expires);
+ }
+
+ /**
+ * @return int|null
+ */
+ public function getExpires() {
+ return parent::getExpires();
+ }
}
diff --git a/lib/private/Authentication/Token/DefaultTokenMapper.php b/lib/private/Authentication/Token/DefaultTokenMapper.php
index 41d1b9f203d..a67d7d151e9 100644
--- a/lib/private/Authentication/Token/DefaultTokenMapper.php
+++ b/lib/private/Authentication/Token/DefaultTokenMapper.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -29,12 +30,12 @@
namespace OC\Authentication\Token;
use OCP\AppFramework\Db\DoesNotExistException;
-use OCP\AppFramework\Db\Mapper;
+use OCP\AppFramework\Db\QBMapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\IUser;
-class DefaultTokenMapper extends Mapper {
+class DefaultTokenMapper extends QBMapper {
public function __construct(IDBConnection $db) {
parent::__construct($db, 'authtoken');
@@ -45,7 +46,7 @@ class DefaultTokenMapper extends Mapper {
*
* @param string $token
*/
- public function invalidate($token) {
+ public function invalidate(string $token) {
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
$qb->delete('authtoken')
@@ -58,7 +59,7 @@ class DefaultTokenMapper extends Mapper {
* @param int $olderThan
* @param int $remember
*/
- public function invalidateOld($olderThan, $remember = IToken::DO_NOT_REMEMBER) {
+ public function invalidateOld(int $olderThan, int $remember = IToken::DO_NOT_REMEMBER) {
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
$qb->delete('authtoken')
@@ -75,10 +76,10 @@ class DefaultTokenMapper extends Mapper {
* @throws DoesNotExistException
* @return DefaultToken
*/
- public function getToken($token) {
+ public function getToken(string $token): DefaultToken {
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
- $result = $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'remember', 'token', 'last_activity', 'last_check', 'scope')
+ $result = $qb->select('*')
->from('authtoken')
->where($qb->expr()->eq('token', $qb->createNamedParameter($token)))
->execute();
@@ -94,14 +95,14 @@ class DefaultTokenMapper extends Mapper {
/**
* Get the token for $id
*
- * @param string $id
+ * @param int $id
* @throws DoesNotExistException
* @return DefaultToken
*/
- public function getTokenById($id) {
+ public function getTokenById(int $id): DefaultToken {
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
- $result = $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'token', 'last_activity', 'last_check', 'scope')
+ $result = $qb->select('*')
->from('authtoken')
->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
->execute();
@@ -123,10 +124,10 @@ class DefaultTokenMapper extends Mapper {
* @param IUser $user
* @return DefaultToken[]
*/
- public function getTokenByUser(IUser $user) {
+ public function getTokenByUser(IUser $user): array {
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
- $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'remember', 'token', 'last_activity', 'last_check', 'scope')
+ $qb->select('*')
->from('authtoken')
->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
->setMaxResults(1000);
@@ -145,7 +146,7 @@ class DefaultTokenMapper extends Mapper {
* @param IUser $user
* @param int $id
*/
- public function deleteById(IUser $user, $id) {
+ public function deleteById(IUser $user, int $id) {
/* @var $qb IQueryBuilder */
$qb = $this->db->getQueryBuilder();
$qb->delete('authtoken')
@@ -159,7 +160,7 @@ class DefaultTokenMapper extends Mapper {
*
* @param string $name
*/
- public function deleteByName($name) {
+ public function deleteByName(string $name) {
$qb = $this->db->getQueryBuilder();
$qb->delete('authtoken')
->where($qb->expr()->eq('name', $qb->createNamedParameter($name), IQueryBuilder::PARAM_STR));
diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php
index 36a8b1d5464..5df74cadac4 100644
--- a/lib/private/Authentication/Token/DefaultTokenProvider.php
+++ b/lib/private/Authentication/Token/DefaultTokenProvider.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @copyright Copyright (c) 2016, Christoph Wurst <christoph@winzerhof-wurst.at>
@@ -85,7 +86,13 @@ class DefaultTokenProvider implements IProvider {
* @param int $remember whether the session token should be used for remember-me
* @return IToken
*/
- public function generateToken($token, $uid, $loginName, $password, $name, $type = IToken::TEMPORARY_TOKEN, $remember = IToken::DO_NOT_REMEMBER) {
+ public function generateToken(string $token,
+ string $uid,
+ string $loginName,
+ $password,
+ string $name,
+ int $type = IToken::TEMPORARY_TOKEN,
+ int $remember = IToken::DO_NOT_REMEMBER): IToken {
$dbToken = new DefaultToken();
$dbToken->setUid($uid);
$dbToken->setLoginName($loginName);
@@ -145,7 +152,7 @@ class DefaultTokenProvider implements IProvider {
* @param IUser $user
* @return IToken[]
*/
- public function getTokenByUser(IUser $user) {
+ public function getTokenByUser(IUser $user): array {
return $this->mapper->getTokenByUser($user);
}
@@ -154,29 +161,43 @@ class DefaultTokenProvider implements IProvider {
*
* @param string $tokenId
* @throws InvalidTokenException
- * @return DefaultToken
+ * @throws ExpiredTokenException
+ * @return IToken
*/
- public function getToken($tokenId) {
+ public function getToken(string $tokenId): IToken {
try {
- return $this->mapper->getToken($this->hashToken($tokenId));
+ $token = $this->mapper->getToken($this->hashToken($tokenId));
} catch (DoesNotExistException $ex) {
throw new InvalidTokenException();
}
+
+ if ($token->getExpires() !== null && $token->getExpires() < $this->time->getTime()) {
+ throw new ExpiredTokenException($token);
+ }
+
+ return $token;
}
/**
* Get a token by token id
*
- * @param string $tokenId
+ * @param int $tokenId
* @throws InvalidTokenException
- * @return DefaultToken
+ * @throws ExpiredTokenException
+ * @return IToken
*/
- public function getTokenById($tokenId) {
+ public function getTokenById(int $tokenId): IToken {
try {
- return $this->mapper->getTokenById($tokenId);
+ $token = $this->mapper->getTokenById($tokenId);
} catch (DoesNotExistException $ex) {
throw new InvalidTokenException();
}
+
+ if ($token->getExpires() !== null && $token->getExpires() < $this->time->getTime()) {
+ throw new ExpiredTokenException($token);
+ }
+
+ return $token;
}
/**
@@ -184,7 +205,7 @@ class DefaultTokenProvider implements IProvider {
* @param string $sessionId
* @throws InvalidTokenException
*/
- public function renewSessionToken($oldSessionId, $sessionId) {
+ public function renewSessionToken(string $oldSessionId, string $sessionId) {
$token = $this->getToken($oldSessionId);
$newToken = new DefaultToken();
@@ -210,7 +231,7 @@ class DefaultTokenProvider implements IProvider {
* @throws PasswordlessTokenException
* @return string
*/
- public function getPassword(IToken $savedToken, $tokenId) {
+ public function getPassword(IToken $savedToken, string $tokenId): string {
$password = $savedToken->getPassword();
if (is_null($password)) {
throw new PasswordlessTokenException();
@@ -226,7 +247,7 @@ class DefaultTokenProvider implements IProvider {
* @param string $password
* @throws InvalidTokenException
*/
- public function setPassword(IToken $token, $tokenId, $password) {
+ public function setPassword(IToken $token, string $tokenId, string $password) {
if (!($token instanceof DefaultToken)) {
throw new InvalidTokenException();
}
@@ -240,7 +261,7 @@ class DefaultTokenProvider implements IProvider {
*
* @param string $token
*/
- public function invalidateToken($token) {
+ public function invalidateToken(string $token) {
$this->mapper->invalidate($this->hashToken($token));
}
@@ -250,7 +271,7 @@ class DefaultTokenProvider implements IProvider {
* @param IUser $user
* @param int $id
*/
- public function invalidateTokenById(IUser $user, $id) {
+ public function invalidateTokenById(IUser $user, int $id) {
$this->mapper->deleteById($user, $id);
}
@@ -267,10 +288,32 @@ class DefaultTokenProvider implements IProvider {
}
/**
+ * Rotate the token. Usefull for for example oauth tokens
+ *
+ * @param IToken $token
+ * @param string $oldTokenId
+ * @param string $newTokenId
+ * @return IToken
+ */
+ public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken {
+ try {
+ $password = $this->getPassword($token, $oldTokenId);
+ $token->setPassword($this->encryptPassword($password, $newTokenId));
+ } catch (PasswordlessTokenException $e) {
+
+ }
+
+ $token->setToken($this->hashToken($newTokenId));
+ $this->updateToken($token);
+
+ return $token;
+ }
+
+ /**
* @param string $token
* @return string
*/
- private function hashToken($token) {
+ private function hashToken(string $token) {
$secret = $this->config->getSystemValue('secret');
return hash('sha512', $token . $secret);
}
@@ -284,7 +327,7 @@ class DefaultTokenProvider implements IProvider {
* @param string $token
* @return string encrypted password
*/
- private function encryptPassword($password, $token) {
+ private function encryptPassword(string $password, string $token): string {
$secret = $this->config->getSystemValue('secret');
return $this->crypto->encrypt($password, $token . $secret);
}
@@ -299,7 +342,7 @@ class DefaultTokenProvider implements IProvider {
* @throws InvalidTokenException
* @return string the decrypted key
*/
- private function decryptPassword($password, $token) {
+ private function decryptPassword(string $password, string $token): string {
$secret = $this->config->getSystemValue('secret');
try {
return $this->crypto->decrypt($password, $token . $secret);
diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php
index e1cc8182ff0..0efffefac68 100644
--- a/lib/private/Authentication/Token/IProvider.php
+++ b/lib/private/Authentication/Token/IProvider.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -44,25 +45,33 @@ interface IProvider {
* @param int $remember whether the session token should be used for remember-me
* @return IToken
*/
- public function generateToken($token, $uid, $loginName, $password, $name, $type = IToken::TEMPORARY_TOKEN, $remember = IToken::DO_NOT_REMEMBER);
+ public function generateToken(string $token,
+ string $uid,
+ string $loginName,
+ $password,
+ string $name,
+ int $type = IToken::TEMPORARY_TOKEN,
+ int $remember = IToken::DO_NOT_REMEMBER): IToken;
/**
* Get a token by token id
*
* @param string $tokenId
* @throws InvalidTokenException
+ * @throws ExpiredTokenException
* @return IToken
*/
- public function getToken($tokenId);
+ public function getToken(string $tokenId): IToken;
/**
* Get a token by token id
*
- * @param string $tokenId
+ * @param int $tokenId
* @throws InvalidTokenException
- * @return DefaultToken
+ * @throws ExpiredTokenException
+ * @return IToken
*/
- public function getTokenById($tokenId);
+ public function getTokenById(int $tokenId): IToken;
/**
* Duplicate an existing session token
@@ -71,14 +80,14 @@ interface IProvider {
* @param string $sessionId
* @throws InvalidTokenException
*/
- public function renewSessionToken($oldSessionId, $sessionId);
+ public function renewSessionToken(string $oldSessionId, string $sessionId);
/**
* Invalidate (delete) the given session token
*
* @param string $token
*/
- public function invalidateToken($token);
+ public function invalidateToken(string $token);
/**
* Invalidate (delete) the given token
@@ -86,7 +95,7 @@ interface IProvider {
* @param IUser $user
* @param int $id
*/
- public function invalidateTokenById(IUser $user, $id);
+ public function invalidateTokenById(IUser $user, int $id);
/**
* Invalidate (delete) old session tokens
@@ -116,7 +125,7 @@ interface IProvider {
* @param IUser $user
* @return IToken[]
*/
- public function getTokenByUser(IUser $user);
+ public function getTokenByUser(IUser $user): array;
/**
* Get the (unencrypted) password of the given token
@@ -127,7 +136,7 @@ interface IProvider {
* @throws PasswordlessTokenException
* @return string
*/
- public function getPassword(IToken $token, $tokenId);
+ public function getPassword(IToken $token, string $tokenId): string;
/**
* Encrypt and set the password of the given token
@@ -137,5 +146,15 @@ interface IProvider {
* @param string $password
* @throws InvalidTokenException
*/
- public function setPassword(IToken $token, $tokenId, $password);
+ public function setPassword(IToken $token, string $tokenId, string $password);
+
+ /**
+ * Rotate the token. Usefull for for example oauth tokens
+ *
+ * @param IToken $token
+ * @param string $oldTokenId
+ * @param string $newTokenId
+ * @return IToken
+ */
+ public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken;
}
diff --git a/lib/private/Authentication/Token/IToken.php b/lib/private/Authentication/Token/IToken.php
index a24d31e2ed2..e122ec02764 100644
--- a/lib/private/Authentication/Token/IToken.php
+++ b/lib/private/Authentication/Token/IToken.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -37,26 +38,26 @@ interface IToken extends JsonSerializable {
*
* @return int
*/
- public function getId();
+ public function getId(): int;
/**
* Get the user UID
*
* @return string
*/
- public function getUID();
+ public function getUID(): string;
/**
* Get the login name used when generating the token
*
* @return string
*/
- public function getLoginName();
+ public function getLoginName(): string;
/**
* Get the (encrypted) login password
*
- * @return string
+ * @return string|null
*/
public function getPassword();
@@ -65,28 +66,28 @@ interface IToken extends JsonSerializable {
*
* @return int
*/
- public function getLastCheck();
+ public function getLastCheck(): int;
/**
* Set the timestamp of the last password check
*
* @param int $time
*/
- public function setLastCheck($time);
+ public function setLastCheck(int $time);
/**
* Get the authentication scope for this token
*
* @return string
*/
- public function getScope();
+ public function getScope(): string;
/**
* Get the authentication scope for this token
*
* @return array
*/
- public function getScopeAsArray();
+ public function getScopeAsArray(): array;
/**
* Set the authentication scope for this token
@@ -94,4 +95,38 @@ interface IToken extends JsonSerializable {
* @param array $scope
*/
public function setScope($scope);
+
+ /**
+ * Get the name of the token
+ * @return string
+ */
+ public function getName(): string;
+
+ /**
+ * Get the remember state of the token
+ *
+ * @return int
+ */
+ public function getRemember(): int;
+
+ /**
+ * Set the token
+ *
+ * @param string $token
+ */
+ public function setToken(string $token);
+
+ /**
+ * Set the password
+ *
+ * @param string $password
+ */
+ public function setPassword(string $password);
+
+ /**
+ * Set the expiration time of the token
+ *
+ * @param int|null $expires
+ */
+ public function setExpires($expires);
}
diff --git a/lib/private/Files/AppData/AppData.php b/lib/private/Files/AppData/AppData.php
index 270e834b8e5..e25bf450446 100644
--- a/lib/private/Files/AppData/AppData.php
+++ b/lib/private/Files/AppData/AppData.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
*
@@ -31,6 +32,7 @@ use OC\SystemConfig;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
+use OCP\Files\SimpleFS\ISimpleFolder;
class AppData implements IAppData {
@@ -55,7 +57,7 @@ class AppData implements IAppData {
*/
public function __construct(IRootFolder $rootFolder,
SystemConfig $systemConfig,
- $appId) {
+ string $appId) {
$this->rootFolder = $rootFolder;
$this->config = $systemConfig;
@@ -66,7 +68,7 @@ class AppData implements IAppData {
* @return Folder
* @throws \RuntimeException
*/
- private function getAppDataFolder() {
+ private function getAppDataFolder(): Folder {
if ($this->folder === null) {
$instanceId = $this->config->getValue('instanceid', null);
if ($instanceId === null) {
@@ -101,20 +103,20 @@ class AppData implements IAppData {
return $this->folder;
}
- public function getFolder($name) {
+ public function getFolder(string $name): ISimpleFolder {
$node = $this->getAppDataFolder()->get($name);
/** @var Folder $node */
return new SimpleFolder($node);
}
- public function newFolder($name) {
+ public function newFolder(string $name): ISimpleFolder {
$folder = $this->getAppDataFolder()->newFolder($name);
return new SimpleFolder($folder);
}
- public function getDirectoryListing() {
+ public function getDirectoryListing(): array {
$listing = $this->getAppDataFolder()->getDirectoryListing();
$fileListing = array_map(function(Node $folder) {
@@ -128,4 +130,8 @@ class AppData implements IAppData {
return array_values($fileListing);
}
+
+ public function getId(): int {
+ return $this->getAppDataFolder()->getId();
+ }
}
diff --git a/lib/private/Files/AppData/Factory.php b/lib/private/Files/AppData/Factory.php
index 85c75733796..fba2232db06 100644
--- a/lib/private/Files/AppData/Factory.php
+++ b/lib/private/Files/AppData/Factory.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
*
@@ -44,7 +45,7 @@ class Factory {
* @param string $appId
* @return AppData
*/
- public function get($appId) {
+ public function get(string $appId): AppData {
return new AppData($this->rootFolder, $this->config, $appId);
}
}
diff --git a/lib/private/Preview/BackgroundCleanupJob.php b/lib/private/Preview/BackgroundCleanupJob.php
new file mode 100644
index 00000000000..25bf354e28b
--- /dev/null
+++ b/lib/private/Preview/BackgroundCleanupJob.php
@@ -0,0 +1,91 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2018, Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Preview;
+
+use OC\BackgroundJob\TimedJob;
+use OC\Files\AppData\Factory;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\Files\NotFoundException;
+use OCP\Files\NotPermittedException;
+use OCP\IDBConnection;
+
+class BackgroundCleanupJob extends TimedJob {
+
+ /** @var IDBConnection */
+ private $connection;
+
+ /** @var Factory */
+ private $appDataFactory;
+
+ /** @var bool */
+ private $isCLI;
+
+ public function __construct(IDBConnection $connection,
+ Factory $appDataFactory,
+ bool $isCLI) {
+ // Run at most once an hour
+ $this->setInterval(3600);
+
+ $this->connection = $connection;
+ $this->appDataFactory = $appDataFactory;
+ $this->isCLI = $isCLI;
+ }
+
+ public function run($argument) {
+ $previews = $this->appDataFactory->get('preview');
+
+ $previewFodlerId = $previews->getId();
+
+ $qb = $this->connection->getQueryBuilder();
+ $qb->select('a.name')
+ ->from('filecache', 'a')
+ ->leftJoin('a', 'filecache', 'b', $qb->expr()->eq(
+ $qb->expr()->castColumn('a.name', IQueryBuilder::PARAM_INT), 'b.fileid'
+ ))
+ ->where(
+ $qb->expr()->isNull('b.fileid')
+ )->andWhere(
+ $qb->expr()->eq('a.parent', $qb->createNamedParameter($previewFodlerId))
+ );
+
+ if (!$this->isCLI) {
+ $qb->setMaxResults(10);
+ }
+
+ $cursor = $qb->execute();
+
+ while ($row = $cursor->fetch()) {
+ try {
+ $preview = $previews->getFolder($row['name']);
+ $preview->delete();
+ } catch (NotFoundException $e) {
+ // continue
+ } catch (NotPermittedException $e) {
+ // continue
+ }
+ }
+
+ $cursor->closeCursor();
+ }
+}
diff --git a/lib/private/Preview/Watcher.php b/lib/private/Preview/Watcher.php
index 8d091b84b0e..0c0531dff94 100644
--- a/lib/private/Preview/Watcher.php
+++ b/lib/private/Preview/Watcher.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
@@ -22,7 +23,6 @@
*/
namespace OC\Preview;
-use OCP\Files\File;
use OCP\Files\Node;
use OCP\Files\Folder;
use OCP\Files\IAppData;
@@ -39,9 +39,6 @@ class Watcher {
/** @var IAppData */
private $appData;
- /** @var int[] */
- private $toDelete = [];
-
/**
* Watcher constructor.
*
@@ -52,53 +49,26 @@ class Watcher {
}
public function postWrite(Node $node) {
+ $this->deleteNode($node);
+ }
+
+ protected function deleteNode(Node $node) {
// We only handle files
if ($node instanceof Folder) {
return;
}
try {
- $folder = $this->appData->getFolder($node->getId());
+ $folder = $this->appData->getFolder((string)$node->getId());
$folder->delete();
} catch (NotFoundException $e) {
//Nothing to do
}
}
- public function preDelete(Node $node) {
- // To avoid cycles
- if ($this->toDelete !== []) {
- return;
- }
-
- if ($node instanceof File) {
- $this->toDelete[] = $node->getId();
- return;
- }
-
- /** @var Folder $node */
- $this->deleteFolder($node);
- }
-
- private function deleteFolder(Folder $folder) {
- $nodes = $folder->getDirectoryListing();
- foreach ($nodes as $node) {
- if ($node instanceof File) {
- $this->toDelete[] = $node->getId();
- } else if ($node instanceof Folder) {
- $this->deleteFolder($node);
- }
- }
- }
-
- public function postDelete(Node $node) {
- foreach ($this->toDelete as $fid) {
- try {
- $folder = $this->appData->getFolder($fid);
- $folder->delete();
- } catch (NotFoundException $e) {
- // continue
- }
+ public function versionRollback(array $data) {
+ if (isset($data['node'])) {
+ $this->deleteNode($data['node']);
}
}
}
diff --git a/lib/private/Preview/WatcherConnector.php b/lib/private/Preview/WatcherConnector.php
index 4e6e786cec7..f374b909d8f 100644
--- a/lib/private/Preview/WatcherConnector.php
+++ b/lib/private/Preview/WatcherConnector.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, Roeland Jago Douma <roeland@famdouma.nl>
*
@@ -49,7 +50,7 @@ class WatcherConnector {
/**
* @return Watcher
*/
- private function getWatcher() {
+ private function getWatcher(): Watcher {
return \OC::$server->query(Watcher::class);
}
@@ -60,13 +61,7 @@ class WatcherConnector {
$this->getWatcher()->postWrite($node);
});
- $this->root->listen('\OC\Files', 'preDelete', function (Node $node) {
- $this->getWatcher()->preDelete($node);
- });
-
- $this->root->listen('\OC\Files', 'postDelete', function (Node $node) {
- $this->getWatcher()->postDelete($node);
- });
+ \OC_Hook::connect('\OCP\Versions', 'rollback', $this->getWatcher(), 'versionRollback');
}
}
}
diff --git a/lib/private/Repair.php b/lib/private/Repair.php
index a257ef061e7..8746f1e6f27 100644
--- a/lib/private/Repair.php
+++ b/lib/private/Repair.php
@@ -36,6 +36,7 @@ use OC\Repair\Collation;
use OC\Repair\MoveUpdaterStepFile;
use OC\Repair\NC11\FixMountStorages;
use OC\Repair\NC13\AddLogRotateJob;
+use OC\Repair\NC14\AddPreviewBackgroundCleanupJob;
use OC\Repair\OldGroupMembershipShares;
use OC\Repair\Owncloud\DropAccountTermsTable;
use OC\Repair\Owncloud\SaveAccountsTableData;
@@ -132,7 +133,8 @@ class Repair implements IOutput{
new FixMountStorages(\OC::$server->getDatabaseConnection()),
new RepairInvalidPaths(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig()),
new AddLogRotateJob(\OC::$server->getJobList()),
- new ClearFrontendCaches(\OC::$server->getMemCacheFactory(), \OC::$server->query(SCSSCacher::class), \OC::$server->query(JSCombiner::class))
+ new ClearFrontendCaches(\OC::$server->getMemCacheFactory(), \OC::$server->query(SCSSCacher::class), \OC::$server->query(JSCombiner::class)),
+ new AddPreviewBackgroundCleanupJob(\OC::$server->getJobList()),
];
}
diff --git a/lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php b/lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php
new file mode 100644
index 00000000000..b58fabcba50
--- /dev/null
+++ b/lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php
@@ -0,0 +1,48 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright 2018, Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OC\Repair\NC14;
+
+use OC\Preview\BackgroundCleanupJob;
+use OCP\BackgroundJob\IJobList;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+class AddPreviewBackgroundCleanupJob implements IRepairStep {
+
+ /** @var IJobList */
+ private $jobList;
+
+ public function __construct(IJobList $jobList) {
+ $this->jobList = $jobList;
+ }
+
+ public function getName(): string {
+ return 'Add preview background cleanup job';
+ }
+
+ public function run(IOutput $output) {
+ $this->jobList->add(BackgroundCleanupJob::class);
+ }
+
+}
diff --git a/lib/private/Setup.php b/lib/private/Setup.php
index 5564bb5b072..25e0b4d8817 100644
--- a/lib/private/Setup.php
+++ b/lib/private/Setup.php
@@ -47,6 +47,7 @@ use OC\App\AppStore\Bundles\BundleFetcher;
use OC\Authentication\Token\DefaultTokenCleanupJob;
use OC\Authentication\Token\DefaultTokenProvider;
use OC\Log\Rotate;
+use OC\Preview\BackgroundCleanupJob;
use OCP\Defaults;
use OCP\IL10N;
use OCP\ILogger;
@@ -419,6 +420,7 @@ class Setup {
$jobList = \OC::$server->getJobList();
$jobList->add(DefaultTokenCleanupJob::class);
$jobList->add(Rotate::class);
+ $jobList->add(BackgroundCleanupJob::class);
}
/**