diff options
69 files changed, 1222 insertions, 296 deletions
diff --git a/apps/encryption/appinfo/application.php b/apps/encryption/appinfo/application.php index 0d6f57f46e9..10ad610cd4a 100644 --- a/apps/encryption/appinfo/application.php +++ b/apps/encryption/appinfo/application.php @@ -104,7 +104,8 @@ class Application extends \OCP\AppFramework\App { $container->query('Crypt'), $container->query('KeyManager'), $container->query('Util'), - $container->getServer()->getLogger() + $container->getServer()->getLogger(), + $container->getServer()->getL10N($container->getAppName()) ); }); @@ -209,7 +210,8 @@ class Application extends \OCP\AppFramework\App { $c->query('Crypt'), $server->getLogger(), $server->getUserSession(), - $server->getConfig()); + $server->getConfig(), + $server->getUserManager()); }); } diff --git a/apps/encryption/appinfo/info.xml b/apps/encryption/appinfo/info.xml index 53a2459f864..8d3b680fc08 100644 --- a/apps/encryption/appinfo/info.xml +++ b/apps/encryption/appinfo/info.xml @@ -16,7 +16,7 @@ based on AES 128 or 256 bit keys. More information is available in the Encryption documentation </description> - <name>ownCloud Default Encryption Module</name> + <name>Default encryption module</name> <license>AGPL</license> <author>Bjoern Schiessle, Clark Tomlinson</author> <requiremin>8</requiremin> diff --git a/apps/encryption/l10n/es.js b/apps/encryption/l10n/es.js index dd49810f03a..a5a6f086fd0 100644 --- a/apps/encryption/l10n/es.js +++ b/apps/encryption/l10n/es.js @@ -25,6 +25,7 @@ OC.L10N.register( "Encryption App is enabled but your keys are not initialized, please log-out and log-in again" : "La app de cifrado está habilitada pero sus claves no se han inicializado, por favor, cierre la sesión y vuelva a iniciarla de nuevo.", "Enable recovery key" : "Activa la clave de recuperación", "Disable recovery key" : "Desactiva la clave de recuperación", + "The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password." : "La clave de recuperación es una clave de cifrado extra que se usa para cifrar ficheros. Permite la recuperación de los ficheros de un usuario si él o ella olvida su contraseña.", "Recovery key password" : "Contraseña de clave de recuperación", "Repeat recovery key password" : "Repita la contraseña de recuperación", "Change recovery key password:" : "Cambiar la contraseña de la clave de recuperación", diff --git a/apps/encryption/l10n/es.json b/apps/encryption/l10n/es.json index 54811d078c9..911d1f8b893 100644 --- a/apps/encryption/l10n/es.json +++ b/apps/encryption/l10n/es.json @@ -23,6 +23,7 @@ "Encryption App is enabled but your keys are not initialized, please log-out and log-in again" : "La app de cifrado está habilitada pero sus claves no se han inicializado, por favor, cierre la sesión y vuelva a iniciarla de nuevo.", "Enable recovery key" : "Activa la clave de recuperación", "Disable recovery key" : "Desactiva la clave de recuperación", + "The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password." : "La clave de recuperación es una clave de cifrado extra que se usa para cifrar ficheros. Permite la recuperación de los ficheros de un usuario si él o ella olvida su contraseña.", "Recovery key password" : "Contraseña de clave de recuperación", "Repeat recovery key password" : "Repita la contraseña de recuperación", "Change recovery key password:" : "Cambiar la contraseña de la clave de recuperación", diff --git a/apps/encryption/l10n/id.js b/apps/encryption/l10n/id.js index f1aebdbe1ac..4feb1de4186 100644 --- a/apps/encryption/l10n/id.js +++ b/apps/encryption/l10n/id.js @@ -8,20 +8,32 @@ OC.L10N.register( "Could not enable recovery key. Please check your recovery key password!" : "Tidak dapat mengaktifkan kunci pemulihan. Silakan periksa sandi kunci pemulihan Anda!", "Recovery key successfully disabled" : "Kunci pemulihan berhasil dinonaktifkan", "Could not disable recovery key. Please check your recovery key password!" : "Tidak dapat menonaktifkan kunci pemulihan. Silakan periksa sandi kunci pemulihan Anda!", + "Missing parameters" : "Parameter salah", "Please provide the old recovery password" : "Mohon berikan sandi pemulihan lama", "Please provide a new recovery password" : "Mohon berikan sandi pemulihan baru", "Please repeat the new recovery password" : "Silakan ulangi sandi pemulihan baru", "Password successfully changed." : "Sandi berhasil diubah", "Could not change the password. Maybe the old password was not correct." : "Tidak dapat mengubah sandi. Kemungkinan sandi lama yang dimasukkan salah.", + "Recovery Key disabled" : "Kunci Pemulihan dinonaktifkan", + "Recovery Key enabled" : "Kunci Pemulihan diaktifkan", + "Could not enable the recovery key, please try again or contact your administrator" : "Tidak dapat mengaktifkan kunci pemulihan, silakan coba lagi atau hubungi administrator Anda", "Could not update the private key password." : "Tidak dapat memperbarui sandi kunci private.", "The old password was not correct, please try again." : "Sandi lama salah, mohon coba lagi.", "The current log-in password was not correct, please try again." : "Sandi masuk saat ini salah, mohon coba lagi.", "Private key password successfully updated." : "Sandi kunci privat berhasil diperbarui.", "Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." : "Kunci privat tidak sah untuk Aplikasi Enskripsi. Silakan perbarui sandi kunci privat anda pada pengaturan pribadi untuk memulihkan akses ke berkas anda yang dienskripsi.", "Encryption App is enabled but your keys are not initialized, please log-out and log-in again" : "Aplikasi Enskripsi telah diaktifkan tetapi kunci tidak diinisialisasi, silakan log-out dan log-in lagi", + "Enable recovery key" : "Aktifkan kunci pemulihan", + "Disable recovery key" : "Nonaktifkan kunci pemulihan", + "The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password." : "Kunci pemulihan adalah kunci enkripsi tambahan yang digunakan untuk mengenkripsi berkas. Kunci pemulihan memungkinkan untuk memulihkan berkas-berkas pengguna ketika pengguna tersebut melupakan sandi mereka.", "Recovery key password" : "Sandi kunci pemulihan", + "Repeat recovery key password" : "Ulangi sandi kunci pemulihan", "Change recovery key password:" : "Ubah sandi kunci pemulihan:", + "Old recovery key password" : "Sandi kunci pemulihan lama", + "New recovery key password" : "Sandi kunci pemulihan baru", + "Repeat new recovery key password" : "Ulangi sandi kunci pemulihan baru", "Change Password" : "Ubah Sandi", + "ownCloud basic encryption module" : "Modul enkripsi dasar ownCloud", "Your private key password no longer matches your log-in password." : "Sandi kunci private Anda tidak lagi cocok dengan sandi masuk Anda.", "Set your old private key password to your current log-in password:" : "Setel sandi kunci private Anda untuk sandi masuk Anda saat ini:", " If you don't remember your old password you can ask your administrator to recover your files." : "Jika Anda tidak ingat sandi lama, Anda dapat meminta administrator Anda untuk memulihkan berkas.", diff --git a/apps/encryption/l10n/id.json b/apps/encryption/l10n/id.json index 25433f810ac..da2bf575939 100644 --- a/apps/encryption/l10n/id.json +++ b/apps/encryption/l10n/id.json @@ -6,20 +6,32 @@ "Could not enable recovery key. Please check your recovery key password!" : "Tidak dapat mengaktifkan kunci pemulihan. Silakan periksa sandi kunci pemulihan Anda!", "Recovery key successfully disabled" : "Kunci pemulihan berhasil dinonaktifkan", "Could not disable recovery key. Please check your recovery key password!" : "Tidak dapat menonaktifkan kunci pemulihan. Silakan periksa sandi kunci pemulihan Anda!", + "Missing parameters" : "Parameter salah", "Please provide the old recovery password" : "Mohon berikan sandi pemulihan lama", "Please provide a new recovery password" : "Mohon berikan sandi pemulihan baru", "Please repeat the new recovery password" : "Silakan ulangi sandi pemulihan baru", "Password successfully changed." : "Sandi berhasil diubah", "Could not change the password. Maybe the old password was not correct." : "Tidak dapat mengubah sandi. Kemungkinan sandi lama yang dimasukkan salah.", + "Recovery Key disabled" : "Kunci Pemulihan dinonaktifkan", + "Recovery Key enabled" : "Kunci Pemulihan diaktifkan", + "Could not enable the recovery key, please try again or contact your administrator" : "Tidak dapat mengaktifkan kunci pemulihan, silakan coba lagi atau hubungi administrator Anda", "Could not update the private key password." : "Tidak dapat memperbarui sandi kunci private.", "The old password was not correct, please try again." : "Sandi lama salah, mohon coba lagi.", "The current log-in password was not correct, please try again." : "Sandi masuk saat ini salah, mohon coba lagi.", "Private key password successfully updated." : "Sandi kunci privat berhasil diperbarui.", "Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." : "Kunci privat tidak sah untuk Aplikasi Enskripsi. Silakan perbarui sandi kunci privat anda pada pengaturan pribadi untuk memulihkan akses ke berkas anda yang dienskripsi.", "Encryption App is enabled but your keys are not initialized, please log-out and log-in again" : "Aplikasi Enskripsi telah diaktifkan tetapi kunci tidak diinisialisasi, silakan log-out dan log-in lagi", + "Enable recovery key" : "Aktifkan kunci pemulihan", + "Disable recovery key" : "Nonaktifkan kunci pemulihan", + "The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password." : "Kunci pemulihan adalah kunci enkripsi tambahan yang digunakan untuk mengenkripsi berkas. Kunci pemulihan memungkinkan untuk memulihkan berkas-berkas pengguna ketika pengguna tersebut melupakan sandi mereka.", "Recovery key password" : "Sandi kunci pemulihan", + "Repeat recovery key password" : "Ulangi sandi kunci pemulihan", "Change recovery key password:" : "Ubah sandi kunci pemulihan:", + "Old recovery key password" : "Sandi kunci pemulihan lama", + "New recovery key password" : "Sandi kunci pemulihan baru", + "Repeat new recovery key password" : "Ulangi sandi kunci pemulihan baru", "Change Password" : "Ubah Sandi", + "ownCloud basic encryption module" : "Modul enkripsi dasar ownCloud", "Your private key password no longer matches your log-in password." : "Sandi kunci private Anda tidak lagi cocok dengan sandi masuk Anda.", "Set your old private key password to your current log-in password:" : "Setel sandi kunci private Anda untuk sandi masuk Anda saat ini:", " If you don't remember your old password you can ask your administrator to recover your files." : "Jika Anda tidak ingat sandi lama, Anda dapat meminta administrator Anda untuk memulihkan berkas.", diff --git a/apps/encryption/l10n/pt_BR.js b/apps/encryption/l10n/pt_BR.js index f68cd3ae667..4d25a18c137 100644 --- a/apps/encryption/l10n/pt_BR.js +++ b/apps/encryption/l10n/pt_BR.js @@ -25,6 +25,7 @@ OC.L10N.register( "Encryption App is enabled but your keys are not initialized, please log-out and log-in again" : "App de criptografia está ativado, mas as chaves não estão inicializadas, por favor log-out e faça login novamente", "Enable recovery key" : "Habilitar recuperação de chave", "Disable recovery key" : "Dasabilitar chave de recuperação", + "The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password." : "A chave de recuperação é uma chave de encriptação extra que é utilizada para encriptar arquivos. Ela permite a recuperação de arquivos de um usuário esquecer sua senha.", "Recovery key password" : "Senha da chave de recuperação", "Repeat recovery key password" : "Repita senha da chave de recuperação", "Change recovery key password:" : "Mudar a senha da chave de recuperação:", diff --git a/apps/encryption/l10n/pt_BR.json b/apps/encryption/l10n/pt_BR.json index aecf8ee11c1..1c7b13e2e7d 100644 --- a/apps/encryption/l10n/pt_BR.json +++ b/apps/encryption/l10n/pt_BR.json @@ -23,6 +23,7 @@ "Encryption App is enabled but your keys are not initialized, please log-out and log-in again" : "App de criptografia está ativado, mas as chaves não estão inicializadas, por favor log-out e faça login novamente", "Enable recovery key" : "Habilitar recuperação de chave", "Disable recovery key" : "Dasabilitar chave de recuperação", + "The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password." : "A chave de recuperação é uma chave de encriptação extra que é utilizada para encriptar arquivos. Ela permite a recuperação de arquivos de um usuário esquecer sua senha.", "Recovery key password" : "Senha da chave de recuperação", "Repeat recovery key password" : "Repita senha da chave de recuperação", "Change recovery key password:" : "Mudar a senha da chave de recuperação:", diff --git a/apps/encryption/lib/crypto/encryption.php b/apps/encryption/lib/crypto/encryption.php index a4abcd7dc5a..f527955b496 100644 --- a/apps/encryption/lib/crypto/encryption.php +++ b/apps/encryption/lib/crypto/encryption.php @@ -25,16 +25,18 @@ namespace OCA\Encryption\Crypto; +use OC\Encryption\Exceptions\DecryptionFailedException; use OCA\Encryption\Exceptions\PublicKeyMissingException; use OCA\Encryption\Util; use OCP\Encryption\IEncryptionModule; use OCA\Encryption\KeyManager; +use OCP\IL10N; use OCP\ILogger; class Encryption implements IEncryptionModule { const ID = 'OC_DEFAULT_MODULE'; - const DISPLAY_NAME = 'ownCloud Default Encryption'; + const DISPLAY_NAME = 'Default encryption module'; /** * @var Crypt @@ -68,25 +70,30 @@ class Encryption implements IEncryptionModule { /** @var Util */ private $util; - /** @var ILogger */ private $logger; + /** @var IL10N */ + private $l; + /** * * @param Crypt $crypt * @param KeyManager $keyManager * @param Util $util * @param ILogger $logger + * @param IL10N $il10n */ public function __construct(Crypt $crypt, KeyManager $keyManager, Util $util, - ILogger $logger) { + ILogger $logger, + IL10N $il10n) { $this->crypt = $crypt; $this->keyManager = $keyManager; $this->util = $util; $this->logger = $logger; + $this->l = $il10n; } /** @@ -268,8 +275,18 @@ class Encryption implements IEncryptionModule { * * @param string $data you want to decrypt * @return mixed decrypted data + * @throws DecryptionFailedException */ public function decrypt($data) { + if (empty($this->fileKey)) { + $msg = $this->l->t('Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you.'); + $this->logger->error('Can not decrypt this file, + probably this is a shared file. + Please ask the file owner to reshare the file with you.'); + + throw new DecryptionFailedException($msg); + } + $result = ''; if (!empty($data)) { $result = $this->crypt->symmetricDecryptFileContent($data, $this->fileKey, $this->cipher); @@ -287,7 +304,7 @@ class Encryption implements IEncryptionModule { */ public function update($path, $uid, array $accessList) { $fileKey = $this->keyManager->getFileKey($path, $uid); - + if (!empty($fileKey)) { $publicKeys = array(); @@ -321,7 +338,7 @@ class Encryption implements IEncryptionModule { */ public function shouldEncrypt($path) { $parts = explode('/', $path); - if (count($parts) < 3) { + if (count($parts) < 4) { return false; } @@ -331,6 +348,9 @@ class Encryption implements IEncryptionModule { if ($parts[2] == 'files_versions') { return true; } + if ($parts[2] == 'files_trashbin') { + return true; + } return false; } @@ -346,6 +366,36 @@ class Encryption implements IEncryptionModule { } /** + * check if the encryption module is able to read the file, + * e.g. if all encryption keys exists + * + * @param string $path + * @param string $uid user for whom we want to check if he can read the file + * @return bool + * @throws DecryptionFailedException + */ + public function isReadable($path, $uid) { + $fileKey = $this->keyManager->getFileKey($path, $uid); + if (empty($fileKey)) { + $owner = $this->util->getOwner($path); + if ($owner !== $uid) { + // if it is a shared file we throw a exception with a useful + // error message because in this case it means that the file was + // shared with the user at a point where the user didn't had a + // valid private/public key + $msg = 'Encryption module "' . $this->getDisplayName() . + '" is not able to read ' . $path; + $hint = $this->l->t('Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you.'); + $this->logger->warning($msg); + throw new DecryptionFailedException($msg, 0, null, $hint); + } + return false; + } + + return true; + } + + /** * @param string $path * @return string */ @@ -360,4 +410,5 @@ class Encryption implements IEncryptionModule { return $realPath; } + } diff --git a/apps/encryption/lib/util.php b/apps/encryption/lib/util.php index 51d5241122f..afed96aaa38 100644 --- a/apps/encryption/lib/util.php +++ b/apps/encryption/lib/util.php @@ -29,6 +29,7 @@ use OCA\Encryption\Crypto\Crypt; use OCP\IConfig; use OCP\ILogger; use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; use OCP\PreConditionNotMetException; @@ -53,6 +54,10 @@ class Util { * @var IConfig */ private $config; + /** + * @var IUserManager + */ + private $userManager; /** * Util constructor. @@ -62,18 +67,21 @@ class Util { * @param ILogger $logger * @param IUserSession $userSession * @param IConfig $config + * @param IUserManager $userManager */ public function __construct(View $files, Crypt $crypt, ILogger $logger, IUserSession $userSession, - IConfig $config + IConfig $config, + IUserManager $userManager ) { $this->files = $files; $this->crypt = $crypt; $this->logger = $logger; $this->user = $userSession && $userSession->isLoggedIn() ? $userSession->getUser() : false; $this->config = $config; + $this->userManager = $userManager; } /** @@ -117,5 +125,26 @@ class Util { return $this->files->file_exists($uid . '/files'); } + /** + * get owner from give path, path relative to data/ expected + * + * @param string $path relative to data/ + * @return string + * @throws \BadMethodCallException + */ + public function getOwner($path) { + $owner = ''; + $parts = explode('/', $path, 3); + if (count($parts) > 1) { + $owner = $parts[1]; + if ($this->userManager->userExists($owner) === false) { + throw new \BadMethodCallException('Unknown user: ' . + 'method expects path to a user folder relative to the data folder'); + } + + } + + return $owner; + } } diff --git a/apps/encryption/settings/settings-personal.php b/apps/encryption/settings/settings-personal.php index 003a27da71d..3815626ee64 100644 --- a/apps/encryption/settings/settings-personal.php +++ b/apps/encryption/settings/settings-personal.php @@ -35,7 +35,8 @@ $util = new \OCA\Encryption\Util( $crypt, \OC::$server->getLogger(), $userSession, - \OC::$server->getConfig()); + \OC::$server->getConfig(), + \OC::$server->getUserManager()); $keyManager = new \OCA\Encryption\KeyManager( \OC::$server->getEncryptionKeyStorage(), diff --git a/apps/encryption/tests/lib/UtilTest.php b/apps/encryption/tests/lib/UtilTest.php index eab912b82d4..18cf0386793 100644 --- a/apps/encryption/tests/lib/UtilTest.php +++ b/apps/encryption/tests/lib/UtilTest.php @@ -28,11 +28,17 @@ use Test\TestCase; class UtilTest extends TestCase { private static $tempStorage = []; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ private $configMock; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ private $filesMock; - /** - * @var Util - */ + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $userManagerMock; + + /** @var Util */ private $instance; public function testSetRecoveryForUser() { @@ -40,9 +46,6 @@ class UtilTest extends TestCase { $this->assertArrayHasKey('recoveryEnabled', self::$tempStorage); } - /** - * - */ public function testIsRecoveryEnabledForUser() { $this->assertTrue($this->instance->isRecoveryEnabledForUser('admin')); @@ -62,6 +65,7 @@ class UtilTest extends TestCase { protected function setUp() { parent::setUp(); $this->filesMock = $this->getMock('OC\Files\View'); + $this->userManagerMock = $this->getMock('\OCP\IUserManager'); $cryptMock = $this->getMockBuilder('OCA\Encryption\Crypto\Crypt') ->disableOriginalConstructor() @@ -98,7 +102,7 @@ class UtilTest extends TestCase { ->method('setUserValue') ->will($this->returnCallback([$this, 'setValueTester'])); - $this->instance = new Util($this->filesMock, $cryptMock, $loggerMock, $userSessionMock, $configMock); + $this->instance = new Util($this->filesMock, $cryptMock, $loggerMock, $userSessionMock, $configMock, $this->userManagerMock); } /** diff --git a/apps/encryption/tests/lib/crypto/encryptionTest.php b/apps/encryption/tests/lib/crypto/encryptionTest.php index aa28a8b44a4..d33aff877bf 100644 --- a/apps/encryption/tests/lib/crypto/encryptionTest.php +++ b/apps/encryption/tests/lib/crypto/encryptionTest.php @@ -42,6 +42,9 @@ class EncryptionTest extends TestCase { /** @var \PHPUnit_Framework_MockObject_MockObject */ private $loggerMock; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $l10nMock; + public function setUp() { parent::setUp(); @@ -57,12 +60,20 @@ class EncryptionTest extends TestCase { $this->loggerMock = $this->getMockBuilder('OCP\ILogger') ->disableOriginalConstructor() ->getMock(); + $this->l10nMock = $this->getMockBuilder('OCP\IL10N') + ->disableOriginalConstructor() + ->getMock(); + $this->l10nMock->expects($this->any()) + ->method('t') + ->with($this->anything()) + ->willReturnArgument(0); $this->instance = new Encryption( $this->cryptMock, $this->keyManagerMock, $this->utilMock, - $this->loggerMock + $this->loggerMock, + $this->l10nMock ); } @@ -220,4 +231,36 @@ class EncryptionTest extends TestCase { ); } + /** + * by default the encryption module should encrypt regular files, files in + * files_versions and files in files_trashbin + * + * @dataProvider dataTestShouldEncrypt + */ + public function testShouldEncrypt($path, $expected) { + $this->assertSame($expected, + $this->instance->shouldEncrypt($path) + ); + } + + public function dataTestShouldEncrypt() { + return array( + array('/user1/files/foo.txt', true), + array('/user1/files_versions/foo.txt', true), + array('/user1/files_trashbin/foo.txt', true), + array('/user1/some_folder/foo.txt', false), + array('/user1/foo.txt', false), + array('/user1/files', false), + array('/user1/files_trashbin', false), + array('/user1/files_versions', false), + ); + } + + /** + * @expectedException \OC\Encryption\Exceptions\DecryptionFailedException + * @expectedExceptionMessage Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you. + */ + public function testDecrypt() { + $this->instance->decrypt('abc'); + } } diff --git a/apps/files/l10n/pt_PT.js b/apps/files/l10n/pt_PT.js index 072141105c8..09974a0321d 100644 --- a/apps/files/l10n/pt_PT.js +++ b/apps/files/l10n/pt_PT.js @@ -42,6 +42,7 @@ OC.L10N.register( "Delete" : "Apagar", "Disconnect storage" : "Desconete o armazenamento", "Unshare" : "Deixar de partilhar", + "No permission to delete" : "Não tem permissão para apagar", "Download" : "Transferir", "Select" : "Selecionar", "Pending" : "Pendente", diff --git a/apps/files/l10n/pt_PT.json b/apps/files/l10n/pt_PT.json index 66230a0e6c9..4172185936a 100644 --- a/apps/files/l10n/pt_PT.json +++ b/apps/files/l10n/pt_PT.json @@ -40,6 +40,7 @@ "Delete" : "Apagar", "Disconnect storage" : "Desconete o armazenamento", "Unshare" : "Deixar de partilhar", + "No permission to delete" : "Não tem permissão para apagar", "Download" : "Transferir", "Select" : "Selecionar", "Pending" : "Pendente", diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 33b7f887e19..10a37c7dae9 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -217,7 +217,13 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { } public function isReadable($path) { - return $this->file_exists($path); + $isReadable = false; + if ($source = $this->getSourcePath($path)) { + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); + $isReadable = $storage->isReadable($internalPath); + } + + return $isReadable && $this->file_exists($path); } public function isUpdatable($path) { diff --git a/apps/files_sharing/publicwebdav.php b/apps/files_sharing/publicwebdav.php index 3be464c64f0..c2a16e933b3 100644 --- a/apps/files_sharing/publicwebdav.php +++ b/apps/files_sharing/publicwebdav.php @@ -48,7 +48,8 @@ $server->setBaseUri($baseuri); // Load plugins $defaults = new OC_Defaults(); $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, $defaults->getName())); -$server->addPlugin(new \Sabre\DAV\Browser\Plugin(false)); // Show something in the Browser, but no upload +// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to / +$server->addPlugin(new \OC\Connector\Sabre\DummyGetResponsePlugin()); $server->addPlugin(new \OC\Connector\Sabre\FilesPlugin($objectTree)); $server->addPlugin(new \OC\Connector\Sabre\MaintenancePlugin()); $server->addPlugin(new \OC\Connector\Sabre\ExceptionLoggerPlugin('webdav', \OC::$server->getLogger())); diff --git a/apps/provisioning_api/lib/users.php b/apps/provisioning_api/lib/users.php index 505a141c032..43cf22b071b 100644 --- a/apps/provisioning_api/lib/users.php +++ b/apps/provisioning_api/lib/users.php @@ -155,7 +155,14 @@ class Users { case 'quota': $quota = $parameters['_put']['value']; if($quota !== 'none' and $quota !== 'default') { - $quota = OC_Helper::computerFileSize($quota); + if (is_numeric($quota)) { + $quota = floatval($quota); + } else { + $quota = OC_Helper::computerFileSize($quota); + } + if ($quota === false) { + return new OC_OCS_Result(null, 103, "Invalid quota value {$parameters['_put']['value']}"); + } if($quota == 0) { $quota = 'default'; }else if($quota == -1){ diff --git a/apps/provisioning_api/tests/userstest.php b/apps/provisioning_api/tests/userstest.php index b7e83a3c4fe..c6a6133b7d2 100644 --- a/apps/provisioning_api/tests/userstest.php +++ b/apps/provisioning_api/tests/userstest.php @@ -187,20 +187,36 @@ class UsersTest extends TestCase { } - public function testEditOwnQuota() { + /** + * @dataProvider providesQuotas + * @param $expected + * @param $quota + */ + public function testEditOwnQuota($expected, $quota) { $user = $this->generateUsers(); + \OC_Group::addToGroup($user, 'admin'); \OC_User::setUserId($user); $result = \OCA\provisioning_API\Users::editUser( - array( + [ 'userid' => $user, - '_put' => array( + '_put' => [ 'key' => 'quota', - 'value' => '20G', - ), - ) + 'value' => $quota, + ], + ] ); $this->assertInstanceOf('OC_OCS_Result', $result); - $this->assertFalse($result->succeeded()); + $this->assertEquals($expected, $result->succeeded()); + } + + public function providesQuotas() { + return [ + [true, '20G'], + [true, '1234567'], + [true, 'none'], + [true, 'default'], + [false, 'qwertzu'], + ]; } public function testAdminEditOwnQuota() { diff --git a/apps/user_ldap/ajax/testConfiguration.php b/apps/user_ldap/ajax/testConfiguration.php index 31f72a38e0b..f5fd5f23b87 100644 --- a/apps/user_ldap/ajax/testConfiguration.php +++ b/apps/user_ldap/ajax/testConfiguration.php @@ -34,16 +34,38 @@ $ldapWrapper = new OCA\user_ldap\lib\LDAP(); $connection = new \OCA\user_ldap\lib\Connection($ldapWrapper, '', null); //needs to be true, otherwise it will also fail with an irritating message $_POST['ldap_configuration_active'] = 1; -if($connection->setConfiguration($_POST)) { - //Configuration is okay - if($connection->bind()) { - OCP\JSON::success(array('message' + +try { + if ($connection->setConfiguration($_POST)) { + //Configuration is okay + if ($connection->bind()) { + /* + * This shiny if block is an ugly hack to find out whether anonymous + * bind is possible on AD or not. Because AD happily and constantly + * replies with success to any anonymous bind request, we need to + * fire up a broken operation. If AD does not allow anonymous bind, + * it will end up with LDAP error code 1 which is turned into an + * exception by the LDAP wrapper. We catch this. Other cases may + * pass (like e.g. expected syntax error). + */ + try { + $ldapWrapper->read($connection->getConnectionResource(), 'neverwhere', 'objectClass=*', array('dn')); + } catch (\Exception $e) { + if($e->getCode() === 1) { + OCP\JSON::error(array('message' => $l->t('The configuration is invalid: anonymous bind is not allowed.'))); + exit; + } + } + OCP\JSON::success(array('message' => $l->t('The configuration is valid and the connection could be established!'))); + } else { + OCP\JSON::error(array('message' + => $l->t('The configuration is valid, but the Bind failed. Please check the server settings and credentials.'))); + } } else { OCP\JSON::error(array('message' - => $l->t('The configuration is valid, but the Bind failed. Please check the server settings and credentials.'))); - } -} else { - OCP\JSON::error(array('message' => $l->t('The configuration is invalid. Please have a look at the logs for further details.'))); + } +} catch (\Exception $e) { + OCP\JSON::error(array('message' => $e->getMessage())); } diff --git a/apps/user_ldap/js/wizard/wizardTabElementary.js b/apps/user_ldap/js/wizard/wizardTabElementary.js index b8ab367dfd1..75664275a9c 100644 --- a/apps/user_ldap/js/wizard/wizardTabElementary.js +++ b/apps/user_ldap/js/wizard/wizardTabElementary.js @@ -165,6 +165,12 @@ OCA = OCA || {}; * @inheritdoc */ overrideErrorMessage: function(message, key) { + var original = message; + message = this._super(message, key); + if(original !== message) { + // we pass the parents change + return message; + } switch(key) { case 'ldap_port': if (message === 'Invalid credentials') { @@ -267,7 +273,8 @@ OCA = OCA || {}; message = t('user_ldap', objectsFound + ' entries available within the provided Base DN'); } } else { - message = t('user_ldap', 'An error occurred. Please check the Base DN, as well as connection settings and credentials.'); + message = view.overrideErrorMessage(payload.data.message); + message = message || t('user_ldap', 'An error occurred. Please check the Base DN, as well as connection settings and credentials.'); if(payload.data.message) { console.warn(payload.data.message); } diff --git a/apps/user_ldap/js/wizard/wizardTabGeneric.js b/apps/user_ldap/js/wizard/wizardTabGeneric.js index 720628fa609..b755f3ca060 100644 --- a/apps/user_ldap/js/wizard/wizardTabGeneric.js +++ b/apps/user_ldap/js/wizard/wizardTabGeneric.js @@ -70,6 +70,17 @@ OCA = OCA || {}; * @returns {string} */ overrideErrorMessage: function(message, key) { + if(message === 'LDAP authentication method rejected' + && !this.configModel.configuration.ldap_dn) + { + message = t('user_ldap', 'Anonymous bind is not allowed. Please provide a User DN and Password.'); + } else if (message === 'LDAP Operations error' + && !this.configModel.configuration.ldap_dn + && !this.configModel.configuration.ldap_agent_password) + { + message = t('user_ldap', 'LDAP Operations error. Anonymous bind might not be allowed.'); + } + return message; }, diff --git a/apps/user_ldap/js/wizard/wizardTabUserFilter.js b/apps/user_ldap/js/wizard/wizardTabUserFilter.js index 992c1ccf379..4fe223ee075 100644 --- a/apps/user_ldap/js/wizard/wizardTabUserFilter.js +++ b/apps/user_ldap/js/wizard/wizardTabUserFilter.js @@ -122,6 +122,12 @@ OCA = OCA || {}; * @inheritdoc */ overrideErrorMessage: function(message, key) { + var original = message; + message = this._super(message, key); + if(original !== message) { + // we pass the parents change + return message; + } if( key === 'ldap_userfilter_groups' && message === 'memberOf is not supported by the server' ) { diff --git a/apps/user_ldap/l10n/da.js b/apps/user_ldap/l10n/da.js index f19e3ffa837..1b070f48a90 100644 --- a/apps/user_ldap/l10n/da.js +++ b/apps/user_ldap/l10n/da.js @@ -22,6 +22,7 @@ OC.L10N.register( "Could not detect Base DN, please enter it manually." : "Kunne ikke registrere Base DN - angiv den venligst manuelt.", "{nthServer}. Server" : "{nthServer}. server", "No object found in the given Base DN. Please revise." : "Intet objekt fundet i den givne Base DN. Gennemse venligst.", + "More than 1.000 directory entries available." : "Mere end 1.000 opslag tilgængelige", " entries available within the provided Base DN" : "poster tilgængelige inden for det angivne Base DN.", "An error occurred. Please check the Base DN, as well as connection settings and credentials." : "Der opstod en fejl. Tjek venligst Base DN, såvel som forbindelsesindstillingerne og brugeroplysningerne.", "Do you really want to delete the current Server Configuration?" : "Ønsker du virkelig at slette den nuværende Server Konfiguration?", diff --git a/apps/user_ldap/l10n/da.json b/apps/user_ldap/l10n/da.json index 0e3702e3e80..acd0eaae13e 100644 --- a/apps/user_ldap/l10n/da.json +++ b/apps/user_ldap/l10n/da.json @@ -20,6 +20,7 @@ "Could not detect Base DN, please enter it manually." : "Kunne ikke registrere Base DN - angiv den venligst manuelt.", "{nthServer}. Server" : "{nthServer}. server", "No object found in the given Base DN. Please revise." : "Intet objekt fundet i den givne Base DN. Gennemse venligst.", + "More than 1.000 directory entries available." : "Mere end 1.000 opslag tilgængelige", " entries available within the provided Base DN" : "poster tilgængelige inden for det angivne Base DN.", "An error occurred. Please check the Base DN, as well as connection settings and credentials." : "Der opstod en fejl. Tjek venligst Base DN, såvel som forbindelsesindstillingerne og brugeroplysningerne.", "Do you really want to delete the current Server Configuration?" : "Ønsker du virkelig at slette den nuværende Server Konfiguration?", diff --git a/apps/user_ldap/l10n/id.js b/apps/user_ldap/l10n/id.js index d8ff8b4e24c..23170f99864 100644 --- a/apps/user_ldap/l10n/id.js +++ b/apps/user_ldap/l10n/id.js @@ -35,6 +35,8 @@ OC.L10N.register( "Select attributes" : "Pilih atribut", "User not found. Please check your login attributes and username. Effective filter (to copy-and-paste for command line validation): <br/>" : "Pengguna tidak ditemukan. Mohon periksa atribut login dan nama pengguna Anda. Penyaring efektif (salin dan tempel berikut untuk validasi baris perintah):\n<br/>", "User found and settings verified." : "Pengguna ditemukan dan pengaturan terverifikasi.", + "An unspecified error occurred. Please check the settings and the log." : "Terjadi kesalahan yang tidak disebutkan. Mohon periksa pengaturan dan log.", + "The search filter is invalid, probably due to syntax issues like uneven number of opened and closed brackets. Please revise." : "Penyaring pencarian tidak sah, kemungkinan karena masalah sintaks seperti jumlah kurung buka dan tutup tidak sama. Mohon diperiksa.", "A connection error to LDAP / AD occurred, please check host, port and credentials." : "Terjadi kesalahan sambungan ke LDAP / AD, mohon periksa host, port dan kredensial.", "The group box was disabled, because the LDAP / AD server does not support memberOf." : "Kotak grup telah diaktifkan, karena server LDAP / AD tidak mendukung keanggotaan.", "_%s group found_::_%s groups found_" : ["%s grup ditemukan"], diff --git a/apps/user_ldap/l10n/id.json b/apps/user_ldap/l10n/id.json index 811351a2549..fa0a0a7be20 100644 --- a/apps/user_ldap/l10n/id.json +++ b/apps/user_ldap/l10n/id.json @@ -33,6 +33,8 @@ "Select attributes" : "Pilih atribut", "User not found. Please check your login attributes and username. Effective filter (to copy-and-paste for command line validation): <br/>" : "Pengguna tidak ditemukan. Mohon periksa atribut login dan nama pengguna Anda. Penyaring efektif (salin dan tempel berikut untuk validasi baris perintah):\n<br/>", "User found and settings verified." : "Pengguna ditemukan dan pengaturan terverifikasi.", + "An unspecified error occurred. Please check the settings and the log." : "Terjadi kesalahan yang tidak disebutkan. Mohon periksa pengaturan dan log.", + "The search filter is invalid, probably due to syntax issues like uneven number of opened and closed brackets. Please revise." : "Penyaring pencarian tidak sah, kemungkinan karena masalah sintaks seperti jumlah kurung buka dan tutup tidak sama. Mohon diperiksa.", "A connection error to LDAP / AD occurred, please check host, port and credentials." : "Terjadi kesalahan sambungan ke LDAP / AD, mohon periksa host, port dan kredensial.", "The group box was disabled, because the LDAP / AD server does not support memberOf." : "Kotak grup telah diaktifkan, karena server LDAP / AD tidak mendukung keanggotaan.", "_%s group found_::_%s groups found_" : ["%s grup ditemukan"], diff --git a/apps/user_ldap/l10n/pt_PT.js b/apps/user_ldap/l10n/pt_PT.js index e29158df8d4..55cccb28022 100644 --- a/apps/user_ldap/l10n/pt_PT.js +++ b/apps/user_ldap/l10n/pt_PT.js @@ -10,6 +10,7 @@ OC.L10N.register( "No configuration specified" : "Nenhuma configuração especificada", "No data specified" : "Nenhuma data especificada", " Could not set configuration %s" : "Não foi possível definir a configuração %s", + "Action does not exist" : "Não existe esta acção", "Configuration incorrect" : "Configuração incorreta", "Configuration incomplete" : "Configuração incompleta", "Configuration OK" : "Configuração OK", diff --git a/apps/user_ldap/l10n/pt_PT.json b/apps/user_ldap/l10n/pt_PT.json index 94e5cb6c3af..2b0c81a96f4 100644 --- a/apps/user_ldap/l10n/pt_PT.json +++ b/apps/user_ldap/l10n/pt_PT.json @@ -8,6 +8,7 @@ "No configuration specified" : "Nenhuma configuração especificada", "No data specified" : "Nenhuma data especificada", " Could not set configuration %s" : "Não foi possível definir a configuração %s", + "Action does not exist" : "Não existe esta acção", "Configuration incorrect" : "Configuração incorreta", "Configuration incomplete" : "Configuração incompleta", "Configuration OK" : "Configuração OK", diff --git a/apps/user_ldap/lib/ldap.php b/apps/user_ldap/lib/ldap.php index 74df3dd8ae7..4d45db2e155 100644 --- a/apps/user_ldap/lib/ldap.php +++ b/apps/user_ldap/lib/ldap.php @@ -287,6 +287,10 @@ class LDAP implements ILDAPWrapper { //referrals, we switch them off, but then there is AD :) } else if ($errorCode === -1) { throw new ServerNotAvailableException('Lost connection to LDAP server.'); + } else if ($errorCode === 48) { + throw new \Exception('LDAP authentication method rejected', $errorCode); + } else if ($errorCode === 1) { + throw new \Exception('LDAP Operations error', $errorCode); } else { \OCP\Util::writeLog('user_ldap', 'LDAP error '.$errorMsg.' (' . diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php index 824923eecbf..6c39f406e83 100644 --- a/apps/user_ldap/lib/wizard.php +++ b/apps/user_ldap/lib/wizard.php @@ -657,12 +657,26 @@ class Wizard extends LDAPUtility { \OCP\Util::writeLog('user_ldap', 'Wiz: trying port '. $p . ', TLS '. $t, \OCP\Util::DEBUG); //connectAndBind may throw Exception, it needs to be catched by the //callee of this method - if($this->connectAndBind($p, $t) === true) { - $config = array('ldapPort' => $p, - 'ldapTLS' => intval($t) - ); + + // unallowed anonymous bind throws 48. But if it throws 48, we + // detected port and TLS, i.e. it is successful. + try { + $settingsFound = $this->connectAndBind($p, $t); + } catch (\Exception $e) { + if($e->getCode() === 48) { + $settingsFound = true; + } else { + throw $e; + } + } + + if ($settingsFound === true) { + $config = array( + 'ldapPort' => $p, + 'ldapTLS' => intval($t) + ); $this->configuration->setConfiguration($config); - \OCP\Util::writeLog('user_ldap', 'Wiz: detected Port '. $p, \OCP\Util::DEBUG); + \OCP\Util::writeLog('user_ldap', 'Wiz: detected Port ' . $p, \OCP\Util::DEBUG); $this->result->addChange('ldap_port', $p); return $this->result; } diff --git a/config/ca-bundle.crt b/config/ca-bundle.crt index 7366a6dfaf7..c93d3c4d4a7 100644 --- a/config/ca-bundle.crt +++ b/config/ca-bundle.crt @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Wed Feb 25 16:40:11 2015 +## Certificate data from Mozilla as of: Mon Apr 27 08:58:04 2015 ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.25. -## SHA1: f9bc9fa76145720d94124527f82a7185d921975e +## SHA1: ed3c0bbfb7912bcc00cd2033b0cb85c98d10559c ## @@ -174,23 +174,6 @@ Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- -Equifax Secure Global eBusiness CA -================================== ------BEGIN CERTIFICATE----- -MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp -bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx -HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds -b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV -PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN -qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn -hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j -BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs -MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN -I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY -NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV ------END CERTIFICATE----- - AddTrust Low-Value Services Root ================================ -----BEGIN CERTIFICATE----- @@ -1633,33 +1616,6 @@ JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk vQ== -----END CERTIFICATE----- -TC TrustCenter Class 3 CA II -============================ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy -IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw -MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 -c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE -AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W -yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo -6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ -uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk -2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB -7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 -Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU -cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i -SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE -O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8 -yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9 -IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal -092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc -5A== ------END CERTIFICATE----- - TC TrustCenter Universal CA I ============================= -----BEGIN CERTIFICATE----- @@ -2277,28 +2233,6 @@ yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi LXpUq3DDfSJlgnCW -----END CERTIFICATE----- -E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi -=================================================== ------BEGIN CERTIFICATE----- -MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG -EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz -ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3 -MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0 -cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u -aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY -8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y -jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI -JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk -9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG -SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d -F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq -D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4 -Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq -fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX ------END CERTIFICATE----- - GlobalSign Root CA - R3 ======================= -----BEGIN CERTIFICATE----- @@ -3857,4 +3791,198 @@ h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G3 +================================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y +olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t +x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy +EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K +Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur +mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5 +1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp +07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo +FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE +41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu +yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq +KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1 +v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA +8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b +8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r +mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq +1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI +JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV +tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk= +-----END CERTIFICATE----- + +Staat der Nederlanden EV Root CA +================================ +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M +MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl +cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk +SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW +O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r +0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8 +Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV +XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr +08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV +0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd +74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx +fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa +ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu +c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq +5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN +b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN +f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi +5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4 +WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK +DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy +eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg== +-----END CERTIFICATE----- + +IdenTrust Commercial Root CA 1 +============================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS +b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES +MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB +IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld +hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ +mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi +1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C +XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl +3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy +NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV +WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg +xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix +uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI +hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg +ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt +ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV +YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX +feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro +kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe +2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz +Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R +cGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +IdenTrust Public Sector Root CA 1 +================================= +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv +ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV +UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS +b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy +P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 +Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI +rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf +qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS +mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn +ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh +LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v +iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL +4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B +Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw +DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A +mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt +GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt +m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx +NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 +Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI +ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC +ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ +3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +Entrust Root Certification Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy +bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug +b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw +HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT +DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx +OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP +/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz +HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU +s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y +TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx +AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 +0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z +iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi +nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ +vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO +e4pIb4tF9g== +-----END CERTIFICATE----- + +Entrust Root Certification Authority - EC1 +========================================== +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx +FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn +YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw +FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs +LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg +dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy +AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef +9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h +vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 +kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +CFCA EV ROOT +============ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE +CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB +IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw +MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD +DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV +BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD +7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN +uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW +ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 +xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f +py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K +gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol +hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ +tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf +BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q +ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua +4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG +E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX +BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn +aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy +PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX +kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C +ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su -----END CERTIFICATE-----
\ No newline at end of file diff --git a/config/config.sample.php b/config/config.sample.php index 45aaf6a107d..9a40f82252a 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -487,6 +487,27 @@ $CONFIG = array( 'loglevel' => 2, /** + * Log condition for log level increase based on conditions. Once one of these + * conditions is met, the required log level is set to debug. This allows to + * debug specific requests, users or apps + * + * Supported conditions: + * - ``shared_secret``: if a request parameter with the name `log_secret` is set to + * this value the condition is met + * - ``users``: if the current request is done by one of the specified users, + * this condition is met + * - ``apps``: if the log message is invoked by one of the specified apps, + * this condition is met + * + * Defaults to an empty array. + */ +'log.condition' => [ + 'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9', + 'users' => ['sample-user'], + 'apps' => ['files'], +], + +/** * This uses PHP.date formatting; see http://php.net/manual/en/function.date.php */ 'logdateformat' => 'F d, Y H:i:s', diff --git a/core/css/styles.css b/core/css/styles.css index c8704066cf1..fe259e87d51 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -638,6 +638,9 @@ label.infield { /* Database selector */ #body-login form #selectDbType { text-align:center; white-space: nowrap; } +#body-login form #selectDbType .info { + white-space: normal; +} #body-login form #selectDbType label { position:static; margin:0 -3px 5px; padding:.4em; font-size:12px; background:#f8f8f8; color:#888; cursor:pointer; diff --git a/core/js/maintenance-check.js b/core/js/maintenance-check.js index 061a434214b..663f7fb5f00 100644 --- a/core/js/maintenance-check.js +++ b/core/js/maintenance-check.js @@ -3,10 +3,7 @@ window.setInterval(checkStatus, 20000); function checkStatus() { var request = new XMLHttpRequest(); - var ocroot = location.pathname.substr( - 0, location.pathname.indexOf('index.php') - ); - request.open("GET", ocroot+'status.php', true); + request.open("GET", OC.webroot+'/status.php', true); request.onreadystatechange = function() { if (request.readyState === 4) { var response = request.responseText; diff --git a/core/js/setup.js b/core/js/setup.js index 95237165b40..fd2547867ff 100644 --- a/core/js/setup.js +++ b/core/js/setup.js @@ -9,6 +9,8 @@ $(document).ready(function() { }; $('#selectDbType').buttonset(); + // change links inside an info box back to their default appearance + $('#selectDbType p.info a').button('destroy'); if($('#hasSQLite').val()){ $('#use_other_db').hide(); diff --git a/core/js/share.js b/core/js/share.js index d1ddd2c7c22..415fe41ef5f 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -839,6 +839,24 @@ OC.Share={ $('#defaultExpireMessage').slideDown(OC.menuSpeed); } $.datepicker.setDefaults(datePickerOptions); + }, + /** + * Get the default Expire date + * + * @return {String} The expire date + */ + getDefaultExpirationDate:function() { + var expireDateString = ''; + if (oc_appconfig.core.defaultExpireDateEnabled) { + var date = new Date().getTime(); + var expireAfterMs = oc_appconfig.core.defaultExpireDate * 24 * 60 * 60 * 1000; + var expireDate = new Date(date + expireAfterMs); + var month = expireDate.getMonth() + 1; + var year = expireDate.getFullYear(); + var day = expireDate.getDate(); + expireDateString = year + "-" + month + '-' + day + ' 00:00:00'; + } + return expireDateString; } }; @@ -986,18 +1004,15 @@ $(document).ready(function() { $('#linkPassText').attr('placeholder', t('core', 'Choose a password for the public link')); // Reset link $('#linkText').val(''); + $('#showPassword').prop('checked', false); + $('#linkPass').hide(); + $('#sharingDialogAllowPublicUpload').prop('checked', false); + $('#expirationCheckbox').prop('checked', false); + $('#expirationDate').hide(); var expireDateString = ''; - if (oc_appconfig.core.defaultExpireDateEnabled) { - var date = new Date().getTime(); - var expireAfterMs = oc_appconfig.core.defaultExpireDate * 24 * 60 * 60 * 1000; - var expireDate = new Date(date + expireAfterMs); - var month = expireDate.getMonth() + 1; - var year = expireDate.getFullYear(); - var day = expireDate.getDate(); - expireDateString = year + "-" + month + '-' + day + ' 00:00:00'; - } // Create a link if (oc_appconfig.core.enforcePasswordForPublicLink === false) { + expireDateString = OC.Share.getDefaultExpirationDate(); $loading.removeClass('hidden'); $button.addClass('hidden'); $button.prop('disabled', true); @@ -1135,8 +1150,10 @@ $(document).ready(function() { permissions = OC.PERMISSION_READ; } + var expireDateString = OC.Share.getDefaultExpirationDate(); + $loading.removeClass('hidden'); - OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, $('#linkPassText').val(), permissions, itemSourceName, function(data) { + OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, $('#linkPassText').val(), permissions, itemSourceName, expireDateString, function(data) { $loading.addClass('hidden'); linkPassText.val(''); linkPassText.attr('placeholder', t('core', 'Password protected')); @@ -1145,8 +1162,12 @@ $(document).ready(function() { OC.Share.showLink(data.token, "password set", itemSource); OC.Share.updateIcon(itemType, itemSource); } + $('#dropdown').trigger(new $.Event('sharesChanged', {shares: OC.Share.currentShares})); }); + if (expireDateString !== '') { + OC.Share.showExpirationDate(expireDateString); + } } }); diff --git a/core/js/tests/specs/shareSpec.js b/core/js/tests/specs/shareSpec.js index 3e9a0b247d7..c075351b9f5 100644 --- a/core/js/tests/specs/shareSpec.js +++ b/core/js/tests/specs/shareSpec.js @@ -228,6 +228,112 @@ describe('OC.Share tests', function() { oc_appconfig.core.enforcePasswordForPublicLink = old; }); + it('reset password on toggle of share', function() { + $('#allowShareWithLink').val('yes'); + OC.Share.showDropDown( + 'file', + 123, + $container, + true, + 31, + 'shared_file_name.txt' + ); + $('#dropdown [name=linkCheckbox]').click(); + fakeServer.requests[0].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({data: {token: 'xyz'}, status: 'success'}) + ); + + //Password protection should be unchecked and password field not visible + expect($('#dropdown [name=showPassword]').prop('checked')).toEqual(false); + expect($('#dropdown #linkPass').is(":visible")).toEqual(false); + + // Toggle and set password + $('#dropdown [name=showPassword]').click(); + $('#dropdown #linkPassText').val('foo'); + $('#dropdown #linkPassText').trigger(new $.Event('keyup', {keyCode: 13})); + fakeServer.requests[1].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({data: {token: 'xyz2'}, status: 'success'}) + ); + + // Unshare + $('#dropdown [name=linkCheckbox]').click(); + fakeServer.requests[2].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({status: 'success'}) + ); + + // Toggle share again + $('#dropdown [name=linkCheckbox]').click(); + fakeServer.requests[3].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({data: {token: 'xyz3'}, status: 'success'}) + ); + + + // Password checkbox should be unchecked + expect($('#dropdown [name=showPassword]').prop('checked')).toEqual(false); + expect($('#dropdown #linkPass').is(":visible")).toEqual(false); + }); + it('reset expiration on toggle of share', function() { + $('#allowShareWithLink').val('yes'); + OC.Share.showDropDown( + 'file', + 123, + $container, + true, + 31, + 'shared_file_name.txt' + ); + $('#dropdown [name=linkCheckbox]').click(); + fakeServer.requests[0].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({data: {token: 'xyz'}, status: 'success'}) + ); + + //Expiration should be unchecked and expiration field not visible + expect($('#dropdown [name=expirationCheckbox]').prop('checked')).toEqual(false); + expect($('#dropdown #expirationDate').is(":visible")).toEqual(false); + + // Toggle and set password + $('#dropdown [name=expirationCheckbox]').click(); + d = new Date(); + d.setDate(d.getDate() + 1); + date=d.getDate() + '-' + (d.getMonth()+1) + '-' + d.getFullYear(); + $('#dropdown #expirationDate').val(date); + $('#dropdown #expirationDate').change(); + fakeServer.requests[1].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({data: {token: 'xyz2'}, status: 'success'}) + ); + + // Unshare + $('#dropdown [name=linkCheckbox]').click(); + fakeServer.requests[2].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({status: 'success'}) + ); + + // Toggle share again + $('#dropdown [name=linkCheckbox]').click(); + fakeServer.requests[3].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({data: {token: 'xyz3'}, status: 'success'}) + ); + + // Recheck expire visibility + expect($('#dropdown [name=expirationCheckbox]').prop('checked')).toEqual(false); + expect($('#dropdown #expirationDate').is(":visible")).toEqual(false); + }); it('shows populated link share when a link share exists', function() { loadItemStub.returns({ reshare: [], @@ -419,6 +525,7 @@ describe('OC.Share tests', function() { }; loadItemStub.returns(shareData); oc_appconfig.core.defaultExpireDate = 7; + oc_appconfig.core.enforcePasswordForPublicLink = false; oc_appconfig.core.defaultExpireDateEnabled = false; oc_appconfig.core.defaultExpireDateEnforced = false; }); @@ -474,6 +581,32 @@ describe('OC.Share tests', function() { $('#dropdown [name=expirationCheckbox]').click(); expect($('#dropdown [name=expirationCheckbox]').prop('checked')).toEqual(true); }); + it('enforces default date when enforced date setting is enabled and password is enforced', function() { + /* jshint camelcase:false */ + oc_appconfig.core.enforcePasswordForPublicLink = true; + oc_appconfig.core.defaultExpireDateEnabled = true; + oc_appconfig.core.defaultExpireDateEnforced = true; + showDropDown(); + $('#dropdown [name=linkCheckbox]').click(); + + //Enter password + $('#dropdown #linkPassText').val('foo'); + $('#dropdown #linkPassText').trigger(new $.Event('keyup', {keyCode: 13})); + fakeServer.requests[0].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({data: {token: 'xyz'}, status: 'success'}) + ); + + expect($('#dropdown [name=expirationCheckbox]').prop('checked')).toEqual(true); + // TODO: those zeros must go... + expect($('#dropdown #expirationDate').val()).toEqual('2014-1-27 00:00:00'); + + // disabling is not allowed + expect($('#dropdown [name=expirationCheckbox]').prop('disabled')).toEqual(true); + $('#dropdown [name=expirationCheckbox]').click(); + expect($('#dropdown [name=expirationCheckbox]').prop('checked')).toEqual(true); + }); it('displayes email form when sending emails is enabled', function() { $('input[name=mailPublicNotificationEnabled]').val('yes'); showDropDown(); diff --git a/core/templates/installation.php b/core/templates/installation.php index 911bc05069f..b686a1ca68c 100644 --- a/core/templates/installation.php +++ b/core/templates/installation.php @@ -85,7 +85,12 @@ script('core', [ <div id="selectDbType"> <?php foreach($_['databases'] as $type => $label): ?> <?php if(count($_['databases']) === 1): ?> - <p class="info"><?php p($l->t( 'Only %s is available.', array($label) )); ?>.</p> + <p class="info"> + <?php p($l->t( 'Only %s is available.', array($label) )); ?> + <?php p($l->t( 'Install and activate additional PHP modules to choose other database types.' )); ?><br> + <a href="<?php print_unescaped(link_to_docs('admin-source_install')); ?>" target="_blank"> + <?php p($l->t( 'For more details check out the documentation.' )); ?> ↗</a> + </p> <input type="hidden" id="dbtype" name="dbtype" value="<?php p($type) ?>"> <?php else: ?> <input type="radio" name="dbtype" value="<?php p($type) ?>" id="<?php p($type) ?>" diff --git a/lib/private/connector/sabre/dummygetresponseplugin.php b/lib/private/connector/sabre/dummygetresponseplugin.php index 7d57f6021fa..6057236b635 100644 --- a/lib/private/connector/sabre/dummygetresponseplugin.php +++ b/lib/private/connector/sabre/dummygetresponseplugin.php @@ -20,6 +20,8 @@ */ namespace OC\Connector\Sabre; +use Sabre\HTTP\ResponseInterface; +use Sabre\HTTP\RequestInterface; /** * Class DummyGetResponsePlugin is a plugin used to not show a "Not implemented" @@ -42,15 +44,25 @@ class DummyGetResponsePlugin extends \Sabre\DAV\ServerPlugin { * @param \Sabre\DAV\Server $server * @return void */ - function initialize(\Sabre\DAV\Server $server) { + function initialize(\Sabre\DAV\Server $server) { $this->server = $server; - $this->server->on('method:GET', [$this,'httpGet'], 200); + $this->server->on('method:GET', [$this, 'httpGet'], 200); } /** + * @param RequestInterface $request + * @param ResponseInterface $response * @return false */ - function httpGet() { + function httpGet(RequestInterface $request, ResponseInterface $response) { + $string = 'This is the WebDAV interface. It can only be accessed by ' . + 'WebDAV clients such as the ownCloud desktop sync client.'; + $stream = fopen('php://memory','r+'); + fwrite($stream, $string); + rewind($stream); + + $response->setBody($stream); + return false; } } diff --git a/lib/private/console/application.php b/lib/private/console/application.php index 6d24665e012..f2aacbfc0e6 100644 --- a/lib/private/console/application.php +++ b/lib/private/console/application.php @@ -35,7 +35,7 @@ class Application { if ($this->config->getSystemValue('installed', false)) { if (!\OCP\Util::needUpgrade()) { OC_App::loadApps(); - foreach (OC_App::getAllApps() as $app) { + foreach (\OC::$server->getAppManager()->getInstalledApps() as $app) { $file = OC_App::getAppPath($app) . '/appinfo/register_command.php'; if (file_exists($file)) { require $file; diff --git a/lib/private/encryption/exceptions/decryptionfailedexception.php b/lib/private/encryption/exceptions/decryptionfailedexception.php index 406ae12968e..7e9fa21eaef 100644 --- a/lib/private/encryption/exceptions/decryptionfailedexception.php +++ b/lib/private/encryption/exceptions/decryptionfailedexception.php @@ -27,4 +27,15 @@ use OCP\Encryption\Exceptions\GenericEncryptionException; class DecryptionFailedException extends GenericEncryptionException { + /** + * @param string $message + * @param int $code + * @param \Exception $previous + * @param string $hint + */ + public function __construct($message = '', $code = 0, \Exception $previous = null, $hint = '') { + parent::__construct($message, $code, $previous, $hint); + +} + } diff --git a/lib/private/encryption/manager.php b/lib/private/encryption/manager.php index 1a42646daf6..45f45045643 100644 --- a/lib/private/encryption/manager.php +++ b/lib/private/encryption/manager.php @@ -79,7 +79,7 @@ class Manager implements IManager { $oldEncryption = $this->config->getAppValue('files_encryption', 'installed_version'); if (!empty($oldEncryption)) { $warning = 'Installation is in transit between the old Encryption (ownCloud <= 8.0) - and the new encryption. Please enable the "ownCloud Default Encryption Module" + and the new encryption. Please enable the "Default encryption module" and run \'occ encryption:migrate\''; $this->logger->warning($warning); return false; diff --git a/lib/private/encryption/util.php b/lib/private/encryption/util.php index 45d4dd90d9f..b77672d2f6b 100644 --- a/lib/private/encryption/util.php +++ b/lib/private/encryption/util.php @@ -114,7 +114,7 @@ class Util { // ownCloud <= 8.0 with the old encryption $id = \OCA\Encryption\Crypto\Encryption::ID; } else { - throw new ModuleDoesNotExistsException('ownCloud default encryption module missing'); + throw new ModuleDoesNotExistsException('Default encryption module missing'); } } diff --git a/lib/private/files.php b/lib/private/files.php index 97f9d8163b1..6a739fc844c 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -129,52 +129,60 @@ class OC_Files { $zip = new ZipStreamer(false); } OC_Util::obEnd(); - if ($zip or \OC\Files\Filesystem::isReadable($filename)) { - self::sendHeaders($filename, $name, $zip); - } elseif (!\OC\Files\Filesystem::file_exists($filename)) { - header("HTTP/1.0 404 Not Found"); - $tmpl = new OC_Template('', '404', 'guest'); - $tmpl->printPage(); - } else { - header("HTTP/1.0 403 Forbidden"); - die('403 Forbidden'); - } - if($only_header) { - return ; - } - if ($zip) { - $executionTime = intval(ini_get('max_execution_time')); - set_time_limit(0); - if ($get_type === self::ZIP_FILES) { - foreach ($files as $file) { - $file = $dir . '/' . $file; - if (\OC\Files\Filesystem::is_file($file)) { - $fh = \OC\Files\Filesystem::fopen($file, 'r'); - $zip->addFileFromStream($fh, basename($file)); - fclose($fh); - } elseif (\OC\Files\Filesystem::is_dir($file)) { - self::zipAddDir($file, $zip); + + try { + + if ($zip or \OC\Files\Filesystem::isReadable($filename)) { + self::sendHeaders($filename, $name, $zip); + } elseif (!\OC\Files\Filesystem::file_exists($filename)) { + header("HTTP/1.0 404 Not Found"); + $tmpl = new OC_Template('', '404', 'guest'); + $tmpl->printPage(); + } else { + header("HTTP/1.0 403 Forbidden"); + die('403 Forbidden'); + } + if ($only_header) { + return; + } + if ($zip) { + $executionTime = intval(ini_get('max_execution_time')); + set_time_limit(0); + if ($get_type === self::ZIP_FILES) { + foreach ($files as $file) { + $file = $dir . '/' . $file; + if (\OC\Files\Filesystem::is_file($file)) { + $fh = \OC\Files\Filesystem::fopen($file, 'r'); + $zip->addFileFromStream($fh, basename($file)); + fclose($fh); + } elseif (\OC\Files\Filesystem::is_dir($file)) { + self::zipAddDir($file, $zip); + } } + } elseif ($get_type === self::ZIP_DIR) { + $file = $dir . '/' . $files; + self::zipAddDir($file, $zip); } - } elseif ($get_type === self::ZIP_DIR) { - $file = $dir . '/' . $files; - self::zipAddDir($file, $zip); - } - $zip->finalize(); - set_time_limit($executionTime); - } else { - if ($xsendfile) { - $view = \OC\Files\Filesystem::getView(); - /** @var $storage \OC\Files\Storage\Storage */ - list($storage) = $view->resolvePath($filename); - if ($storage->isLocal()) { - self::addSendfileHeader($filename); + $zip->finalize(); + set_time_limit($executionTime); + } else { + if ($xsendfile) { + $view = \OC\Files\Filesystem::getView(); + /** @var $storage \OC\Files\Storage\Storage */ + list($storage) = $view->resolvePath($filename); + if ($storage->isLocal()) { + self::addSendfileHeader($filename); + } else { + \OC\Files\Filesystem::readfile($filename); + } } else { \OC\Files\Filesystem::readfile($filename); } - } else { - \OC\Files\Filesystem::readfile($filename); } + } catch (\Exception $ex) { + $l = \OC::$server->getL10N('core'); + $hint = method_exists($ex, 'getHint') ? $ex->getHint() : ''; + \OC_Template::printErrorPage($l->t('Can\'t read file'), $hint); } } diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index f7759d91497..5d146b2dd1d 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -245,14 +245,42 @@ class Encryption extends Wrapper { */ public function rmdir($path) { $result = $this->storage->rmdir($path); - if ($result && $this->encryptionManager->isEnabled()) { - $this->keyStorage->deleteAllFileKeys($this->getFullPath($path)); + $fullPath = $this->getFullPath($path); + if ($result && + $this->util->isExcluded($fullPath) === false && + $this->encryptionManager->isEnabled() + ) { + $this->keyStorage->deleteAllFileKeys($fullPath); } return $result; } /** + * check if a file can be read + * + * @param string $path + * @return bool + */ + public function isReadable($path) { + + $isReadable = true; + + $metaData = $this->getMetaData($path); + if ( + !$this->is_dir($path) && + isset($metaData['encrypted']) && + $metaData['encrypted'] === true + ) { + $fullPath = $this->getFullPath($path); + $module = $this->getEncryptionModule($path); + $isReadable = $module->isReadable($fullPath, $this->uid); + } + + return $this->storage->isReadable($path) && $isReadable; + } + + /** * see http://php.net/manual/en/function.copy.php * * @param string $path1 diff --git a/lib/private/files/stream/encryption.php b/lib/private/files/stream/encryption.php index 0262405f367..f2f5b9c9af7 100644 --- a/lib/private/files/stream/encryption.php +++ b/lib/private/files/stream/encryption.php @@ -341,8 +341,8 @@ class Encryption extends Wrapper { } else { $data = ''; } + $this->unencryptedSize = max($this->unencryptedSize, $this->position); } - $this->unencryptedSize = max($this->unencryptedSize, $this->position); return $length; } @@ -356,24 +356,22 @@ class Encryption extends Wrapper { switch ($whence) { case SEEK_SET: - if ($offset < $this->unencryptedSize && $offset >= 0) { - $newPosition = $offset; - } + $newPosition = $offset; break; case SEEK_CUR: - if ($offset >= 0) { - $newPosition = $offset + $this->position; - } + $newPosition = $this->position + $offset; break; case SEEK_END: - if ($this->unencryptedSize + $offset >= 0) { - $newPosition = $this->unencryptedSize + $offset; - } + $newPosition = $this->unencryptedSize + $offset; break; default: return $return; } + if ($newPosition > $this->unencryptedSize || $newPosition < 0) { + return $return; + } + $newFilePosition = floor($newPosition / $this->unencryptedBlockSize) * $this->util->getBlockSize() + $this->headerSize; diff --git a/lib/private/helper.php b/lib/private/helper.php index 144ccbfe228..981447c213b 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -394,6 +394,9 @@ class OC_Helper { */ public static function computerFileSize($str) { $str = strtolower($str); + if (is_numeric($str)) { + return $str; + } $bytes_array = array( 'b' => 1, @@ -413,6 +416,8 @@ class OC_Helper { if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) { $bytes *= $bytes_array[$matches[1]]; + } else { + return false; } $bytes = round($bytes); diff --git a/lib/private/log.php b/lib/private/log.php index 56f36787e09..840713b2eda 100644 --- a/lib/private/log.php +++ b/lib/private/log.php @@ -28,6 +28,7 @@ namespace OC; use \OCP\ILogger; +use OCP\Security\StringUtils; /** * logging utilities @@ -41,15 +42,29 @@ use \OCP\ILogger; class Log implements ILogger { + /** @var string */ private $logger; + /** @var SystemConfig */ + private $config; + + /** @var boolean|null cache the result of the log condition check for the request */ + private $logConditionSatisfied = null; /** * @param string $logger The logger that should be used + * @param SystemConfig $config the system config object */ - public function __construct($logger=null) { + public function __construct($logger=null, SystemConfig $config=null) { + // FIXME: Add this for backwards compatibility, should be fixed at some point probably + if($config === null) { + $config = \OC::$server->getSystemConfig(); + } + + $this->config = $config; + // FIXME: Add this for backwards compatibility, should be fixed at some point probably if($logger === null) { - $this->logger = 'OC_Log_'.ucfirst(\OC_Config::getValue('log_type', 'owncloud')); + $this->logger = 'OC_Log_'.ucfirst($this->config->getValue('log_type', 'owncloud')); call_user_func(array($this->logger, 'init')); } else { $this->logger = $logger; @@ -158,8 +173,22 @@ class Log implements ILogger { * @param array $context */ public function log($level, $message, array $context = array()) { + $minLevel = min($this->config->getValue('loglevel', \OC_Log::WARN), \OC_Log::ERROR); + $logCondition = $this->config->getValue('log.condition', []); + if (isset($context['app'])) { $app = $context['app']; + + /** + * check log condition based on the context of each log message + * once this is met -> change the required log level to debug + */ + if(!empty($logCondition) + && isset($logCondition['apps']) + && in_array($app, $logCondition['apps'], true)) { + $minLevel = \OC_Log::DEBUG; + } + } else { $app = 'no app in context'; } @@ -172,7 +201,45 @@ class Log implements ILogger { // interpolate replacement values into the message and return $message = strtr($message, $replace); - $logger = $this->logger; - call_user_func(array($logger, 'write'), $app, $message, $level); + /** + * check for a special log condition - this enables an increased log on + * a per request/user base + */ + if($this->logConditionSatisfied === null) { + // default to false to just process this once per request + $this->logConditionSatisfied = false; + if(!empty($logCondition)) { + + // check for secret token in the request + if(isset($logCondition['shared_secret'])) { + $request = \OC::$server->getRequest(); + + // if token is found in the request change set the log condition to satisfied + if($request && StringUtils::equals($request->getParam('log_secret'), $logCondition['shared_secret'])) { + $this->logConditionSatisfied = true; + } + } + + // check for user + if(isset($logCondition['users'])) { + $user = \OC::$server->getUserSession()->getUser(); + + // if the user matches set the log condition to satisfied + if($user !== null && in_array($user->getUID(), $logCondition['users'], true)) { + $this->logConditionSatisfied = true; + } + } + } + } + + // if log condition is satisfied change the required log level to DEBUG + if($this->logConditionSatisfied) { + $minLevel = \OC_Log::DEBUG; + } + + if ($level >= $minLevel) { + $logger = $this->logger; + call_user_func(array($logger, 'write'), $app, $message, $level); + } } } diff --git a/lib/private/log/errorlog.php b/lib/private/log/errorlog.php index 007ab307722..ad3605136d0 100644 --- a/lib/private/log/errorlog.php +++ b/lib/private/log/errorlog.php @@ -39,10 +39,7 @@ class OC_Log_Errorlog { * @param int $level */ public static function write($app, $message, $level) { - $minLevel = min(OC_Config::getValue("loglevel", OC_Log::WARN), OC_Log::ERROR); - if ($level >= $minLevel) { - error_log('[owncloud]['.$app.'] '.$message); - } + error_log('[owncloud]['.$app.']['.$level.'] '.$message); } } diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index 049b8dbdfa3..0125164394d 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -69,40 +69,40 @@ class OC_Log_Owncloud { * @param int $level */ public static function write($app, $message, $level) { - $minLevel=min(OC_Config::getValue( "loglevel", OC_Log::WARN ), OC_Log::ERROR); - if($level>=$minLevel) { - // default to ISO8601 - $format = OC_Config::getValue('logdateformat', 'c'); - $logtimezone=OC_Config::getValue( "logtimezone", 'UTC' ); - try { - $timezone = new DateTimeZone($logtimezone); - } catch (Exception $e) { - $timezone = new DateTimeZone('UTC'); - } - $time = new DateTime(null, $timezone); - $request = \OC::$server->getRequest(); - $reqId = $request->getId(); - $remoteAddr = $request->getRemoteAddress(); - // remove username/passwords from URLs before writing the to the log file - $time = $time->format($format); - if($minLevel == OC_Log::DEBUG) { - $url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '--'; - $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '--'; - $entry = compact('reqId', 'remoteAddr', 'app', 'message', 'level', 'time', 'method', 'url'); - } - else { - $entry = compact('reqId', 'remoteAddr', 'app', 'message', 'level', 'time'); - } - $entry = json_encode($entry); - $handle = @fopen(self::$logFile, 'a'); - @chmod(self::$logFile, 0640); - if ($handle) { - fwrite($handle, $entry."\n"); - fclose($handle); - } else { - // Fall back to error_log - error_log($entry); - } + $config = \OC::$server->getSystemConfig(); + + // default to ISO8601 + $format = $config->getValue('logdateformat', 'c'); + $logtimezone = $config->getValue( "logtimezone", 'UTC' ); + try { + $timezone = new DateTimeZone($logtimezone); + } catch (Exception $e) { + $timezone = new DateTimeZone('UTC'); + } + $time = new DateTime(null, $timezone); + $request = \OC::$server->getRequest(); + $reqId = $request->getId(); + $remoteAddr = $request->getRemoteAddress(); + // remove username/passwords from URLs before writing the to the log file + $time = $time->format($format); + $minLevel=min($config->getValue( "loglevel", OC_Log::WARN ), OC_Log::ERROR); + if($minLevel == OC_Log::DEBUG) { + $url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '--'; + $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '--'; + $entry = compact('reqId', 'remoteAddr', 'app', 'message', 'level', 'time', 'method', 'url'); + } + else { + $entry = compact('reqId', 'remoteAddr', 'app', 'message', 'level', 'time'); + } + $entry = json_encode($entry); + $handle = @fopen(self::$logFile, 'a'); + @chmod(self::$logFile, 0640); + if ($handle) { + fwrite($handle, $entry."\n"); + fclose($handle); + } else { + // Fall back to error_log + error_log($entry); } } diff --git a/lib/private/log/syslog.php b/lib/private/log/syslog.php index 1763e6de6d1..8595b707d59 100644 --- a/lib/private/log/syslog.php +++ b/lib/private/log/syslog.php @@ -47,10 +47,7 @@ class OC_Log_Syslog { * @param int $level */ public static function write($app, $message, $level) { - $minLevel = min(OC_Config::getValue("loglevel", OC_Log::WARN), OC_Log::ERROR); - if ($level >= $minLevel) { - $syslog_level = self::$levels[$level]; - syslog($syslog_level, '{'.$app.'} '.$message); - } + $syslog_level = self::$levels[$level]; + syslog($syslog_level, '{'.$app.'} '.$message); } } diff --git a/lib/private/util.php b/lib/private/util.php index 367199f7735..3842d775b24 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -1335,7 +1335,7 @@ class OC_Util { if (ini_get('xcache.admin.enable_auth')) { OC_Log::write('core', 'XCache opcode cache will not be cleared because "xcache.admin.enable_auth" is enabled.', \OC_Log::WARN); } else { - xcache_clear_cache(XC_TYPE_PHP, 0); + @xcache_clear_cache(XC_TYPE_PHP, 0); } } // Opcache (PHP >= 5.5) diff --git a/lib/public/encryption/exceptions/genericencryptionexception.php b/lib/public/encryption/exceptions/genericencryptionexception.php index be96450d431..e97f00c88bf 100644 --- a/lib/public/encryption/exceptions/genericencryptionexception.php +++ b/lib/public/encryption/exceptions/genericencryptionexception.php @@ -30,17 +30,26 @@ namespace OCP\Encryption\Exceptions; */ class GenericEncryptionException extends \Exception { + /** @var string */ + protected $hint; + /** * @param string $message * @param int $code * @param \Exception $previous * @since 8.1.0 */ - public function __construct($message = '', $code = 0, \Exception $previous = null) { + public function __construct($message = '', $code = 0, \Exception $previous = null, $hint = '') { if (empty($message)) { $message = 'Unspecified encryption exception'; } parent::__construct($message, $code, $previous); + + $this->hint = $hint; + } + + public function getHint() { + return $this->hint; } } diff --git a/lib/public/encryption/iencryptionmodule.php b/lib/public/encryption/iencryptionmodule.php index 0dda042d759..975e57744e9 100644 --- a/lib/public/encryption/iencryptionmodule.php +++ b/lib/public/encryption/iencryptionmodule.php @@ -119,4 +119,16 @@ interface IEncryptionModule { * @since 8.1.0 */ public function getUnencryptedBlockSize(); + + /** + * check if the encryption module is able to read the file, + * e.g. if all encryption keys exists + * + * @param string $path + * @param string $uid user for whom we want to check if he can read the file + * @return boolean + * @since 8.1.0 + */ + public function isReadable($path, $uid); + } diff --git a/lib/public/lock/ilockingprovider.php b/lib/public/lock/ilockingprovider.php index a584ec02ef6..0b17580faac 100644 --- a/lib/public/lock/ilockingprovider.php +++ b/lib/public/lock/ilockingprovider.php @@ -35,7 +35,7 @@ interface ILockingProvider { /** * @param string $path * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - * @throws \OCP\Files\Lock\LockedException + * @throws \OCP\Lock\LockedException */ public function acquireLock($path, $type); diff --git a/settings/changepassword/controller.php b/settings/changepassword/controller.php index 4a68636d3f8..69b7ca710a9 100644 --- a/settings/changepassword/controller.php +++ b/settings/changepassword/controller.php @@ -89,7 +89,8 @@ class Controller { $crypt, \OC::$server->getLogger(), \OC::$server->getUserSession(), - \OC::$server->getConfig()); + \OC::$server->getConfig(), + \OC::$server->getUserManager()); $keyManager = new \OCA\Encryption\KeyManager( $keyStorage, $crypt, @@ -113,30 +114,27 @@ class Controller { $recoveryEnabledForUser = false; if ($recoveryAdminEnabled) { $validRecoveryPassword = $keyManager->checkRecoveryPassword($recoveryPassword); - $recoveryEnabledForUser = $recovery->isRecoveryEnabledForUser(); + $recoveryEnabledForUser = $recovery->isRecoveryEnabledForUser($username); } + $l = new \OC_L10n('settings'); if ($recoveryEnabledForUser && $recoveryPassword === '') { - $l = new \OC_L10n('settings'); \OC_JSON::error(array('data' => array( 'message' => $l->t('Please provide an admin recovery password, otherwise all user data will be lost') ))); } elseif ($recoveryEnabledForUser && ! $validRecoveryPassword) { - $l = new \OC_L10n('settings'); \OC_JSON::error(array('data' => array( 'message' => $l->t('Wrong admin recovery password. Please check the password and try again.') ))); } else { // now we know that everything is fine regarding the recovery password, let's try to change the password $result = \OC_User::setPassword($username, $password, $recoveryPassword); if (!$result && $recoveryEnabledForUser) { - $l = new \OC_L10n('settings'); \OC_JSON::error(array( "data" => array( "message" => $l->t("Backend doesn't support password change, but the user's encryption key was successfully updated.") ) )); } elseif (!$result && !$recoveryEnabledForUser) { - $l = new \OC_L10n('settings'); \OC_JSON::error(array("data" => array( "message" => $l->t("Unable to change password" ) ))); } else { \OC_JSON::success(array("data" => array( "username" => $username ))); @@ -147,7 +145,6 @@ class Controller { if (!is_null($password) && \OC_User::setPassword($username, $password)) { \OC_JSON::success(array('data' => array('username' => $username))); } else { - $l = new \OC_L10n('settings'); \OC_JSON::error(array('data' => array('message' => $l->t('Unable to change password')))); } } diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php index e9ffc36904e..d0b5267e3c8 100644 --- a/settings/controller/userscontroller.php +++ b/settings/controller/userscontroller.php @@ -122,10 +122,10 @@ class UsersController extends Controller { $this->subAdminFactory = $subAdminFactory; // check for encryption state - TODO see formatUserForIndex - $this->isEncryptionAppEnabled = $appManager->isEnabledForUser('files_encryption'); + $this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption'); if($this->isEncryptionAppEnabled) { // putting this directly in empty is possible in PHP 5.5+ - $result = $config->getAppValue('files_encryption', 'recoveryAdminEnabled', 0); + $result = $config->getAppValue('encryption', 'recoveryAdminEnabled', 0); $this->isRestoreEnabled = !empty($result); } } @@ -148,7 +148,7 @@ class UsersController extends Controller { if ($this->isEncryptionAppEnabled) { if ($this->isRestoreEnabled) { // check for the users recovery setting - $recoveryMode = $this->config->getUserValue($user->getUID(), 'files_encryption', 'recovery_enabled', '0'); + $recoveryMode = $this->config->getUserValue($user->getUID(), 'encryption', 'recoveryEnabled', '0'); // method call inside empty is possible with PHP 5.5+ $recoveryModeEnabled = !empty($recoveryMode); if ($recoveryModeEnabled) { diff --git a/settings/l10n/id.js b/settings/l10n/id.js index c3064a071a2..177e2f70f95 100644 --- a/settings/l10n/id.js +++ b/settings/l10n/id.js @@ -56,7 +56,7 @@ OC.L10N.register( "All" : "Semua", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Aplikasi resmi dikembangkan oleh komunitas ownCloud. Mereka menawarkan fitur pusat bagi ownCloud dan siap digunakan untuk penggunaan produksi.", "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." : "Aplikasi tersetujui dikembangkan oleh pengembang terpercaya dan telah lulus pemeriksaan keamanan. Mereka secara aktif dipelihara direpositori kode terbuka dan pemelihara sudah memastikan mereka stabil untuk penggunaan normal.", - "This app is not checked for security issues and is new or known to be unstable. Install on your own risk." : "Aplikasi ini belum diperiksa masalah keamanan dan baru atau dikenal tidak stabil. Instal dengan resiko.", + "This app is not checked for security issues and is new or known to be unstable. Install on your own risk." : "Aplikasi ini belum diperiksa masalah keamanan dan masih baru atau dikenal tidak stabil. Instal dengan resiko.", "Please wait...." : "Mohon tunggu....", "Error while disabling app" : "Terjadi kesalahan saat menonaktifkan aplikasi", "Disable" : "Nonaktifkan", @@ -143,6 +143,12 @@ OC.L10N.register( "cron.php is registered at a webcron service to call cron.php every 15 minutes over http." : "cron.php didaftarkan pada layanan webcron untuk memanggil cron.php setiap 15 menit melalui http.", "Use system's cron service to call the cron.php file every 15 minutes." : "Gunakan layanan cron sistem untuk memanggil berkas cron.php setiap 15 menit.", "Enable server-side encryption" : "Aktifkan enkripsi sisi-server", + "Encryption is a one way process. Once encryption is enabled, all files from that point forward will be encrypted on the server and it will not be possible to disable encryption at a later date. This is the final warning: Do you really want to enable encryption?" : "Enkripsi adalah proses satu arah. Setelah enkripsi diaktifkan, semua berkas mulai saat ini akan di enkrispi pada server dan tidak mungkin untuk menonaktifkan enkrispi dikemudian hari. Ini merupakan peringatan terakhir: Apakah Anda yakin ingin mengaktifkan enkripsi?", + "Enable encryption" : "Aktifkan enkripsi", + "No encryption module loaded, please enable an encryption module in the app menu." : "Tidak ada modul enkripsi yang dimuat, mohon aktifkan modul enkripsi di menu aplikasi.", + "Select default encryption module:" : "Pilih modul enkripsi baku:", + "You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please enable the \"ownCloud Default Encryption Module\" and run 'occ encryption:migrate'" : "Anda perlu untuk mengubah kunci enkripsi dari enkripsi lama (ownCloud <= 8.0) ke yang baru. Mohon aktifkan \"Modul Enkripsi Baku ownCloud\" dan jalankan 'occ encryption:migrate'", + "You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one." : "Anda perlu untuk mengubah kunci enkripsi dari enkripsi lama (ownCloud <= 8.0) ke yang baru.", "Start migration" : "Mulai migrasi", "This is used for sending out notifications." : "Ini digunakan untuk mengirim notifikasi keluar.", "Send mode" : "Modus kirim", @@ -167,11 +173,12 @@ OC.L10N.register( "SQLite is used as database. For larger installations we recommend to switch to a different database backend." : "SQLite digunakan sebagai basis data. Untuk instalasi yang lebih besar, kami menyarankan untuk beralih ke backend basis data yang berbeda.", "Especially when using the desktop client for file syncing the use of SQLite is discouraged." : "Terutama saat menggunakan klien desktop untuk sinkronisasi berkas, penggunaan SQLite tidak disarankan.", "To migrate to another database use the command line tool: 'occ db:convert-type', or see the <a target=\"_blank\" href=\"%s\">documentation ↗</a>." : "Untuk migrasi ke basis data lainnya, gunakan alat baris perintah: 'occ db:convert-type', atau lihat <a target=\"_blank\" href=\"%s\">dokumentasi ↗</a>.", - "How to do backups" : "Bagaimana cara mencadangkan", + "How to do backups" : "Bagaimana cara membuat cadangan", "Advanced monitoring" : "Pemantauan tingkat lanjut", "Performance tuning" : "Pemeliharaan performa", "Improving the config.php" : "Memperbaiki config.php", "Theming" : "Tema", + "Hardening and security guidance" : "Panduan Keselamatan dan Keamanan", "Version" : "Versi", "Developer documentation" : "Dokumentasi pengembang", "Experimental applications ahead" : "Aplikasi percobaan terdepan", @@ -261,6 +268,6 @@ OC.L10N.register( "change full name" : "ubah nama lengkap", "set new password" : "setel sandi baru", "change email address" : "ubah alamat email", - "Default" : "Default" + "Default" : "Baku" }, "nplurals=1; plural=0;"); diff --git a/settings/l10n/id.json b/settings/l10n/id.json index f720eb2fc03..30acbef09c2 100644 --- a/settings/l10n/id.json +++ b/settings/l10n/id.json @@ -54,7 +54,7 @@ "All" : "Semua", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Aplikasi resmi dikembangkan oleh komunitas ownCloud. Mereka menawarkan fitur pusat bagi ownCloud dan siap digunakan untuk penggunaan produksi.", "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." : "Aplikasi tersetujui dikembangkan oleh pengembang terpercaya dan telah lulus pemeriksaan keamanan. Mereka secara aktif dipelihara direpositori kode terbuka dan pemelihara sudah memastikan mereka stabil untuk penggunaan normal.", - "This app is not checked for security issues and is new or known to be unstable. Install on your own risk." : "Aplikasi ini belum diperiksa masalah keamanan dan baru atau dikenal tidak stabil. Instal dengan resiko.", + "This app is not checked for security issues and is new or known to be unstable. Install on your own risk." : "Aplikasi ini belum diperiksa masalah keamanan dan masih baru atau dikenal tidak stabil. Instal dengan resiko.", "Please wait...." : "Mohon tunggu....", "Error while disabling app" : "Terjadi kesalahan saat menonaktifkan aplikasi", "Disable" : "Nonaktifkan", @@ -141,6 +141,12 @@ "cron.php is registered at a webcron service to call cron.php every 15 minutes over http." : "cron.php didaftarkan pada layanan webcron untuk memanggil cron.php setiap 15 menit melalui http.", "Use system's cron service to call the cron.php file every 15 minutes." : "Gunakan layanan cron sistem untuk memanggil berkas cron.php setiap 15 menit.", "Enable server-side encryption" : "Aktifkan enkripsi sisi-server", + "Encryption is a one way process. Once encryption is enabled, all files from that point forward will be encrypted on the server and it will not be possible to disable encryption at a later date. This is the final warning: Do you really want to enable encryption?" : "Enkripsi adalah proses satu arah. Setelah enkripsi diaktifkan, semua berkas mulai saat ini akan di enkrispi pada server dan tidak mungkin untuk menonaktifkan enkrispi dikemudian hari. Ini merupakan peringatan terakhir: Apakah Anda yakin ingin mengaktifkan enkripsi?", + "Enable encryption" : "Aktifkan enkripsi", + "No encryption module loaded, please enable an encryption module in the app menu." : "Tidak ada modul enkripsi yang dimuat, mohon aktifkan modul enkripsi di menu aplikasi.", + "Select default encryption module:" : "Pilih modul enkripsi baku:", + "You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please enable the \"ownCloud Default Encryption Module\" and run 'occ encryption:migrate'" : "Anda perlu untuk mengubah kunci enkripsi dari enkripsi lama (ownCloud <= 8.0) ke yang baru. Mohon aktifkan \"Modul Enkripsi Baku ownCloud\" dan jalankan 'occ encryption:migrate'", + "You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one." : "Anda perlu untuk mengubah kunci enkripsi dari enkripsi lama (ownCloud <= 8.0) ke yang baru.", "Start migration" : "Mulai migrasi", "This is used for sending out notifications." : "Ini digunakan untuk mengirim notifikasi keluar.", "Send mode" : "Modus kirim", @@ -165,11 +171,12 @@ "SQLite is used as database. For larger installations we recommend to switch to a different database backend." : "SQLite digunakan sebagai basis data. Untuk instalasi yang lebih besar, kami menyarankan untuk beralih ke backend basis data yang berbeda.", "Especially when using the desktop client for file syncing the use of SQLite is discouraged." : "Terutama saat menggunakan klien desktop untuk sinkronisasi berkas, penggunaan SQLite tidak disarankan.", "To migrate to another database use the command line tool: 'occ db:convert-type', or see the <a target=\"_blank\" href=\"%s\">documentation ↗</a>." : "Untuk migrasi ke basis data lainnya, gunakan alat baris perintah: 'occ db:convert-type', atau lihat <a target=\"_blank\" href=\"%s\">dokumentasi ↗</a>.", - "How to do backups" : "Bagaimana cara mencadangkan", + "How to do backups" : "Bagaimana cara membuat cadangan", "Advanced monitoring" : "Pemantauan tingkat lanjut", "Performance tuning" : "Pemeliharaan performa", "Improving the config.php" : "Memperbaiki config.php", "Theming" : "Tema", + "Hardening and security guidance" : "Panduan Keselamatan dan Keamanan", "Version" : "Versi", "Developer documentation" : "Dokumentasi pengembang", "Experimental applications ahead" : "Aplikasi percobaan terdepan", @@ -259,6 +266,6 @@ "change full name" : "ubah nama lengkap", "set new password" : "setel sandi baru", "change email address" : "ubah alamat email", - "Default" : "Default" + "Default" : "Baku" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/settings/templates/admin.php b/settings/templates/admin.php index 3c21a547092..f9a99b589af 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -358,7 +358,7 @@ if ($_['cronErrors']) { <div id="migrationWarning" class="<?php if ($_['encryptionReady']) p('hidden'); ?>"> <?php if ($_['encryptionReady'] === false && $_['externalBackendsEnabled'] === true) { - p($l->t('You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please enable the "ownCloud Default Encryption Module" and run \'occ encryption:migrate\'')); + p($l->t('You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please enable the "Default encryption module" and run \'occ encryption:migrate\'')); } elseif ($_['encryptionReady'] === false && $_['externalBackendsEnabled'] === false) { p($l->t('You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one.')); ?> <input type="submit" name="startmigration" id="startmigration" diff --git a/tests/lib/connector/sabre/DummyGetResponsePluginTest.php b/tests/lib/connector/sabre/DummyGetResponsePluginTest.php new file mode 100644 index 00000000000..fa8f0694625 --- /dev/null +++ b/tests/lib/connector/sabre/DummyGetResponsePluginTest.php @@ -0,0 +1,65 @@ +<?php +/** + * @author Lukas Reschke <lukas@owncloud.com> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @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 Test\Connector\Sabre; + +use OC\Connector\Sabre\DummyGetResponsePlugin; +use Test\TestCase; + +/** + * Class DummyGetResponsePluginTest + * + * @package Test\Connector\Sabre + */ +class DummyGetResponsePluginTest extends TestCase { + /** @var DummyGetResponsePlugin */ + private $dummyGetResponsePlugin; + + public function setUp() { + parent::setUp(); + + $this->dummyGetResponsePlugin = new DummyGetResponsePlugin(); + } + + public function testInitialize() { + /** @var \Sabre\DAV\Server $server */ + $server = $this->getMock('\Sabre\DAV\Server'); + $server + ->expects($this->once()) + ->method('on') + ->with('method:GET', [$this->dummyGetResponsePlugin, 'httpGet'], 200); + + $this->dummyGetResponsePlugin->initialize($server); + } + + + public function testHttpGet() { + /** @var \Sabre\HTTP\RequestInterface $request */ + $request = $this->getMock('\Sabre\HTTP\RequestInterface'); + /** @var \Sabre\HTTP\ResponseInterface $response */ + $response = $server = $this->getMock('\Sabre\HTTP\ResponseInterface'); + $response + ->expects($this->once()) + ->method('setBody'); + + $this->assertSame(false, $this->dummyGetResponsePlugin->httpGet($request, $response)); + } +} diff --git a/tests/lib/db/migrator.php b/tests/lib/db/migrator.php index 54267740480..6bde68c2d20 100644 --- a/tests/lib/db/migrator.php +++ b/tests/lib/db/migrator.php @@ -26,11 +26,17 @@ class Migrator extends \Test\TestCase { */ private $manager; + /** + * @var IConfig + **/ + private $config; + private $tableName; protected function setUp() { parent::setUp(); + $this->config = \OC::$server->getConfig(); $this->connection = \OC_DB::getConnection(); if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) { $this->markTestSkipped('DB migration tests are not supported on OCI'); @@ -39,7 +45,7 @@ class Migrator extends \Test\TestCase { $this->markTestSkipped('DB migration tests are not supported on MSSQL'); } $this->manager = new \OC\DB\MDB2SchemaManager($this->connection); - $this->tableName = strtolower($this->getUniqueID('oc_test_')); + $this->tableName = strtolower($this->getUniqueID($this->config->getSystemValue('dbtableprefix', 'oc_') . 'test_')); } protected function tearDown() { @@ -109,6 +115,27 @@ class Migrator extends \Test\TestCase { $this->assertTrue(true); } + public function testUpgradeDifferentPrefix() { + $oldTablePrefix = $this->config->getSystemValue('dbtableprefix', 'oc_'); + + $this->config->setSystemValue('dbtableprefix', 'ownc_'); + $this->tableName = strtolower($this->getUniqueID($this->config->getSystemValue('dbtableprefix') . 'test_')); + + list($startSchema, $endSchema) = $this->getDuplicateKeySchemas(); + $migrator = $this->manager->getMigrator(); + $migrator->migrate($startSchema); + + $this->connection->insert($this->tableName, array('id' => 1, 'name' => 'foo')); + $this->connection->insert($this->tableName, array('id' => 2, 'name' => 'bar')); + $this->connection->insert($this->tableName, array('id' => 3, 'name' => 'qwerty')); + + $migrator->checkMigrate($endSchema); + $migrator->migrate($endSchema); + $this->assertTrue(true); + + $this->config->setSystemValue('dbtableprefix', $oldTablePrefix); + } + public function testInsertAfterUpgrade() { list($startSchema, $endSchema) = $this->getDuplicateKeySchemas(); $migrator = $this->manager->getMigrator(); diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php index 97810c9c5dd..39af648cb75 100644 --- a/tests/lib/files/storage/wrapper/encryption.php +++ b/tests/lib/files/storage/wrapper/encryption.php @@ -47,6 +47,22 @@ class Encryption extends \Test\Files\Storage\Storage { */ private $cache; + /** + * @var \OC\Log | \PHPUnit_Framework_MockObject_MockObject + */ + private $logger; + + /** + * @var \OC\Encryption\File | \PHPUnit_Framework_MockObject_MockObject + */ + private $file; + + + /** + * @var \OC\Files\Mount\MountPoint | \PHPUnit_Framework_MockObject_MockObject + */ + private $mount; + /** @var integer dummy unencrypted size */ private $dummySize = -1; @@ -77,13 +93,13 @@ class Encryption extends \Test\Files\Storage\Storage { return ['user1', $path]; }); - $file = $this->getMockBuilder('\OC\Encryption\File') + $this->file = $this->getMockBuilder('\OC\Encryption\File') ->disableOriginalConstructor() ->setMethods(['getAccessList']) ->getMock(); - $file->expects($this->any())->method('getAccessList')->willReturn([]); + $this->file->expects($this->any())->method('getAccessList')->willReturn([]); - $logger = $this->getMock('\OC\Log'); + $this->logger = $this->getMock('\OC\Log'); $this->sourceStorage = new Temporary(array()); @@ -93,11 +109,11 @@ class Encryption extends \Test\Files\Storage\Storage { $this->update = $this->getMockBuilder('\OC\Encryption\Update') ->disableOriginalConstructor()->getMock(); - $mount = $this->getMockBuilder('\OC\Files\Mount\MountPoint') + $this->mount = $this->getMockBuilder('\OC\Files\Mount\MountPoint') ->disableOriginalConstructor() ->setMethods(['getOption']) ->getMock(); - $mount->expects($this->any())->method('getOption')->willReturn(true); + $this->mount->expects($this->any())->method('getOption')->willReturn(true); $this->cache = $this->getMockBuilder('\OC\Files\Cache\Cache') ->disableOriginalConstructor()->getMock(); @@ -112,12 +128,12 @@ class Encryption extends \Test\Files\Storage\Storage { 'storage' => $this->sourceStorage, 'root' => 'foo', 'mountPoint' => '/', - 'mount' => $mount + 'mount' => $this->mount ], - $this->encryptionManager, $this->util, $logger, $file, null, $this->keyStore, $this->update + $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update ] ) - ->setMethods(['getMetaData', 'getCache']) + ->setMethods(['getMetaData', 'getCache', 'getEncryptionModule']) ->getMock(); $this->instance->expects($this->any()) @@ -127,6 +143,10 @@ class Encryption extends \Test\Files\Storage\Storage { $this->instance->expects($this->any()) ->method('getCache') ->willReturn($this->cache); + + $this->instance->expects($this->any()) + ->method('getEncryptionModule') + ->willReturn($mockModule); } /** @@ -135,7 +155,7 @@ class Encryption extends \Test\Files\Storage\Storage { protected function buildMockModule() { $this->encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule') ->disableOriginalConstructor() - ->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize']) + ->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable']) ->getMock(); $this->encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE'); @@ -147,6 +167,7 @@ class Encryption extends \Test\Files\Storage\Storage { $this->encryptionModule->expects($this->any())->method('update')->willReturn(true); $this->encryptionModule->expects($this->any())->method('shouldEncrypt')->willReturn(true); $this->encryptionModule->expects($this->any())->method('getUnencryptedBlockSize')->willReturn(8192); + $this->encryptionModule->expects($this->any())->method('isReadable')->willReturn(true); return $this->encryptionModule; } @@ -252,4 +273,55 @@ class Encryption extends \Test\Files\Storage\Storage { ->method('isEnabled')->willReturn(true); $this->assertFalse($this->instance->isLocal()); } + + /** + * @dataProvider dataTestRmdir + * + * @param string $path + * @param boolean $rmdirResult + * @param boolean $isExcluded + * @param boolean $encryptionEnabled + */ + public function testRmdir($path, $rmdirResult, $isExcluded, $encryptionEnabled) { + $sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage') + ->disableOriginalConstructor()->getMock(); + + $util = $this->getMockBuilder('\OC\Encryption\Util')->disableOriginalConstructor()->getMock(); + + $sourceStorage->expects($this->once())->method('rmdir')->willReturn($rmdirResult); + $util->expects($this->any())->method('isExcluded')-> willReturn($isExcluded); + $this->encryptionManager->expects($this->any())->method('isEnabled')->willReturn($encryptionEnabled); + + $encryptionStorage = new \OC\Files\Storage\Wrapper\Encryption( + [ + 'storage' => $sourceStorage, + 'root' => 'foo', + 'mountPoint' => '/mountPoint', + 'mount' => $this->mount + ], + $this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update + ); + + + if ($rmdirResult === true && $isExcluded === false && $encryptionEnabled === true) { + $this->keyStore->expects($this->once())->method('deleteAllFileKeys')->with('/mountPoint' . $path); + } else { + $this->keyStore->expects($this->never())->method('deleteAllFileKeys'); + } + + $encryptionStorage->rmdir($path); + } + + public function dataTestRmdir() { + return array( + array('/file.txt', true, true, true), + array('/file.txt', false, true, true), + array('/file.txt', true, false, true), + array('/file.txt', false, false, true), + array('/file.txt', true, true, false), + array('/file.txt', false, true, false), + array('/file.txt', true, false, false), + array('/file.txt', false, false, false), + ); + } } diff --git a/tests/lib/files/stream/encryption.php b/tests/lib/files/stream/encryption.php index 892491cbc32..c2388c7682a 100644 --- a/tests/lib/files/stream/encryption.php +++ b/tests/lib/files/stream/encryption.php @@ -7,6 +7,9 @@ use OCA\Encryption_Dummy\DummyModule; class Encryption extends \Test\TestCase { + /** @var \OCP\Encryption\IEncryptionModule | \PHPUnit_Framework_MockObject_MockObject */ + private $encryptionModule; + /** * @param string $fileName * @param string $mode @@ -21,7 +24,7 @@ class Encryption extends \Test\TestCase { $fullPath = $fileName; $header = []; $uid = ''; - $encryptionModule = $this->buildMockModule(); + $this->encryptionModule = $this->buildMockModule(); $storage = $this->getMockBuilder('\OC\Files\Storage\Storage') ->disableOriginalConstructor()->getMock(); $encStorage = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption') @@ -43,7 +46,7 @@ class Encryption extends \Test\TestCase { ->willReturn(['user1', $internalPath]); return \OC\Files\Stream\Encryption::wrap($source, $internalPath, - $fullPath, $header, $uid, $encryptionModule, $storage, $encStorage, + $fullPath, $header, $uid, $this->encryptionModule, $storage, $encStorage, $util, $file, $mode, $size, $unencryptedSize, 8192); } @@ -160,15 +163,6 @@ class Encryption extends \Test\TestCase { $this->assertEquals('foobar', fread($stream, 100)); fclose($stream); - unlink($fileName); - } - - public function testWriteWriteRead() { - $fileName = tempnam("/tmp", "FOO"); - $stream = $this->getStream($fileName, 'w+', 0); - $this->assertEquals(6, fwrite($stream, 'foobar')); - fclose($stream); - $stream = $this->getStream($fileName, 'r+', 6); $this->assertEquals(3, fwrite($stream, 'bar')); fclose($stream); @@ -176,6 +170,8 @@ class Encryption extends \Test\TestCase { $stream = $this->getStream($fileName, 'r', 6); $this->assertEquals('barbar', fread($stream, 100)); fclose($stream); + + unlink($fileName); } public function testRewind() { @@ -191,7 +187,9 @@ class Encryption extends \Test\TestCase { $stream = $this->getStream($fileName, 'r', 6); $this->assertEquals('barbar', fread($stream, 100)); fclose($stream); - } + + unlink($fileName); +} public function testSeek() { $fileName = tempnam("/tmp", "FOO"); @@ -203,6 +201,12 @@ class Encryption extends \Test\TestCase { $stream = $this->getStream($fileName, 'r', 9); $this->assertEquals('foofoobar', fread($stream, 100)); + $this->assertEquals(-1, fseek($stream, 10)); + $this->assertEquals(0, fseek($stream, 9)); + $this->assertEquals(-1, fseek($stream, -10, SEEK_CUR)); + $this->assertEquals(0, fseek($stream, -9, SEEK_CUR)); + $this->assertEquals(-1, fseek($stream, -10, SEEK_END)); + $this->assertEquals(0, fseek($stream, -9, SEEK_END)); fclose($stream); unlink($fileName); @@ -220,10 +224,15 @@ class Encryption extends \Test\TestCase { * @dataProvider dataFilesProvider */ public function testWriteReadBigFile($testFile) { + $expectedData = file_get_contents(\OC::$SERVERROOT . '/tests/data/' . $testFile); // write it $fileName = tempnam("/tmp", "FOO"); $stream = $this->getStream($fileName, 'w+', 0); + // while writing the file from the beginning to the end we should never try + // to read parts of the file. This should only happen for write operations + // in the middle of a file + $this->encryptionModule->expects($this->never())->method('decrypt'); fwrite($stream, $expectedData); fclose($stream); @@ -253,13 +262,14 @@ class Encryption extends \Test\TestCase { protected function buildMockModule() { $encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule') ->disableOriginalConstructor() - ->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize']) + ->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable']) ->getMock(); $encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE'); $encryptionModule->expects($this->any())->method('getDisplayName')->willReturn('Unit test module'); $encryptionModule->expects($this->any())->method('begin')->willReturn([]); $encryptionModule->expects($this->any())->method('end')->willReturn(''); + $encryptionModule->expects($this->any())->method('isReadable')->willReturn(true); $encryptionModule->expects($this->any())->method('encrypt')->willReturnCallback(function($data) { // simulate different block size by adding some padding to the data if (isset($data[6125])) { diff --git a/tests/lib/helper.php b/tests/lib/helper.php index ed15a677300..b7aa185f4e3 100644 --- a/tests/lib/helper.php +++ b/tests/lib/helper.php @@ -53,21 +53,22 @@ class Test_Helper extends \Test\TestCase { } /** - * @dataProvider computerFileSizeProvider + * @dataProvider providesComputerFileSize */ function testComputerFileSize($expected, $input) { $result = OC_Helper::computerFileSize($input); $this->assertEquals($expected, $result); } - function computerFileSizeProvider(){ - return array( - array(0.0, "0 B"), - array(1024.0, "1 kB"), - array(1395864371.0, '1.3 GB'), - array(9961472.0, "9.5 MB"), - array(500041567437.0, "465.7 GB"), - ); + function providesComputerFileSize(){ + return [ + [0.0, "0 B"], + [1024.0, "1 kB"], + [1395864371.0, '1.3 GB'], + [9961472.0, "9.5 MB"], + [500041567437.0, "465.7 GB"], + [false, "12 GB etfrhzui"] + ]; } function testGetMimeType() { diff --git a/tests/lib/logger.php b/tests/lib/logger.php index 700a847917b..9a9f5be12fc 100644 --- a/tests/lib/logger.php +++ b/tests/lib/logger.php @@ -21,14 +21,38 @@ class Logger extends TestCase { parent::setUp(); self::$logs = array(); - $this->logger = new Log('Test\Logger'); + $this->config = $this->getMockBuilder( + '\OC\SystemConfig') + ->disableOriginalConstructor() + ->getMock(); + $this->logger = new Log('Test\Logger', $this->config); } public function testInterpolation() { $logger = $this->logger; - $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); + $logger->warning('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); - $expected = array('1 {Message {nothing} Bob Bar a}'); + $expected = array('2 {Message {nothing} Bob Bar a}'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testAppCondition() { + $this->config->expects($this->any()) + ->method('getValue') + ->will(($this->returnValueMap([ + ['loglevel', \OC_Log::WARN, \OC_Log::WARN], + ['log.condition', [], ['apps' => ['files']]] + ]))); + $logger = $this->logger; + + $logger->info('Don\'t display info messages'); + $logger->info('Show info messages of files app', ['app' => 'files']); + $logger->warning('Show warning messages of other apps'); + + $expected = [ + '1 Show info messages of files app', + '2 Show warning messages of other apps', + ]; $this->assertEquals($expected, $this->getLogs()); } diff --git a/tests/settings/controller/userscontrollertest.php b/tests/settings/controller/userscontrollertest.php index b9d45d786ec..e70b235f603 100644 --- a/tests/settings/controller/userscontrollertest.php +++ b/tests/settings/controller/userscontrollertest.php @@ -1303,14 +1303,14 @@ class UsersControllerTest extends \Test\TestCase { ->expects($this->once()) ->method('isEnabledForUser') ->with( - $this->equalTo('files_encryption') + $this->equalTo('encryption') ) ->will($this->returnValue(true)); $this->container['Config'] ->expects($this->once()) ->method('getAppValue') ->with( - $this->equalTo('files_encryption'), + $this->equalTo('encryption'), $this->equalTo('recoveryAdminEnabled'), $this->anything() ) @@ -1321,8 +1321,8 @@ class UsersControllerTest extends \Test\TestCase { ->method('getUserValue') ->with( $this->anything(), - $this->equalTo('files_encryption'), - $this->equalTo('recovery_enabled'), + $this->equalTo('encryption'), + $this->equalTo('recoveryEnabled'), $this->anything() ) ->will($this->returnValue('1')); @@ -1339,7 +1339,7 @@ class UsersControllerTest extends \Test\TestCase { $this->container['OCP\\App\\IAppManager'] ->method('isEnabledForUser') ->with( - $this->equalTo('files_encryption') + $this->equalTo('encryption') ) ->will($this->returnValue(true)); @@ -1358,14 +1358,14 @@ class UsersControllerTest extends \Test\TestCase { ->expects($this->once()) ->method('isEnabledForUser') ->with( - $this->equalTo('files_encryption') + $this->equalTo('encryption') ) ->will($this->returnValue(true)); $this->container['Config'] ->expects($this->once()) ->method('getAppValue') ->with( - $this->equalTo('files_encryption'), + $this->equalTo('encryption'), $this->equalTo('recoveryAdminEnabled'), $this->anything() ) @@ -1376,8 +1376,8 @@ class UsersControllerTest extends \Test\TestCase { ->method('getUserValue') ->with( $this->anything(), - $this->equalTo('files_encryption'), - $this->equalTo('recovery_enabled'), + $this->equalTo('encryption'), + $this->equalTo('recoveryEnabled'), $this->anything() ) ->will($this->returnValue('0')); diff --git a/version.php b/version.php index 74e83533bbf..26744e47b85 100644 --- a/version.php +++ b/version.php @@ -23,10 +23,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version=array(8, 1, 0, 5); +$OC_Version=array(8, 1, 0, 6); // The human readable string -$OC_VersionString='8.1 beta 1'; +$OC_VersionString='8.1 beta 2'; // The ownCloud channel $OC_Channel='git'; |