share.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  6. * @author Bart Visscher <bartv@thisnet.nl>
  7. * @author Björn Schießle <bjoern@schiessle.org>
  8. * @author Craig Morrissey <craig@owncloud.com>
  9. * @author dampfklon <me@dampfklon.de>
  10. * @author Felix Böhm <felixboehm@gmx.de>
  11. * @author Joas Schilling <coding@schilljs.com>
  12. * @author Leonardo Diez <leio10@users.noreply.github.com>
  13. * @author Lukas Reschke <lukas@statuscode.ch>
  14. * @author Michael Gapczynski <GapczynskiM@gmail.com>
  15. * @author Morris Jobke <hey@morrisjobke.de>
  16. * @author Ramiro Aparicio <rapariciog@gmail.com>
  17. * @author Robin Appelman <robin@icewind.nl>
  18. * @author Roeland Jago Douma <roeland@famdouma.nl>
  19. * @author Thomas Müller <thomas.mueller@tmit.eu>
  20. * @author Thomas Tanghus <thomas@tanghus.net>
  21. *
  22. * @license AGPL-3.0
  23. *
  24. * This code is free software: you can redistribute it and/or modify
  25. * it under the terms of the GNU Affero General Public License, version 3,
  26. * as published by the Free Software Foundation.
  27. *
  28. * This program is distributed in the hope that it will be useful,
  29. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  31. * GNU Affero General Public License for more details.
  32. *
  33. * You should have received a copy of the GNU Affero General Public License, version 3,
  34. * along with this program. If not, see <http://www.gnu.org/licenses/>
  35. *
  36. */
  37. use OCP\IUser;
  38. OC_JSON::checkLoggedIn();
  39. OCP\JSON::callCheck();
  40. $defaults = new \OCP\Defaults();
  41. if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSource'])) {
  42. switch ($_POST['action']) {
  43. case 'informRecipients':
  44. $l = \OC::$server->getL10N('core');
  45. $shareType = (int) $_POST['shareType'];
  46. $itemType = (string)$_POST['itemType'];
  47. $itemSource = (string)$_POST['itemSource'];
  48. $recipient = (string)$_POST['recipient'];
  49. $userManager = \OC::$server->getUserManager();
  50. $recipientList = [];
  51. if($shareType === \OCP\Share::SHARE_TYPE_USER) {
  52. $recipientList[] = $userManager->get($recipient);
  53. } elseif ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
  54. $recipientList = \OC_Group::usersInGroup($recipient);
  55. $group = \OC::$server->getGroupManager()->get($recipient);
  56. $recipientList = $group->searchUsers('');
  57. }
  58. // don't send a mail to the user who shared the file
  59. $recipientList = array_filter($recipientList, function($user) {
  60. /** @var IUser $user */
  61. return $user->getUID() !== \OCP\User::getUser();
  62. });
  63. $mailNotification = new \OC\Share\MailNotifications(
  64. \OC::$server->getUserSession()->getUser(),
  65. \OC::$server->getL10N('lib'),
  66. \OC::$server->getMailer(),
  67. \OC::$server->getLogger(),
  68. $defaults,
  69. \OC::$server->getURLGenerator()
  70. );
  71. $result = $mailNotification->sendInternalShareMail($recipientList, $itemSource, $itemType);
  72. \OCP\Share::setSendMailStatus($itemType, $itemSource, $shareType, $recipient, true);
  73. if (empty($result)) {
  74. OCP\JSON::success();
  75. } else {
  76. OCP\JSON::error(array(
  77. 'data' => array(
  78. 'message' => $l->t("Couldn't send mail to following users: %s ",
  79. implode(', ', $result)
  80. )
  81. )
  82. ));
  83. }
  84. break;
  85. case 'informRecipientsDisabled':
  86. $itemSource = (string)$_POST['itemSource'];
  87. $shareType = (int)$_POST['shareType'];
  88. $itemType = (string)$_POST['itemType'];
  89. $recipient = (string)$_POST['recipient'];
  90. \OCP\Share::setSendMailStatus($itemType, $itemSource, $shareType, $recipient, false);
  91. OCP\JSON::success();
  92. break;
  93. case 'email':
  94. // read post variables
  95. $link = (string)$_POST['link'];
  96. $file = (string)$_POST['file'];
  97. $to_address = (string)$_POST['toaddress'];
  98. $mailNotification = new \OC\Share\MailNotifications(
  99. \OC::$server->getUserSession()->getUser(),
  100. \OC::$server->getL10N('lib'),
  101. \OC::$server->getMailer(),
  102. \OC::$server->getLogger(),
  103. $defaults,
  104. \OC::$server->getURLGenerator()
  105. );
  106. $expiration = null;
  107. if (isset($_POST['expiration']) && $_POST['expiration'] !== '') {
  108. try {
  109. $date = new DateTime((string)$_POST['expiration']);
  110. $expiration = $date->getTimestamp();
  111. } catch (Exception $e) {
  112. \OCP\Util::writeLog('sharing', "Couldn't read date: " . $e->getMessage(), \OCP\Util::ERROR);
  113. }
  114. }
  115. $result = $mailNotification->sendLinkShareMail($to_address, $file, $link, $expiration);
  116. if(empty($result)) {
  117. // Get the token from the link
  118. $linkParts = explode('/', $link);
  119. $token = array_pop($linkParts);
  120. // Get the share for the token
  121. $share = \OCP\Share::getShareByToken($token, false);
  122. if ($share !== false) {
  123. $currentUser = \OC::$server->getUserSession()->getUser()->getUID();
  124. $file = '/' . ltrim($file, '/');
  125. // Check whether share belongs to the user and whether the file is the same
  126. if ($share['file_target'] === $file && $share['uid_owner'] === $currentUser) {
  127. // Get the path for the user
  128. $view = new \OC\Files\View('/' . $currentUser . '/files');
  129. $fileId = (int) $share['item_source'];
  130. $path = $view->getPath((int) $share['item_source']);
  131. if ($path !== null) {
  132. $event = \OC::$server->getActivityManager()->generateEvent();
  133. $event->setApp(\OCA\Files_Sharing\Activity::FILES_SHARING_APP)
  134. ->setType(\OCA\Files_Sharing\Activity::TYPE_SHARED)
  135. ->setAuthor($currentUser)
  136. ->setAffectedUser($currentUser)
  137. ->setObject('files', $fileId, $path)
  138. ->setSubject(\OCA\Files_Sharing\Activity::SUBJECT_SHARED_EMAIL, [$path, $to_address]);
  139. \OC::$server->getActivityManager()->publish($event);
  140. }
  141. }
  142. }
  143. \OCP\JSON::success();
  144. } else {
  145. $l = \OC::$server->getL10N('core');
  146. OCP\JSON::error(array(
  147. 'data' => array(
  148. 'message' => $l->t("Couldn't send mail to following users: %s ",
  149. implode(', ', $result)
  150. )
  151. )
  152. ));
  153. }
  154. break;
  155. }
  156. } else if (isset($_GET['fetch'])) {
  157. switch ($_GET['fetch']) {
  158. case 'getItemsSharedStatuses':
  159. if (isset($_GET['itemType'])) {
  160. $return = OCP\Share::getItemsShared((string)$_GET['itemType'], OCP\Share::FORMAT_STATUSES);
  161. is_array($return) ? OC_JSON::success(array('data' => $return)) : OC_JSON::error();
  162. }
  163. break;
  164. case 'getItem':
  165. if (isset($_GET['itemType'])
  166. && isset($_GET['itemSource'])
  167. && isset($_GET['checkReshare'])
  168. && isset($_GET['checkShares'])) {
  169. if ($_GET['checkReshare'] == 'true') {
  170. $reshare = OCP\Share::getItemSharedWithBySource(
  171. (string)$_GET['itemType'],
  172. (string)$_GET['itemSource'],
  173. OCP\Share::FORMAT_NONE,
  174. null,
  175. true
  176. );
  177. } else {
  178. $reshare = false;
  179. }
  180. if ($_GET['checkShares'] == 'true') {
  181. $shares = OCP\Share::getItemShared(
  182. (string)$_GET['itemType'],
  183. (string)$_GET['itemSource'],
  184. OCP\Share::FORMAT_NONE,
  185. null,
  186. true
  187. );
  188. } else {
  189. $shares = false;
  190. }
  191. OC_JSON::success(array('data' => array('reshare' => $reshare, 'shares' => $shares)));
  192. }
  193. break;
  194. case 'getShareWithEmail':
  195. $result = array();
  196. if (isset($_GET['search'])) {
  197. $cm = OC::$server->getContactsManager();
  198. if (!is_null($cm) && $cm->isEnabled()) {
  199. $contacts = $cm->search((string)$_GET['search'], array('FN', 'EMAIL'));
  200. foreach ($contacts as $contact) {
  201. if (!isset($contact['EMAIL'])) {
  202. continue;
  203. }
  204. $emails = $contact['EMAIL'];
  205. if (!is_array($emails)) {
  206. $emails = array($emails);
  207. }
  208. foreach($emails as $email) {
  209. $result[] = array(
  210. 'id' => $contact['id'],
  211. 'email' => $email,
  212. 'displayname' => $contact['FN'],
  213. );
  214. }
  215. }
  216. }
  217. }
  218. OC_JSON::success(array('data' => $result));
  219. break;
  220. case 'getShareWith':
  221. if (isset($_GET['search'])) {
  222. $shareWithinGroupOnly = OC\Share\Share::shareWithGroupMembersOnly();
  223. $shareWith = array();
  224. $groups = OC_Group::getGroups((string)$_GET['search']);
  225. if ($shareWithinGroupOnly) {
  226. $usergroups = OC_Group::getUserGroups(OC_User::getUser());
  227. $groups = array_intersect($groups, $usergroups);
  228. }
  229. $sharedUsers = [];
  230. $sharedGroups = [];
  231. if (isset($_GET['itemShares'])) {
  232. if (isset($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER]) &&
  233. is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER])) {
  234. $sharedUsers = $_GET['itemShares'][OCP\Share::SHARE_TYPE_USER];
  235. }
  236. if (isset($_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP]) &&
  237. is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP])) {
  238. $sharedGroups = $_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP];
  239. }
  240. }
  241. $count = 0;
  242. $users = array();
  243. $limit = 0;
  244. $offset = 0;
  245. // limit defaults to 15 if not specified via request parameter and can be no larger than 500
  246. $request_limit = min((int)$_GET['limit'] ?: 15, 500);
  247. while ($count < $request_limit && count($users) == $limit) {
  248. $limit = $request_limit - $count;
  249. if ($shareWithinGroupOnly) {
  250. $users = OC_Group::displayNamesInGroups($usergroups, (string)$_GET['search'], $limit, $offset);
  251. } else {
  252. $users = OC_User::getDisplayNames((string)$_GET['search'], $limit, $offset);
  253. }
  254. $offset += $limit;
  255. foreach ($users as $uid => $displayName) {
  256. if (in_array($uid, $sharedUsers)) {
  257. continue;
  258. }
  259. if ((!isset($_GET['itemShares'])
  260. || !is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER])
  261. || !in_array($uid, $_GET['itemShares'][OCP\Share::SHARE_TYPE_USER]))
  262. && $uid != OC_User::getUser()) {
  263. $shareWith[] = array(
  264. 'label' => $displayName,
  265. 'value' => array(
  266. 'shareType' => OCP\Share::SHARE_TYPE_USER,
  267. 'shareWith' => $uid)
  268. );
  269. $count++;
  270. }
  271. }
  272. }
  273. $count = 0;
  274. // enable l10n support
  275. $l = \OC::$server->getL10N('core');
  276. foreach ($groups as $group) {
  277. if (in_array($group, $sharedGroups)) {
  278. continue;
  279. }
  280. if ($count < $request_limit) {
  281. if (!isset($_GET['itemShares'])
  282. || !isset($_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP])
  283. || !is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP])
  284. || !in_array($group, $_GET['itemShares'][OCP\Share::SHARE_TYPE_GROUP])) {
  285. $shareWith[] = array(
  286. 'label' => $group,
  287. 'value' => array(
  288. 'shareType' => OCP\Share::SHARE_TYPE_GROUP,
  289. 'shareWith' => $group
  290. )
  291. );
  292. $count++;
  293. }
  294. } else {
  295. break;
  296. }
  297. }
  298. // allow user to add unknown remote addresses for server-to-server share
  299. $backend = \OCP\Share::getBackend((string)$_GET['itemType']);
  300. if ($backend->isShareTypeAllowed(\OCP\Share::SHARE_TYPE_REMOTE)) {
  301. if (substr_count((string)$_GET['search'], '@') >= 1) {
  302. $shareWith[] = array(
  303. 'label' => (string)$_GET['search'],
  304. 'value' => array(
  305. 'shareType' => \OCP\Share::SHARE_TYPE_REMOTE,
  306. 'shareWith' => (string)$_GET['search']
  307. )
  308. );
  309. }
  310. $contactManager = \OC::$server->getContactsManager();
  311. $addressBookContacts = $contactManager->search($_GET['search'], ['CLOUD', 'FN']);
  312. foreach ($addressBookContacts as $contact) {
  313. if (isset($contact['CLOUD'])) {
  314. foreach ($contact['CLOUD'] as $cloudId) {
  315. $shareWith[] = array(
  316. 'label' => $contact['FN'] . ' (' . $cloudId . ')',
  317. 'value' => array(
  318. 'shareType' => \OCP\Share::SHARE_TYPE_REMOTE,
  319. 'shareWith' => $cloudId
  320. )
  321. );
  322. }
  323. }
  324. }
  325. }
  326. $sharingAutocompletion = \OC::$server->getConfig()
  327. ->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes');
  328. if ($sharingAutocompletion !== 'yes') {
  329. $searchTerm = strtolower($_GET['search']);
  330. $shareWith = array_filter($shareWith, function($user) use ($searchTerm) {
  331. return strtolower($user['label']) === $searchTerm
  332. || strtolower($user['value']['shareWith']) === $searchTerm;
  333. });
  334. }
  335. $sorter = new \OC\Share\SearchResultSorter((string)$_GET['search'],
  336. 'label',
  337. \OC::$server->getLogger());
  338. usort($shareWith, array($sorter, 'sort'));
  339. OC_JSON::success(array('data' => $shareWith));
  340. }
  341. break;
  342. }
  343. }