diff options
author | Robin Appelman <icewind@owncloud.com> | 2014-01-09 13:54:58 +0100 |
---|---|---|
committer | Robin Appelman <icewind@owncloud.com> | 2014-01-09 13:54:58 +0100 |
commit | 5d456c7cc21f7640435c4638932984a52b4cdbac (patch) | |
tree | 0227a865782fab4895f602a7c118d92e21998cbb /apps | |
parent | d50c7391d8e78c9555b073fb9ccc6a91d5da34bc (diff) | |
parent | d8b8abb429d3d66598a16d25cf55f7dc19e3f996 (diff) | |
download | nextcloud-server-5d456c7cc21f7640435c4638932984a52b4cdbac.tar.gz nextcloud-server-5d456c7cc21f7640435c4638932984a52b4cdbac.zip |
Merge branch 'master' into memcache-public
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files/download.php | 7 | ||||
-rw-r--r-- | apps/files/l10n/et_EE.php | 2 | ||||
-rw-r--r-- | apps/files/l10n/ur.php | 7 | ||||
-rw-r--r-- | apps/files_encryption/l10n/id.php | 37 | ||||
-rw-r--r-- | apps/files_external/appinfo/app.php | 1 | ||||
-rwxr-xr-x | apps/files_external/lib/config.php | 26 | ||||
-rw-r--r-- | apps/files_external/lib/owncloud.php | 51 | ||||
-rw-r--r-- | apps/files_external/lib/webdav.php | 2 | ||||
-rw-r--r-- | apps/files_external/tests/config.php | 7 | ||||
-rw-r--r-- | apps/files_external/tests/owncloud.php | 31 | ||||
-rw-r--r-- | apps/files_sharing/l10n/el.php | 10 | ||||
-rw-r--r-- | apps/files_sharing/l10n/id.php | 15 | ||||
-rw-r--r-- | apps/files_trashbin/download.php | 51 | ||||
-rw-r--r-- | apps/files_trashbin/l10n/el.php | 4 | ||||
-rw-r--r-- | apps/files_versions/download.php | 7 | ||||
-rw-r--r-- | apps/files_versions/l10n/el.php | 2 | ||||
-rw-r--r-- | apps/user_ldap/l10n/ur.php | 6 | ||||
-rw-r--r-- | apps/user_ldap/lib/access.php | 145 | ||||
-rw-r--r-- | apps/user_ldap/tests/user_ldap.php | 54 | ||||
-rw-r--r-- | apps/user_ldap/user_ldap.php | 15 | ||||
-rw-r--r-- | apps/user_ldap/user_proxy.php | 15 |
21 files changed, 383 insertions, 112 deletions
diff --git a/apps/files/download.php b/apps/files/download.php index e3fe24e45d7..6b055e99a53 100644 --- a/apps/files/download.php +++ b/apps/files/download.php @@ -37,12 +37,7 @@ if(!\OC\Files\Filesystem::file_exists($filename)) { $ftype=\OC\Files\Filesystem::getMimeType( $filename ); header('Content-Type:'.$ftype); -if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) { - header( 'Content-Disposition: attachment; filename="' . rawurlencode( basename($filename) ) . '"' ); -} else { - header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode( basename($filename) ) - . '; filename="' . rawurlencode( basename($filename) ) . '"' ); -} +OCP\Response::setContentDispositionHeader(basename($filename), 'attachment'); OCP\Response::disableCaching(); header('Content-Length: '.\OC\Files\Filesystem::filesize($filename)); diff --git a/apps/files/l10n/et_EE.php b/apps/files/l10n/et_EE.php index 98f74e1f001..fd031527738 100644 --- a/apps/files/l10n/et_EE.php +++ b/apps/files/l10n/et_EE.php @@ -6,6 +6,7 @@ $TRANSLATIONS = array( "File name must not contain \"/\". Please choose a different name." => "Faili nimi ei tohi sisaldada \"/\". Palun vali mõni teine nimi.", "The name %s is already used in the folder %s. Please choose a different name." => "Nimi %s on juba kasutusel kataloogis %s. Palun vali mõni teine nimi.", "Not a valid source" => "Pole korrektne lähteallikas", +"Server is not allowed to open URLs, please check the server configuration" => "Server ei võimalda URL-ide avamist, palun kontrolli serveri seadistust", "Error while downloading %s to %s" => "Viga %s allalaadimisel %s", "Error when creating the file" => "Viga faili loomisel", "Folder name cannot be empty." => "Kataloogi nimi ei saa olla tühi.", @@ -36,6 +37,7 @@ $TRANSLATIONS = array( "{new_name} already exists" => "{new_name} on juba olemas", "Could not create file" => "Ei suuda luua faili", "Could not create folder" => "Ei suuda luua kataloogi", +"Error fetching URL" => "Viga URL-i haaramisel", "Share" => "Jaga", "Delete permanently" => "Kustuta jäädavalt", "Rename" => "Nimeta ümber", diff --git a/apps/files/l10n/ur.php b/apps/files/l10n/ur.php new file mode 100644 index 00000000000..0157af093e9 --- /dev/null +++ b/apps/files/l10n/ur.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_encryption/l10n/id.php b/apps/files_encryption/l10n/id.php index 32c348bd8ba..a719d445820 100644 --- a/apps/files_encryption/l10n/id.php +++ b/apps/files_encryption/l10n/id.php @@ -1,6 +1,41 @@ <?php $TRANSLATIONS = array( +"Recovery key successfully enabled" => "Kunci pemulihan berhasil diaktifkan", +"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!", +"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.", +"Private key password successfully updated." => "Sandi kunci privat berhasil diperbarui.", +"Could not update the private key password. Maybe the old password was not correct." => "Tidak dapat memperbarui sandi kunci privat. Kemungkinan sandi lama yang Anda masukkan salah.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Tidak dapat mendekripsi berkas ini, mungkin ini adalah berkas bersama. Silakan meminta pemilik berkas ini untuk membagikan kembali dengan Anda.", +"Unknown error please check your system settings or contact your administrator" => "Kesalahan tak dikenal, silakan periksa pengaturan sistem Anda atau hubungi admin.", +"Missing requirements." => "Persyaratan yang hilang.", +"Following users are not set up for encryption:" => "Pengguna berikut belum diatur untuk enkripsi:", +"Initial encryption started... This can take some time. Please wait." => "Inisial enskripsi dijalankan... Ini dapat memakan waktu. Silakan tunggu.", "Saving..." => "Menyimpan...", -"Encryption" => "Enkripsi" +"Go directly to your " => "Langsung ke anda", +"personal settings" => "pengaturan pribadi", +"Encryption" => "Enkripsi", +"Enable recovery key (allow to recover users files in case of password loss):" => "Aktifkan kunci pemulihan (memungkinkan pengguna untuk memulihkan berkas dalam kasus kehilangan sandi):", +"Recovery key password" => "Sandi kunci pemulihan", +"Repeat Recovery key password" => "Ulangi sandi kunci Pemulihan", +"Enabled" => "Diaktifkan", +"Disabled" => "Dinonaktifkan", +"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", +"Your private key password no longer match your log-in password:" => "Sandi kunci privat Anda tidak lagi cocok dengan sandi masuk:", +"Set your old private key password to your current log-in password." => "Atur sandi kunci privat lama Anda sebagai 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.", +"Old log-in password" => "Sandi masuk yang lama", +"Current log-in password" => "Sandi masuk saat ini", +"Update Private Key Password" => "Perbarui Sandi Kunci Privat", +"Enable password recovery:" => "Aktifkan sandi pemulihan:", +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Mengaktifkan opsi ini memungkinkan Anda untuk mendapatkan kembali akses ke berkas terenkripsi Anda dalam kasus kehilangan sandi", +"File recovery settings updated" => "Pengaturan pemulihan berkas diperbarui", +"Could not update file recovery" => "Tidak dapat memperbarui pemulihan berkas" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index f78f3abf0fa..5b1cd86a170 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -9,6 +9,7 @@ OC::$CLASSPATH['OC\Files\Storage\StreamWrapper'] = 'files_external/lib/streamwrapper.php'; OC::$CLASSPATH['OC\Files\Storage\FTP'] = 'files_external/lib/ftp.php'; OC::$CLASSPATH['OC\Files\Storage\DAV'] = 'files_external/lib/webdav.php'; +OC::$CLASSPATH['OC\Files\Storage\OwnCloud'] = 'files_external/lib/owncloud.php'; OC::$CLASSPATH['OC\Files\Storage\Google'] = 'files_external/lib/google.php'; OC::$CLASSPATH['OC\Files\Storage\Swift'] = 'files_external/lib/swift.php'; OC::$CLASSPATH['OC\Files\Storage\SMB'] = 'files_external/lib/smb.php'; diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 122cc57debc..2abf7acb91e 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -114,14 +114,24 @@ class OC_Mount_Config { } } - if(OC_Mount_Config::checkcurl()) $backends['\OC\Files\Storage\DAV']=array( - 'backend' => 'ownCloud / WebDAV', - 'configuration' => array( - 'host' => 'URL', - 'user' => 'Username', - 'password' => '*Password', - 'root' => '&Root', - 'secure' => '!Secure https://')); + if(OC_Mount_Config::checkcurl()){ + $backends['\OC\Files\Storage\DAV']=array( + 'backend' => 'WebDAV', + 'configuration' => array( + 'host' => 'URL', + 'user' => 'Username', + 'password' => '*Password', + 'root' => '&Root', + 'secure' => '!Secure https://')); + $backends['\OC\Files\Storage\OwnCloud']=array( + 'backend' => 'ownCloud', + 'configuration' => array( + 'host' => 'URL', + 'user' => 'Username', + 'password' => '*Password', + 'root' => '&Remote subfolder', + 'secure' => '!Secure https://')); + } $backends['\OC\Files\Storage\SFTP']=array( 'backend' => 'SFTP', diff --git a/apps/files_external/lib/owncloud.php b/apps/files_external/lib/owncloud.php new file mode 100644 index 00000000000..98314102a64 --- /dev/null +++ b/apps/files_external/lib/owncloud.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright (c) 2013 Vincent Petry <pvince81@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; + +/** + * ownCloud backend for external storage based on DAV backend. + * + * The ownCloud URL consists of three parts: + * http://%host/%context/remote.php/webdav/%root + * + */ +class OwnCloud extends \OC\Files\Storage\DAV{ + const OC_URL_SUFFIX = 'remote.php/webdav'; + + public function __construct($params) { + // extract context path from host if specified + // (owncloud install path on host) + $host = $params['host']; + $contextPath = ''; + $hostSlashPos = strpos($host, '/'); + if ($hostSlashPos !== false){ + $contextPath = substr($host, $hostSlashPos); + $host = substr($host, 0, $hostSlashPos); + } + + if (substr($contextPath , 1) !== '/'){ + $contextPath .= '/'; + } + + if (isset($params['root'])){ + $root = $params['root']; + if (substr($root, 1) !== '/'){ + $root = '/' . $root; + } + } + else{ + $root = '/'; + } + + $params['host'] = $host; + $params['root'] = $contextPath . self::OC_URL_SUFFIX . $root; + + parent::__construct($params); + } +} diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 02f6cb5fc4f..cc7f3a5c9e2 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -79,7 +79,7 @@ class DAV extends \OC\Files\Storage\Common{ return 'webdav::' . $this->user . '@' . $this->host . '/' . $this->root; } - private function createBaseUri() { + protected function createBaseUri() { $baseUri='http'; if ($this->secure) { $baseUri.='s'; diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php index a523809e2f9..e296bfcb5b2 100644 --- a/apps/files_external/tests/config.php +++ b/apps/files_external/tests/config.php @@ -23,6 +23,13 @@ return array( 'password'=>'test', 'root'=>'/owncloud/files/webdav.php', ), + 'owncloud'=>array( + 'run'=>true, + 'host'=>'localhost/owncloud', + 'user'=>'test', + 'password'=>'test', + 'root'=>'', + ), 'google'=>array( 'run'=> false, 'configured' => 'true', diff --git a/apps/files_external/tests/owncloud.php b/apps/files_external/tests/owncloud.php new file mode 100644 index 00000000000..408a55864f2 --- /dev/null +++ b/apps/files_external/tests/owncloud.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright (c) 2013 Vincent Petry <pvince81@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Storage; + +class OwnCloud extends Storage { + + private $config; + + public function setUp() { + $id = uniqid(); + $this->config = include('files_external/tests/config.php'); + if ( ! is_array($this->config) or ! isset($this->config['owncloud']) or ! $this->config['owncloud']['run']) { + $this->markTestSkipped('ownCloud backend not configured'); + } + $this->config['owncloud']['root'] .= '/' . $id; //make sure we have an new empty folder to work in + $this->instance = new \OC\Files\Storage\OwnCloud($this->config['owncloud']); + $this->instance->mkdir('/'); + } + + public function tearDown() { + if ($this->instance) { + $this->instance->rmdir('/'); + } + } +} diff --git a/apps/files_sharing/l10n/el.php b/apps/files_sharing/l10n/el.php index 79387a91472..3ea666504b1 100644 --- a/apps/files_sharing/l10n/el.php +++ b/apps/files_sharing/l10n/el.php @@ -1,19 +1,19 @@ <?php $TRANSLATIONS = array( "This share is password-protected" => "Αυτός ο κοινόχρηστος φάκελος προστατεύεται με κωδικό", -"The password is wrong. Try again." => "Εσφαλμένο συνθηματικό. Προσπαθήστε ξανά.", -"Password" => "Συνθηματικό", +"The password is wrong. Try again." => "Εσφαλμένος κωδικός πρόσβασης. Προσπαθήστε ξανά.", +"Password" => "Κωδικός πρόσβασης", "Sorry, this link doesn’t seem to work anymore." => "Συγγνώμη, αυτός ο σύνδεσμος μοιάζει να μην ισχύει πια.", "Reasons might be:" => "Οι λόγοι μπορεί να είναι:", "the item was removed" => "το αντικείμενο απομακρύνθηκε", "the link expired" => "ο σύνδεσμος έληξε", "sharing is disabled" => "ο διαμοιρασμός απενεργοποιήθηκε", "For more info, please ask the person who sent this link." => "Για περισσότερες πληροφορίες, παρακαλώ ρωτήστε το άτομο που σας έστειλε αυτόν τον σύνδεσμο.", -"%s shared the folder %s with you" => "%s μοιράστηκε τον φάκελο %s μαζί σας", -"%s shared the file %s with you" => "%s μοιράστηκε το αρχείο %s μαζί σας", +"%s shared the folder %s with you" => "Ο %s μοιράστηκε τον φάκελο %s μαζί σας", +"%s shared the file %s with you" => "Ο %s μοιράστηκε το αρχείο %s μαζί σας", "Download" => "Λήψη", "Upload" => "Μεταφόρτωση", -"Cancel upload" => "Ακύρωση αποστολής", +"Cancel upload" => "Ακύρωση μεταφόρτωσης", "No preview available for" => "Δεν υπάρχει διαθέσιμη προεπισκόπηση για", "Direct link" => "Άμεσος σύνδεσμος" ); diff --git a/apps/files_sharing/l10n/id.php b/apps/files_sharing/l10n/id.php index e91ef94bf38..865a951c2d2 100644 --- a/apps/files_sharing/l10n/id.php +++ b/apps/files_sharing/l10n/id.php @@ -1,11 +1,20 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Berbagi ini dilindungi sandi", +"The password is wrong. Try again." => "Sandi salah. Coba lagi", "Password" => "Sandi", +"Sorry, this link doesn’t seem to work anymore." => "Maaf, tautan ini tampaknya tidak berfungsi lagi.", +"Reasons might be:" => "Alasan mungkin:", +"the item was removed" => "item telah dihapus", +"the link expired" => "tautan telah kadaluarsa", +"sharing is disabled" => "berbagi dinonaktifkan", +"For more info, please ask the person who sent this link." => "Untuk info lebih lanjut, silakan tanyakan orang yang mengirim tautan ini.", "%s shared the folder %s with you" => "%s membagikan folder %s dengan Anda", -"%s shared the file %s with you" => "%s membagikan file %s dengan Anda", +"%s shared the file %s with you" => "%s membagikan berkas %s dengan Anda", "Download" => "Unduh", "Upload" => "Unggah", -"Cancel upload" => "Batal pengunggahan", -"No preview available for" => "Tidak ada pratinjau tersedia untuk" +"Cancel upload" => "Batal unggah", +"No preview available for" => "Tidak ada pratinjau yang tersedia untuk", +"Direct link" => "Tautan langsung" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/download.php b/apps/files_trashbin/download.php deleted file mode 100644 index 60328e1dddb..00000000000 --- a/apps/files_trashbin/download.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php - -/** -* ownCloud - trash bin -* -* @author Bjoern Schiessle -* @copyright 2013 Bjoern Schiessle schiessle@owncloud.com -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -// Check if we are a user -OCP\User::checkLoggedIn(); - -$filename = $_GET["file"]; - -$view = new OC_FilesystemView('/'.\OCP\User::getUser().'/files_trashbin/files'); - -if(!$view->file_exists($filename)) { - header("HTTP/1.0 404 Not Found"); - $tmpl = new OCP\Template( '', '404', 'guest' ); - $tmpl->assign('file', $filename); - $tmpl->printPage(); - exit; -} - -$ftype=$view->getMimeType( $filename ); - -header('Content-Type:'.$ftype);if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) { - header( 'Content-Disposition: attachment; filename="' . rawurlencode( basename($filename) ) . '"' ); -} else { - header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode( basename($filename) ) - . '; filename="' . rawurlencode( basename($filename) ) . '"' ); -} -OCP\Response::disableCaching(); -header('Content-Length: '. $view->filesize($filename)); - -OC_Util::obEnd(); -$view->readfile( $filename ); diff --git a/apps/files_trashbin/l10n/el.php b/apps/files_trashbin/l10n/el.php index ffeafb7e9d5..b4ee30c578d 100644 --- a/apps/files_trashbin/l10n/el.php +++ b/apps/files_trashbin/l10n/el.php @@ -3,11 +3,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Αδύνατη η μόνιμη διαγραφή του %s", "Couldn't restore %s" => "Αδυναμία επαναφοράς %s", "Error" => "Σφάλμα", -"restored" => "έγινε επαναφορά", +"restored" => "επαναφέρθηκαν", "Nothing in here. Your trash bin is empty!" => "Δεν υπάρχει τίποτα εδώ. Ο κάδος σας είναι άδειος!", "Name" => "Όνομα", "Restore" => "Επαναφορά", -"Deleted" => "Διαγράφηκε", +"Deleted" => "Διαγραμμένα", "Delete" => "Διαγραφή", "Deleted Files" => "Διαγραμμένα Αρχεία" ); diff --git a/apps/files_versions/download.php b/apps/files_versions/download.php index 040a662e61b..2fe56d2e638 100644 --- a/apps/files_versions/download.php +++ b/apps/files_versions/download.php @@ -36,12 +36,7 @@ $view = new OC\Files\View('/'); $ftype = $view->getMimeType('/'.$uid.'/files/'.$filename); header('Content-Type:'.$ftype); -if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) { - header( 'Content-Disposition: attachment; filename="' . rawurlencode( basename($filename) ) . '"' ); -} else { - header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode( basename($filename) ) - . '; filename="' . rawurlencode( basename($filename) ) . '"' ); -} +OCP\Response::setContentDispositionHeader(basename($filename), 'attachment'); OCP\Response::disableCaching(); header('Content-Length: '.$view->filesize($versionName)); diff --git a/apps/files_versions/l10n/el.php b/apps/files_versions/l10n/el.php index af608e7c042..5337f3b5a48 100644 --- a/apps/files_versions/l10n/el.php +++ b/apps/files_versions/l10n/el.php @@ -1,6 +1,6 @@ <?php $TRANSLATIONS = array( -"Could not revert: %s" => "Αδυναμία επαναφοράς του: %s", +"Could not revert: %s" => "Αδυναμία επαναφοράς: %s", "Versions" => "Εκδόσεις", "Failed to revert {file} to revision {timestamp}." => "Αποτυχία επαναφοράς του {file} στην αναθεώρηση {timestamp}.", "More versions..." => "Περισσότερες εκδόσεις...", diff --git a/apps/user_ldap/l10n/ur.php b/apps/user_ldap/l10n/ur.php new file mode 100644 index 00000000000..3a1e002311c --- /dev/null +++ b/apps/user_ldap/l10n/ur.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index ecc74b6cf54..72f9c740921 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -634,6 +634,10 @@ class Access extends LDAPUtility { return $this->search($filter, $this->connection->ldapBaseUsers, $attr, $limit, $offset); } + public function countUsers($filter, $attr = array('dn'), $limit = null, $offset = null) { + return $this->count($filter, $this->connection->ldapBaseGroups, $attr, $limit, $offset); + } + /** * @brief executes an LDAP search, optimized for Groups * @param $filter the LDAP filter for the search @@ -647,61 +651,68 @@ class Access extends LDAPUtility { } /** - * @brief executes an LDAP search + * @brief prepares and executes an LDAP search operation * @param $filter the LDAP filter for the search * @param $base an array containing the LDAP subtree(s) that shall be searched * @param $attr optional, array, one or more attributes that shall be * retrieved. Results will according to the order in the array. - * @returns array with the search result - * - * Executes an LDAP search + * @param $limit optional, maximum results to be counted + * @param $offset optional, a starting point + * @returns array with the search result as first value and pagedSearchOK as + * second | false if not successful */ - private function search($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) { + private function executeSearch($filter, $base, &$attr = null, $limit = null, $offset = null) { if(!is_null($attr) && !is_array($attr)) { $attr = array(mb_strtolower($attr, 'UTF-8')); } // See if we have a resource, in case not cancel with message - $link_resource = $this->connection->getConnectionResource(); - if(!$this->ldap->isResource($link_resource)) { + $cr = $this->connection->getConnectionResource(); + if(!$this->ldap->isResource($cr)) { // Seems like we didn't find any resource. // Return an empty array just like before. \OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG); - return array(); + return false; } //check wether paged search should be attempted $pagedSearchOK = $this->initPagedSearch($filter, $base, $attr, $limit, $offset); - $linkResources = array_pad(array(), count($base), $link_resource); + $linkResources = array_pad(array(), count($base), $cr); $sr = $this->ldap->search($linkResources, $base, $filter, $attr); - $error = $this->ldap->errno($link_resource); + $error = $this->ldap->errno($cr); if(!is_array($sr) || $error !== 0) { \OCP\Util::writeLog('user_ldap', - 'Error when searching: '.$this->ldap->error($link_resource). - ' code '.$this->ldap->errno($link_resource), + 'Error when searching: '.$this->ldap->error($cr). + ' code '.$this->ldap->errno($cr), \OCP\Util::ERROR); \OCP\Util::writeLog('user_ldap', 'Attempt for Paging? '.print_r($pagedSearchOK, true), \OCP\Util::ERROR); - return array(); + return false; } - // Do the server-side sorting - foreach(array_reverse($attr) as $sortAttr){ - foreach($sr as $searchResource) { - $this->ldap->sort($link_resource, $searchResource, $sortAttr); - } - } + return array($sr, $pagedSearchOK); + } - $findings = array(); - foreach($sr as $key => $res) { - $findings = array_merge($findings, $this->ldap->getEntries($link_resource, $res )); - } + /** + * @brief processes an LDAP paged search operation + * @param $sr the array containing the LDAP search resources + * @param $filter the LDAP filter for the search + * @param $base an array containing the LDAP subtree(s) that shall be searched + * @param $iFoundItems number of results in the search operation + * @param $limit maximum results to be counted + * @param $offset a starting point + * @param $pagedSearchOK whether a paged search has been executed + * @param $skipHandling required for paged search when cookies to + * prior results need to be gained + * @returns array with the search result as first value and pagedSearchOK as + * second | false if not successful + */ + private function processPagedSearchStatus($sr, $filter, $base, $iFoundItems, $limit, $offset, $pagedSearchOK, $skipHandling) { if($pagedSearchOK) { - \OCP\Util::writeLog('user_ldap', 'Paged search successful', \OCP\Util::INFO); + $cr = $this->connection->getConnectionResource(); foreach($sr as $key => $res) { $cookie = null; - if($this->ldap->controlPagedResultResponse($link_resource, $res, $cookie)) { - \OCP\Util::writeLog('user_ldap', 'Set paged search cookie', \OCP\Util::INFO); + if($this->ldap->controlPagedResultResponse($cr, $res, $cookie)) { $this->setPagedResultCookie($base[$key], $filter, $limit, $offset, $cookie); } } @@ -713,7 +724,7 @@ class Access extends LDAPUtility { // if count is bigger, then the server does not support // paged search. Instead, he did a normal search. We set a // flag here, so the callee knows how to deal with it. - if($findings['count'] <= $limit) { + if($iFoundItems <= $limit) { $this->pagedSearchedSuccessful = true; } } else { @@ -721,6 +732,86 @@ class Access extends LDAPUtility { \OCP\Util::writeLog('user_ldap', 'Paged search failed :(', \OCP\Util::INFO); } } + } + + /** + * @brief executes an LDAP search, but counts the results only + * @param $filter the LDAP filter for the search + * @param $base an array containing the LDAP subtree(s) that shall be searched + * @param $attr optional, array, one or more attributes that shall be + * retrieved. Results will according to the order in the array. + * @param $limit optional, maximum results to be counted + * @param $offset optional, a starting point + * @param $skipHandling indicates whether the pages search operation is + * completed + * @returns int | false if the search could not be initialized + * + */ + private function count($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) { + \OCP\Util::writeLog('user_ldap', 'Count filter: '.print_r($filter, true), \OCP\Util::DEBUG); + $search = $this->executeSearch($filter, $base, $attr, $limit, $offset); + if($search === false) { + return false; + } + list($sr, $pagedSearchOK) = $search; + $cr = $this->connection->getConnectionResource(); + $counter = 0; + foreach($sr as $key => $res) { + $count = $this->ldap->countEntries($cr, $res); + if($count !== false) { + $counter += $count; + } + } + + $this->processPagedSearchStatus($sr, $filter, $base, $counter, $limit, + $offset, $pagedSearchOK, $skipHandling); + + return $counter; + } + + /** + * @brief executes an LDAP search + * @param $filter the LDAP filter for the search + * @param $base an array containing the LDAP subtree(s) that shall be searched + * @param $attr optional, array, one or more attributes that shall be + * retrieved. Results will according to the order in the array. + * @returns array with the search result + * + * Executes an LDAP search + */ + private function search($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) { + $search = $this->executeSearch($filter, $base, $attr, $limit, $offset); + if($search === false) { + return array(); + } + list($sr, $pagedSearchOK) = $search; + $cr = $this->connection->getConnectionResource(); + + if($skipHandling) { + //i.e. result do not need to be fetched, we just need the cookie + //thus pass 1 or any other value as $iFoundItems because it is not + //used + $this->processPagedSearchStatus($sr, $filter, $base, 1, $limit, + $offset, $pagedSearchOK, + $skipHandling); + return; + } + + // Do the server-side sorting + foreach(array_reverse($attr) as $sortAttr){ + foreach($sr as $searchResource) { + $this->ldap->sort($cr, $searchResource, $sortAttr); + } + } + + $findings = array(); + foreach($sr as $key => $res) { + $findings = array_merge($findings, $this->ldap->getEntries($cr , $res )); + } + + $this->processPagedSearchStatus($sr, $filter, $base, $findings['count'], + $limit, $offset, $pagedSearchOK, + $skipHandling); // if we're here, probably no connection resource is returned. // to make ownCloud behave nicely, we simply give back an empty array. diff --git a/apps/user_ldap/tests/user_ldap.php b/apps/user_ldap/tests/user_ldap.php index 6b9b8b3e185..9193a005ae5 100644 --- a/apps/user_ldap/tests/user_ldap.php +++ b/apps/user_ldap/tests/user_ldap.php @@ -408,4 +408,58 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase { //no test for getDisplayNames, because it just invokes getUsers and //getDisplayName + + public function testCountUsers() { + $access = $this->getAccessMock(); + + $access->connection->expects($this->once()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'ldapLoginFilter') { + return 'uid=%uid'; + } + return null; + })); + + $access->expects($this->once()) + ->method('countUsers') + ->will($this->returnCallback(function($filter, $a, $b, $c) { + if($filter !== 'uid=*') { + return false; + } + return 5; + })); + + $backend = new UserLDAP($access); + + $result = $backend->countUsers(); + $this->assertEquals(5, $result); + } + + public function testCountUsersFailing() { + $access = $this->getAccessMock(); + + $access->connection->expects($this->once()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'ldapLoginFilter') { + return 'invalidFilter'; + } + return null; + })); + + $access->expects($this->once()) + ->method('countUsers') + ->will($this->returnCallback(function($filter, $a, $b, $c) { + if($filter !== 'uid=*') { + return false; + } + return 5; + })); + + $backend = new UserLDAP($access); + + $result = $backend->countUsers(); + $this->assertFalse($result); + } }
\ No newline at end of file diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 527a5c10b85..a19af86086c 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -363,7 +363,8 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { return (bool)((OC_USER_BACKEND_CHECK_PASSWORD | OC_USER_BACKEND_GET_HOME | OC_USER_BACKEND_GET_DISPLAYNAME - | OC_USER_BACKEND_PROVIDE_AVATAR) + | OC_USER_BACKEND_PROVIDE_AVATAR + | OC_USER_BACKEND_COUNT_USERS) & $actions); } @@ -373,4 +374,16 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { public function hasUserListings() { return true; } + + /** + * counts the users in LDAP + * + * @return int | bool + */ + public function countUsers() { + $filter = \OCP\Util::mb_str_replace( + '%uid', '*', $this->access->connection->ldapLoginFilter, 'UTF-8'); + $entries = $this->access->countUsers($filter); + return $entries; + } } diff --git a/apps/user_ldap/user_proxy.php b/apps/user_ldap/user_proxy.php index b073b143e74..5ad127197f3 100644 --- a/apps/user_ldap/user_proxy.php +++ b/apps/user_ldap/user_proxy.php @@ -210,4 +210,19 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface { return $this->refBackend->hasUserListings(); } + /** + * @brief Count the number of users + * @returns int | bool + */ + public function countUsers() { + $users = false; + foreach($this->backends as $backend) { + $backendUsers = $backend->countUsers(); + if ($backendUsers !== false) { + $users += $backendUsers; + } + } + return $users; + } + } |