diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files/ajax/list.php | 3 | ||||
-rw-r--r-- | apps/files/lib/helper.php | 2 | ||||
-rw-r--r-- | apps/files_encryption/ajax/adminrecovery.php | 48 | ||||
-rw-r--r-- | apps/files_encryption/ajax/changeRecoveryPassword.php | 26 | ||||
-rw-r--r-- | apps/files_encryption/ajax/userrecovery.php | 8 | ||||
-rw-r--r-- | apps/files_encryption/js/settings-admin.js | 43 | ||||
-rw-r--r-- | apps/files_encryption/js/settings-personal.js | 21 | ||||
-rw-r--r-- | apps/files_encryption/templates/settings-admin.php | 15 | ||||
-rw-r--r-- | apps/files_encryption/templates/settings-personal.php | 5 | ||||
-rw-r--r-- | apps/files_external/appinfo/version | 2 | ||||
-rw-r--r-- | apps/files_external/lib/amazons3.php | 257 |
11 files changed, 228 insertions, 202 deletions
diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php index 16e48a2c2af..4abf5ad7607 100644 --- a/apps/files/ajax/list.php +++ b/apps/files/ajax/list.php @@ -32,6 +32,7 @@ try { OCP\JSON::success(array('data' => $data)); } catch (\OCP\Files\StorageNotAvailableException $e) { + \OCP\Util::logException('files', $e); OCP\JSON::error(array( 'data' => array( 'exception' => '\OCP\Files\StorageNotAvailableException', @@ -39,6 +40,7 @@ try { ) )); } catch (\OCP\Files\StorageInvalidException $e) { + \OCP\Util::logException('files', $e); OCP\JSON::error(array( 'data' => array( 'exception' => '\OCP\Files\StorageInvalidException', @@ -46,6 +48,7 @@ try { ) )); } catch (\Exception $e) { + \OCP\Util::logException('files', $e); OCP\JSON::error(array( 'data' => array( 'exception' => '\Exception', diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php index 2a5233b6542..e4bfcb4e9ee 100644 --- a/apps/files/lib/helper.php +++ b/apps/files/lib/helper.php @@ -93,7 +93,7 @@ class Helper public static function compareSize($a, $b) { $aSize = $a->getSize(); $bSize = $b->getSize(); - return $aSize - $bSize; + return ($aSize < $bSize) ? -1 : 1; } /** diff --git a/apps/files_encryption/ajax/adminrecovery.php b/apps/files_encryption/ajax/adminrecovery.php index 070ca6f667e..684fd51ae13 100644 --- a/apps/files_encryption/ajax/adminrecovery.php +++ b/apps/files_encryption/ajax/adminrecovery.php @@ -16,8 +16,28 @@ use OCA\Encryption; $l = \OC::$server->getL10N('files_encryption'); $return = false; -// Enable recoveryAdmin +$errorMessage = $l->t("Unknown error"); + +//check if both passwords are the same +if (empty($_POST['recoveryPassword'])) { + $errorMessage = $l->t('Missing recovery key password'); + \OCP\JSON::error(array('data' => array('message' => $errorMessage))); + exit(); +} +if (empty($_POST['confirmPassword'])) { + $errorMessage = $l->t('Please repeat the recovery key password'); + \OCP\JSON::error(array('data' => array('message' => $errorMessage))); + exit(); +} + +if ($_POST['recoveryPassword'] !== $_POST['confirmPassword']) { + $errorMessage = $l->t('Repeated recovery key password does not match the provided recovery key password'); + \OCP\JSON::error(array('data' => array('message' => $errorMessage))); + exit(); +} + +// Enable recoveryAdmin $recoveryKeyId = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryKeyId'); if (isset($_POST['adminEnableRecovery']) && $_POST['adminEnableRecovery'] === '1') { @@ -26,14 +46,9 @@ if (isset($_POST['adminEnableRecovery']) && $_POST['adminEnableRecovery'] === '1 // Return success or failure if ($return) { - \OCP\JSON::success(array('data' => array('message' => $l->t('Recovery key successfully enabled')))); + $successMessage = $l->t('Recovery key successfully enabled'); } else { - \OCP\JSON::error(array( - 'data' => array( - 'message' => $l->t( - 'Could not enable recovery key. Please check your recovery key password!') - ) - )); + $errorMessage = $l->t('Could not disable recovery key. Please check your recovery key password!'); } // Disable recoveryAdmin @@ -43,17 +58,16 @@ if (isset($_POST['adminEnableRecovery']) && $_POST['adminEnableRecovery'] === '1 ) { $return = \OCA\Encryption\Helper::adminDisableRecovery($_POST['recoveryPassword']); - // Return success or failure if ($return) { - \OCP\JSON::success(array('data' => array('message' => $l->t('Recovery key successfully disabled')))); + $successMessage = $l->t('Recovery key successfully disabled'); } else { - \OCP\JSON::error(array( - 'data' => array( - 'message' => $l->t( - 'Could not disable recovery key. Please check your recovery key password!') - ) - )); + $errorMessage = $l->t('Could not disable recovery key. Please check your recovery key password!'); } } - +// Return success or failure +if ($return) { + \OCP\JSON::success(array('data' => array('message' => $successMessage))); +} else { + \OCP\JSON::error(array('data' => array('message' => $errorMessage))); +} diff --git a/apps/files_encryption/ajax/changeRecoveryPassword.php b/apps/files_encryption/ajax/changeRecoveryPassword.php index 71fbe333fe0..bf647f2c8fa 100644 --- a/apps/files_encryption/ajax/changeRecoveryPassword.php +++ b/apps/files_encryption/ajax/changeRecoveryPassword.php @@ -21,6 +21,32 @@ $return = false; $oldPassword = $_POST['oldPassword']; $newPassword = $_POST['newPassword']; +$confirmPassword = $_POST['confirmPassword']; + +//check if both passwords are the same +if (empty($_POST['oldPassword'])) { + $errorMessage = $l->t('Please provide the old recovery password'); + \OCP\JSON::error(array('data' => array('message' => $errorMessage))); + exit(); +} + +if (empty($_POST['newPassword'])) { + $errorMessage = $l->t('Please provide a new recovery password'); + \OCP\JSON::error(array('data' => array('message' => $errorMessage))); + exit(); +} + +if (empty($_POST['confirmPassword'])) { + $errorMessage = $l->t('Please repeat the new recovery password'); + \OCP\JSON::error(array('data' => array('message' => $errorMessage))); + exit(); +} + +if ($_POST['newPassword'] !== $_POST['confirmPassword']) { + $errorMessage = $l->t('Repeated recovery key password does not match the provided recovery key password'); + \OCP\JSON::error(array('data' => array('message' => $errorMessage))); + exit(); +} $view = new \OC\Files\View('/'); $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \OCP\User::getUser()); diff --git a/apps/files_encryption/ajax/userrecovery.php b/apps/files_encryption/ajax/userrecovery.php index 0f3b973d69a..a5b89fa7233 100644 --- a/apps/files_encryption/ajax/userrecovery.php +++ b/apps/files_encryption/ajax/userrecovery.php @@ -13,6 +13,8 @@ use OCA\Encryption; \OCP\JSON::checkAppEnabled('files_encryption'); \OCP\JSON::callCheck(); +$l = \OC::$server->getL10N('files_encryption'); + if ( isset($_POST['userEnableRecovery']) && (0 == $_POST['userEnableRecovery'] || '1' === $_POST['userEnableRecovery']) @@ -38,4 +40,8 @@ if ( } // Return success or failure -($return) ? \OCP\JSON::success() : \OCP\JSON::error(); +if ($return) { + \OCP\JSON::success(array('data' => array('message' => $l->t('File recovery settings updated')))); +} else { + \OCP\JSON::error(array('data' => array('message' => $l->t('Could not update file recovery')))); +} diff --git a/apps/files_encryption/js/settings-admin.js b/apps/files_encryption/js/settings-admin.js index 4c6b1bac2f7..2242c1f7124 100644 --- a/apps/files_encryption/js/settings-admin.js +++ b/apps/files_encryption/js/settings-admin.js @@ -9,32 +9,21 @@ $(document).ready(function(){ - $('input:password[name="encryptionRecoveryPassword"]').keyup(function(event) { - var recoveryPassword = $( '#encryptionRecoveryPassword' ).val(); - var recoveryPasswordRepeated = $( '#repeatEncryptionRecoveryPassword' ).val(); - var checkedButton = $('input:radio[name="adminEnableRecovery"]:checked').val(); - var uncheckedValue = (1+parseInt(checkedButton)) % 2; - if (recoveryPassword !== '' && recoveryPassword === recoveryPasswordRepeated) { - $('input:radio[name="adminEnableRecovery"][value="'+uncheckedValue.toString()+'"]').removeAttr("disabled"); - } else { - $('input:radio[name="adminEnableRecovery"][value="'+uncheckedValue.toString()+'"]').attr("disabled", "true"); - } - }); - $( 'input:radio[name="adminEnableRecovery"]' ).change( function() { var recoveryStatus = $( this ).val(); var oldStatus = (1+parseInt(recoveryStatus)) % 2; var recoveryPassword = $( '#encryptionRecoveryPassword' ).val(); + var confirmPassword = $( '#repeatEncryptionRecoveryPassword' ).val(); + OC.msg.startSaving('#encryptionSetRecoveryKey .msg'); $.post( OC.filePath( 'files_encryption', 'ajax', 'adminrecovery.php' ) - , { adminEnableRecovery: recoveryStatus, recoveryPassword: recoveryPassword } + , { adminEnableRecovery: recoveryStatus, recoveryPassword: recoveryPassword, confirmPassword: confirmPassword } , function( result ) { + OC.msg.finishedSaving('#encryptionSetRecoveryKey .msg', result); if (result.status === "error") { - OC.Notification.show(t('admin', result.data.message)); $('input:radio[name="adminEnableRecovery"][value="'+oldStatus.toString()+'"]').attr("checked", "true"); } else { - OC.Notification.hide(); if (recoveryStatus === "0") { $('p[name="changeRecoveryPasswordBlock"]').addClass("hidden"); } else { @@ -49,33 +38,17 @@ $(document).ready(function(){ // change recovery password - $('input:password[name="changeRecoveryPassword"]').keyup(function(event) { - var oldRecoveryPassword = $('#oldEncryptionRecoveryPassword').val(); - var newRecoveryPassword = $('#newEncryptionRecoveryPassword').val(); - var newRecoveryPasswordRepeated = $('#repeatedNewEncryptionRecoveryPassword').val(); - - if (newRecoveryPassword !== '' && oldRecoveryPassword !== '' && newRecoveryPassword === newRecoveryPasswordRepeated) { - $('button:button[name="submitChangeRecoveryKey"]').removeAttr("disabled"); - } else { - $('button:button[name="submitChangeRecoveryKey"]').attr("disabled", "true"); - } - }); - - $('button:button[name="submitChangeRecoveryKey"]').click(function() { var oldRecoveryPassword = $('#oldEncryptionRecoveryPassword').val(); var newRecoveryPassword = $('#newEncryptionRecoveryPassword').val(); - OC.msg.startSaving('#encryption .msg'); + var confirmNewPassword = $('#repeatedNewEncryptionRecoveryPassword').val(); + OC.msg.startSaving('#encryptionChangeRecoveryKey .msg'); $.post( OC.filePath( 'files_encryption', 'ajax', 'changeRecoveryPassword.php' ) - , { oldPassword: oldRecoveryPassword, newPassword: newRecoveryPassword } + , { oldPassword: oldRecoveryPassword, newPassword: newRecoveryPassword, confirmPassword: confirmNewPassword } , function( data ) { - if (data.status == "error") { - OC.msg.finishedSaving('#encryption .msg', data); - } else { - OC.msg.finishedSaving('#encryption .msg', data); + OC.msg.finishedSaving('#encryptionChangeRecoveryKey .msg', data); } - } ); }); diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js index f857c2c9f05..b798ba7e4e1 100644 --- a/apps/files_encryption/js/settings-personal.js +++ b/apps/files_encryption/js/settings-personal.js @@ -26,36 +26,27 @@ $(document).ready(function(){ // Trigger ajax on recoveryAdmin status change $( 'input:radio[name="userEnableRecovery"]' ).change( function() { - - // Hide feedback messages in case they're already visible - $('#recoveryEnabledSuccess').hide(); - $('#recoveryEnabledError').hide(); - var recoveryStatus = $( this ).val(); - + OC.msg.startAction('#userEnableRecovery .msg', 'Updating recovery keys. This can take some time...'); $.post( OC.filePath( 'files_encryption', 'ajax', 'userrecovery.php' ) , { userEnableRecovery: recoveryStatus } , function( data ) { - if ( data.status == "success" ) { - $('#recoveryEnabledSuccess').show(); - } else { - $('#recoveryEnabledError').show(); - } + OC.msg.finishedAction('#userEnableRecovery .msg', data); } ); // Ensure page is not reloaded on form submit return false; } ); - + $("#encryptAll").click( function(){ - + // Hide feedback messages in case they're already visible $('#encryptAllSuccess').hide(); $('#encryptAllError').hide(); - + var userPassword = $( '#userPassword' ).val(); var encryptAll = $( '#encryptAll' ).val(); @@ -73,7 +64,7 @@ $(document).ready(function(){ // Ensure page is not reloaded on form submit return false; } - + ); // update private key password diff --git a/apps/files_encryption/templates/settings-admin.php b/apps/files_encryption/templates/settings-admin.php index 2d5f7084c96..d003f245bb3 100644 --- a/apps/files_encryption/templates/settings-admin.php +++ b/apps/files_encryption/templates/settings-admin.php @@ -4,8 +4,9 @@ <?php if($_["initStatus"] === \OCA\Encryption\Session::NOT_INITIALIZED): ?> <?php p($l->t("Encryption App is enabled but your keys are not initialized, please log-out and log-in again")); ?> <?php else: ?> - <p> + <p id="encryptionSetRecoveryKey"> <?php p($l->t("Enable recovery key (allow to recover users files in case of password loss):")); ?> + <span class="msg"></span> <br/> <br/> <input type="password" name="encryptionRecoveryPassword" id="encryptionRecoveryPassword"/> @@ -19,7 +20,7 @@ id='adminEnableRecovery' name='adminEnableRecovery' value='1' - <?php echo($_["recoveryEnabled"] === '1' ? 'checked="checked"' : 'disabled'); ?> /> + <?php echo($_["recoveryEnabled"] === '1' ? 'checked="checked"' : ''); ?> /> <label for="adminEnableRecovery"><?php p($l->t("Enabled")); ?></label> <br/> @@ -28,13 +29,14 @@ id='adminDisableRecovery' name='adminEnableRecovery' value='0' - <?php echo($_["recoveryEnabled"] === '0' ? 'checked="checked"' : 'disabled'); ?> /> + <?php echo($_["recoveryEnabled"] === '0' ? 'checked="checked"' : ''); ?> /> <label for="adminDisableRecovery"><?php p($l->t("Disabled")); ?></label> </p> <br/><br/> - <p name="changeRecoveryPasswordBlock" <?php if ($_['recoveryEnabled'] === '0') print_unescaped('class="hidden"');?>> + <p name="changeRecoveryPasswordBlock" id="encryptionChangeRecoveryKey" <?php if ($_['recoveryEnabled'] === '0') print_unescaped('class="hidden"');?>> <strong><?php p($l->t("Change recovery key password:")); ?></strong> + <span class="msg"></span> <br/><br/> <input type="password" @@ -57,10 +59,9 @@ <br/> <button type="button" - name="submitChangeRecoveryKey" - disabled><?php p($l->t("Change Password")); ?> + name="submitChangeRecoveryKey"> + <?php p($l->t("Change Password")); ?> </button> - <span class="msg"></span> </p> <?php endif; ?> </form> diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index a1221240422..ce8cf6aec28 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -39,8 +39,9 @@ <?php elseif ( $_["recoveryEnabled"] && $_["privateKeySet"] && $_["initialized"] === \OCA\Encryption\Session::INIT_SUCCESSFUL ): ?>
<br />
- <p>
+ <p id="userEnableRecovery">
<label for="userEnableRecovery"><?php p( $l->t( "Enable password recovery:" ) ); ?></label>
+ <span class="msg"></span>
<br />
<em><?php p( $l->t( "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" ) ); ?></em>
<br />
@@ -60,8 +61,6 @@ value='0'
<?php echo ( $_["recoveryEnabledForUser"] === false ? 'checked="checked"' : '' ); ?> />
<label for="userDisableRecovery"><?php p( $l->t( "Disabled" ) ); ?></label>
- <div id="recoveryEnabledSuccess"><?php p( $l->t( 'File recovery settings updated' ) ); ?></div>
- <div id="recoveryEnabledError"><?php p( $l->t( 'Could not update file recovery' ) ); ?></div>
</p>
<?php endif; ?>
</form>
diff --git a/apps/files_external/appinfo/version b/apps/files_external/appinfo/version index 7dff5b89211..f4778493c50 100644 --- a/apps/files_external/appinfo/version +++ b/apps/files_external/appinfo/version @@ -1 +1 @@ -0.2.1
\ No newline at end of file +0.2.2
\ No newline at end of file diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 9daac83e066..808de16c8a8 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -53,6 +53,10 @@ class AmazonS3 extends \OC\Files\Storage\Common { * @var int */ private $timeout = 15; + /** + * @var int in seconds + */ + private $rescanDelay = 10; /** * @param string $path @@ -68,32 +72,41 @@ class AmazonS3 extends \OC\Files\Storage\Common { return $path; } + /** + * when running the tests wait to let the buckets catch up + */ private function testTimeout() { if ($this->test) { sleep($this->timeout); } } + private function isRoot($path) { + return $path === '.'; + } + private function cleanKey($path) { - if ($path === '.') { + if ($this->isRoot($path)) { return '/'; } return $path; } public function __construct($params) { - if (!isset($params['key']) || !isset($params['secret']) || !isset($params['bucket'])) { + if (empty($params['key']) || empty($params['secret']) || empty($params['bucket'])) { throw new \Exception("Access Key, Secret and Bucket have to be configured."); } - $this->id = 'amazon::' . $params['key'] . md5($params['secret']); + $this->id = 'amazon::' . $params['bucket']; + $this->updateLegacyId($params); $this->bucket = $params['bucket']; $scheme = ($params['use_ssl'] === 'false') ? 'http' : 'https'; $this->test = isset($params['test']); $this->timeout = (!isset($params['timeout'])) ? 15 : $params['timeout']; - $params['region'] = (!isset($params['region']) || $params['region'] === '') ? 'eu-west-1' : $params['region']; - $params['hostname'] = (!isset($params['hostname']) || $params['hostname'] === '') ? 's3.amazonaws.com' : $params['hostname']; + $this->rescanDelay = (!isset($params['rescanDelay'])) ? 10 : $params['rescanDelay']; + $params['region'] = empty($params['region']) ? 'eu-west-1' : $params['region']; + $params['hostname'] = empty($params['hostname']) ? 's3.amazonaws.com' : $params['hostname']; if (!isset($params['port']) || $params['port'] === '') { $params['port'] = ($params['use_ssl'] === 'false') ? 80 : 443; } @@ -112,7 +125,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { if (!$this->connection->doesBucketExist($this->bucket)) { try { - $result = $this->connection->createBucket(array( + $this->connection->createBucket(array( 'Bucket' => $this->bucket )); $this->connection->waitUntilBucketExists(array( @@ -122,19 +135,41 @@ class AmazonS3 extends \OC\Files\Storage\Common { )); $this->testTimeout(); } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); - throw new \Exception("Creation of bucket failed."); + \OCP\Util::logException('files_external', $e); + throw new \Exception('Creation of bucket failed. '.$e->getMessage()); } } - if (!$this->file_exists('.')) { - $result = $this->connection->putObject(array( - 'Bucket' => $this->bucket, - 'Key' => $this->cleanKey('.'), - 'Body' => '', - 'ContentType' => 'httpd/unix-directory', - 'ContentLength' => 0 - )); - $this->testTimeout(); + } + + /** + * Updates old storage ids (v0.2.1 and older) that are based on key and secret to new ones based on the bucket name. + * TODO Do this in an update.php. requires iterating over all users and loading the mount.json from their home + * + * @param array $params + */ + public function updateLegacyId (array $params) { + $stmt = \OC::$server->getDatabaseConnection()->prepare( + 'UPDATE `*PREFIX*storages` SET `id` = ? WHERE `id` = ?' + ); + $oldId = 'amazon::' . $params['key'] . md5($params['secret']); + $stmt->execute(array($this->id, $oldId)); + } + + /** + * Remove a file or folder + * + * @param string $path + * @return bool + */ + protected function remove($path) { + // remember fileType to reduce http calls + $fileType = $this->filetype($path); + if ($fileType === 'dir') { + return $this->rmdir($path); + } else if ($fileType === 'file') { + return $this->unlink($path); + } else { + return false; } } @@ -149,13 +184,11 @@ class AmazonS3 extends \OC\Files\Storage\Common { $this->connection->putObject(array( 'Bucket' => $this->bucket, 'Key' => $path . '/', - 'Body' => '', - 'ContentType' => 'httpd/unix-directory', - 'ContentLength' => 0 + 'ContentType' => 'httpd/unix-directory' )); $this->testTimeout(); } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + \OCP\Util::logException('files_external', $e); return false; } @@ -163,32 +196,14 @@ class AmazonS3 extends \OC\Files\Storage\Common { } public function file_exists($path) { - $path = $this->normalizePath($path); - - if (!$path) { - $path = '.'; - } else if ($path != '.' && $this->is_dir($path)) { - $path .= '/'; - } - - try { - $result = $this->connection->doesObjectExist( - $this->bucket, - $this->cleanKey($path) - ); - } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); - return false; - } - - return $result; + return $this->filetype($path) !== false; } public function rmdir($path) { $path = $this->normalizePath($path); - if ($path === '.') { + if ($this->isRoot($path)) { return $this->clearBucket(); } @@ -196,55 +211,54 @@ class AmazonS3 extends \OC\Files\Storage\Common { return false; } - // Since there are no real directories on S3, we need - // to delete all objects prefixed with the path. - $objects = $this->connection->listObjects(array( - 'Bucket' => $this->bucket, - 'Prefix' => $path . '/' - )); - - try { - $this->connection->deleteObjects(array( - 'Bucket' => $this->bucket, - 'Objects' => $objects['Contents'] - )); - $this->testTimeout(); - } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); - return false; - } - - return true; + return $this->batchDelete($path); } protected function clearBucket() { try { $this->connection->clearBucket($this->bucket); + return true; // clearBucket() is not working with Ceph, so if it fails we try the slower approach } catch (\Exception $e) { - try { - $iterator = $this->connection->getIterator('ListObjects', array( - 'Bucket' => $this->bucket - )); + return $this->batchDelete(); + } + return false; + } - foreach ($iterator as $object) { - $this->connection->deleteObject(array( - 'Bucket' => $this->bucket, - 'Key' => $object['Key'] - )); - } - } catch (S3Exception $e) { - return false; - } + private function batchDelete ($path = null) { + $params = array( + 'Bucket' => $this->bucket + ); + if ($path !== null) { + $params['Prefix'] = $path . '/'; } + try { + // Since there are no real directories on S3, we need + // to delete all objects prefixed with the path. + do { + // instead of the iterator, manually loop over the list ... + $objects = $this->connection->listObjects($params); + // ... so we can delete the files in batches + $this->connection->deleteObjects(array( + 'Bucket' => $this->bucket, + 'Objects' => $objects['Contents'] + )); + $this->testTimeout(); + // we reached the end when the list is no longer truncated + } while ($objects['IsTruncated']); + } catch (S3Exception $e) { + \OCP\Util::logException('files_external', $e); + return false; + } + return true; } public function opendir($path) { $path = $this->normalizePath($path); - if ($path === '.') { + if ($this->isRoot($path)) { $path = ''; - } else if ($path) { + } else { $path .= '/'; } @@ -270,7 +284,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return opendir('fakedir://amazons3' . $path); } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + \OCP\Util::logException('files_external', $e); return false; } } @@ -279,27 +293,29 @@ class AmazonS3 extends \OC\Files\Storage\Common { $path = $this->normalizePath($path); try { - if ($this->is_dir($path) && $path != '.') { - $path .= '/'; - } - - $result = $this->connection->headObject(array( - 'Bucket' => $this->bucket, - 'Key' => $this->cleanKey($path) - )); - $stat = array(); - $stat['size'] = $result['ContentLength'] ? $result['ContentLength'] : 0; - if ($result['Metadata']['lastmodified']) { - $stat['mtime'] = strtotime($result['Metadata']['lastmodified']); + if ($this->is_dir($path)) { + //folders don't really exist + $stat['size'] = -1; //unknown + $stat['mtime'] = time() - $this->rescanDelay * 1000; } else { - $stat['mtime'] = strtotime($result['LastModified']); + $result = $this->connection->headObject(array( + 'Bucket' => $this->bucket, + 'Key' => $path + )); + + $stat['size'] = $result['ContentLength'] ? $result['ContentLength'] : 0; + if ($result['Metadata']['lastmodified']) { + $stat['mtime'] = strtotime($result['Metadata']['lastmodified']); + } else { + $stat['mtime'] = strtotime($result['LastModified']); + } } $stat['atime'] = time(); return $stat; - } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + } catch(S3Exception $e) { + \OCP\Util::logException('files_external', $e); return false; } } @@ -307,19 +323,19 @@ class AmazonS3 extends \OC\Files\Storage\Common { public function filetype($path) { $path = $this->normalizePath($path); + if ($this->isRoot($path)) { + return 'dir'; + } + try { - if ($path != '.' && $this->connection->doesObjectExist($this->bucket, $path)) { + if ($this->connection->doesObjectExist($this->bucket, $path)) { return 'file'; } - - if ($path != '.') { - $path .= '/'; - } - if ($this->connection->doesObjectExist($this->bucket, $this->cleanKey($path))) { + if ($this->connection->doesObjectExist($this->bucket, $path.'/')) { return 'dir'; } } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + \OCP\Util::logException('files_external', $e); return false; } @@ -334,13 +350,13 @@ class AmazonS3 extends \OC\Files\Storage\Common { } try { - $result = $this->connection->deleteObject(array( + $this->connection->deleteObject(array( 'Bucket' => $this->bucket, - 'Key' => $this->cleanKey($path) + 'Key' => $path )); $this->testTimeout(); } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + \OCP\Util::logException('files_external', $e); return false; } @@ -357,13 +373,13 @@ class AmazonS3 extends \OC\Files\Storage\Common { self::$tmpFiles[$tmpFile] = $path; try { - $result = $this->connection->getObject(array( + $this->connection->getObject(array( 'Bucket' => $this->bucket, - 'Key' => $this->cleanKey($path), + 'Key' => $path, 'SaveAs' => $tmpFile )); } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + \OCP\Util::logException('files_external', $e); return false; } @@ -407,10 +423,10 @@ class AmazonS3 extends \OC\Files\Storage\Common { try { $result = $this->connection->headObject(array( 'Bucket' => $this->bucket, - 'Key' => $this->cleanKey($path) + 'Key' => $path )); } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + \OCP\Util::logException('files_external', $e); return false; } @@ -427,12 +443,13 @@ class AmazonS3 extends \OC\Files\Storage\Common { $metadata = array('lastmodified' => $mtime); } + $fileType = $this->filetype($path); try { - if ($this->file_exists($path)) { - if ($this->is_dir($path) && $path != '.') { + if ($fileType !== false) { + if ($fileType === 'dir' && ! $this->isRoot($path)) { $path .= '/'; } - $result = $this->connection->copyObject(array( + $this->connection->copyObject(array( 'Bucket' => $this->bucket, 'Key' => $this->cleanKey($path), 'Metadata' => $metadata, @@ -440,7 +457,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { )); $this->testTimeout(); } else { - $result = $this->connection->putObject(array( + $this->connection->putObject(array( 'Bucket' => $this->bucket, 'Key' => $this->cleanKey($path), 'Metadata' => $metadata, @@ -449,7 +466,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { $this->testTimeout(); } } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + \OCP\Util::logException('files_external', $e); return false; } @@ -462,32 +479,28 @@ class AmazonS3 extends \OC\Files\Storage\Common { if ($this->is_file($path1)) { try { - $result = $this->connection->copyObject(array( + $this->connection->copyObject(array( 'Bucket' => $this->bucket, 'Key' => $this->cleanKey($path2), 'CopySource' => S3Client::encodeKey($this->bucket . '/' . $path1) )); $this->testTimeout(); } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + \OCP\Util::logException('files_external', $e); return false; } } else { - if ($this->is_dir($path2)) { - $this->rmdir($path2); - } else if ($this->file_exists($path2)) { - $this->unlink($path2); - } + $this->remove($path2); try { - $result = $this->connection->copyObject(array( + $this->connection->copyObject(array( 'Bucket' => $this->bucket, 'Key' => $path2 . '/', 'CopySource' => S3Client::encodeKey($this->bucket . '/' . $path1 . '/') )); $this->testTimeout(); } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + \OCP\Util::logException('files_external', $e); return false; } @@ -561,7 +574,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { } try { - $result = $this->connection->putObject(array( + $this->connection->putObject(array( 'Bucket' => $this->bucket, 'Key' => $this->cleanKey(self::$tmpFiles[$tmpFile]), 'SourceFile' => $tmpFile, @@ -572,7 +585,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { unlink($tmpFile); } catch (S3Exception $e) { - \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + \OCP\Util::logException('files_external', $e); return false; } } |