Moved dependencies out of Crypt methods (encKeyfileToMultipleUsers)(DI)
Fixed bug preventing sharing with users other than 'ownCloud' Added comments Moved functionality into filterShareReadyUsers() Other changes
This commit is contained in:
parent
14ae373dfe
commit
1b880f2f96
|
@ -20,7 +20,7 @@ OCP\Util::connectHook( 'OCP\Share', 'post_unshare', 'OCA\Encryption\Hooks', 'pos
|
||||||
OCP\Util::connectHook( 'OCP\Share', 'post_unshareAll', 'OCA\Encryption\Hooks', 'postUnshareAll' );
|
OCP\Util::connectHook( 'OCP\Share', 'post_unshareAll', 'OCA\Encryption\Hooks', 'postUnshareAll' );
|
||||||
|
|
||||||
// Webdav-related hooks
|
// Webdav-related hooks
|
||||||
OCP\Util::connectHook( 'OC_Webdav_Properties', 'update', 'OCA\Encryption\Hooks', 'updateKeyfile' );
|
OCP\Util::connectHook( 'OC_Webdav_Properties', 'update', 'OCA\Encryption\Hooks', 'updateKeyfileFromClient' );
|
||||||
|
|
||||||
stream_wrapper_register( 'crypt', 'OCA\Encryption\Stream' );
|
stream_wrapper_register( 'crypt', 'OCA\Encryption\Stream' );
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ class Hooks {
|
||||||
/**
|
/**
|
||||||
* @brief update the encryption key of the file uploaded by the client
|
* @brief update the encryption key of the file uploaded by the client
|
||||||
*/
|
*/
|
||||||
public static function updateKeyfile( $params ) {
|
public static function updateKeyfileFromClient( $params ) {
|
||||||
|
|
||||||
if ( Crypt::mode() == 'client' ) {
|
if ( Crypt::mode() == 'client' ) {
|
||||||
|
|
||||||
|
@ -175,12 +175,13 @@ class Hooks {
|
||||||
// uidOwner -> owner of the original file being shared
|
// uidOwner -> owner of the original file being shared
|
||||||
|
|
||||||
$view = new \OC_FilesystemView( '/' );
|
$view = new \OC_FilesystemView( '/' );
|
||||||
|
$session = new Session();
|
||||||
$userId = \OCP\User::getUser();
|
$userId = \OCP\User::getUser();
|
||||||
$util = new Util( $view, $userId );
|
$util = new Util( $view, $userId );
|
||||||
|
|
||||||
$path = Util::getFilePath($params['itemSource']);
|
$path = Util::getFilePath( $params['itemSource'] );
|
||||||
|
|
||||||
return Crypt::updateKeyfile($path);
|
return Crypt::updateKeyfile( $view, $session, $path );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,18 +189,26 @@ class Hooks {
|
||||||
* @brief
|
* @brief
|
||||||
*/
|
*/
|
||||||
public static function postUnshare( $params ) {
|
public static function postUnshare( $params ) {
|
||||||
$path = Util::getFilePath($params['itemSource']);
|
|
||||||
|
$view = new \OC_FilesystemView( '/' );
|
||||||
|
$session = new Session();
|
||||||
|
$path = Util::getFilePath( $params['itemSource'] );
|
||||||
|
|
||||||
|
return Crypt::updateKeyfile( $view, $session, $path );
|
||||||
|
|
||||||
return Crypt::updateKeyfile($path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*/
|
*/
|
||||||
public static function postUnshareAll( $params ) {
|
public static function postUnshareAll( $params ) {
|
||||||
$path = Util::getFilePath($params['itemSource']);
|
|
||||||
|
$view = new \OC_FilesystemView( '/' );
|
||||||
|
$session = new Session();
|
||||||
|
$path = Util::getFilePath( $params['itemSource'] );
|
||||||
|
|
||||||
|
return Crypt::updateKeyfile( $view, $session, $path );
|
||||||
|
|
||||||
return Crypt::updateKeyfile($path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -746,52 +746,44 @@ class Crypt {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief encrypt file key to multiple users
|
* @brief Encrypt keyfile to multiple users
|
||||||
* @param $users list of users which should be able to access the file
|
* @param array $users list of users which should be able to access the file
|
||||||
* @param $fileTarget target of the file
|
* @param string $filePath path of the file to be shared
|
||||||
*/
|
*/
|
||||||
private static function encKeyfileToMultipleUsers($users, $filePath) {
|
private static function encKeyfileToMultipleUsers( \OC_FilesystemView $view, Util $util, Session $session, $userId, array $users, $filePath ) {
|
||||||
$view = new \OC_FilesystemView( '/' );
|
|
||||||
$owner = \OCP\User::getUser();
|
// Make sure users are capable of sharing
|
||||||
$util = new Util( $view, $userId );
|
$filteredUids = $util->filterShareReadyUsers( $users );
|
||||||
$session = new Session();
|
|
||||||
|
|
||||||
$userIds = array();
|
// Get public keys for each user, ready for generating sharekeys
|
||||||
|
$userPubKeys = Keymanager::getPublicKeys( $view, $filteredUids ); // TODO: check this includes the owner's public key
|
||||||
foreach ( $users as $user ) {
|
|
||||||
|
|
||||||
$util = new Util( $view, $user );
|
|
||||||
|
|
||||||
// Check that the user is encryption capable
|
|
||||||
if ( $util->ready() && $user == 'ownCloud' ) {
|
|
||||||
// Construct array of just UIDs for Keymanager{}
|
|
||||||
$userIds[] = $user;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Log warning; we can't do necessary setup here
|
|
||||||
// because we don't have the user passphrase
|
|
||||||
// TODO: Provide user feedback indicating that
|
|
||||||
// sharing failed
|
|
||||||
\OC_Log::write( 'Encryption library', 'File cannot be shared: user "'.$user.'" is not setup for encryption', \OC_Log::WARN );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$userPubKeys = Keymanager::getPublicKeys( $view, $userIds );
|
|
||||||
|
|
||||||
\OC_FileProxy::$enabled = false;
|
\OC_FileProxy::$enabled = false;
|
||||||
|
|
||||||
// get the keyfile
|
// Get the current users's private key for decrypting existing keyfile
|
||||||
|
$privateKey = $session->getPrivateKey();
|
||||||
|
|
||||||
|
// We need to get a decrypted key for the file
|
||||||
|
// Determine how to decrypt the keyfile by checking if current user is owner
|
||||||
|
if ( $userId == \OC\Files\Filesystem::getOwner( $filePath ) ) {
|
||||||
|
|
||||||
|
// If current user is owner, decrypt without using sharekey
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Current user is resharing a file they don't own
|
||||||
|
// Decrypt keyfile using sharekey
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the existing keyfile
|
||||||
$encKeyfile = Keymanager::getFileKey( $view, $owner, $filePath );
|
$encKeyfile = Keymanager::getFileKey( $view, $owner, $filePath );
|
||||||
|
|
||||||
$privateKey = $session->getPrivateKey();
|
// decrypt the existing keyfile
|
||||||
|
|
||||||
// decrypt the keyfile
|
|
||||||
$plainKeyfile = Crypt::keyDecrypt( $encKeyfile, $privateKey );
|
$plainKeyfile = Crypt::keyDecrypt( $encKeyfile, $privateKey );
|
||||||
|
|
||||||
|
trigger_error("PUBKEYS = ". var_export($userPubKeys, 1));
|
||||||
|
|
||||||
// re-enc keyfile to sharekeys
|
// re-enc keyfile to sharekeys
|
||||||
$shareKeys = Crypt::multiKeyEncrypt( $plainKeyfile, $userPubKeys );
|
$shareKeys = Crypt::multiKeyEncrypt( $plainKeyfile, $userPubKeys );
|
||||||
|
|
||||||
|
@ -816,29 +808,42 @@ class Crypt {
|
||||||
* @param path which needs to be updated
|
* @param path which needs to be updated
|
||||||
* @return bool success
|
* @return bool success
|
||||||
*/
|
*/
|
||||||
public static function updateKeyfile($path) {
|
public static function updateKeyfile( \OC_FilesystemView $view, Util $util, Session $session, $path ) {
|
||||||
|
|
||||||
$filesView = \OCP\Files::getStorage('files');
|
// Make path include 'files' dir for OC_FSV operations
|
||||||
|
$fPath = 'files' . $path;
|
||||||
|
|
||||||
$result = true;
|
$result = true;
|
||||||
|
|
||||||
if ( $filesView->is_dir($path) ) {
|
if ( ! $view->is_dir( $fPath ) ) {
|
||||||
$content = $filesView->getDirectoryContent($path);
|
|
||||||
foreach ( $content as $c) {
|
$shares = \OCP\Share::getUsersSharingFile( $path, true );
|
||||||
|
$result = self::encKeyfileToMultipleUsers( $view, $util, $session, $shares, $path );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$content = $view->getDirectoryContent( $fPath );
|
||||||
|
|
||||||
|
foreach ( $content as $c ) {
|
||||||
|
|
||||||
$path = substr($c['path'], 5);
|
$path = substr($c['path'], 5);
|
||||||
if ( $filesView->is_dir($path) ) {
|
|
||||||
$result &= self::updateKeyfile($path);
|
if ( $view->is_dir( $fPath ) ) {
|
||||||
|
|
||||||
|
$result &= self::updateKeyfile( $path );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$shares = \OCP\Share::getUsersSharingFile( $path, true );
|
$shares = \OCP\Share::getUsersSharingFile( $path, true );
|
||||||
$result &= self::encKeyfileToMultipleUsers($shares, $path);
|
$result &= self::encKeyfileToMultipleUsers( $view, $util, $session, $shares, $path );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$shares = \OCP\Share::getUsersSharingFile( $path, true );
|
|
||||||
$result = self::encKeyfileToMultipleUsers($shares, $path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -486,5 +486,46 @@ class Util {
|
||||||
$row = $result->fetchRow();
|
$row = $result->fetchRow();
|
||||||
return substr($row['path'], 5);
|
return substr($row['path'], 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Filter an array of UIDs to return only ones ready for sharing
|
||||||
|
* @param array $unfilteredUsers users to be checked for sharing readiness
|
||||||
|
* @return array $userIds filtered users
|
||||||
|
*/
|
||||||
|
public function filterShareReadyUsers( $unfilteredUsers ) {
|
||||||
|
|
||||||
|
// This array will collect the filtered IDs
|
||||||
|
$userIds = array();
|
||||||
|
|
||||||
|
// Loop through users and create array of UIDs that need new keyfiles
|
||||||
|
foreach ( $unfilteredUsers as $user ) {
|
||||||
|
|
||||||
|
$util = new Util( $this->view, $user );
|
||||||
|
|
||||||
|
// Check that the user is encryption capable, or is the
|
||||||
|
// public system user 'ownCloud' (for public shares)
|
||||||
|
if (
|
||||||
|
$util->ready()
|
||||||
|
or $user == 'ownCloud'
|
||||||
|
) {
|
||||||
|
|
||||||
|
// Construct array of just UIDs for Keymanager{}
|
||||||
|
$userIds[] = $user;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Log warning; we can't do necessary setup here
|
||||||
|
// because we don't have the user passphrase
|
||||||
|
// TODO: Provide user feedback indicating that
|
||||||
|
// sharing failed
|
||||||
|
\OC_Log::write( 'Encryption library', '"'.$user.'" is not setup for encryption', \OC_Log::WARN );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $userIds;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue