helper.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <?php
  2. /**
  3. * ownCloud
  4. *
  5. * @author Bjoern Schiessle
  6. * @copyright 2014 Bjoern Schiessle <schiessle@owncloud.com>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  10. * License as published by the Free Software Foundation; either
  11. * version 3 of the License, or any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public
  19. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. namespace OC\Share;
  22. class Helper extends \OC\Share\Constants {
  23. /**
  24. * Generate a unique target for the item
  25. * @param string $itemType
  26. * @param string $itemSource
  27. * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
  28. * @param string $shareWith User or group the item is being shared with
  29. * @param string $uidOwner User that is the owner of shared item
  30. * @param string $suggestedTarget The suggested target originating from a reshare (optional)
  31. * @param int $groupParent The id of the parent group share (optional)
  32. * @throws \Exception
  33. * @return string Item target
  34. */
  35. public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
  36. $suggestedTarget = null, $groupParent = null) {
  37. $backend = \OC\Share\Share::getBackend($itemType);
  38. if ($shareType == self::SHARE_TYPE_LINK) {
  39. if (isset($suggestedTarget)) {
  40. return $suggestedTarget;
  41. }
  42. return $backend->generateTarget($itemSource, false);
  43. } else {
  44. if ($itemType == 'file' || $itemType == 'folder') {
  45. $column = 'file_target';
  46. $columnSource = 'file_source';
  47. } else {
  48. $column = 'item_target';
  49. $columnSource = 'item_source';
  50. }
  51. if ($shareType == self::SHARE_TYPE_USER) {
  52. // Share with is a user, so set share type to user and groups
  53. $shareType = self::$shareTypeUserAndGroups;
  54. $userAndGroups = array_merge(array($shareWith), \OC_Group::getUserGroups($shareWith));
  55. } else {
  56. $userAndGroups = false;
  57. }
  58. $exclude = null;
  59. // Backend has 3 opportunities to generate a unique target
  60. for ($i = 0; $i < 2; $i++) {
  61. // Check if suggested target exists first
  62. if ($i == 0 && isset($suggestedTarget)) {
  63. $target = $suggestedTarget;
  64. } else {
  65. if ($shareType == self::SHARE_TYPE_GROUP) {
  66. $target = $backend->generateTarget($itemSource, false, $exclude);
  67. } else {
  68. $target = $backend->generateTarget($itemSource, $shareWith, $exclude);
  69. }
  70. if (is_array($exclude) && in_array($target, $exclude)) {
  71. break;
  72. }
  73. }
  74. // Check if target already exists
  75. $checkTarget = \OC\Share\Share::getItems($itemType, $target, $shareType, $shareWith);
  76. if (!empty($checkTarget)) {
  77. foreach ($checkTarget as $item) {
  78. // Skip item if it is the group parent row
  79. if (isset($groupParent) && $item['id'] == $groupParent) {
  80. if (count($checkTarget) == 1) {
  81. return $target;
  82. } else {
  83. continue;
  84. }
  85. }
  86. if ($item['uid_owner'] == $uidOwner) {
  87. if ($itemType == 'file' || $itemType == 'folder') {
  88. $meta = \OC\Files\Filesystem::getFileInfo($itemSource);
  89. if ($item['file_source'] == $meta['fileid']) {
  90. return $target;
  91. }
  92. } else if ($item['item_source'] == $itemSource) {
  93. return $target;
  94. }
  95. }
  96. }
  97. if (!isset($exclude)) {
  98. $exclude = array();
  99. }
  100. // Find similar targets to improve backend's chances to generate a unqiue target
  101. if ($userAndGroups) {
  102. if ($column == 'file_target') {
  103. $checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
  104. .' WHERE `item_type` IN (\'file\', \'folder\')'
  105. .' AND `share_type` IN (?,?,?)'
  106. .' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')');
  107. $result = $checkTargets->execute(array(self::SHARE_TYPE_USER, self::SHARE_TYPE_GROUP,
  108. self::$shareTypeGroupUserUnique));
  109. } else {
  110. $checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
  111. .' WHERE `item_type` = ? AND `share_type` IN (?,?,?)'
  112. .' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')');
  113. $result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_USER,
  114. self::SHARE_TYPE_GROUP, self::$shareTypeGroupUserUnique));
  115. }
  116. } else {
  117. if ($column == 'file_target') {
  118. $checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
  119. .' WHERE `item_type` IN (\'file\', \'folder\')'
  120. .' AND `share_type` = ? AND `share_with` = ?');
  121. $result = $checkTargets->execute(array(self::SHARE_TYPE_GROUP, $shareWith));
  122. } else {
  123. $checkTargets = \OC_DB::prepare('SELECT `'.$column.'` FROM `*PREFIX*share`'
  124. .' WHERE `item_type` = ? AND `share_type` = ? AND `share_with` = ?');
  125. $result = $checkTargets->execute(array($itemType, self::SHARE_TYPE_GROUP, $shareWith));
  126. }
  127. }
  128. while ($row = $result->fetchRow()) {
  129. $exclude[] = $row[$column];
  130. }
  131. } else {
  132. return $target;
  133. }
  134. }
  135. }
  136. $message = 'Sharing backend registered for '.$itemType.' did not generate a unique target for '.$itemSource;
  137. \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
  138. throw new \Exception($message);
  139. }
  140. /**
  141. * Delete all reshares of an item
  142. * @param int $parent Id of item to delete
  143. * @param bool $excludeParent If true, exclude the parent from the delete (optional)
  144. * @param string $uidOwner The user that the parent was shared with (optional)
  145. */
  146. public static function delete($parent, $excludeParent = false, $uidOwner = null) {
  147. $ids = array($parent);
  148. $deletedItems = array();
  149. $parents = array($parent);
  150. while (!empty($parents)) {
  151. $parents = "'".implode("','", $parents)."'";
  152. // Check the owner on the first search of reshares, useful for
  153. // finding and deleting the reshares by a single user of a group share
  154. if (count($ids) == 1 && isset($uidOwner)) {
  155. $query = \OC_DB::prepare('SELECT `id`, `share_with`, `item_type`, `share_type`, `item_target`, `file_target`, `parent`'
  156. .' FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.') AND `uid_owner` = ?');
  157. $result = $query->execute(array($uidOwner));
  158. } else {
  159. $query = \OC_DB::prepare('SELECT `id`, `share_with`, `item_type`, `share_type`, `item_target`, `file_target`, `parent`, `uid_owner`'
  160. .' FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.')');
  161. $result = $query->execute();
  162. }
  163. // Reset parents array, only go through loop again if items are found
  164. $parents = array();
  165. while ($item = $result->fetchRow()) {
  166. $ids[] = $item['id'];
  167. $parents[] = $item['id'];
  168. $tmpItem = array(
  169. 'id' => $item['id'],
  170. 'shareWith' => $item['share_with'],
  171. 'itemTarget' => $item['item_target'],
  172. 'itemType' => $item['item_type'],
  173. 'shareType' => (int)$item['share_type'],
  174. );
  175. if (isset($item['file_target'])) {
  176. $tmpItem['fileTarget'] = $item['file_target'];
  177. }
  178. $deletedItems[] = $tmpItem;
  179. }
  180. }
  181. if ($excludeParent) {
  182. unset($ids[0]);
  183. }
  184. if (!empty($ids)) {
  185. $idList = "'".implode("','", $ids)."'";
  186. $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` IN ('.$idList.')');
  187. $query->execute();
  188. }
  189. return $deletedItems;
  190. }
  191. /**
  192. * get default expire settings defined by the admin
  193. * @return array contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
  194. */
  195. public static function getDefaultExpireSetting() {
  196. $defaultExpireSettings = array('defaultExpireDateSet' => false);
  197. // get default expire settings
  198. $defaultExpireDate = \OC_Appconfig::getValue('core', 'shareapi_default_expire_date', 'no');
  199. if ($defaultExpireDate === 'yes') {
  200. $enforceExpireDate = \OC_Appconfig::getValue('core', 'shareapi_enforce_expire_date', 'no');
  201. $defaultExpireSettings['defaultExpireDateSet'] = true;
  202. $defaultExpireSettings['expireAfterDays'] = (int)\OC_Appconfig::getValue('core', 'shareapi_expire_after_n_days', '7');
  203. $defaultExpireSettings['enforceExpireDate'] = $enforceExpireDate === 'yes' ? true : false;
  204. }
  205. return $defaultExpireSettings;
  206. }
  207. public static function calcExpireDate() {
  208. $expireAfter = \OC\Share\Share::getExpireInterval() * 24 * 60 * 60;
  209. $expireAt = time() + $expireAfter;
  210. $date = new \DateTime();
  211. $date->setTimestamp($expireAt);
  212. $date->setTime(0, 0, 0);
  213. //$dateString = $date->format('Y-m-d') . ' 00:00:00';
  214. return $date;
  215. }
  216. /**
  217. * calculate expire date
  218. * @param array $defaultExpireSettings contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
  219. * @param int $creationTime timestamp when the share was created
  220. * @param int $userExpireDate expire timestamp set by the user
  221. * @return mixed integer timestamp or False
  222. */
  223. public static function calculateExpireDate($defaultExpireSettings, $creationTime, $userExpireDate = null) {
  224. $expires = false;
  225. if (!empty($defaultExpireSettings['defaultExpireDateSet'])) {
  226. $expires = $creationTime + $defaultExpireSettings['expireAfterDays'] * 86400;
  227. }
  228. if (isset($userExpireDate)) {
  229. // if the admin decided to enforce the default expire date then we only take
  230. // the user defined expire date of it is before the default expire date
  231. if ($expires && !empty($defaultExpireSettings['enforceExpireDate'])) {
  232. $expires = min($userExpireDate, $expires);
  233. } else {
  234. $expires = $userExpireDate;
  235. }
  236. }
  237. return $expires;
  238. }
  239. }