From d5808f07ca729c99482a44aa3e320ad5060cb86a Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle <schiessle@owncloud.com>
Date: Fri, 3 Aug 2012 11:49:55 +0200
Subject: [PATCH] return a list of all public keys for a given file

---
 apps/files_encryption/lib/crypt.php      |  9 +++--
 apps/files_encryption/lib/keymanager.php | 44 +++++++++++++++++++++---
 lib/ocs.php                              | 37 +++++++++-----------
 3 files changed, 61 insertions(+), 29 deletions(-)

diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php
index 90b24dc8ddb..64bbc17ec11 100644
--- a/apps/files_encryption/lib/crypt.php
+++ b/apps/files_encryption/lib/crypt.php
@@ -38,8 +38,11 @@ class Crypt {
 	public static function mode( $user = null ) {
 		
 		$mode = \OC_Appconfig::getValue( 'files_encryption', 'mode', 'none' );
-		
-		if ( $mode == 'user') {
+
+		if ( $mode == 'user') {
+			if ( !$user ) {
+				$user = \OCP\User::getUser();
+			}
 			$mode = 'none';
 			if ( $user ) {
 				$query = \OC_DB::prepare( "SELECT mode FROM *PREFIX*encryption WHERE uid = ?" );
@@ -49,7 +52,7 @@ class Crypt {
 				}
 			}
 		}
-		
+
 		return $mode;
 	}
 	
diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php
index 7f67fc7e5ea..6e3dcaf0ad9 100644
--- a/apps/files_encryption/lib/keymanager.php
+++ b/apps/files_encryption/lib/keymanager.php
@@ -43,14 +43,48 @@ class Keymanager {
 	}
 	
 	/**
-	 * @brief retrieve public key from a user
+	 * @brief retrieve a list of the public key from all users with access to the file
 	 *
-	 * @param string user name
-	 * @return string private key or false
+	 * @param string path to file
+	 * @return array of public keys for the given file
 	 */
-	public static function getPublicKey($user) {
+	public static function getPublicKeys($path) {
+		$userId = \OCP\User::getUser();
+		$path = ltrim( $path, '/' );
+		$filepath = '/'.$userId.'/files/'.$path;
+		
+		// check if file was shared with other users
+		$query = \OC_DB::prepare( "SELECT uid_owner, source, target, uid_shared_with FROM `*PREFIX*sharing` WHERE ( target = ? AND uid_shared_with = ? ) OR source = ? " );
+		$result = $query->execute( array ($filepath, $userId, $filepath));
+		$users = array();
+		if ($row = $result->fetchRow()){
+			$source = $row['source'];
+			$owner = $row['uid_owner'];
+			$users[] = $owner;
+			// get the uids of all user with access to the file
+			$query = \OC_DB::prepare( "SELECT source, uid_shared_with FROM `*PREFIX*sharing` WHERE source = ?" );
+			$result = $query->execute( array ($source));
+			while ( ($row = $result->fetchRow()) ) {
+				$users[] = $row['uid_shared_with'];
+			}
+		} else {
+			// check if it is a file owned by the user and not shared at all
+			$userview = new \OC_FilesystemView( '/'.$userId.'/files/' );
+			if ($userview->file_exists($path)) {
+				$users[] = $userId;
+			}
+		}
+		
 		$view = new \OC_FilesystemView( '/public-keys/' );
-		return $view->file_get_contents($user.'.public.key');
+		
+		$keylist = array();
+		$count = 0;
+		foreach ($users as $user) {
+			$keylist['key'.++$count] = $view->file_get_contents($user.'.public.key');
+		}
+
+		return $keylist;
+		
 	}
 	
 	/**
diff --git a/lib/ocs.php b/lib/ocs.php
index 17ae649deb6..6617beb8066 100644
--- a/lib/ocs.php
+++ b/lib/ocs.php
@@ -169,9 +169,9 @@ class OC_OCS {
 			OC_OCS::quotaset($format,$user,$quota);
 
 		// keygetpublic 
-		}elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){
-			$user=$ex[$paracount-3];
-			OC_OCS::publicKeyGet($format,$user);
+		}elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'file') and ($ex[$paracount-2] == 'publickeys')){
+			$file=urldecode($ex[$paracount-3]);
+			OC_OCS::publicKeyGet($format,$file);
 
 		//keysetpublic
 		}elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){
@@ -671,27 +671,22 @@ class OC_OCS {
         /**
         * get the public key of a user
         * @param string $format
-        * @param string $user
-        * @return string xml/json
+        * @param string $file
+        * @return string xml/json list of public keys
         */
-        private static function publicKeyGet($format, $user) {
+        private static function publicKeyGet($format, $file) {
         	$login=OC_OCS::checkpassword();
-        	if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') {
-        		if(OC_User::userExists($user)){
-        			if (($key = OCA_Encryption\Keymanager::getPublicKey($user))) {
-        				$xml=array();
-        				$xml['key'] = $key;
-        				$txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
-        				echo($txt);
-        			}
-        			else {
-        				echo self::generateXml('', 'fail', 404, 'public key does not exist');
-        			}
-        		} else {
-        			echo self::generateXml('', 'fail', 300, 'User does not exist');
+        	if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode() === 'client') {
+        		if (($keys = OCA_Encryption\Keymanager::getPublicKeys($file))) {
+        			$xml=$keys;
+        			$txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
+        			echo($txt);
+        		}
+        		else {
+        			echo self::generateXml('', 'fail', 404, 'public key does not exist');
         		}
         	} else {
-        		echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user);
+        		echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled');
         	}
         }
 
@@ -782,7 +777,7 @@ class OC_OCS {
 				if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') {
 					if (($key = OCA_Encryption\Keymanager::getFileKey($user, $file))) {
 						$xml=array();
-						$xml['key']=$key;
+						$xml['key']=$key;					
 						$txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
 						echo($txt);
 					} else {
-- 
GitLab