summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/comments/l10n/ru.js2
-rw-r--r--apps/comments/l10n/ru.json2
-rw-r--r--apps/dav/lib/Connector/Sabre/FilesReportPlugin.php12
-rw-r--r--apps/dav/lib/Files/RootCollection.php1
-rw-r--r--apps/dav/lib/Server.php40
-rw-r--r--apps/federatedfilesharing/l10n/de.js1
-rw-r--r--apps/federatedfilesharing/l10n/de.json1
-rw-r--r--apps/federatedfilesharing/l10n/de_DE.js1
-rw-r--r--apps/federatedfilesharing/l10n/de_DE.json1
-rw-r--r--apps/federation/lib/DAV/FedAuth.php8
-rwxr-xr-xautotest-external.sh7
-rw-r--r--build/integration/features/bootstrap/WebDav.php24
-rw-r--r--build/integration/features/webdav-related.feature16
-rw-r--r--core/Command/Integrity/SignApp.php11
-rw-r--r--core/Command/Integrity/SignCore.php12
-rw-r--r--lib/private/IntegrityCheck/Checker.php48
-rw-r--r--lib/private/IntegrityCheck/Helpers/FileAccessHelper.php29
-rw-r--r--settings/l10n/de.js2
-rw-r--r--settings/l10n/de.json2
-rw-r--r--settings/l10n/de_DE.js2
-rw-r--r--settings/l10n/de_DE.json2
-rw-r--r--settings/l10n/fr.js1
-rw-r--r--settings/l10n/fr.json1
-rw-r--r--tests/Core/Command/TwoFactorAuth/DisableTest.php99
-rw-r--r--tests/Core/Command/TwoFactorAuth/EnableTest.php99
-rw-r--r--tests/lib/Command/Integrity/SignAppTest.php62
-rw-r--r--tests/lib/Command/Integrity/SignCoreTest.php60
-rw-r--r--tests/lib/IntegrityCheck/CheckerTest.php97
-rw-r--r--tests/lib/IntegrityCheck/Helpers/FileAccessHelperTest.php25
29 files changed, 587 insertions, 81 deletions
diff --git a/apps/comments/l10n/ru.js b/apps/comments/l10n/ru.js
index 92ccc845075..650ff5c7d3d 100644
--- a/apps/comments/l10n/ru.js
+++ b/apps/comments/l10n/ru.js
@@ -2,7 +2,7 @@ OC.L10N.register(
"comments",
{
"Comments" : "Комментарии",
- "Unknown user" : "Пользователь неизвестен",
+ "Unknown user" : "Неизвестный пользователь",
"New comment …" : "Новый комментарий...",
"Delete comment" : "Удалить комментарий",
"Post" : "Опубликовать",
diff --git a/apps/comments/l10n/ru.json b/apps/comments/l10n/ru.json
index 18a0e76bb1b..91974f9cdad 100644
--- a/apps/comments/l10n/ru.json
+++ b/apps/comments/l10n/ru.json
@@ -1,6 +1,6 @@
{ "translations": {
"Comments" : "Комментарии",
- "Unknown user" : "Пользователь неизвестен",
+ "Unknown user" : "Неизвестный пользователь",
"New comment …" : "Новый комментарий...",
"Delete comment" : "Удалить комментарий",
"Post" : "Опубликовать",
diff --git a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php
index bc0c1c2f603..81c082b9105 100644
--- a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php
@@ -24,9 +24,7 @@
namespace OCA\DAV\Connector\Sabre;
use OC\Files\View;
-use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\Exception\PreconditionFailed;
-use Sabre\DAV\Exception\ReportNotSupported;
use Sabre\DAV\Exception\BadRequest;
use Sabre\DAV\ServerPlugin;
use Sabre\DAV\Tree;
@@ -105,7 +103,7 @@ class FilesReportPlugin extends ServerPlugin {
* @param ITagManager $fileTagger manager for private tags
* @param IUserSession $userSession
* @param IGroupManager $groupManager
- * @param Folder $userfolder
+ * @param Folder $userFolder
*/
public function __construct(Tree $tree,
View $view,
@@ -161,11 +159,12 @@ class FilesReportPlugin extends ServerPlugin {
* REPORT operations to look for files
*
* @param string $reportName
- * @param [] $report
+ * @param $report
* @param string $uri
* @return bool
- * @throws NotFound
- * @throws ReportNotSupported
+ * @throws BadRequest
+ * @throws PreconditionFailed
+ * @internal param $ [] $report
*/
public function onReport($reportName, $report, $uri) {
$reportTargetNode = $this->server->tree->getNodeForPath($uri);
@@ -232,7 +231,6 @@ class FilesReportPlugin extends ServerPlugin {
private function getFilesBaseUri($uri, $subPath) {
$uri = trim($uri, '/');
$subPath = trim($subPath, '/');
- $filesUri = '';
if (empty($subPath)) {
$filesUri = $uri;
} else {
diff --git a/apps/dav/lib/Files/RootCollection.php b/apps/dav/lib/Files/RootCollection.php
index 345015530e2..c73d7c175ce 100644
--- a/apps/dav/lib/Files/RootCollection.php
+++ b/apps/dav/lib/Files/RootCollection.php
@@ -21,6 +21,7 @@
*/
namespace OCA\DAV\Files;
+use Sabre\DAV\INode;
use Sabre\DAVACL\AbstractPrincipalCollection;
use Sabre\HTTP\URLUtil;
use Sabre\DAV\SimpleCollection;
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index 1205d018241..79c4301a8d8 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -33,11 +33,14 @@ use OCA\DAV\CardDAV\ImageExportPlugin;
use OCA\DAV\Comments\CommentsPlugin;
use OCA\DAV\Connector\Sabre\Auth;
use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin;
+use OCA\DAV\Connector\Sabre\CommentPropertiesPlugin;
use OCA\DAV\Connector\Sabre\CopyEtagHeaderPlugin;
use OCA\DAV\Connector\Sabre\DavAclPlugin;
use OCA\DAV\Connector\Sabre\DummyGetResponsePlugin;
use OCA\DAV\Connector\Sabre\FakeLockerPlugin;
use OCA\DAV\Connector\Sabre\FilesPlugin;
+use OCA\DAV\Connector\Sabre\FilesReportPlugin;
+use OCA\DAV\Connector\Sabre\SharesPlugin;
use OCA\DAV\DAV\PublicAuth;
use OCA\DAV\Connector\Sabre\QuotaPlugin;
use OCA\DAV\Files\BrowserErrorPagePlugin;
@@ -85,7 +88,6 @@ class Server {
$this->server->addPlugin(new BlockLegacyClientPlugin(\OC::$server->getConfig()));
$authPlugin = new Plugin();
- $authPlugin->addBackend($authBackend);
$authPlugin->addBackend(new PublicAuth());
$this->server->addPlugin($authPlugin);
@@ -166,7 +168,7 @@ class Server {
// custom properties plugin must be the last one
$userSession = \OC::$server->getUserSession();
$user = $userSession->getUser();
- if (!is_null($user)) {
+ if ($user !== null) {
$view = \OC\Files\Filesystem::getView();
$this->server->addPlugin(
new FilesPlugin(
@@ -188,9 +190,10 @@ class Server {
)
)
);
- $this->server->addPlugin(
- new QuotaPlugin($view)
- );
+ if ($view !== null) {
+ $this->server->addPlugin(
+ new QuotaPlugin($view));
+ }
$this->server->addPlugin(
new TagsPlugin(
$this->server->tree, \OC::$server->getTagManager()
@@ -198,28 +201,29 @@ class Server {
);
// TODO: switch to LazyUserFolder
$userFolder = \OC::$server->getUserFolder();
- $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\SharesPlugin(
+ $this->server->addPlugin(new SharesPlugin(
$this->server->tree,
$userSession,
$userFolder,
\OC::$server->getShareManager()
));
- $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin(
+ $this->server->addPlugin(new CommentPropertiesPlugin(
\OC::$server->getCommentsManager(),
$userSession
));
- $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesReportPlugin(
- $this->server->tree,
- $view,
- \OC::$server->getSystemTagManager(),
- \OC::$server->getSystemTagObjectMapper(),
- \OC::$server->getTagManager(),
- $userSession,
- \OC::$server->getGroupManager(),
- $userFolder
- ));
+ if ($view !== null) {
+ $this->server->addPlugin(new FilesReportPlugin(
+ $this->server->tree,
+ $view,
+ \OC::$server->getSystemTagManager(),
+ \OC::$server->getSystemTagObjectMapper(),
+ \OC::$server->getTagManager(),
+ $userSession,
+ \OC::$server->getGroupManager(),
+ $userFolder
+ ));
+ }
}
- $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\CopyEtagHeaderPlugin());
});
}
diff --git a/apps/federatedfilesharing/l10n/de.js b/apps/federatedfilesharing/l10n/de.js
index 335f2c89815..ef4085d222a 100644
--- a/apps/federatedfilesharing/l10n/de.js
+++ b/apps/federatedfilesharing/l10n/de.js
@@ -41,6 +41,7 @@ OC.L10N.register(
"Open documentation" : "Dokumentation öffnen",
"Allow users on this server to send shares to other servers" : "Benutzern auf diesem Server das Senden von Freigaben an andere Server erlauben",
"Allow users on this server to receive shares from other servers" : "Benutzern auf diesem Server das Empfangen von Freigaben von anderen Servern erlauben",
+ "Search global and public address book for users" : "Globale Suche und ein öffentliches Adresbuch für Nutzer",
"Federated Cloud" : "Federated Cloud",
"Your Federated Cloud ID:" : "Deine Federated-Cloud-ID:",
"Share it:" : "Zum Teilen:",
diff --git a/apps/federatedfilesharing/l10n/de.json b/apps/federatedfilesharing/l10n/de.json
index e29b867f3b3..4e02478be20 100644
--- a/apps/federatedfilesharing/l10n/de.json
+++ b/apps/federatedfilesharing/l10n/de.json
@@ -39,6 +39,7 @@
"Open documentation" : "Dokumentation öffnen",
"Allow users on this server to send shares to other servers" : "Benutzern auf diesem Server das Senden von Freigaben an andere Server erlauben",
"Allow users on this server to receive shares from other servers" : "Benutzern auf diesem Server das Empfangen von Freigaben von anderen Servern erlauben",
+ "Search global and public address book for users" : "Globale Suche und ein öffentliches Adresbuch für Nutzer",
"Federated Cloud" : "Federated Cloud",
"Your Federated Cloud ID:" : "Deine Federated-Cloud-ID:",
"Share it:" : "Zum Teilen:",
diff --git a/apps/federatedfilesharing/l10n/de_DE.js b/apps/federatedfilesharing/l10n/de_DE.js
index 677371b423c..6bb9513d048 100644
--- a/apps/federatedfilesharing/l10n/de_DE.js
+++ b/apps/federatedfilesharing/l10n/de_DE.js
@@ -41,6 +41,7 @@ OC.L10N.register(
"Open documentation" : "Dokumentation öffnen",
"Allow users on this server to send shares to other servers" : "Benutzern auf diesem Server das Senden von Freigaben an andere Server erlauben",
"Allow users on this server to receive shares from other servers" : "Benutzern auf diesem Server das Empfangen von Freigaben von anderen Servern erlauben",
+ "Search global and public address book for users" : "Globale Suche und ein öffentliches Adresbuch für Nutzer",
"Federated Cloud" : "Federated Cloud",
"Your Federated Cloud ID:" : "Ihre Federated-Cloud-ID:",
"Share it:" : "Zum Teilen:",
diff --git a/apps/federatedfilesharing/l10n/de_DE.json b/apps/federatedfilesharing/l10n/de_DE.json
index 4451011acaa..6a9be77cda4 100644
--- a/apps/federatedfilesharing/l10n/de_DE.json
+++ b/apps/federatedfilesharing/l10n/de_DE.json
@@ -39,6 +39,7 @@
"Open documentation" : "Dokumentation öffnen",
"Allow users on this server to send shares to other servers" : "Benutzern auf diesem Server das Senden von Freigaben an andere Server erlauben",
"Allow users on this server to receive shares from other servers" : "Benutzern auf diesem Server das Empfangen von Freigaben von anderen Servern erlauben",
+ "Search global and public address book for users" : "Globale Suche und ein öffentliches Adresbuch für Nutzer",
"Federated Cloud" : "Federated Cloud",
"Your Federated Cloud ID:" : "Ihre Federated-Cloud-ID:",
"Share it:" : "Zum Teilen:",
diff --git a/apps/federation/lib/DAV/FedAuth.php b/apps/federation/lib/DAV/FedAuth.php
index 705ccbdd3bb..ae78ffeded9 100644
--- a/apps/federation/lib/DAV/FedAuth.php
+++ b/apps/federation/lib/DAV/FedAuth.php
@@ -24,6 +24,8 @@ namespace OCA\Federation\DAV;
use OCA\Federation\DbHandler;
use Sabre\DAV\Auth\Backend\AbstractBasic;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
class FedAuth extends AbstractBasic {
@@ -57,4 +59,10 @@ class FedAuth extends AbstractBasic {
protected function validateUserPass($username, $password) {
return $this->db->auth($username, $password);
}
+
+ /**
+ * @inheritdoc
+ */
+ function challenge(RequestInterface $request, ResponseInterface $response) {
+ }
}
diff --git a/autotest-external.sh b/autotest-external.sh
index a6ca077ebb0..1f1ca330ac5 100755
--- a/autotest-external.sh
+++ b/autotest-external.sh
@@ -210,16 +210,19 @@ EOF
rm -rf "coverage-external-html-$1-$name"
mkdir "coverage-external-html-$1-$name"
"$PHPUNIT" --configuration phpunit-autotest-external.xml --log-junit "autotest-external-results-$1-$name.xml" --coverage-clover "autotest-external-clover-$1-$name.xml" --coverage-html "coverage-external-html-$1-$name" "$FILES_EXTERNAL_BACKEND_PATH/$testToRun"
- RESULT=$?
else
echo "No coverage"
"$PHPUNIT" --configuration phpunit-autotest-external.xml --log-junit "autotest-external-results-$1-$name.xml" "$FILES_EXTERNAL_BACKEND_PATH/$testToRun"
- RESULT=$?
fi
else
DOEXIT=1
fi
+ if [[ $? -ne 0 ]]; then
+ echo "Error during phpunit execution ... terminating"
+ exit 1
+ fi
+
# calculate stop file
stopFile=`echo "$startFile" | sed 's/start/stop/'`
echo "stop: $stopFile"
diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php
index c44a6175579..6438a871fb1 100644
--- a/build/integration/features/bootstrap/WebDav.php
+++ b/build/integration/features/bootstrap/WebDav.php
@@ -657,4 +657,28 @@ trait WebDav {
$this->asGetsPropertiesOfFolderWith($user, 'entry', $path, $propertiesTable);
PHPUnit_Framework_Assert::assertNotEquals($this->response['{DAV:}getetag'], $this->storedETAG[$user][$path]);
}
+
+ /**
+ * @When Connecting to dav endpoint
+ */
+ public function connectingToDavEndpoint() {
+ try {
+ $this->response = $this->makeDavRequest(null, 'PROPFIND', '', []);
+ } catch (\GuzzleHttp\Exception\ClientException $e) {
+ $this->response = $e->getResponse();
+ }
+ }
+
+ /**
+ * @Then there are no duplicate headers
+ */
+ public function thereAreNoDuplicateHeaders() {
+ $headers = $this->response->getHeaders();
+ foreach ($headers as $headerName => $headerValues) {
+ // if a header has multiple values, they must be different
+ if (count($headerValues) > 1 && count(array_unique($headerValues)) < count($headerValues)) {
+ throw new \Exception('Duplicate header found: ' . $headerName);
+ }
+ }
+ }
}
diff --git a/build/integration/features/webdav-related.feature b/build/integration/features/webdav-related.feature
index b75fdd35618..c3aa6145527 100644
--- a/build/integration/features/webdav-related.feature
+++ b/build/integration/features/webdav-related.feature
@@ -2,6 +2,22 @@ Feature: webdav-related
Background:
Given using api version "1"
+ Scenario: Unauthenticated call old dav path
+ Given using old dav path
+ When connecting to dav endpoint
+ Then the HTTP status code should be "401"
+ And there are no duplicate headers
+ And The following headers should be set
+ |WWW-Authenticate|Basic realm="Nextcloud"|
+
+ Scenario: Unauthenticated call new dav path
+ Given using new dav path
+ When connecting to dav endpoint
+ Then the HTTP status code should be "401"
+ And there are no duplicate headers
+ And The following headers should be set
+ |WWW-Authenticate|Basic realm="Nextcloud"|
+
Scenario: Moving a file
Given using old dav path
And As an "admin"
diff --git a/core/Command/Integrity/SignApp.php b/core/Command/Integrity/SignApp.php
index 3bc79eb0114..26d2791475b 100644
--- a/core/Command/Integrity/SignApp.php
+++ b/core/Command/Integrity/SignApp.php
@@ -101,8 +101,13 @@ class SignApp extends Command {
$x509 = new X509();
$x509->loadX509($keyBundle);
$x509->setPrivateKey($rsa);
- $this->checker->writeAppSignature($path, $x509, $rsa);
-
- $output->writeln('Successfully signed "'.$path.'"');
+ try {
+ $this->checker->writeAppSignature($path, $x509, $rsa);
+ $output->writeln('Successfully signed "'.$path.'"');
+ } catch (\Exception $e){
+ $output->writeln('Error: ' . $e->getMessage());
+ return 1;
+ }
+ return 0;
}
}
diff --git a/core/Command/Integrity/SignCore.php b/core/Command/Integrity/SignCore.php
index 440c3da3b23..8f951204a58 100644
--- a/core/Command/Integrity/SignCore.php
+++ b/core/Command/Integrity/SignCore.php
@@ -23,12 +23,10 @@
namespace OC\Core\Command\Integrity;
use OC\IntegrityCheck\Checker;
-use OC\IntegrityCheck\Helpers\EnvironmentHelper;
use OC\IntegrityCheck\Helpers\FileAccessHelper;
use phpseclib\Crypt\RSA;
use phpseclib\File\X509;
use Symfony\Component\Console\Command\Command;
-use OCP\IConfig;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
@@ -94,8 +92,14 @@ class SignCore extends Command {
$x509 = new X509();
$x509->loadX509($keyBundle);
$x509->setPrivateKey($rsa);
- $this->checker->writeCoreSignature($x509, $rsa, $path);
- $output->writeln('Successfully signed "core"');
+ try {
+ $this->checker->writeCoreSignature($x509, $rsa, $path);
+ $output->writeln('Successfully signed "core"');
+ } catch (\Exception $e){
+ $output->writeln('Error: ' . $e->getMessage());
+ return 1;
+ }
+ return 0;
}
}
diff --git a/lib/private/IntegrityCheck/Checker.php b/lib/private/IntegrityCheck/Checker.php
index cba290e6aa7..419f989fa0f 100644
--- a/lib/private/IntegrityCheck/Checker.php
+++ b/lib/private/IntegrityCheck/Checker.php
@@ -267,16 +267,23 @@ class Checker {
public function writeAppSignature($path,
X509 $certificate,
RSA $privateKey) {
- if(!is_dir($path)) {
- throw new \Exception('Directory does not exist.');
- }
- $iterator = $this->getFolderIterator($path);
- $hashes = $this->generateHashes($iterator, $path);
- $signature = $this->createSignatureData($hashes, $certificate, $privateKey);
- $this->fileAccessHelper->file_put_contents(
- $path . '/appinfo/signature.json',
+ $appInfoDir = $path . '/appinfo';
+ try {
+ $this->fileAccessHelper->assertDirectoryExists($appInfoDir);
+
+ $iterator = $this->getFolderIterator($path);
+ $hashes = $this->generateHashes($iterator, $path);
+ $signature = $this->createSignatureData($hashes, $certificate, $privateKey);
+ $this->fileAccessHelper->file_put_contents(
+ $appInfoDir . '/signature.json',
json_encode($signature, JSON_PRETTY_PRINT)
- );
+ );
+ } catch (\Exception $e){
+ if (!$this->fileAccessHelper->is_writable($appInfoDir)) {
+ throw new \Exception($appInfoDir . ' is not writable');
+ }
+ throw $e;
+ }
}
/**
@@ -285,17 +292,28 @@ class Checker {
* @param X509 $certificate
* @param RSA $rsa
* @param string $path
+ * @throws \Exception
*/
public function writeCoreSignature(X509 $certificate,
RSA $rsa,
$path) {
- $iterator = $this->getFolderIterator($path, $path);
- $hashes = $this->generateHashes($iterator, $path);
- $signatureData = $this->createSignatureData($hashes, $certificate, $rsa);
- $this->fileAccessHelper->file_put_contents(
- $path . '/core/signature.json',
+ $coreDir = $path . '/core';
+ try {
+
+ $this->fileAccessHelper->assertDirectoryExists($coreDir);
+ $iterator = $this->getFolderIterator($path, $path);
+ $hashes = $this->generateHashes($iterator, $path);
+ $signatureData = $this->createSignatureData($hashes, $certificate, $rsa);
+ $this->fileAccessHelper->file_put_contents(
+ $coreDir . '/signature.json',
json_encode($signatureData, JSON_PRETTY_PRINT)
- );
+ );
+ } catch (\Exception $e){
+ if (!$this->fileAccessHelper->is_writable($coreDir)) {
+ throw new \Exception($coreDir . ' is not writable');
+ }
+ throw $e;
+ }
}
/**
diff --git a/lib/private/IntegrityCheck/Helpers/FileAccessHelper.php b/lib/private/IntegrityCheck/Helpers/FileAccessHelper.php
index 9e2b76ce11a..a7e378c165e 100644
--- a/lib/private/IntegrityCheck/Helpers/FileAccessHelper.php
+++ b/lib/private/IntegrityCheck/Helpers/FileAccessHelper.php
@@ -53,10 +53,33 @@ class FileAccessHelper {
* Wrapper around file_put_contents($filename, $data)
*
* @param string $filename
- * @param $data
- * @return int|false
+ * @param string $data
+ * @return int
+ * @throws \Exception
*/
public function file_put_contents($filename, $data) {
- return file_put_contents($filename, $data);
+ $bytesWritten = @file_put_contents($filename, $data);
+ if ($bytesWritten === false || $bytesWritten !== strlen($data)){
+ throw new \Exception('Failed to write into ' . $filename);
+ }
+ return $bytesWritten;
+ }
+
+ /**
+ * @param string $path
+ * @return bool
+ */
+ public function is_writable($path) {
+ return is_writable($path);
+ }
+
+ /**
+ * @param string $path
+ * @throws \Exception
+ */
+ public function assertDirectoryExists($path) {
+ if (!is_dir($path)) {
+ throw new \Exception('Directory ' . $path . ' does not exist.');
+ }
}
}
diff --git a/settings/l10n/de.js b/settings/l10n/de.js
index 95a5eb38343..e99970226ad 100644
--- a/settings/l10n/de.js
+++ b/settings/l10n/de.js
@@ -58,6 +58,7 @@ OC.L10N.register(
"Official apps are developed by and within the community. They offer central functionality and are ready for production use." : "Offizielle Apps werden von und innerhalb der Community entwickelt. Sie stellen die zentralen Funktionen bereit und sind für den produktiven Einsatz geeignet.",
"Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Geprüfte Apps werden von vertrauenswürdigen Entwicklern entwickelt und haben eine oberflächliche Sicherheitsprüfung durchlaufen. Sie werden innerhalb eines offenen Code-Repositorys aktiv gepflegt und ihre Betreuer erachten sie als stabil genug für für den gelegentlichen bis normalen Einsatz.",
"This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Diese App ist nicht auf Sicherheitsprobleme hin überprüft und ist neu oder bekanntermaßen instabil. Die Installation erfolgt auf eigenes Risiko.",
+ "Enabling app …" : "Aktiviere App ...",
"Error while disabling app" : "Beim Deaktivieren der App ist ein Fehler aufgetreten",
"Disable" : "Deaktivieren",
"Enable" : "Aktivieren",
@@ -246,6 +247,7 @@ OC.L10N.register(
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Für diese App wurde keine obere Versionsgrenze für Nextcloud gesetzt. Dies wird zukünftig als Fehler behandelt.",
"This app cannot be installed because the following dependencies are not fulfilled:" : "Die App kann nicht installiert werden, weil die folgenden Abhängigkeiten nicht erfüllt sind:",
"Enable only for specific groups" : "Nur für bestimmte Gruppen aktivieren",
+ "Uninstall app" : "App deinstallieren",
"SSL Root Certificates" : "SSL Root Zertifikate",
"Common Name" : "Allgemeiner Name",
"Valid until" : "Gültig bis",
diff --git a/settings/l10n/de.json b/settings/l10n/de.json
index b165917e537..0d293aeb338 100644
--- a/settings/l10n/de.json
+++ b/settings/l10n/de.json
@@ -56,6 +56,7 @@
"Official apps are developed by and within the community. They offer central functionality and are ready for production use." : "Offizielle Apps werden von und innerhalb der Community entwickelt. Sie stellen die zentralen Funktionen bereit und sind für den produktiven Einsatz geeignet.",
"Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Geprüfte Apps werden von vertrauenswürdigen Entwicklern entwickelt und haben eine oberflächliche Sicherheitsprüfung durchlaufen. Sie werden innerhalb eines offenen Code-Repositorys aktiv gepflegt und ihre Betreuer erachten sie als stabil genug für für den gelegentlichen bis normalen Einsatz.",
"This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Diese App ist nicht auf Sicherheitsprobleme hin überprüft und ist neu oder bekanntermaßen instabil. Die Installation erfolgt auf eigenes Risiko.",
+ "Enabling app …" : "Aktiviere App ...",
"Error while disabling app" : "Beim Deaktivieren der App ist ein Fehler aufgetreten",
"Disable" : "Deaktivieren",
"Enable" : "Aktivieren",
@@ -244,6 +245,7 @@
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Für diese App wurde keine obere Versionsgrenze für Nextcloud gesetzt. Dies wird zukünftig als Fehler behandelt.",
"This app cannot be installed because the following dependencies are not fulfilled:" : "Die App kann nicht installiert werden, weil die folgenden Abhängigkeiten nicht erfüllt sind:",
"Enable only for specific groups" : "Nur für bestimmte Gruppen aktivieren",
+ "Uninstall app" : "App deinstallieren",
"SSL Root Certificates" : "SSL Root Zertifikate",
"Common Name" : "Allgemeiner Name",
"Valid until" : "Gültig bis",
diff --git a/settings/l10n/de_DE.js b/settings/l10n/de_DE.js
index 8e59f2d5b9a..6021ccc58f1 100644
--- a/settings/l10n/de_DE.js
+++ b/settings/l10n/de_DE.js
@@ -58,6 +58,7 @@ OC.L10N.register(
"Official apps are developed by and within the community. They offer central functionality and are ready for production use." : "Offizielle Apps werden von und innerhalb der Community entwickelt. Sie stellen die zentralen Funktionen bereit und sind für den produktiven Einsatz geeignet.",
"Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Geprüfte Apps werden von vertrauenswürdigen Entwicklern entwickelt und haben eine oberflächliche Sicherheitsprüfung durchlaufen. Sie werden innerhalb eines offenen Code-Repositorys aktiv gepflegt und ihre Betreuer erachten sie als stabil genug für für den gelegentlichen bis normalen Einsatz.",
"This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Diese App ist nicht auf Sicherheitsprobleme hin überprüft und ist neu oder bekanntermaßen instabil. Die Installation erfolgt auf eigenes Risiko.",
+ "Enabling app …" : "Aktiviere App ...",
"Error while disabling app" : "Beim Deaktivieren der App ist ein Fehler aufgetreten",
"Disable" : "Deaktivieren",
"Enable" : "Aktivieren",
@@ -246,6 +247,7 @@ OC.L10N.register(
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Für diese App wurde keine obere Versionsgrenze für Nextcloud gesetzt. Dies wird zukünftig als Fehler behandelt.",
"This app cannot be installed because the following dependencies are not fulfilled:" : "Diese App kann nicht installiert werden, weil die folgenden Abhängigkeiten nicht erfüllt sind:",
"Enable only for specific groups" : "Nur für bestimmte Gruppen aktivieren",
+ "Uninstall app" : "App deinstallieren",
"SSL Root Certificates" : "SSL Root Zertifikate",
"Common Name" : "Allgemeiner Name",
"Valid until" : "Gültig bis",
diff --git a/settings/l10n/de_DE.json b/settings/l10n/de_DE.json
index 938fbec8e19..944cb578a87 100644
--- a/settings/l10n/de_DE.json
+++ b/settings/l10n/de_DE.json
@@ -56,6 +56,7 @@
"Official apps are developed by and within the community. They offer central functionality and are ready for production use." : "Offizielle Apps werden von und innerhalb der Community entwickelt. Sie stellen die zentralen Funktionen bereit und sind für den produktiven Einsatz geeignet.",
"Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Geprüfte Apps werden von vertrauenswürdigen Entwicklern entwickelt und haben eine oberflächliche Sicherheitsprüfung durchlaufen. Sie werden innerhalb eines offenen Code-Repositorys aktiv gepflegt und ihre Betreuer erachten sie als stabil genug für für den gelegentlichen bis normalen Einsatz.",
"This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Diese App ist nicht auf Sicherheitsprobleme hin überprüft und ist neu oder bekanntermaßen instabil. Die Installation erfolgt auf eigenes Risiko.",
+ "Enabling app …" : "Aktiviere App ...",
"Error while disabling app" : "Beim Deaktivieren der App ist ein Fehler aufgetreten",
"Disable" : "Deaktivieren",
"Enable" : "Aktivieren",
@@ -244,6 +245,7 @@
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Für diese App wurde keine obere Versionsgrenze für Nextcloud gesetzt. Dies wird zukünftig als Fehler behandelt.",
"This app cannot be installed because the following dependencies are not fulfilled:" : "Diese App kann nicht installiert werden, weil die folgenden Abhängigkeiten nicht erfüllt sind:",
"Enable only for specific groups" : "Nur für bestimmte Gruppen aktivieren",
+ "Uninstall app" : "App deinstallieren",
"SSL Root Certificates" : "SSL Root Zertifikate",
"Common Name" : "Allgemeiner Name",
"Valid until" : "Gültig bis",
diff --git a/settings/l10n/fr.js b/settings/l10n/fr.js
index fba68be5171..03802660f36 100644
--- a/settings/l10n/fr.js
+++ b/settings/l10n/fr.js
@@ -246,6 +246,7 @@ OC.L10N.register(
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Cette application n'a pas de version maximum Nextcloud exigée. Ce sera considéré comme une erreur à l'avenir.",
"This app cannot be installed because the following dependencies are not fulfilled:" : "Cette application ne peut être installée à cause de ces dépendances non satisfaites :",
"Enable only for specific groups" : "Activer uniquement pour certains groupes",
+ "Uninstall app" : "Désinstaller l'application",
"SSL Root Certificates" : "Certificats Racines SSL",
"Common Name" : "Nom d'usage",
"Valid until" : "Valide jusqu'à",
diff --git a/settings/l10n/fr.json b/settings/l10n/fr.json
index 4457cf9f1e8..04b3ab0e1c0 100644
--- a/settings/l10n/fr.json
+++ b/settings/l10n/fr.json
@@ -244,6 +244,7 @@
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Cette application n'a pas de version maximum Nextcloud exigée. Ce sera considéré comme une erreur à l'avenir.",
"This app cannot be installed because the following dependencies are not fulfilled:" : "Cette application ne peut être installée à cause de ces dépendances non satisfaites :",
"Enable only for specific groups" : "Activer uniquement pour certains groupes",
+ "Uninstall app" : "Désinstaller l'application",
"SSL Root Certificates" : "Certificats Racines SSL",
"Common Name" : "Nom d'usage",
"Valid until" : "Valide jusqu'à",
diff --git a/tests/Core/Command/TwoFactorAuth/DisableTest.php b/tests/Core/Command/TwoFactorAuth/DisableTest.php
new file mode 100644
index 00000000000..1a0bbc6c3d3
--- /dev/null
+++ b/tests/Core/Command/TwoFactorAuth/DisableTest.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * @copyright 2016, 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 Test\Core\Command\TwoFactorAuth;
+
+use OC\Authentication\TwoFactorAuth\Manager;
+use OC\Core\Command\TwoFactorAuth\Disable;
+use OCP\IUser;
+use OCP\IUserManager;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Test\TestCase;
+
+class DisableTest extends TestCase {
+
+ /** @var Manager|\PHPUnit_Framework_MockObject_MockObject */
+ private $manager;
+
+ /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
+ private $userManager;
+
+ /** @var Disable */
+ private $command;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->manager = $this->createMock(Manager::class);
+ $this->userManager = $this->createMock(IUserManager::class);
+
+ $this->command = new Disable($this->manager, $this->userManager);
+ }
+
+ public function testDisableSuccess() {
+ $user = $this->createMock(IUser::class);
+
+ $input = $this->createMock(InputInterface::class);
+ $output = $this->createMock(OutputInterface::class);
+
+ $input->method('getArgument')
+ ->with($this->equalTo('uid'))
+ ->willReturn('user');
+
+ $this->userManager->method('get')
+ ->with('user')
+ ->willReturn($user);
+
+ $this->manager->expects($this->once())
+ ->method('disableTwoFactorAuthentication')
+ ->with($this->equalTo($user));
+
+ $output->expects($this->once())
+ ->method('writeln')
+ ->with('Two-factor authentication disabled for user user');
+
+ $this->invokePrivate($this->command, 'execute', [$input, $output]);
+ }
+
+ public function testEnableFail() {
+ $input = $this->createMock(InputInterface::class);
+ $output = $this->createMock(OutputInterface::class);
+
+ $input->method('getArgument')
+ ->with($this->equalTo('uid'))
+ ->willReturn('user');
+
+ $this->userManager->method('get')
+ ->with('user')
+ ->willReturn(null);
+
+ $this->manager->expects($this->never())
+ ->method($this->anything());
+
+ $output->expects($this->once())
+ ->method('writeln')
+ ->with('<error>Invalid UID</error>');
+
+ $this->invokePrivate($this->command, 'execute', [$input, $output]);
+ }
+}
diff --git a/tests/Core/Command/TwoFactorAuth/EnableTest.php b/tests/Core/Command/TwoFactorAuth/EnableTest.php
new file mode 100644
index 00000000000..ebca40df9a5
--- /dev/null
+++ b/tests/Core/Command/TwoFactorAuth/EnableTest.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * @copyright 2016, 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 Test\Core\Command\TwoFactorAuth;
+
+use OC\Authentication\TwoFactorAuth\Manager;
+use OC\Core\Command\TwoFactorAuth\Enable;
+use OCP\IUser;
+use OCP\IUserManager;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Test\TestCase;
+
+class EnableTest extends TestCase {
+
+ /** @var Manager|\PHPUnit_Framework_MockObject_MockObject */
+ private $manager;
+
+ /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
+ private $userManager;
+
+ /** @var Enable */
+ private $command;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->manager = $this->createMock(Manager::class);
+ $this->userManager = $this->createMock(IUserManager::class);
+
+ $this->command = new Enable($this->manager, $this->userManager);
+ }
+
+ public function testEnableSuccess() {
+ $user = $this->createMock(IUser::class);
+
+ $input = $this->createMock(InputInterface::class);
+ $output = $this->createMock(OutputInterface::class);
+
+ $input->method('getArgument')
+ ->with($this->equalTo('uid'))
+ ->willReturn('user');
+
+ $this->userManager->method('get')
+ ->with('user')
+ ->willReturn($user);
+
+ $this->manager->expects($this->once())
+ ->method('enableTwoFactorAuthentication')
+ ->with($this->equalTo($user));
+
+ $output->expects($this->once())
+ ->method('writeln')
+ ->with('Two-factor authentication enabled for user user');
+
+ $this->invokePrivate($this->command, 'execute', [$input, $output]);
+ }
+
+ public function testEnableFail() {
+ $input = $this->createMock(InputInterface::class);
+ $output = $this->createMock(OutputInterface::class);
+
+ $input->method('getArgument')
+ ->with($this->equalTo('uid'))
+ ->willReturn('user');
+
+ $this->userManager->method('get')
+ ->with('user')
+ ->willReturn(null);
+
+ $this->manager->expects($this->never())
+ ->method($this->anything());
+
+ $output->expects($this->once())
+ ->method('writeln')
+ ->with('<error>Invalid UID</error>');
+
+ $this->invokePrivate($this->command, 'execute', [$input, $output]);
+ }
+}
diff --git a/tests/lib/Command/Integrity/SignAppTest.php b/tests/lib/Command/Integrity/SignAppTest.php
index 71d9946ee88..013290b56e9 100644
--- a/tests/lib/Command/Integrity/SignAppTest.php
+++ b/tests/lib/Command/Integrity/SignAppTest.php
@@ -29,13 +29,13 @@ use Symfony\Component\Console\Output\OutputInterface;
use Test\TestCase;
class SignAppTest extends TestCase {
- /** @var Checker */
+ /** @var Checker|\PHPUnit_Framework_MockObject_MockObject */
private $checker;
/** @var SignApp */
private $signApp;
- /** @var FileAccessHelper */
+ /** @var FileAccessHelper|\PHPUnit_Framework_MockObject_MockObject */
private $fileAccessHelper;
- /** @var IURLGenerator */
+ /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
private $urlGenerator;
public function setUp() {
@@ -75,7 +75,7 @@ class SignAppTest extends TestCase {
->method('writeln')
->with('This command requires the --path, --privateKey and --certificate.');
- $this->invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertNull(self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
}
public function testExecuteWithMissingPrivateKey() {
@@ -103,7 +103,7 @@ class SignAppTest extends TestCase {
->method('writeln')
->with('This command requires the --path, --privateKey and --certificate.');
- $this->invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertNull(self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
}
public function testExecuteWithMissingCertificate() {
@@ -131,7 +131,7 @@ class SignAppTest extends TestCase {
->method('writeln')
->with('This command requires the --path, --privateKey and --certificate.');
- $this->invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertNull(self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
}
public function testExecuteWithNotExistingPrivateKey() {
@@ -165,7 +165,7 @@ class SignAppTest extends TestCase {
->method('writeln')
->with('Private key "privateKey" does not exists.');
- $this->invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertNull(self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
}
public function testExecuteWithNotExistingCertificate() {
@@ -204,7 +204,51 @@ class SignAppTest extends TestCase {
->method('writeln')
->with('Certificate "certificate" does not exists.');
- $this->invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertNull(self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithException() {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->at(0))
+ ->method('getOption')
+ ->with('path')
+ ->will($this->returnValue('AppId'));
+ $inputInterface
+ ->expects($this->at(1))
+ ->method('getOption')
+ ->with('privateKey')
+ ->will($this->returnValue('privateKey'));
+ $inputInterface
+ ->expects($this->at(2))
+ ->method('getOption')
+ ->with('certificate')
+ ->will($this->returnValue('certificate'));
+
+ $this->fileAccessHelper
+ ->expects($this->at(0))
+ ->method('file_get_contents')
+ ->with('privateKey')
+ ->will($this->returnValue(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key'));
+ $this->fileAccessHelper
+ ->expects($this->at(1))
+ ->method('file_get_contents')
+ ->with('certificate')
+ ->will($this->returnValue(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt'));
+
+ $this->checker
+ ->expects($this->once())
+ ->method('writeAppSignature')
+ ->willThrowException(new \Exception('My error message'));
+
+ $outputInterface
+ ->expects($this->at(0))
+ ->method('writeln')
+ ->with('Error: My error message');
+
+ $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
}
public function testExecute() {
@@ -247,6 +291,6 @@ class SignAppTest extends TestCase {
->method('writeln')
->with('Successfully signed "AppId"');
- $this->invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertSame(0, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
}
}
diff --git a/tests/lib/Command/Integrity/SignCoreTest.php b/tests/lib/Command/Integrity/SignCoreTest.php
index f3c242ae9fb..35e52b951da 100644
--- a/tests/lib/Command/Integrity/SignCoreTest.php
+++ b/tests/lib/Command/Integrity/SignCoreTest.php
@@ -28,12 +28,12 @@ use Symfony\Component\Console\Output\OutputInterface;
use Test\TestCase;
class SignCoreTest extends TestCase {
- /** @var Checker */
+ /** @var Checker|\PHPUnit_Framework_MockObject_MockObject */
private $checker;
+ /** @var FileAccessHelper|\PHPUnit_Framework_MockObject_MockObject */
+ private $fileAccessHelper;
/** @var SignCore */
private $signCore;
- /** @var FileAccessHelper */
- private $fileAccessHelper;
public function setUp() {
parent::setUp();
@@ -65,7 +65,7 @@ class SignCoreTest extends TestCase {
->method('writeln')
->with('--privateKey, --certificate and --path are required.');
- $this->invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertNull(self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
}
public function testExecuteWithMissingCertificate() {
@@ -88,7 +88,7 @@ class SignCoreTest extends TestCase {
->method('writeln')
->with('--privateKey, --certificate and --path are required.');
- $this->invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertNull(self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
}
public function testExecuteWithNotExistingPrivateKey() {
@@ -122,7 +122,7 @@ class SignCoreTest extends TestCase {
->method('writeln')
->with('Private key "privateKey" does not exists.');
- $this->invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertNull(self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
}
public function testExecuteWithNotExistingCertificate() {
@@ -161,7 +161,51 @@ class SignCoreTest extends TestCase {
->method('writeln')
->with('Certificate "certificate" does not exists.');
- $this->invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertNull(self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithException() {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->at(0))
+ ->method('getOption')
+ ->with('privateKey')
+ ->will($this->returnValue('privateKey'));
+ $inputInterface
+ ->expects($this->at(1))
+ ->method('getOption')
+ ->with('certificate')
+ ->will($this->returnValue('certificate'));
+ $inputInterface
+ ->expects($this->at(2))
+ ->method('getOption')
+ ->with('path')
+ ->will($this->returnValue('certificate'));
+
+ $this->fileAccessHelper
+ ->expects($this->at(0))
+ ->method('file_get_contents')
+ ->with('privateKey')
+ ->will($this->returnValue(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key'));
+ $this->fileAccessHelper
+ ->expects($this->at(1))
+ ->method('file_get_contents')
+ ->with('certificate')
+ ->will($this->returnValue(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt'));
+
+ $this->checker
+ ->expects($this->once())
+ ->method('writeCoreSignature')
+ ->willThrowException(new \Exception('My exception message'));
+
+ $outputInterface
+ ->expects($this->at(0))
+ ->method('writeln')
+ ->with('Error: My exception message');
+
+ $this->assertEquals(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
}
public function testExecute() {
@@ -204,6 +248,6 @@ class SignCoreTest extends TestCase {
->method('writeln')
->with('Successfully signed "core"');
- $this->invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]);
+ $this->assertEquals(0, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
}
}
diff --git a/tests/lib/IntegrityCheck/CheckerTest.php b/tests/lib/IntegrityCheck/CheckerTest.php
index 0e6bd52a5df..049017cb5e8 100644
--- a/tests/lib/IntegrityCheck/CheckerTest.php
+++ b/tests/lib/IntegrityCheck/CheckerTest.php
@@ -34,19 +34,19 @@ use OCP\ICacheFactory;
use OCP\App\IAppManager;
class CheckerTest extends TestCase {
- /** @var EnvironmentHelper */
+ /** @var EnvironmentHelper|\PHPUnit_Framework_MockObject_MockObject */
private $environmentHelper;
- /** @var AppLocator */
+ /** @var AppLocator|\PHPUnit_Framework_MockObject_MockObject */
private $appLocator;
/** @var Checker */
private $checker;
- /** @var FileAccessHelper */
+ /** @var FileAccessHelper|\PHPUnit_Framework_MockObject_MockObject */
private $fileAccessHelper;
- /** @var IConfig */
+ /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
private $config;
- /** @var ICacheFactory */
+ /** @var ICacheFactory|\PHPUnit_Framework_MockObject_MockObject */
private $cacheFactory;
- /** @var IAppManager */
+ /** @var IAppManager|\PHPUnit_Framework_MockObject_MockObject */
private $appManager;
public function setUp() {
@@ -77,9 +77,20 @@ class CheckerTest extends TestCase {
/**
* @expectedException \Exception
- * @expectedExceptionMessage Directory does not exist.
+ * @expectedExceptionMessage Exception message
*/
public function testWriteAppSignatureOfNotExistingApp() {
+ $this->fileAccessHelper
+ ->expects($this->at(0))
+ ->method('assertDirectoryExists')
+ ->with('NotExistingApp/appinfo')
+ ->willThrowException(new \Exception('Exception message'));
+ $this->fileAccessHelper
+ ->expects($this->at(1))
+ ->method('is_writable')
+ ->with('NotExistingApp/appinfo')
+ ->willReturn(true);
+
$keyBundle = file_get_contents(__DIR__ .'/../../data/integritycheck/SomeApp.crt');
$rsaPrivateKey = file_get_contents(__DIR__ .'/../../data/integritycheck/SomeApp.key');
$rsa = new RSA();
@@ -89,6 +100,25 @@ class CheckerTest extends TestCase {
$this->checker->writeAppSignature('NotExistingApp', $x509, $rsa);
}
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessageRegExp /[a-zA-Z\/_-]+ is not writable/
+ */
+ public function testWriteAppSignatureWrongPermissions() {
+ $this->fileAccessHelper
+ ->expects($this->once())
+ ->method('file_put_contents')
+ ->will($this->throwException(new \Exception('Exception message')));
+
+ $keyBundle = file_get_contents(__DIR__ .'/../../data/integritycheck/SomeApp.crt');
+ $rsaPrivateKey = file_get_contents(__DIR__ .'/../../data/integritycheck/SomeApp.key');
+ $rsa = new RSA();
+ $rsa->loadKey($rsaPrivateKey);
+ $x509 = new X509();
+ $x509->loadX509($keyBundle);
+ $this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa);
+ }
+
public function testWriteAppSignature() {
$expectedSignatureFileData = '{
"hashes": {
@@ -443,6 +473,54 @@ class CheckerTest extends TestCase {
$this->assertSame([], $this->checker->verifyAppSignature('SomeApp'));
}
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage Exception message
+ */
+ public function testWriteCoreSignatureWithException() {
+ $this->fileAccessHelper
+ ->expects($this->at(0))
+ ->method('assertDirectoryExists')
+ ->will($this->throwException(new \Exception('Exception message')));
+ $this->fileAccessHelper
+ ->expects($this->at(1))
+ ->method('is_writable')
+ ->with(__DIR__ . '/core')
+ ->willReturn(true);
+
+ $keyBundle = file_get_contents(__DIR__ .'/../../data/integritycheck/SomeApp.crt');
+ $rsaPrivateKey = file_get_contents(__DIR__ .'/../../data/integritycheck/SomeApp.key');
+ $rsa = new RSA();
+ $rsa->loadKey($rsaPrivateKey);
+ $x509 = new X509();
+ $x509->loadX509($keyBundle);
+ $this->checker->writeCoreSignature($x509, $rsa, __DIR__);
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessageRegExp /[a-zA-Z\/_-]+ is not writable/
+ */
+ public function testWriteCoreSignatureWrongPermissions() {
+ $this->fileAccessHelper
+ ->expects($this->at(0))
+ ->method('assertDirectoryExists')
+ ->will($this->throwException(new \Exception('Exception message')));
+ $this->fileAccessHelper
+ ->expects($this->at(1))
+ ->method('is_writable')
+ ->with(__DIR__ . '/core')
+ ->willReturn(false);
+
+ $keyBundle = file_get_contents(__DIR__ .'/../../data/integritycheck/SomeApp.crt');
+ $rsaPrivateKey = file_get_contents(__DIR__ .'/../../data/integritycheck/SomeApp.key');
+ $rsa = new RSA();
+ $rsa->loadKey($rsaPrivateKey);
+ $x509 = new X509();
+ $x509->loadX509($keyBundle);
+ $this->checker->writeCoreSignature($x509, $rsa, __DIR__);
+ }
+
public function testWriteCoreSignature() {
$expectedSignatureFileData = '{
"hashes": {
@@ -948,7 +1026,7 @@ class CheckerTest extends TestCase {
->method('verifyCoreSignature');
$this->appLocator
->expects($this->at(0))
- ->Method('getAllApps')
+ ->method('getAllApps')
->will($this->returnValue([
'files',
'calendar',
@@ -1074,7 +1152,6 @@ class CheckerTest extends TestCase {
->with('integrity.check.disabled', false)
->will($this->returnValue(true));
- $result = $this->invokePrivate($this->checker, 'isCodeCheckEnforced');
- $this->assertSame(false, $result);
+ $this->assertFalse(self::invokePrivate($this->checker, 'isCodeCheckEnforced'));
}
}
diff --git a/tests/lib/IntegrityCheck/Helpers/FileAccessHelperTest.php b/tests/lib/IntegrityCheck/Helpers/FileAccessHelperTest.php
index 740b14e61c4..de4aeec78cc 100644
--- a/tests/lib/IntegrityCheck/Helpers/FileAccessHelperTest.php
+++ b/tests/lib/IntegrityCheck/Helpers/FileAccessHelperTest.php
@@ -40,4 +40,29 @@ class FileAccessHelperTest extends TestCase {
$this->fileAccessHelper->file_put_contents($filePath, $data);
$this->assertSame($data, $this->fileAccessHelper->file_get_contents($filePath));
}
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage Failed to write into /anabsolutelynotexistingfolder/on/the/system.txt
+ */
+ public function testFile_put_contentsWithException() {
+ $this->fileAccessHelper->file_put_contents('/anabsolutelynotexistingfolder/on/the/system.txt', 'MyFiles');
+ }
+
+ public function testIs_writable() {
+ $this->assertFalse($this->fileAccessHelper->is_writable('/anabsolutelynotexistingfolder/on/the/system.txt'));
+ $this->assertTrue($this->fileAccessHelper->is_writable(\OC::$server->getTempManager()->getTemporaryFile('MyFile')));
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage Directory /anabsolutelynotexistingfolder/on/the/system does not exist.
+ */
+ public function testAssertDirectoryExistsWithException() {
+ $this->fileAccessHelper->assertDirectoryExists('/anabsolutelynotexistingfolder/on/the/system');
+ }
+
+ public function testAssertDirectoryExists() {
+ $this->fileAccessHelper->assertDirectoryExists(\OC::$server->getTempManager()->getTemporaryFolder('/testfolder/'));
+ }
}