Added pre_share hook

Switched it for post_share hook in encryption hooks
Stop a file from being shared if the encryption procedure fails for any users
This commit is contained in:
Sam Tuke 2013-05-08 16:22:08 +02:00
parent fdc49e7acb
commit 28866de44b
4 changed files with 130 additions and 67 deletions

View File

@ -16,7 +16,7 @@ OCP\Util::connectHook( 'OC_User', 'post_login', 'OCA\Encryption\Hooks', 'login'
OCP\Util::connectHook( 'OC_User', 'pre_setPassword', 'OCA\Encryption\Hooks', 'setPassphrase' ); OCP\Util::connectHook( 'OC_User', 'pre_setPassword', 'OCA\Encryption\Hooks', 'setPassphrase' );
// Sharing-related hooks // Sharing-related hooks
OCP\Util::connectHook( 'OCP\Share', 'post_shared', 'OCA\Encryption\Hooks', 'postShared' ); OCP\Util::connectHook( 'OCP\Share', 'pre_shared', 'OCA\Encryption\Hooks', 'preShared' );
OCP\Util::connectHook( 'OCP\Share', 'post_unshare', 'OCA\Encryption\Hooks', 'postUnshare' ); OCP\Util::connectHook( 'OCP\Share', 'post_unshare', 'OCA\Encryption\Hooks', 'postUnshare' );
OCP\Util::connectHook( 'OCP\Share', 'post_unshareAll', 'OCA\Encryption\Hooks', 'postUnshareAll' ); OCP\Util::connectHook( 'OCP\Share', 'post_unshareAll', 'OCA\Encryption\Hooks', 'postUnshareAll' );

View File

@ -183,7 +183,7 @@ class Hooks {
/** /**
* @brief * @brief
*/ */
public static function postShared( $params ) { public static function preShared( $params ) {
// NOTE: $params has keys: // NOTE: $params has keys:
// [itemType] => file // [itemType] => file
@ -201,6 +201,7 @@ class Hooks {
// [fileTarget] => /test8 // [fileTarget] => /test8
// [id] => 10 // [id] => 10
// [token] => // [token] =>
// [run] => whether emitting script should continue to run
// TODO: Should other kinds of item be encrypted too? // TODO: Should other kinds of item be encrypted too?
if ( $params['itemType'] === 'file' || $params['itemType'] === 'folder' ) { if ( $params['itemType'] === 'file' || $params['itemType'] === 'folder' ) {
@ -249,7 +250,7 @@ class Hooks {
// rebuild path // rebuild path
foreach ( $targetPathSplit as $pathPart ) { foreach ( $targetPathSplit as $pathPart ) {
if( $pathPart !== $sharedPart ) { if ( $pathPart !== $sharedPart ) {
$path = '/' . $pathPart . $path; $path = '/' . $pathPart . $path;
@ -295,15 +296,13 @@ class Hooks {
$failed[] = $path; $failed[] = $path;
} }
} }
// If no attempts to set keyfiles failed
if ( empty( $failed ) ) {
return true; // If some attempts to set keyfiles failed
if ( ! empty( $failed ) ) {
} else { // Set flag var 'run' to notify emitting
// script that hook execution failed
return false; $params['run']->run = false;
} }
} }

View File

@ -146,7 +146,7 @@ class Util {
return false; return false;
} else { } else {
return true; return true;
} }
@ -855,15 +855,14 @@ class Util {
* @param string $filePath path of the file to be shared * @param string $filePath path of the file to be shared
*/ */
public function setSharedFileKeyfiles( Session $session, array $users, $filePath ) { public function setSharedFileKeyfiles( Session $session, array $users, $filePath ) {
// Make sure users are capable of sharing // Make sure users are capable of sharing
$filteredUids = $this->filterShareReadyUsers( $users ); $filteredUids = $this->filterShareReadyUsers( $users );
if ( ! empty( $filteredUids['unready'] ) ) { if ( ! empty( $filteredUids['unready'] ) ) {
// Notify user of unready userDir // TODO: Notify user of unready userDir
// TODO: Move this out of here; it belongs somewhere else \OC_Log::write( 'Encryption library', 'Sharing to these user(s) failed as they are unready for encryption:"'.print_r( $filteredUids['unready'], 1 ), \OC_Log::WARN );
\OCP\JSON::error();
} }

View File

@ -1223,42 +1223,12 @@ class Share {
} else { } else {
$groupFileTarget = null; $groupFileTarget = null;
} }
$query->execute(array($itemType, $itemSource, $groupItemTarget, $parent, $shareType, // Trigger hooks before the share is added to DB
$shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget, $token)); // Set flag indicating if execution should continue.
// Save this id, any extra rows for this group share will need to reference it // Use an object as workaround for pass by reference issues
$parent = \OC_DB::insertid('*PREFIX*share'); $run = new \stdClass();
// Loop through all users of this group in case we need to add an extra row $run->run = true;
foreach ($shareWith['users'] as $uid) { $params = array(
$itemTarget = self::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $uid,
$uidOwner, $suggestedItemTarget, $parent);
if (isset($fileSource)) {
if ($parentFolder) {
if ($parentFolder === true) {
$fileTarget = self::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $uid,
$uidOwner, $suggestedFileTarget, $parent);
if ($fileTarget != $groupFileTarget) {
$parentFolders[$uid]['folder'] = $fileTarget;
}
} else if (isset($parentFolder[$uid])) {
$fileTarget = $parentFolder[$uid]['folder'].$itemSource;
$parent = $parentFolder[$uid]['id'];
}
} else {
$fileTarget = self::generateTarget('file', $filePath, self::SHARE_TYPE_USER,
$uid, $uidOwner, $suggestedFileTarget, $parent);
}
} else {
$fileTarget = null;
}
// Insert an extra row for the group share if the item or file target is unique for this user
if ($itemTarget != $groupItemTarget || (isset($fileSource) && $fileTarget != $groupFileTarget)) {
$query->execute(array($itemType, $itemSource, $itemTarget, $parent,
self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(),
$fileSource, $fileTarget, $token));
$id = \OC_DB::insertid('*PREFIX*share');
}
}
\OC_Hook::emit('OCP\Share', 'post_shared', array(
'itemType' => $itemType, 'itemType' => $itemType,
'itemSource' => $itemSource, 'itemSource' => $itemSource,
'itemTarget' => $groupItemTarget, 'itemTarget' => $groupItemTarget,
@ -1270,11 +1240,73 @@ class Share {
'fileSource' => $fileSource, 'fileSource' => $fileSource,
'fileTarget' => $groupFileTarget, 'fileTarget' => $groupFileTarget,
'id' => $parent, 'id' => $parent,
'token' => $token 'token' => $token,
)); 'run' => $run
if ($parentFolder === true) { );
// Return parent folders to preserve file target paths for potential children $run = \OC_Hook::emit(
return $parentFolders; 'OCP\Share'
, 'pre_shared'
, $params
);
// If hook execution didn't encounter errors
if ( ! $run->run ) {
$message = 'Sharing '.$itemSource.' failed, because pre share hooks failed';
\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
return false;
} else {
$query->execute(array($itemType, $itemSource, $groupItemTarget, $parent, $shareType,
$shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget, $token));
// Save this id, any extra rows for this group share will need to reference it
$parent = \OC_DB::insertid('*PREFIX*share');
// Loop through all users of this group in case we need to add an extra row
foreach ($shareWith['users'] as $uid) {
$itemTarget = self::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $uid,
$uidOwner, $suggestedItemTarget, $parent);
if (isset($fileSource)) {
if ($parentFolder) {
if ($parentFolder === true) {
$fileTarget = self::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $uid,
$uidOwner, $suggestedFileTarget, $parent);
if ($fileTarget != $groupFileTarget) {
$parentFolders[$uid]['folder'] = $fileTarget;
}
} else if (isset($parentFolder[$uid])) {
$fileTarget = $parentFolder[$uid]['folder'].$itemSource;
$parent = $parentFolder[$uid]['id'];
}
} else {
$fileTarget = self::generateTarget('file', $filePath, self::SHARE_TYPE_USER,
$uid, $uidOwner, $suggestedFileTarget, $parent);
}
} else {
$fileTarget = null;
}
// Insert an extra row for the group share if the item or file target is unique for this user
if ($itemTarget != $groupItemTarget || (isset($fileSource) && $fileTarget != $groupFileTarget)) {
$query->execute(array($itemType, $itemSource, $itemTarget, $parent,
self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(),
$fileSource, $fileTarget, $token));
$id = \OC_DB::insertid('*PREFIX*share');
}
}
\OC_Hook::emit('OCP\Share', 'post_shared', array(
'itemType' => $itemType,
'itemSource' => $itemSource,
'itemTarget' => $groupItemTarget,
'parent' => $parent,
'shareType' => $shareType,
'shareWith' => $shareWith['group'],
'uidOwner' => $uidOwner,
'permissions' => $permissions,
'fileSource' => $fileSource,
'fileTarget' => $groupFileTarget,
'id' => $parent,
'token' => $token
));
if ($parentFolder === true) {
// Return parent folders to preserve file target paths for potential children
return $parentFolders;
}
} }
} else { } else {
$itemTarget = self::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $itemTarget = self::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
@ -1296,10 +1328,14 @@ class Share {
} else { } else {
$fileTarget = null; $fileTarget = null;
} }
$query->execute(array($itemType, $itemSource, $itemTarget, $parent, $shareType, $shareWith, $uidOwner, // Trigger hooks before the share is added to DB
$permissions, time(), $fileSource, $fileTarget, $token)); // Set flag indicating if execution should continue.
$id = \OC_DB::insertid('*PREFIX*share'); // Use an object as workaround for pass by reference issues
\OC_Hook::emit('OCP\Share', 'post_shared', array( $run = new \stdClass();
$run->run = true;
// NOTE: [id] isn't included as it's not yet available
// (hasn't been inserted)
$params = array(
'itemType' => $itemType, 'itemType' => $itemType,
'itemSource' => $itemSource, 'itemSource' => $itemSource,
'itemTarget' => $itemTarget, 'itemTarget' => $itemTarget,
@ -1310,13 +1346,42 @@ class Share {
'permissions' => $permissions, 'permissions' => $permissions,
'fileSource' => $fileSource, 'fileSource' => $fileSource,
'fileTarget' => $fileTarget, 'fileTarget' => $fileTarget,
'id' => $id, 'token' => $token,
'token' => $token 'run' => $run
)); );
if ($parentFolder === true) { \OC_Hook::emit(
$parentFolders['id'] = $id; 'OCP\Share'
// Return parent folder to preserve file target paths for potential children , 'pre_shared'
return $parentFolders; , $params
);
// If hook execution didn't encounter errors
if ( ! $run->run ) {
$message = 'Sharing '.$itemSource.' failed, because pre share hooks failed';
\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
return false;
} else {
$query->execute(array($itemType, $itemSource, $itemTarget, $parent, $shareType, $shareWith, $uidOwner,
$permissions, time(), $fileSource, $fileTarget, $token));
$id = \OC_DB::insertid('*PREFIX*share');
\OC_Hook::emit('OCP\Share', 'post_shared', array(
'itemType' => $itemType,
'itemSource' => $itemSource,
'itemTarget' => $itemTarget,
'parent' => $parent,
'shareType' => $shareType,
'shareWith' => $shareWith,
'uidOwner' => $uidOwner,
'permissions' => $permissions,
'fileSource' => $fileSource,
'fileTarget' => $fileTarget,
'id' => $id,
'token' => $token
));
if ($parentFolder === true) {
$parentFolders['id'] = $id;
// Return parent folder to preserve file target paths for potential children
return $parentFolders;
}
} }
} }
return true; return true;