You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
4.9 KiB

9 years ago
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Björn Schießle <bjoern@schiessle.org>
  6. *
  7. * @license AGPL-3.0
  8. *
  9. * This code is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License, version 3,
  11. * as published by the Free Software Foundation.
  12. *
  13. * This program 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 License, version 3,
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>
  20. *
  21. */
  22. namespace OCA\FederatedFileSharing;
  23. use OC\HintException;
  24. use OCP\IL10N;
  25. use OCP\IURLGenerator;
  26. /**
  27. * Class AddressHandler - parse, modify and construct federated sharing addresses
  28. *
  29. * @package OCA\FederatedFileSharing
  30. */
  31. class AddressHandler {
  32. /** @var IL10N */
  33. private $l;
  34. /** @var IURLGenerator */
  35. private $urlGenerator;
  36. /**
  37. * AddressHandler constructor.
  38. *
  39. * @param IURLGenerator $urlGenerator
  40. * @param IL10N $il10n
  41. */
  42. public function __construct(
  43. IURLGenerator $urlGenerator,
  44. IL10N $il10n
  45. ) {
  46. $this->l = $il10n;
  47. $this->urlGenerator = $urlGenerator;
  48. }
  49. /**
  50. * split user and remote from federated cloud id
  51. *
  52. * @param string $address federated share address
  53. * @return array [user, remoteURL]
  54. * @throws HintException
  55. */
  56. public function splitUserRemote($address) {
  57. if (strpos($address, '@') === false) {
  58. $hint = $this->l->t('Invalid Federated Cloud ID');
  59. throw new HintException('Invalid Federated Cloud ID', $hint);
  60. }
  61. // Find the first character that is not allowed in user names
  62. $id = str_replace('\\', '/', $address);
  63. $posSlash = strpos($id, '/');
  64. $posColon = strpos($id, ':');
  65. if ($posSlash === false && $posColon === false) {
  66. $invalidPos = strlen($id);
  67. } else if ($posSlash === false) {
  68. $invalidPos = $posColon;
  69. } else if ($posColon === false) {
  70. $invalidPos = $posSlash;
  71. } else {
  72. $invalidPos = min($posSlash, $posColon);
  73. }
  74. // Find the last @ before $invalidPos
  75. $pos = $lastAtPos = 0;
  76. while ($lastAtPos !== false && $lastAtPos <= $invalidPos) {
  77. $pos = $lastAtPos;
  78. $lastAtPos = strpos($id, '@', $pos + 1);
  79. }
  80. if ($pos !== false) {
  81. $user = substr($id, 0, $pos);
  82. $remote = substr($id, $pos + 1);
  83. $remote = $this->fixRemoteURL($remote);
  84. if (!empty($user) && !empty($remote)) {
  85. return array($user, $remote);
  86. }
  87. }
  88. $hint = $this->l->t('Invalid Federated Cloud ID');
  89. throw new HintException('Invalid Federated Cloud ID', $hint);
  90. }
  91. /**
  92. * generate remote URL part of federated ID
  93. *
  94. * @return string url of the current server
  95. */
  96. public function generateRemoteURL() {
  97. $url = $this->urlGenerator->getAbsoluteURL('/');
  98. return $url;
  99. }
  100. /**
  101. * check if two federated cloud IDs refer to the same user
  102. *
  103. * @param string $user1
  104. * @param string $server1
  105. * @param string $user2
  106. * @param string $server2
  107. * @return bool true if both users and servers are the same
  108. */
  109. public function compareAddresses($user1, $server1, $user2, $server2) {
  110. $normalizedServer1 = strtolower($this->removeProtocolFromUrl($server1));
  111. $normalizedServer2 = strtolower($this->removeProtocolFromUrl($server2));
  112. if (rtrim($normalizedServer1, '/') === rtrim($normalizedServer2, '/')) {
  113. // FIXME this should be a method in the user management instead
  114. \OCP\Util::emitHook(
  115. '\OCA\Files_Sharing\API\Server2Server',
  116. 'preLoginNameUsedAsUserName',
  117. array('uid' => &$user1)
  118. );
  119. \OCP\Util::emitHook(
  120. '\OCA\Files_Sharing\API\Server2Server',
  121. 'preLoginNameUsedAsUserName',
  122. array('uid' => &$user2)
  123. );
  124. if ($user1 === $user2) {
  125. return true;
  126. }
  127. }
  128. return false;
  129. }
  130. /**
  131. * remove protocol from URL
  132. *
  133. * @param string $url
  134. * @return string
  135. */
  136. public function removeProtocolFromUrl($url) {
  137. if (strpos($url, 'https://') === 0) {
  138. return substr($url, strlen('https://'));
  139. } else if (strpos($url, 'http://') === 0) {
  140. return substr($url, strlen('http://'));
  141. }
  142. return $url;
  143. }
  144. /**
  145. * check if the url contain the protocol (http or https)
  146. *
  147. * @param string $url
  148. * @return bool
  149. */
  150. public function urlContainProtocol($url) {
  151. if (strpos($url, 'https://') === 0 ||
  152. strpos($url, 'http://') === 0) {
  153. return true;
  154. }
  155. return false;
  156. }
  157. /**
  158. * Strips away a potential file names and trailing slashes:
  159. * - http://localhost
  160. * - http://localhost/
  161. * - http://localhost/index.php
  162. * - http://localhost/index.php/s/{shareToken}
  163. *
  164. * all return: http://localhost
  165. *
  166. * @param string $remote
  167. * @return string
  168. */
  169. protected function fixRemoteURL($remote) {
  170. $remote = str_replace('\\', '/', $remote);
  171. if ($fileNamePosition = strpos($remote, '/index.php')) {
  172. $remote = substr($remote, 0, $fileNamePosition);
  173. }
  174. $remote = rtrim($remote, '/');
  175. return $remote;
  176. }
  177. }