Completed
Pull Request — master (#3385)
by Christoph
18:07
created
apps/files_sharing/lib/Activity/Settings/PublicLinks.php 1 patch
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -27,72 +27,72 @@
 block discarded – undo
27 27
 
28 28
 class PublicLinks implements ISetting {
29 29
 
30
-	/** @var IL10N */
31
-	protected $l;
30
+    /** @var IL10N */
31
+    protected $l;
32 32
 
33
-	/**
34
-	 * @param IL10N $l
35
-	 */
36
-	public function __construct(IL10N $l) {
37
-		$this->l = $l;
38
-	}
33
+    /**
34
+     * @param IL10N $l
35
+     */
36
+    public function __construct(IL10N $l) {
37
+        $this->l = $l;
38
+    }
39 39
 
40
-	/**
41
-	 * @return string Lowercase a-z and underscore only identifier
42
-	 * @since 11.0.0
43
-	 */
44
-	public function getIdentifier() {
45
-		return 'public_links';
46
-	}
40
+    /**
41
+     * @return string Lowercase a-z and underscore only identifier
42
+     * @since 11.0.0
43
+     */
44
+    public function getIdentifier() {
45
+        return 'public_links';
46
+    }
47 47
 
48
-	/**
49
-	 * @return string A translated string
50
-	 * @since 11.0.0
51
-	 */
52
-	public function getName() {
53
-		return $this->l->t('A file or folder shared by mail or by public link was <strong>downloaded</strong>');
54
-	}
48
+    /**
49
+     * @return string A translated string
50
+     * @since 11.0.0
51
+     */
52
+    public function getName() {
53
+        return $this->l->t('A file or folder shared by mail or by public link was <strong>downloaded</strong>');
54
+    }
55 55
 
56
-	/**
57
-	 * @return int whether the filter should be rather on the top or bottom of
58
-	 * the admin section. The filters are arranged in ascending order of the
59
-	 * priority values. It is required to return a value between 0 and 100.
60
-	 * @since 11.0.0
61
-	 */
62
-	public function getPriority() {
63
-		return 20;
64
-	}
56
+    /**
57
+     * @return int whether the filter should be rather on the top or bottom of
58
+     * the admin section. The filters are arranged in ascending order of the
59
+     * priority values. It is required to return a value between 0 and 100.
60
+     * @since 11.0.0
61
+     */
62
+    public function getPriority() {
63
+        return 20;
64
+    }
65 65
 
66
-	/**
67
-	 * @return bool True when the option can be changed for the stream
68
-	 * @since 11.0.0
69
-	 */
70
-	public function canChangeStream() {
71
-		return true;
72
-	}
66
+    /**
67
+     * @return bool True when the option can be changed for the stream
68
+     * @since 11.0.0
69
+     */
70
+    public function canChangeStream() {
71
+        return true;
72
+    }
73 73
 
74
-	/**
75
-	 * @return bool True when the option can be changed for the stream
76
-	 * @since 11.0.0
77
-	 */
78
-	public function isDefaultEnabledStream() {
79
-		return true;
80
-	}
74
+    /**
75
+     * @return bool True when the option can be changed for the stream
76
+     * @since 11.0.0
77
+     */
78
+    public function isDefaultEnabledStream() {
79
+        return true;
80
+    }
81 81
 
82
-	/**
83
-	 * @return bool True when the option can be changed for the mail
84
-	 * @since 11.0.0
85
-	 */
86
-	public function canChangeMail() {
87
-		return true;
88
-	}
82
+    /**
83
+     * @return bool True when the option can be changed for the mail
84
+     * @since 11.0.0
85
+     */
86
+    public function canChangeMail() {
87
+        return true;
88
+    }
89 89
 
90
-	/**
91
-	 * @return bool True when the option can be changed for the stream
92
-	 * @since 11.0.0
93
-	 */
94
-	public function isDefaultEnabledMail() {
95
-		return false;
96
-	}
90
+    /**
91
+     * @return bool True when the option can be changed for the stream
92
+     * @since 11.0.0
93
+     */
94
+    public function isDefaultEnabledMail() {
95
+        return false;
96
+    }
97 97
 }
98 98
 
Please login to merge, or discard this patch.
apps/files_sharing/lib/Activity/Settings/RemoteShare.php 1 patch
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -27,72 +27,72 @@
 block discarded – undo
27 27
 
28 28
 class RemoteShare implements ISetting {
29 29
 
30
-	/** @var IL10N */
31
-	protected $l;
30
+    /** @var IL10N */
31
+    protected $l;
32 32
 
33
-	/**
34
-	 * @param IL10N $l
35
-	 */
36
-	public function __construct(IL10N $l) {
37
-		$this->l = $l;
38
-	}
33
+    /**
34
+     * @param IL10N $l
35
+     */
36
+    public function __construct(IL10N $l) {
37
+        $this->l = $l;
38
+    }
39 39
 
40
-	/**
41
-	 * @return string Lowercase a-z and underscore only identifier
42
-	 * @since 11.0.0
43
-	 */
44
-	public function getIdentifier() {
45
-		return 'remote_share';
46
-	}
40
+    /**
41
+     * @return string Lowercase a-z and underscore only identifier
42
+     * @since 11.0.0
43
+     */
44
+    public function getIdentifier() {
45
+        return 'remote_share';
46
+    }
47 47
 
48
-	/**
49
-	 * @return string A translated string
50
-	 * @since 11.0.0
51
-	 */
52
-	public function getName() {
53
-		return $this->l->t('A file or folder was shared from <strong>another server</strong>');
54
-	}
48
+    /**
49
+     * @return string A translated string
50
+     * @since 11.0.0
51
+     */
52
+    public function getName() {
53
+        return $this->l->t('A file or folder was shared from <strong>another server</strong>');
54
+    }
55 55
 
56
-	/**
57
-	 * @return int whether the filter should be rather on the top or bottom of
58
-	 * the admin section. The filters are arranged in ascending order of the
59
-	 * priority values. It is required to return a value between 0 and 100.
60
-	 * @since 11.0.0
61
-	 */
62
-	public function getPriority() {
63
-		return 11;
64
-	}
56
+    /**
57
+     * @return int whether the filter should be rather on the top or bottom of
58
+     * the admin section. The filters are arranged in ascending order of the
59
+     * priority values. It is required to return a value between 0 and 100.
60
+     * @since 11.0.0
61
+     */
62
+    public function getPriority() {
63
+        return 11;
64
+    }
65 65
 
66
-	/**
67
-	 * @return bool True when the option can be changed for the stream
68
-	 * @since 11.0.0
69
-	 */
70
-	public function canChangeStream() {
71
-		return true;
72
-	}
66
+    /**
67
+     * @return bool True when the option can be changed for the stream
68
+     * @since 11.0.0
69
+     */
70
+    public function canChangeStream() {
71
+        return true;
72
+    }
73 73
 
74
-	/**
75
-	 * @return bool True when the option can be changed for the stream
76
-	 * @since 11.0.0
77
-	 */
78
-	public function isDefaultEnabledStream() {
79
-		return true;
80
-	}
74
+    /**
75
+     * @return bool True when the option can be changed for the stream
76
+     * @since 11.0.0
77
+     */
78
+    public function isDefaultEnabledStream() {
79
+        return true;
80
+    }
81 81
 
82
-	/**
83
-	 * @return bool True when the option can be changed for the mail
84
-	 * @since 11.0.0
85
-	 */
86
-	public function canChangeMail() {
87
-		return true;
88
-	}
82
+    /**
83
+     * @return bool True when the option can be changed for the mail
84
+     * @since 11.0.0
85
+     */
86
+    public function canChangeMail() {
87
+        return true;
88
+    }
89 89
 
90
-	/**
91
-	 * @return bool True when the option can be changed for the stream
92
-	 * @since 11.0.0
93
-	 */
94
-	public function isDefaultEnabledMail() {
95
-		return true;
96
-	}
90
+    /**
91
+     * @return bool True when the option can be changed for the stream
92
+     * @since 11.0.0
93
+     */
94
+    public function isDefaultEnabledMail() {
95
+        return true;
96
+    }
97 97
 }
98 98
 
Please login to merge, or discard this patch.
apps/files_sharing/lib/Activity/Filter.php 1 patch
Indentation   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -27,69 +27,69 @@
 block discarded – undo
27 27
 use OCP\IURLGenerator;
28 28
 
29 29
 class Filter implements IFilter {
30
-	const TYPE_REMOTE_SHARE = 'remote_share';
31
-	const TYPE_SHARED = 'shared';
30
+    const TYPE_REMOTE_SHARE = 'remote_share';
31
+    const TYPE_SHARED = 'shared';
32 32
 
33
-	/** @var IL10N */
34
-	protected $l;
33
+    /** @var IL10N */
34
+    protected $l;
35 35
 
36
-	/** @var IURLGenerator */
37
-	protected $url;
36
+    /** @var IURLGenerator */
37
+    protected $url;
38 38
 
39
-	public function __construct(IL10N $l, IURLGenerator $url) {
40
-		$this->l = $l;
41
-		$this->url = $url;
42
-	}
39
+    public function __construct(IL10N $l, IURLGenerator $url) {
40
+        $this->l = $l;
41
+        $this->url = $url;
42
+    }
43 43
 
44
-	/**
45
-	 * @return string Lowercase a-z only identifier
46
-	 * @since 11.0.0
47
-	 */
48
-	public function getIdentifier() {
49
-		return 'files_sharing';
50
-	}
44
+    /**
45
+     * @return string Lowercase a-z only identifier
46
+     * @since 11.0.0
47
+     */
48
+    public function getIdentifier() {
49
+        return 'files_sharing';
50
+    }
51 51
 
52
-	/**
53
-	 * @return string A translated string
54
-	 * @since 11.0.0
55
-	 */
56
-	public function getName() {
57
-		return $this->l->t('File shares');
58
-	}
52
+    /**
53
+     * @return string A translated string
54
+     * @since 11.0.0
55
+     */
56
+    public function getName() {
57
+        return $this->l->t('File shares');
58
+    }
59 59
 
60
-	/**
61
-	 * @return int
62
-	 * @since 11.0.0
63
-	 */
64
-	public function getPriority() {
65
-		return 31;
66
-	}
60
+    /**
61
+     * @return int
62
+     * @since 11.0.0
63
+     */
64
+    public function getPriority() {
65
+        return 31;
66
+    }
67 67
 
68
-	/**
69
-	 * @return string Full URL to an icon, empty string when none is given
70
-	 * @since 11.0.0
71
-	 */
72
-	public function getIcon() {
73
-		return $this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/share.svg'));
74
-	}
68
+    /**
69
+     * @return string Full URL to an icon, empty string when none is given
70
+     * @since 11.0.0
71
+     */
72
+    public function getIcon() {
73
+        return $this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/share.svg'));
74
+    }
75 75
 
76
-	/**
77
-	 * @param string[] $types
78
-	 * @return string[] An array of allowed apps from which activities should be displayed
79
-	 * @since 11.0.0
80
-	 */
81
-	public function filterTypes(array $types) {
82
-		return array_intersect([
83
-			self::TYPE_SHARED,
84
-			self::TYPE_REMOTE_SHARE
85
-		], $types);
86
-	}
76
+    /**
77
+     * @param string[] $types
78
+     * @return string[] An array of allowed apps from which activities should be displayed
79
+     * @since 11.0.0
80
+     */
81
+    public function filterTypes(array $types) {
82
+        return array_intersect([
83
+            self::TYPE_SHARED,
84
+            self::TYPE_REMOTE_SHARE
85
+        ], $types);
86
+    }
87 87
 
88
-	/**
89
-	 * @return string[] An array of allowed apps from which activities should be displayed
90
-	 * @since 11.0.0
91
-	 */
92
-	public function allowedApps() {
93
-		return ['files_sharing'];
94
-	}
88
+    /**
89
+     * @return string[] An array of allowed apps from which activities should be displayed
90
+     * @since 11.0.0
91
+     */
92
+    public function allowedApps() {
93
+        return ['files_sharing'];
94
+    }
95 95
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Cache.php 1 patch
Indentation   +99 added lines, -99 removed lines patch added patch discarded remove patch
@@ -37,103 +37,103 @@
 block discarded – undo
37 37
  * don't use this class directly if you need to get metadata, use \OC\Files\Filesystem::getFileInfo instead
38 38
  */
39 39
 class Cache extends CacheJail {
40
-	/**
41
-	 * @var \OCA\Files_Sharing\SharedStorage
42
-	 */
43
-	private $storage;
44
-
45
-	/**
46
-	 * @var ICacheEntry
47
-	 */
48
-	private $sourceRootInfo;
49
-
50
-	private $rootUnchanged = true;
51
-
52
-	private $ownerDisplayName;
53
-
54
-	/**
55
-	 * @param \OCA\Files_Sharing\SharedStorage $storage
56
-	 * @param ICacheEntry $sourceRootInfo
57
-	 */
58
-	public function __construct($storage, ICacheEntry $sourceRootInfo) {
59
-		$this->storage = $storage;
60
-		$this->sourceRootInfo = $sourceRootInfo;
61
-		parent::__construct(
62
-			null,
63
-			$this->sourceRootInfo->getPath()
64
-		);
65
-	}
66
-
67
-	public function getCache() {
68
-		if (is_null($this->cache)) {
69
-			$this->cache = $this->storage->getSourceStorage()->getCache();
70
-		}
71
-		return $this->cache;
72
-	}
73
-
74
-	public function getNumericStorageId() {
75
-		if (isset($this->numericId)) {
76
-			return $this->numericId;
77
-		} else {
78
-			return false;
79
-		}
80
-	}
81
-
82
-	public function get($file) {
83
-		if ($this->rootUnchanged && ($file === '' || $file === $this->sourceRootInfo->getId())) {
84
-			return $this->formatCacheEntry(clone $this->sourceRootInfo);
85
-		}
86
-		return parent::get($file);
87
-	}
88
-
89
-	public function update($id, array $data) {
90
-		$this->rootUnchanged = false;
91
-		parent::update($id, $data);
92
-	}
93
-
94
-	public function insert($file, array $data) {
95
-		$this->rootUnchanged = false;
96
-		return parent::insert($file, $data);
97
-	}
98
-
99
-	public function remove($file) {
100
-		$this->rootUnchanged = false;
101
-		parent::remove($file);
102
-	}
103
-
104
-	public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) {
105
-		$this->rootUnchanged = false;
106
-		return parent::moveFromCache($sourceCache, $sourcePath, $targetPath);
107
-	}
108
-
109
-	protected function formatCacheEntry($entry) {
110
-		$path = isset($entry['path']) ? $entry['path'] : '';
111
-		$entry = parent::formatCacheEntry($entry);
112
-		$sharePermissions = $this->storage->getPermissions($path);
113
-		if (isset($entry['permissions'])) {
114
-			$entry['permissions'] &= $sharePermissions;
115
-		} else {
116
-			$entry['permissions'] = $sharePermissions;
117
-		}
118
-		$entry['uid_owner'] = $this->storage->getOwner($path);
119
-		$entry['displayname_owner'] = $this->getOwnerDisplayName();
120
-		if ($path === '') {
121
-			$entry['is_share_mount_point'] = true;
122
-		}
123
-		return $entry;
124
-	}
125
-
126
-	private function getOwnerDisplayName() {
127
-		if (!$this->ownerDisplayName) {
128
-			$this->ownerDisplayName = \OC_User::getDisplayName($this->storage->getOwner(''));
129
-		}
130
-		return $this->ownerDisplayName;
131
-	}
132
-
133
-	/**
134
-	 * remove all entries for files that are stored on the storage from the cache
135
-	 */
136
-	public function clear() {
137
-		// Not a valid action for Shared Cache
138
-	}
40
+    /**
41
+     * @var \OCA\Files_Sharing\SharedStorage
42
+     */
43
+    private $storage;
44
+
45
+    /**
46
+     * @var ICacheEntry
47
+     */
48
+    private $sourceRootInfo;
49
+
50
+    private $rootUnchanged = true;
51
+
52
+    private $ownerDisplayName;
53
+
54
+    /**
55
+     * @param \OCA\Files_Sharing\SharedStorage $storage
56
+     * @param ICacheEntry $sourceRootInfo
57
+     */
58
+    public function __construct($storage, ICacheEntry $sourceRootInfo) {
59
+        $this->storage = $storage;
60
+        $this->sourceRootInfo = $sourceRootInfo;
61
+        parent::__construct(
62
+            null,
63
+            $this->sourceRootInfo->getPath()
64
+        );
65
+    }
66
+
67
+    public function getCache() {
68
+        if (is_null($this->cache)) {
69
+            $this->cache = $this->storage->getSourceStorage()->getCache();
70
+        }
71
+        return $this->cache;
72
+    }
73
+
74
+    public function getNumericStorageId() {
75
+        if (isset($this->numericId)) {
76
+            return $this->numericId;
77
+        } else {
78
+            return false;
79
+        }
80
+    }
81
+
82
+    public function get($file) {
83
+        if ($this->rootUnchanged && ($file === '' || $file === $this->sourceRootInfo->getId())) {
84
+            return $this->formatCacheEntry(clone $this->sourceRootInfo);
85
+        }
86
+        return parent::get($file);
87
+    }
88
+
89
+    public function update($id, array $data) {
90
+        $this->rootUnchanged = false;
91
+        parent::update($id, $data);
92
+    }
93
+
94
+    public function insert($file, array $data) {
95
+        $this->rootUnchanged = false;
96
+        return parent::insert($file, $data);
97
+    }
98
+
99
+    public function remove($file) {
100
+        $this->rootUnchanged = false;
101
+        parent::remove($file);
102
+    }
103
+
104
+    public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) {
105
+        $this->rootUnchanged = false;
106
+        return parent::moveFromCache($sourceCache, $sourcePath, $targetPath);
107
+    }
108
+
109
+    protected function formatCacheEntry($entry) {
110
+        $path = isset($entry['path']) ? $entry['path'] : '';
111
+        $entry = parent::formatCacheEntry($entry);
112
+        $sharePermissions = $this->storage->getPermissions($path);
113
+        if (isset($entry['permissions'])) {
114
+            $entry['permissions'] &= $sharePermissions;
115
+        } else {
116
+            $entry['permissions'] = $sharePermissions;
117
+        }
118
+        $entry['uid_owner'] = $this->storage->getOwner($path);
119
+        $entry['displayname_owner'] = $this->getOwnerDisplayName();
120
+        if ($path === '') {
121
+            $entry['is_share_mount_point'] = true;
122
+        }
123
+        return $entry;
124
+    }
125
+
126
+    private function getOwnerDisplayName() {
127
+        if (!$this->ownerDisplayName) {
128
+            $this->ownerDisplayName = \OC_User::getDisplayName($this->storage->getOwner(''));
129
+        }
130
+        return $this->ownerDisplayName;
131
+    }
132
+
133
+    /**
134
+     * remove all entries for files that are stored on the storage from the cache
135
+     */
136
+    public function clear() {
137
+        // Not a valid action for Shared Cache
138
+    }
139 139
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Migration.php 1 patch
Indentation   +247 added lines, -247 removed lines patch added patch discarded remove patch
@@ -39,252 +39,252 @@
 block discarded – undo
39 39
  */
40 40
 class Migration {
41 41
 
42
-	/** @var IDBConnection */
43
-	private $connection;
44
-
45
-	/** @var  IConfig */
46
-	private $config;
47
-
48
-	/** @var  ICache with all shares we already saw */
49
-	private $shareCache;
50
-
51
-	/** @var string */
52
-	private $table = 'share';
53
-
54
-	public function __construct(IDBConnection $connection, IConfig $config) {
55
-		$this->connection = $connection;
56
-		$this->config = $config;
57
-
58
-		// We cache up to 10k share items (~20MB)
59
-		$this->shareCache = new CappedMemoryCache(10000);
60
-	}
61
-
62
-	/**
63
-	 * move all re-shares to the owner in order to have a flat list of shares
64
-	 * upgrade from oC 8.2 to 9.0 with the new sharing
65
-	 */
66
-	public function removeReShares() {
67
-
68
-		$stmt = $this->getReShares();
69
-
70
-		$owners = [];
71
-		while($share = $stmt->fetch()) {
72
-
73
-			$this->shareCache[$share['id']] = $share;
74
-
75
-			$owners[$share['id']] = [
76
-					'owner' => $this->findOwner($share),
77
-					'initiator' => $share['uid_owner'],
78
-					'type' => $share['share_type'],
79
-			];
80
-
81
-			if (count($owners) === 1000) {
82
-				$this->updateOwners($owners);
83
-				$owners = [];
84
-			}
85
-		}
86
-
87
-		$stmt->closeCursor();
88
-
89
-		if (count($owners)) {
90
-			$this->updateOwners($owners);
91
-		}
92
-	}
93
-
94
-	/**
95
-	 * update all owner information so that all shares have an owner
96
-	 * and an initiator for the upgrade from oC 8.2 to 9.0 with the new sharing
97
-	 */
98
-	public function updateInitiatorInfo() {
99
-		while (true) {
100
-			$shares = $this->getMissingInitiator(1000);
101
-
102
-			if (empty($shares)) {
103
-				break;
104
-			}
105
-
106
-			$owners = [];
107
-			foreach ($shares as $share) {
108
-				$owners[$share['id']] = [
109
-					'owner' => $share['uid_owner'],
110
-					'initiator' => $share['uid_owner'],
111
-					'type' => $share['share_type'],
112
-				];
113
-			}
114
-			$this->updateOwners($owners);
115
-		}
116
-	}
117
-
118
-	/**
119
-	 * this was dropped for Nextcloud 11 in favour of share by mail
120
-	 */
121
-	public function removeSendMailOption() {
122
-		$this->config->deleteAppValue('core', 'shareapi_allow_mail_notification');
123
-		$this->config->deleteAppValue('core', 'shareapi_allow_public_notification');
124
-	}
125
-
126
-	/**
127
-	 * find the owner of a re-shared file/folder
128
-	 *
129
-	 * @param array $share
130
-	 * @return array
131
-	 */
132
-	private function findOwner($share) {
133
-		$currentShare = $share;
134
-		while(!is_null($currentShare['parent'])) {
135
-			if (isset($this->shareCache[$currentShare['parent']])) {
136
-				$currentShare = $this->shareCache[$currentShare['parent']];
137
-			} else {
138
-				$currentShare = $this->getShare((int)$currentShare['parent']);
139
-				$this->shareCache[$currentShare['id']] = $currentShare;
140
-			}
141
-		}
142
-
143
-		return $currentShare['uid_owner'];
144
-	}
145
-
146
-	/**
147
-	 * Get $n re-shares from the database
148
-	 *
149
-	 * @param int $n The max number of shares to fetch
150
-	 * @return \Doctrine\DBAL\Driver\Statement
151
-	 */
152
-	private function getReShares() {
153
-		$query = $this->connection->getQueryBuilder();
154
-		$query->select(['id', 'parent', 'uid_owner', 'share_type'])
155
-			->from($this->table)
156
-			->where($query->expr()->in(
157
-				'share_type',
158
-				$query->createNamedParameter(
159
-					[
160
-						\OCP\Share::SHARE_TYPE_USER,
161
-						\OCP\Share::SHARE_TYPE_GROUP,
162
-						\OCP\Share::SHARE_TYPE_LINK,
163
-						\OCP\Share::SHARE_TYPE_REMOTE,
164
-					],
165
-					Connection::PARAM_INT_ARRAY
166
-				)
167
-			))
168
-			->andWhere($query->expr()->in(
169
-				'item_type',
170
-				$query->createNamedParameter(
171
-					['file', 'folder'],
172
-					Connection::PARAM_STR_ARRAY
173
-				)
174
-			))
175
-			->andWhere($query->expr()->isNotNull('parent'))
176
-			->orderBy('id', 'asc');
177
-		return $query->execute();
178
-
179
-
180
-		$shares = $result->fetchAll();
181
-		$result->closeCursor();
182
-
183
-		$ordered = [];
184
-		foreach ($shares as $share) {
185
-			$ordered[(int)$share['id']] = $share;
186
-		}
187
-
188
-		return $ordered;
189
-	}
190
-
191
-	/**
192
-	 * Get $n re-shares from the database
193
-	 *
194
-	 * @param int $n The max number of shares to fetch
195
-	 * @return array
196
-	 */
197
-	private function getMissingInitiator($n = 1000) {
198
-		$query = $this->connection->getQueryBuilder();
199
-		$query->select(['id', 'uid_owner', 'share_type'])
200
-			->from($this->table)
201
-			->where($query->expr()->in(
202
-				'share_type',
203
-				$query->createNamedParameter(
204
-					[
205
-						\OCP\Share::SHARE_TYPE_USER,
206
-						\OCP\Share::SHARE_TYPE_GROUP,
207
-						\OCP\Share::SHARE_TYPE_LINK,
208
-						\OCP\Share::SHARE_TYPE_REMOTE,
209
-					],
210
-					Connection::PARAM_INT_ARRAY
211
-				)
212
-			))
213
-			->andWhere($query->expr()->in(
214
-				'item_type',
215
-				$query->createNamedParameter(
216
-					['file', 'folder'],
217
-					Connection::PARAM_STR_ARRAY
218
-				)
219
-			))
220
-			->andWhere($query->expr()->isNull('uid_initiator'))
221
-			->orderBy('id', 'asc')
222
-			->setMaxResults($n);
223
-		$result = $query->execute();
224
-		$shares = $result->fetchAll();
225
-		$result->closeCursor();
226
-
227
-		$ordered = [];
228
-		foreach ($shares as $share) {
229
-			$ordered[(int)$share['id']] = $share;
230
-		}
231
-
232
-		return $ordered;
233
-	}
234
-
235
-	/**
236
-	 * get a specific share
237
-	 *
238
-	 * @param int $id
239
-	 * @return array
240
-	 */
241
-	private function getShare($id) {
242
-		$query = $this->connection->getQueryBuilder();
243
-		$query->select(['id', 'parent', 'uid_owner'])
244
-			->from($this->table)
245
-			->where($query->expr()->eq('id', $query->createNamedParameter($id)));
246
-		$result = $query->execute();
247
-		$share = $result->fetchAll();
248
-		$result->closeCursor();
249
-
250
-		return $share[0];
251
-	}
252
-
253
-	/**
254
-	 * update database with the new owners
255
-	 *
256
-	 * @param array $owners
257
-	 * @throws \Exception
258
-	 */
259
-	private function updateOwners($owners) {
260
-
261
-		$this->connection->beginTransaction();
262
-
263
-		try {
264
-
265
-			foreach ($owners as $id => $owner) {
266
-				$query = $this->connection->getQueryBuilder();
267
-				$query->update($this->table)
268
-					->set('uid_owner', $query->createNamedParameter($owner['owner']))
269
-					->set('uid_initiator', $query->createNamedParameter($owner['initiator']));
270
-
271
-
272
-				if ((int)$owner['type'] !== \OCP\Share::SHARE_TYPE_LINK) {
273
-					$query->set('parent', $query->createNamedParameter(null));
274
-				}
275
-
276
-				$query->where($query->expr()->eq('id', $query->createNamedParameter($id)));
277
-
278
-				$query->execute();
279
-			}
280
-
281
-			$this->connection->commit();
282
-
283
-		} catch (\Exception $e) {
284
-			$this->connection->rollBack();
285
-			throw $e;
286
-		}
287
-
288
-	}
42
+    /** @var IDBConnection */
43
+    private $connection;
44
+
45
+    /** @var  IConfig */
46
+    private $config;
47
+
48
+    /** @var  ICache with all shares we already saw */
49
+    private $shareCache;
50
+
51
+    /** @var string */
52
+    private $table = 'share';
53
+
54
+    public function __construct(IDBConnection $connection, IConfig $config) {
55
+        $this->connection = $connection;
56
+        $this->config = $config;
57
+
58
+        // We cache up to 10k share items (~20MB)
59
+        $this->shareCache = new CappedMemoryCache(10000);
60
+    }
61
+
62
+    /**
63
+     * move all re-shares to the owner in order to have a flat list of shares
64
+     * upgrade from oC 8.2 to 9.0 with the new sharing
65
+     */
66
+    public function removeReShares() {
67
+
68
+        $stmt = $this->getReShares();
69
+
70
+        $owners = [];
71
+        while($share = $stmt->fetch()) {
72
+
73
+            $this->shareCache[$share['id']] = $share;
74
+
75
+            $owners[$share['id']] = [
76
+                    'owner' => $this->findOwner($share),
77
+                    'initiator' => $share['uid_owner'],
78
+                    'type' => $share['share_type'],
79
+            ];
80
+
81
+            if (count($owners) === 1000) {
82
+                $this->updateOwners($owners);
83
+                $owners = [];
84
+            }
85
+        }
86
+
87
+        $stmt->closeCursor();
88
+
89
+        if (count($owners)) {
90
+            $this->updateOwners($owners);
91
+        }
92
+    }
93
+
94
+    /**
95
+     * update all owner information so that all shares have an owner
96
+     * and an initiator for the upgrade from oC 8.2 to 9.0 with the new sharing
97
+     */
98
+    public function updateInitiatorInfo() {
99
+        while (true) {
100
+            $shares = $this->getMissingInitiator(1000);
101
+
102
+            if (empty($shares)) {
103
+                break;
104
+            }
105
+
106
+            $owners = [];
107
+            foreach ($shares as $share) {
108
+                $owners[$share['id']] = [
109
+                    'owner' => $share['uid_owner'],
110
+                    'initiator' => $share['uid_owner'],
111
+                    'type' => $share['share_type'],
112
+                ];
113
+            }
114
+            $this->updateOwners($owners);
115
+        }
116
+    }
117
+
118
+    /**
119
+     * this was dropped for Nextcloud 11 in favour of share by mail
120
+     */
121
+    public function removeSendMailOption() {
122
+        $this->config->deleteAppValue('core', 'shareapi_allow_mail_notification');
123
+        $this->config->deleteAppValue('core', 'shareapi_allow_public_notification');
124
+    }
125
+
126
+    /**
127
+     * find the owner of a re-shared file/folder
128
+     *
129
+     * @param array $share
130
+     * @return array
131
+     */
132
+    private function findOwner($share) {
133
+        $currentShare = $share;
134
+        while(!is_null($currentShare['parent'])) {
135
+            if (isset($this->shareCache[$currentShare['parent']])) {
136
+                $currentShare = $this->shareCache[$currentShare['parent']];
137
+            } else {
138
+                $currentShare = $this->getShare((int)$currentShare['parent']);
139
+                $this->shareCache[$currentShare['id']] = $currentShare;
140
+            }
141
+        }
142
+
143
+        return $currentShare['uid_owner'];
144
+    }
145
+
146
+    /**
147
+     * Get $n re-shares from the database
148
+     *
149
+     * @param int $n The max number of shares to fetch
150
+     * @return \Doctrine\DBAL\Driver\Statement
151
+     */
152
+    private function getReShares() {
153
+        $query = $this->connection->getQueryBuilder();
154
+        $query->select(['id', 'parent', 'uid_owner', 'share_type'])
155
+            ->from($this->table)
156
+            ->where($query->expr()->in(
157
+                'share_type',
158
+                $query->createNamedParameter(
159
+                    [
160
+                        \OCP\Share::SHARE_TYPE_USER,
161
+                        \OCP\Share::SHARE_TYPE_GROUP,
162
+                        \OCP\Share::SHARE_TYPE_LINK,
163
+                        \OCP\Share::SHARE_TYPE_REMOTE,
164
+                    ],
165
+                    Connection::PARAM_INT_ARRAY
166
+                )
167
+            ))
168
+            ->andWhere($query->expr()->in(
169
+                'item_type',
170
+                $query->createNamedParameter(
171
+                    ['file', 'folder'],
172
+                    Connection::PARAM_STR_ARRAY
173
+                )
174
+            ))
175
+            ->andWhere($query->expr()->isNotNull('parent'))
176
+            ->orderBy('id', 'asc');
177
+        return $query->execute();
178
+
179
+
180
+        $shares = $result->fetchAll();
181
+        $result->closeCursor();
182
+
183
+        $ordered = [];
184
+        foreach ($shares as $share) {
185
+            $ordered[(int)$share['id']] = $share;
186
+        }
187
+
188
+        return $ordered;
189
+    }
190
+
191
+    /**
192
+     * Get $n re-shares from the database
193
+     *
194
+     * @param int $n The max number of shares to fetch
195
+     * @return array
196
+     */
197
+    private function getMissingInitiator($n = 1000) {
198
+        $query = $this->connection->getQueryBuilder();
199
+        $query->select(['id', 'uid_owner', 'share_type'])
200
+            ->from($this->table)
201
+            ->where($query->expr()->in(
202
+                'share_type',
203
+                $query->createNamedParameter(
204
+                    [
205
+                        \OCP\Share::SHARE_TYPE_USER,
206
+                        \OCP\Share::SHARE_TYPE_GROUP,
207
+                        \OCP\Share::SHARE_TYPE_LINK,
208
+                        \OCP\Share::SHARE_TYPE_REMOTE,
209
+                    ],
210
+                    Connection::PARAM_INT_ARRAY
211
+                )
212
+            ))
213
+            ->andWhere($query->expr()->in(
214
+                'item_type',
215
+                $query->createNamedParameter(
216
+                    ['file', 'folder'],
217
+                    Connection::PARAM_STR_ARRAY
218
+                )
219
+            ))
220
+            ->andWhere($query->expr()->isNull('uid_initiator'))
221
+            ->orderBy('id', 'asc')
222
+            ->setMaxResults($n);
223
+        $result = $query->execute();
224
+        $shares = $result->fetchAll();
225
+        $result->closeCursor();
226
+
227
+        $ordered = [];
228
+        foreach ($shares as $share) {
229
+            $ordered[(int)$share['id']] = $share;
230
+        }
231
+
232
+        return $ordered;
233
+    }
234
+
235
+    /**
236
+     * get a specific share
237
+     *
238
+     * @param int $id
239
+     * @return array
240
+     */
241
+    private function getShare($id) {
242
+        $query = $this->connection->getQueryBuilder();
243
+        $query->select(['id', 'parent', 'uid_owner'])
244
+            ->from($this->table)
245
+            ->where($query->expr()->eq('id', $query->createNamedParameter($id)));
246
+        $result = $query->execute();
247
+        $share = $result->fetchAll();
248
+        $result->closeCursor();
249
+
250
+        return $share[0];
251
+    }
252
+
253
+    /**
254
+     * update database with the new owners
255
+     *
256
+     * @param array $owners
257
+     * @throws \Exception
258
+     */
259
+    private function updateOwners($owners) {
260
+
261
+        $this->connection->beginTransaction();
262
+
263
+        try {
264
+
265
+            foreach ($owners as $id => $owner) {
266
+                $query = $this->connection->getQueryBuilder();
267
+                $query->update($this->table)
268
+                    ->set('uid_owner', $query->createNamedParameter($owner['owner']))
269
+                    ->set('uid_initiator', $query->createNamedParameter($owner['initiator']));
270
+
271
+
272
+                if ((int)$owner['type'] !== \OCP\Share::SHARE_TYPE_LINK) {
273
+                    $query->set('parent', $query->createNamedParameter(null));
274
+                }
275
+
276
+                $query->where($query->expr()->eq('id', $query->createNamedParameter($id)));
277
+
278
+                $query->execute();
279
+            }
280
+
281
+            $this->connection->commit();
282
+
283
+        } catch (\Exception $e) {
284
+            $this->connection->rollBack();
285
+            throw $e;
286
+        }
287
+
288
+    }
289 289
 
290 290
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/ExpireSharesJob.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -29,49 +29,49 @@
 block discarded – undo
29 29
  */
30 30
 class ExpireSharesJob extends TimedJob {
31 31
 
32
-	/**
33
-	 * sets the correct interval for this timed job
34
-	 */
35
-	public function __construct() {
36
-		// Run once a day
37
-		$this->setInterval(24 * 60 * 60);
38
-	}
32
+    /**
33
+     * sets the correct interval for this timed job
34
+     */
35
+    public function __construct() {
36
+        // Run once a day
37
+        $this->setInterval(24 * 60 * 60);
38
+    }
39 39
 
40
-	/**
41
-	 * Makes the background job do its work
42
-	 *
43
-	 * @param array $argument unused argument
44
-	 */
45
-	public function run($argument) {
46
-		$connection = \OC::$server->getDatabaseConnection();
47
-		$logger = \OC::$server->getLogger();
40
+    /**
41
+     * Makes the background job do its work
42
+     *
43
+     * @param array $argument unused argument
44
+     */
45
+    public function run($argument) {
46
+        $connection = \OC::$server->getDatabaseConnection();
47
+        $logger = \OC::$server->getLogger();
48 48
 
49
-		//Current time
50
-		$now = new \DateTime();
51
-		$now = $now->format('Y-m-d H:i:s');
49
+        //Current time
50
+        $now = new \DateTime();
51
+        $now = $now->format('Y-m-d H:i:s');
52 52
 
53
-		/*
53
+        /*
54 54
 		 * Expire file link shares only (for now)
55 55
 		 */
56
-		$qb = $connection->getQueryBuilder();
57
-		$qb->select('id', 'file_source', 'uid_owner', 'item_type')
58
-			->from('share')
59
-			->where(
60
-				$qb->expr()->andX(
61
-					$qb->expr()->eq('share_type', $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK)),
62
-					$qb->expr()->lte('expiration', $qb->expr()->literal($now)),
63
-					$qb->expr()->orX(
64
-						$qb->expr()->eq('item_type', $qb->expr()->literal('file')),
65
-						$qb->expr()->eq('item_type', $qb->expr()->literal('folder'))
66
-					)
67
-				)
68
-			);
56
+        $qb = $connection->getQueryBuilder();
57
+        $qb->select('id', 'file_source', 'uid_owner', 'item_type')
58
+            ->from('share')
59
+            ->where(
60
+                $qb->expr()->andX(
61
+                    $qb->expr()->eq('share_type', $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK)),
62
+                    $qb->expr()->lte('expiration', $qb->expr()->literal($now)),
63
+                    $qb->expr()->orX(
64
+                        $qb->expr()->eq('item_type', $qb->expr()->literal('file')),
65
+                        $qb->expr()->eq('item_type', $qb->expr()->literal('folder'))
66
+                    )
67
+                )
68
+            );
69 69
 
70
-		$shares = $qb->execute();
71
-		while($share = $shares->fetch()) {
72
-			\OCP\Share::unshare($share['item_type'], $share['file_source'], \OCP\Share::SHARE_TYPE_LINK, null, $share['uid_owner']);
73
-		}
74
-		$shares->closeCursor();
75
-	}
70
+        $shares = $qb->execute();
71
+        while($share = $shares->fetch()) {
72
+            \OCP\Share::unshare($share['item_type'], $share['file_source'], \OCP\Share::SHARE_TYPE_LINK, null, $share['uid_owner']);
73
+        }
74
+        $shares->closeCursor();
75
+    }
76 76
 
77 77
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ExternalSharesController.php 1 patch
Indentation   +100 added lines, -100 removed lines patch added patch discarded remove patch
@@ -39,112 +39,112 @@
 block discarded – undo
39 39
  */
40 40
 class ExternalSharesController extends Controller {
41 41
 
42
-	/** @var \OCA\Files_Sharing\External\Manager */
43
-	private $externalManager;
44
-	/** @var IClientService */
45
-	private $clientService;
42
+    /** @var \OCA\Files_Sharing\External\Manager */
43
+    private $externalManager;
44
+    /** @var IClientService */
45
+    private $clientService;
46 46
 
47
-	/**
48
-	 * @param string $appName
49
-	 * @param IRequest $request
50
-	 * @param \OCA\Files_Sharing\External\Manager $externalManager
51
-	 * @param IClientService $clientService
52
-	 */
53
-	public function __construct($appName,
54
-								IRequest $request,
55
-								\OCA\Files_Sharing\External\Manager $externalManager,
56
-								IClientService $clientService) {
57
-		parent::__construct($appName, $request);
58
-		$this->externalManager = $externalManager;
59
-		$this->clientService = $clientService;
60
-	}
47
+    /**
48
+     * @param string $appName
49
+     * @param IRequest $request
50
+     * @param \OCA\Files_Sharing\External\Manager $externalManager
51
+     * @param IClientService $clientService
52
+     */
53
+    public function __construct($appName,
54
+                                IRequest $request,
55
+                                \OCA\Files_Sharing\External\Manager $externalManager,
56
+                                IClientService $clientService) {
57
+        parent::__construct($appName, $request);
58
+        $this->externalManager = $externalManager;
59
+        $this->clientService = $clientService;
60
+    }
61 61
 
62
-	/**
63
-	 * @NoAdminRequired
64
-	 * @NoOutgoingFederatedSharingRequired
65
-	 *
66
-	 * @return JSONResponse
67
-	 */
68
-	public function index() {
69
-		return new JSONResponse($this->externalManager->getOpenShares());
70
-	}
62
+    /**
63
+     * @NoAdminRequired
64
+     * @NoOutgoingFederatedSharingRequired
65
+     *
66
+     * @return JSONResponse
67
+     */
68
+    public function index() {
69
+        return new JSONResponse($this->externalManager->getOpenShares());
70
+    }
71 71
 
72
-	/**
73
-	 * @NoAdminRequired
74
-	 * @NoOutgoingFederatedSharingRequired
75
-	 *
76
-	 * @param int $id
77
-	 * @return JSONResponse
78
-	 */
79
-	public function create($id) {
80
-		$this->externalManager->acceptShare($id);
81
-		return new JSONResponse();
82
-	}
72
+    /**
73
+     * @NoAdminRequired
74
+     * @NoOutgoingFederatedSharingRequired
75
+     *
76
+     * @param int $id
77
+     * @return JSONResponse
78
+     */
79
+    public function create($id) {
80
+        $this->externalManager->acceptShare($id);
81
+        return new JSONResponse();
82
+    }
83 83
 
84
-	/**
85
-	 * @NoAdminRequired
86
-	 * @NoOutgoingFederatedSharingRequired
87
-	 *
88
-	 * @param integer $id
89
-	 * @return JSONResponse
90
-	 */
91
-	public function destroy($id) {
92
-		$this->externalManager->declineShare($id);
93
-		return new JSONResponse();
94
-	}
84
+    /**
85
+     * @NoAdminRequired
86
+     * @NoOutgoingFederatedSharingRequired
87
+     *
88
+     * @param integer $id
89
+     * @return JSONResponse
90
+     */
91
+    public function destroy($id) {
92
+        $this->externalManager->declineShare($id);
93
+        return new JSONResponse();
94
+    }
95 95
 
96
-	/**
97
-	 * Test whether the specified remote is accessible
98
-	 *
99
-	 * @param string $remote
100
-	 * @param bool $checkVersion
101
-	 * @return bool
102
-	 */
103
-	protected function testUrl($remote, $checkVersion = false) {
104
-		try {
105
-			$client = $this->clientService->newClient();
106
-			$response = json_decode($client->get(
107
-				$remote,
108
-				[
109
-					'timeout' => 3,
110
-					'connect_timeout' => 3,
111
-				]
112
-			)->getBody());
96
+    /**
97
+     * Test whether the specified remote is accessible
98
+     *
99
+     * @param string $remote
100
+     * @param bool $checkVersion
101
+     * @return bool
102
+     */
103
+    protected function testUrl($remote, $checkVersion = false) {
104
+        try {
105
+            $client = $this->clientService->newClient();
106
+            $response = json_decode($client->get(
107
+                $remote,
108
+                [
109
+                    'timeout' => 3,
110
+                    'connect_timeout' => 3,
111
+                ]
112
+            )->getBody());
113 113
 
114
-			if ($checkVersion) {
115
-				return !empty($response->version) && version_compare($response->version, '7.0.0', '>=');
116
-			} else {
117
-				return is_object($response);
118
-			}
119
-		} catch (\Exception $e) {
120
-			return false;
121
-		}
122
-	}
114
+            if ($checkVersion) {
115
+                return !empty($response->version) && version_compare($response->version, '7.0.0', '>=');
116
+            } else {
117
+                return is_object($response);
118
+            }
119
+        } catch (\Exception $e) {
120
+            return false;
121
+        }
122
+    }
123 123
 
124
-	/**
125
-	 * @PublicPage
126
-	 * @NoOutgoingFederatedSharingRequired
127
-	 * @NoIncomingFederatedSharingRequired
128
-	 *
129
-	 * @param string $remote
130
-	 * @return DataResponse
131
-	 */
132
-	public function testRemote($remote) {
133
-		if (
134
-			$this->testUrl('https://' . $remote . '/ocs-provider/') ||
135
-			$this->testUrl('https://' . $remote . '/ocs-provider/index.php') ||
136
-			$this->testUrl('https://' . $remote . '/status.php', true)
137
-		) {
138
-			return new DataResponse('https');
139
-		} elseif (
140
-			$this->testUrl('http://' . $remote . '/ocs-provider/') ||
141
-			$this->testUrl('http://' . $remote . '/ocs-provider/index.php') ||
142
-			$this->testUrl('http://' . $remote . '/status.php', true)
143
-		) {
144
-			return new DataResponse('http');
145
-		} else {
146
-			return new DataResponse(false);
147
-		}
148
-	}
124
+    /**
125
+     * @PublicPage
126
+     * @NoOutgoingFederatedSharingRequired
127
+     * @NoIncomingFederatedSharingRequired
128
+     *
129
+     * @param string $remote
130
+     * @return DataResponse
131
+     */
132
+    public function testRemote($remote) {
133
+        if (
134
+            $this->testUrl('https://' . $remote . '/ocs-provider/') ||
135
+            $this->testUrl('https://' . $remote . '/ocs-provider/index.php') ||
136
+            $this->testUrl('https://' . $remote . '/status.php', true)
137
+        ) {
138
+            return new DataResponse('https');
139
+        } elseif (
140
+            $this->testUrl('http://' . $remote . '/ocs-provider/') ||
141
+            $this->testUrl('http://' . $remote . '/ocs-provider/index.php') ||
142
+            $this->testUrl('http://' . $remote . '/status.php', true)
143
+        ) {
144
+            return new DataResponse('http');
145
+        } else {
146
+            return new DataResponse(false);
147
+        }
148
+    }
149 149
 
150 150
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareAPIController.php 1 patch
Indentation   +807 added lines, -807 removed lines patch added patch discarded remove patch
@@ -51,820 +51,820 @@
 block discarded – undo
51 51
  */
52 52
 class ShareAPIController extends OCSController {
53 53
 
54
-	/** @var IManager */
55
-	private $shareManager;
56
-	/** @var IGroupManager */
57
-	private $groupManager;
58
-	/** @var IUserManager */
59
-	private $userManager;
60
-	/** @var IRequest */
61
-	protected $request;
62
-	/** @var IRootFolder */
63
-	private $rootFolder;
64
-	/** @var IURLGenerator */
65
-	private $urlGenerator;
66
-	/** @var string */
67
-	private $currentUser;
68
-	/** @var IL10N */
69
-	private $l;
70
-	/** @var \OCP\Files\Node */
71
-	private $lockedNode;
72
-
73
-	/**
74
-	 * Share20OCS constructor.
75
-	 *
76
-	 * @param string $appName
77
-	 * @param IRequest $request
78
-	 * @param IManager $shareManager
79
-	 * @param IGroupManager $groupManager
80
-	 * @param IUserManager $userManager
81
-	 * @param IRootFolder $rootFolder
82
-	 * @param IURLGenerator $urlGenerator
83
-	 * @param string $userId
84
-	 * @param IL10N $l10n
85
-	 */
86
-	public function __construct(
87
-		$appName,
88
-		IRequest $request,
89
-		IManager $shareManager,
90
-		IGroupManager $groupManager,
91
-		IUserManager $userManager,
92
-		IRootFolder $rootFolder,
93
-		IURLGenerator $urlGenerator,
94
-		$userId,
95
-		IL10N $l10n
96
-	) {
97
-		parent::__construct($appName, $request);
98
-
99
-		$this->shareManager = $shareManager;
100
-		$this->userManager = $userManager;
101
-		$this->groupManager = $groupManager;
102
-		$this->request = $request;
103
-		$this->rootFolder = $rootFolder;
104
-		$this->urlGenerator = $urlGenerator;
105
-		$this->currentUser = $userId;
106
-		$this->l = $l10n;
107
-	}
108
-
109
-	/**
110
-	 * Convert an IShare to an array for OCS output
111
-	 *
112
-	 * @param \OCP\Share\IShare $share
113
-	 * @param Node|null $recipientNode
114
-	 * @return array
115
-	 * @throws NotFoundException In case the node can't be resolved.
116
-	 */
117
-	protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null) {
118
-		$sharedBy = $this->userManager->get($share->getSharedBy());
119
-		$shareOwner = $this->userManager->get($share->getShareOwner());
120
-
121
-		$result = [
122
-			'id' => $share->getId(),
123
-			'share_type' => $share->getShareType(),
124
-			'uid_owner' => $share->getSharedBy(),
125
-			'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
126
-			'permissions' => $share->getPermissions(),
127
-			'stime' => $share->getShareTime()->getTimestamp(),
128
-			'parent' => null,
129
-			'expiration' => null,
130
-			'token' => null,
131
-			'uid_file_owner' => $share->getShareOwner(),
132
-			'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
133
-		];
134
-
135
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
136
-		if ($recipientNode) {
137
-			$node = $recipientNode;
138
-		} else {
139
-			$nodes = $userFolder->getById($share->getNodeId());
140
-
141
-			if (empty($nodes)) {
142
-				// fallback to guessing the path
143
-				$node = $userFolder->get($share->getTarget());
144
-				if ($node === null) {
145
-					throw new NotFoundException();
146
-				}
147
-			} else {
148
-				$node = $nodes[0];
149
-			}
150
-		}
151
-
152
-		$result['path'] = $userFolder->getRelativePath($node->getPath());
153
-		if ($node instanceOf \OCP\Files\Folder) {
154
-			$result['item_type'] = 'folder';
155
-		} else {
156
-			$result['item_type'] = 'file';
157
-		}
158
-		$result['mimetype'] = $node->getMimetype();
159
-		$result['storage_id'] = $node->getStorage()->getId();
160
-		$result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
161
-		$result['item_source'] = $node->getId();
162
-		$result['file_source'] = $node->getId();
163
-		$result['file_parent'] = $node->getParent()->getId();
164
-		$result['file_target'] = $share->getTarget();
165
-
166
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
167
-			$sharedWith = $this->userManager->get($share->getSharedWith());
168
-			$result['share_with'] = $share->getSharedWith();
169
-			$result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
170
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
171
-			$group = $this->groupManager->get($share->getSharedWith());
172
-			$result['share_with'] = $share->getSharedWith();
173
-			$result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
174
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
175
-
176
-			$result['share_with'] = $share->getPassword();
177
-			$result['share_with_displayname'] = $share->getPassword();
178
-
179
-			$result['token'] = $share->getToken();
180
-			$result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
181
-
182
-			$expiration = $share->getExpirationDate();
183
-			if ($expiration !== null) {
184
-				$result['expiration'] = $expiration->format('Y-m-d 00:00:00');
185
-			}
186
-
187
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
188
-			$result['share_with'] = $share->getSharedWith();
189
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
190
-			$result['token'] = $share->getToken();
191
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
192
-			$result['share_with'] = $share->getSharedWith();
193
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
194
-			$result['token'] = $share->getToken();
195
-		}
196
-
197
-		$result['mail_send'] = $share->getMailSend() ? 1 : 0;
198
-
199
-		return $result;
200
-	}
201
-
202
-	/**
203
-	 * Check if one of the users address books knows the exact property, if
204
-	 * yes we return the full name.
205
-	 *
206
-	 * @param string $query
207
-	 * @param string $property
208
-	 * @return string
209
-	 */
210
-	private function getDisplayNameFromAddressBook($query, $property) {
211
-		// FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
212
-		$result = \OC::$server->getContactsManager()->search($query, [$property]);
213
-		foreach ($result as $r) {
214
-			foreach($r[$property] as $value) {
215
-				if ($value === $query) {
216
-					return $r['FN'];
217
-				}
218
-			}
219
-		}
220
-
221
-		return $query;
222
-	}
223
-
224
-	/**
225
-	 * Get a specific share by id
226
-	 *
227
-	 * @NoAdminRequired
228
-	 *
229
-	 * @param string $id
230
-	 * @return DataResponse
231
-	 * @throws OCSNotFoundException
232
-	 */
233
-	public function getShare($id) {
234
-		try {
235
-			$share = $this->getShareById($id);
236
-		} catch (ShareNotFound $e) {
237
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
238
-		}
239
-
240
-		if ($this->canAccessShare($share)) {
241
-			try {
242
-				$share = $this->formatShare($share);
243
-				return new DataResponse([$share]);
244
-			} catch (NotFoundException $e) {
245
-				//Fall trough
246
-			}
247
-		}
248
-
249
-		throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
250
-	}
251
-
252
-	/**
253
-	 * Delete a share
254
-	 *
255
-	 * @NoAdminRequired
256
-	 *
257
-	 * @param string $id
258
-	 * @return DataResponse
259
-	 * @throws OCSNotFoundException
260
-	 */
261
-	public function deleteShare($id) {
262
-		try {
263
-			$share = $this->getShareById($id);
264
-		} catch (ShareNotFound $e) {
265
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
266
-		}
267
-
268
-		try {
269
-			$this->lock($share->getNode());
270
-		} catch (LockedException $e) {
271
-			throw new OCSNotFoundException($this->l->t('could not delete share'));
272
-		}
273
-
274
-		if (!$this->canAccessShare($share)) {
275
-			throw new OCSNotFoundException($this->l->t('Could not delete share'));
276
-		}
277
-
278
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP &&
279
-			$share->getShareOwner() !== $this->currentUser &&
280
-			$share->getSharedBy() !== $this->currentUser) {
281
-			$this->shareManager->deleteFromSelf($share, $this->currentUser);
282
-		} else {
283
-			$this->shareManager->deleteShare($share);
284
-		}
285
-
286
-		return new DataResponse();
287
-	}
288
-
289
-	/**
290
-	 * @NoAdminRequired
291
-	 *
292
-	 * @param string $path
293
-	 * @param int $permissions
294
-	 * @param int $shareType
295
-	 * @param string $shareWith
296
-	 * @param string $publicUpload
297
-	 * @param string $password
298
-	 * @param string $expireDate
299
-	 *
300
-	 * @return DataResponse
301
-	 * @throws OCSNotFoundException
302
-	 * @throws OCSForbiddenException
303
-	 * @throws OCSBadRequestException
304
-	 * @throws OCSException
305
-	 */
306
-	public function createShare(
307
-		$path = null,
308
-		$permissions = \OCP\Constants::PERMISSION_ALL,
309
-		$shareType = -1,
310
-		$shareWith = null,
311
-		$publicUpload = 'false',
312
-		$password = '',
313
-		$expireDate = ''
314
-	) {
315
-		$share = $this->shareManager->newShare();
316
-
317
-		// Verify path
318
-		if ($path === null) {
319
-			throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
320
-		}
321
-
322
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
323
-		try {
324
-			$path = $userFolder->get($path);
325
-		} catch (NotFoundException $e) {
326
-			throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
327
-		}
328
-
329
-		$share->setNode($path);
330
-
331
-		try {
332
-			$this->lock($share->getNode());
333
-		} catch (LockedException $e) {
334
-			throw new OCSNotFoundException($this->l->t('Could not create share'));
335
-		}
336
-
337
-		if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) {
338
-			throw new OCSNotFoundException($this->l->t('invalid permissions'));
339
-		}
340
-
341
-		// Shares always require read permissions
342
-		$permissions |= \OCP\Constants::PERMISSION_READ;
343
-
344
-		if ($path instanceof \OCP\Files\File) {
345
-			// Single file shares should never have delete or create permissions
346
-			$permissions &= ~\OCP\Constants::PERMISSION_DELETE;
347
-			$permissions &= ~\OCP\Constants::PERMISSION_CREATE;
348
-		}
349
-
350
-		/*
54
+    /** @var IManager */
55
+    private $shareManager;
56
+    /** @var IGroupManager */
57
+    private $groupManager;
58
+    /** @var IUserManager */
59
+    private $userManager;
60
+    /** @var IRequest */
61
+    protected $request;
62
+    /** @var IRootFolder */
63
+    private $rootFolder;
64
+    /** @var IURLGenerator */
65
+    private $urlGenerator;
66
+    /** @var string */
67
+    private $currentUser;
68
+    /** @var IL10N */
69
+    private $l;
70
+    /** @var \OCP\Files\Node */
71
+    private $lockedNode;
72
+
73
+    /**
74
+     * Share20OCS constructor.
75
+     *
76
+     * @param string $appName
77
+     * @param IRequest $request
78
+     * @param IManager $shareManager
79
+     * @param IGroupManager $groupManager
80
+     * @param IUserManager $userManager
81
+     * @param IRootFolder $rootFolder
82
+     * @param IURLGenerator $urlGenerator
83
+     * @param string $userId
84
+     * @param IL10N $l10n
85
+     */
86
+    public function __construct(
87
+        $appName,
88
+        IRequest $request,
89
+        IManager $shareManager,
90
+        IGroupManager $groupManager,
91
+        IUserManager $userManager,
92
+        IRootFolder $rootFolder,
93
+        IURLGenerator $urlGenerator,
94
+        $userId,
95
+        IL10N $l10n
96
+    ) {
97
+        parent::__construct($appName, $request);
98
+
99
+        $this->shareManager = $shareManager;
100
+        $this->userManager = $userManager;
101
+        $this->groupManager = $groupManager;
102
+        $this->request = $request;
103
+        $this->rootFolder = $rootFolder;
104
+        $this->urlGenerator = $urlGenerator;
105
+        $this->currentUser = $userId;
106
+        $this->l = $l10n;
107
+    }
108
+
109
+    /**
110
+     * Convert an IShare to an array for OCS output
111
+     *
112
+     * @param \OCP\Share\IShare $share
113
+     * @param Node|null $recipientNode
114
+     * @return array
115
+     * @throws NotFoundException In case the node can't be resolved.
116
+     */
117
+    protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null) {
118
+        $sharedBy = $this->userManager->get($share->getSharedBy());
119
+        $shareOwner = $this->userManager->get($share->getShareOwner());
120
+
121
+        $result = [
122
+            'id' => $share->getId(),
123
+            'share_type' => $share->getShareType(),
124
+            'uid_owner' => $share->getSharedBy(),
125
+            'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
126
+            'permissions' => $share->getPermissions(),
127
+            'stime' => $share->getShareTime()->getTimestamp(),
128
+            'parent' => null,
129
+            'expiration' => null,
130
+            'token' => null,
131
+            'uid_file_owner' => $share->getShareOwner(),
132
+            'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
133
+        ];
134
+
135
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
136
+        if ($recipientNode) {
137
+            $node = $recipientNode;
138
+        } else {
139
+            $nodes = $userFolder->getById($share->getNodeId());
140
+
141
+            if (empty($nodes)) {
142
+                // fallback to guessing the path
143
+                $node = $userFolder->get($share->getTarget());
144
+                if ($node === null) {
145
+                    throw new NotFoundException();
146
+                }
147
+            } else {
148
+                $node = $nodes[0];
149
+            }
150
+        }
151
+
152
+        $result['path'] = $userFolder->getRelativePath($node->getPath());
153
+        if ($node instanceOf \OCP\Files\Folder) {
154
+            $result['item_type'] = 'folder';
155
+        } else {
156
+            $result['item_type'] = 'file';
157
+        }
158
+        $result['mimetype'] = $node->getMimetype();
159
+        $result['storage_id'] = $node->getStorage()->getId();
160
+        $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
161
+        $result['item_source'] = $node->getId();
162
+        $result['file_source'] = $node->getId();
163
+        $result['file_parent'] = $node->getParent()->getId();
164
+        $result['file_target'] = $share->getTarget();
165
+
166
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
167
+            $sharedWith = $this->userManager->get($share->getSharedWith());
168
+            $result['share_with'] = $share->getSharedWith();
169
+            $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
170
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
171
+            $group = $this->groupManager->get($share->getSharedWith());
172
+            $result['share_with'] = $share->getSharedWith();
173
+            $result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
174
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
175
+
176
+            $result['share_with'] = $share->getPassword();
177
+            $result['share_with_displayname'] = $share->getPassword();
178
+
179
+            $result['token'] = $share->getToken();
180
+            $result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
181
+
182
+            $expiration = $share->getExpirationDate();
183
+            if ($expiration !== null) {
184
+                $result['expiration'] = $expiration->format('Y-m-d 00:00:00');
185
+            }
186
+
187
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
188
+            $result['share_with'] = $share->getSharedWith();
189
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
190
+            $result['token'] = $share->getToken();
191
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
192
+            $result['share_with'] = $share->getSharedWith();
193
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
194
+            $result['token'] = $share->getToken();
195
+        }
196
+
197
+        $result['mail_send'] = $share->getMailSend() ? 1 : 0;
198
+
199
+        return $result;
200
+    }
201
+
202
+    /**
203
+     * Check if one of the users address books knows the exact property, if
204
+     * yes we return the full name.
205
+     *
206
+     * @param string $query
207
+     * @param string $property
208
+     * @return string
209
+     */
210
+    private function getDisplayNameFromAddressBook($query, $property) {
211
+        // FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
212
+        $result = \OC::$server->getContactsManager()->search($query, [$property]);
213
+        foreach ($result as $r) {
214
+            foreach($r[$property] as $value) {
215
+                if ($value === $query) {
216
+                    return $r['FN'];
217
+                }
218
+            }
219
+        }
220
+
221
+        return $query;
222
+    }
223
+
224
+    /**
225
+     * Get a specific share by id
226
+     *
227
+     * @NoAdminRequired
228
+     *
229
+     * @param string $id
230
+     * @return DataResponse
231
+     * @throws OCSNotFoundException
232
+     */
233
+    public function getShare($id) {
234
+        try {
235
+            $share = $this->getShareById($id);
236
+        } catch (ShareNotFound $e) {
237
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
238
+        }
239
+
240
+        if ($this->canAccessShare($share)) {
241
+            try {
242
+                $share = $this->formatShare($share);
243
+                return new DataResponse([$share]);
244
+            } catch (NotFoundException $e) {
245
+                //Fall trough
246
+            }
247
+        }
248
+
249
+        throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
250
+    }
251
+
252
+    /**
253
+     * Delete a share
254
+     *
255
+     * @NoAdminRequired
256
+     *
257
+     * @param string $id
258
+     * @return DataResponse
259
+     * @throws OCSNotFoundException
260
+     */
261
+    public function deleteShare($id) {
262
+        try {
263
+            $share = $this->getShareById($id);
264
+        } catch (ShareNotFound $e) {
265
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
266
+        }
267
+
268
+        try {
269
+            $this->lock($share->getNode());
270
+        } catch (LockedException $e) {
271
+            throw new OCSNotFoundException($this->l->t('could not delete share'));
272
+        }
273
+
274
+        if (!$this->canAccessShare($share)) {
275
+            throw new OCSNotFoundException($this->l->t('Could not delete share'));
276
+        }
277
+
278
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP &&
279
+            $share->getShareOwner() !== $this->currentUser &&
280
+            $share->getSharedBy() !== $this->currentUser) {
281
+            $this->shareManager->deleteFromSelf($share, $this->currentUser);
282
+        } else {
283
+            $this->shareManager->deleteShare($share);
284
+        }
285
+
286
+        return new DataResponse();
287
+    }
288
+
289
+    /**
290
+     * @NoAdminRequired
291
+     *
292
+     * @param string $path
293
+     * @param int $permissions
294
+     * @param int $shareType
295
+     * @param string $shareWith
296
+     * @param string $publicUpload
297
+     * @param string $password
298
+     * @param string $expireDate
299
+     *
300
+     * @return DataResponse
301
+     * @throws OCSNotFoundException
302
+     * @throws OCSForbiddenException
303
+     * @throws OCSBadRequestException
304
+     * @throws OCSException
305
+     */
306
+    public function createShare(
307
+        $path = null,
308
+        $permissions = \OCP\Constants::PERMISSION_ALL,
309
+        $shareType = -1,
310
+        $shareWith = null,
311
+        $publicUpload = 'false',
312
+        $password = '',
313
+        $expireDate = ''
314
+    ) {
315
+        $share = $this->shareManager->newShare();
316
+
317
+        // Verify path
318
+        if ($path === null) {
319
+            throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
320
+        }
321
+
322
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
323
+        try {
324
+            $path = $userFolder->get($path);
325
+        } catch (NotFoundException $e) {
326
+            throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
327
+        }
328
+
329
+        $share->setNode($path);
330
+
331
+        try {
332
+            $this->lock($share->getNode());
333
+        } catch (LockedException $e) {
334
+            throw new OCSNotFoundException($this->l->t('Could not create share'));
335
+        }
336
+
337
+        if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) {
338
+            throw new OCSNotFoundException($this->l->t('invalid permissions'));
339
+        }
340
+
341
+        // Shares always require read permissions
342
+        $permissions |= \OCP\Constants::PERMISSION_READ;
343
+
344
+        if ($path instanceof \OCP\Files\File) {
345
+            // Single file shares should never have delete or create permissions
346
+            $permissions &= ~\OCP\Constants::PERMISSION_DELETE;
347
+            $permissions &= ~\OCP\Constants::PERMISSION_CREATE;
348
+        }
349
+
350
+        /*
351 351
 		 * Hack for https://github.com/owncloud/core/issues/22587
352 352
 		 * We check the permissions via webdav. But the permissions of the mount point
353 353
 		 * do not equal the share permissions. Here we fix that for federated mounts.
354 354
 		 */
355
-		if ($path->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
356
-			$permissions &= ~($permissions & ~$path->getPermissions());
357
-		}
358
-
359
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
360
-			// Valid user is required to share
361
-			if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
362
-				throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
363
-			}
364
-			$share->setSharedWith($shareWith);
365
-			$share->setPermissions($permissions);
366
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
367
-			if (!$this->shareManager->allowGroupSharing()) {
368
-				throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
369
-			}
370
-
371
-			// Valid group is required to share
372
-			if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
373
-				throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
374
-			}
375
-			$share->setSharedWith($shareWith);
376
-			$share->setPermissions($permissions);
377
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
378
-			//Can we even share links?
379
-			if (!$this->shareManager->shareApiAllowLinks()) {
380
-				throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
381
-			}
382
-
383
-			/*
355
+        if ($path->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
356
+            $permissions &= ~($permissions & ~$path->getPermissions());
357
+        }
358
+
359
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
360
+            // Valid user is required to share
361
+            if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
362
+                throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
363
+            }
364
+            $share->setSharedWith($shareWith);
365
+            $share->setPermissions($permissions);
366
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
367
+            if (!$this->shareManager->allowGroupSharing()) {
368
+                throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
369
+            }
370
+
371
+            // Valid group is required to share
372
+            if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
373
+                throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
374
+            }
375
+            $share->setSharedWith($shareWith);
376
+            $share->setPermissions($permissions);
377
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
378
+            //Can we even share links?
379
+            if (!$this->shareManager->shareApiAllowLinks()) {
380
+                throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
381
+            }
382
+
383
+            /*
384 384
 			 * For now we only allow 1 link share.
385 385
 			 * Return the existing link share if this is a duplicate
386 386
 			 */
387
-			$existingShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0);
388
-			if (!empty($existingShares)) {
389
-				return new DataResponse($this->formatShare($existingShares[0]));
390
-			}
391
-
392
-			if ($publicUpload === 'true') {
393
-				// Check if public upload is allowed
394
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
395
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
396
-				}
397
-
398
-				// Public upload can only be set for folders
399
-				if ($path instanceof \OCP\Files\File) {
400
-					throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
401
-				}
402
-
403
-				$share->setPermissions(
404
-					\OCP\Constants::PERMISSION_READ |
405
-					\OCP\Constants::PERMISSION_CREATE |
406
-					\OCP\Constants::PERMISSION_UPDATE |
407
-					\OCP\Constants::PERMISSION_DELETE
408
-				);
409
-			} else {
410
-				$share->setPermissions(\OCP\Constants::PERMISSION_READ);
411
-			}
412
-
413
-			// Set password
414
-			if ($password !== '') {
415
-				$share->setPassword($password);
416
-			}
417
-
418
-			//Expire date
419
-			if ($expireDate !== '') {
420
-				try {
421
-					$expireDate = $this->parseDate($expireDate);
422
-					$share->setExpirationDate($expireDate);
423
-				} catch (\Exception $e) {
424
-					throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
425
-				}
426
-			}
427
-
428
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
429
-			if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
430
-				throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
431
-			}
432
-
433
-			$share->setSharedWith($shareWith);
434
-			$share->setPermissions($permissions);
435
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_EMAIL) {
436
-			if ($share->getNodeType() === 'file') {
437
-				$share->setPermissions(\OCP\Constants::PERMISSION_READ);
438
-			} else {
439
-				$share->setPermissions(
440
-					\OCP\Constants::PERMISSION_READ |
441
-					\OCP\Constants::PERMISSION_CREATE |
442
-					\OCP\Constants::PERMISSION_UPDATE |
443
-					\OCP\Constants::PERMISSION_DELETE);
444
-			}
445
-			$share->setSharedWith($shareWith);
446
-		} else {
447
-			throw new OCSBadRequestException($this->l->t('Unknown share type'));
448
-		}
449
-
450
-		$share->setShareType($shareType);
451
-		$share->setSharedBy($this->currentUser);
452
-
453
-		try {
454
-			$share = $this->shareManager->createShare($share);
455
-		} catch (GenericShareException $e) {
456
-			$code = $e->getCode() === 0 ? 403 : $e->getCode();
457
-			throw new OCSException($e->getHint(), $code);
458
-		} catch (\Exception $e) {
459
-			throw new OCSForbiddenException($e->getMessage());
460
-		}
461
-
462
-		$output = $this->formatShare($share);
463
-
464
-		return new DataResponse($output);
465
-	}
466
-
467
-	/**
468
-	 * @param \OCP\Files\File|\OCP\Files\Folder $node
469
-	 * @return DataResponse
470
-	 */
471
-	private function getSharedWithMe($node = null) {
472
-		$userShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, -1, 0);
473
-		$groupShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0);
474
-
475
-		$shares = array_merge($userShares, $groupShares);
476
-
477
-		$shares = array_filter($shares, function (IShare $share) {
478
-			return $share->getShareOwner() !== $this->currentUser;
479
-		});
480
-
481
-		$formatted = [];
482
-		foreach ($shares as $share) {
483
-			if ($this->canAccessShare($share)) {
484
-				try {
485
-					$formatted[] = $this->formatShare($share);
486
-				} catch (NotFoundException $e) {
487
-					// Ignore this share
488
-				}
489
-			}
490
-		}
491
-
492
-		return new DataResponse($formatted);
493
-	}
494
-
495
-	/**
496
-	 * @param \OCP\Files\Folder $folder
497
-	 * @return DataResponse
498
-	 * @throws OCSBadRequestException
499
-	 */
500
-	private function getSharesInDir($folder) {
501
-		if (!($folder instanceof \OCP\Files\Folder)) {
502
-			throw new OCSBadRequestException($this->l->t('Not a directory'));
503
-		}
504
-
505
-		$nodes = $folder->getDirectoryListing();
506
-		/** @var \OCP\Share\IShare[] $shares */
507
-		$shares = [];
508
-		foreach ($nodes as $node) {
509
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0));
510
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
511
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0));
512
-			if($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
513
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
514
-			}
515
-			if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
516
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
517
-			}
518
-		}
519
-
520
-		$formatted = [];
521
-		foreach ($shares as $share) {
522
-			try {
523
-				$formatted[] = $this->formatShare($share);
524
-			} catch (NotFoundException $e) {
525
-				//Ignore this share
526
-			}
527
-		}
528
-
529
-		return new DataResponse($formatted);
530
-	}
531
-
532
-	/**
533
-	 * The getShares function.
534
-	 *
535
-	 * @NoAdminRequired
536
-	 *
537
-	 * @param string $shared_with_me
538
-	 * @param string $reshares
539
-	 * @param string $subfiles
540
-	 * @param string $path
541
-	 *
542
-	 * - Get shares by the current user
543
-	 * - Get shares by the current user and reshares (?reshares=true)
544
-	 * - Get shares with the current user (?shared_with_me=true)
545
-	 * - Get shares for a specific path (?path=...)
546
-	 * - Get all shares in a folder (?subfiles=true&path=..)
547
-	 *
548
-	 * @return DataResponse
549
-	 * @throws OCSNotFoundException
550
-	 */
551
-	public function getShares(
552
-		$shared_with_me = 'false',
553
-		$reshares = 'false',
554
-		$subfiles = 'false',
555
-		$path = null
556
-	) {
557
-
558
-		if ($path !== null) {
559
-			$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
560
-			try {
561
-				$path = $userFolder->get($path);
562
-				$this->lock($path);
563
-			} catch (\OCP\Files\NotFoundException $e) {
564
-				throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
565
-			} catch (LockedException $e) {
566
-				throw new OCSNotFoundException($this->l->t('Could not lock path'));
567
-			}
568
-		}
569
-
570
-		if ($shared_with_me === 'true') {
571
-			$result = $this->getSharedWithMe($path);
572
-			return $result;
573
-		}
574
-
575
-		if ($subfiles === 'true') {
576
-			$result = $this->getSharesInDir($path);
577
-			return $result;
578
-		}
579
-
580
-		if ($reshares === 'true') {
581
-			$reshares = true;
582
-		} else {
583
-			$reshares = false;
584
-		}
585
-
586
-		// Get all shares
587
-		$userShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
588
-		$groupShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
589
-		$linkShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
590
-		if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
591
-			$mailShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
592
-		} else {
593
-			$mailShares = [];
594
-		}
595
-		$shares = array_merge($userShares, $groupShares, $linkShares, $mailShares);
596
-
597
-		if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
598
-			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
599
-			$shares = array_merge($shares, $federatedShares);
600
-		}
601
-
602
-		$formatted = [];
603
-		foreach ($shares as $share) {
604
-			try {
605
-				$formatted[] = $this->formatShare($share, $path);
606
-			} catch (NotFoundException $e) {
607
-				//Ignore share
608
-			}
609
-		}
610
-
611
-		return new DataResponse($formatted);
612
-	}
613
-
614
-	/**
615
-	 * @NoAdminRequired
616
-	 *
617
-	 * @param int $id
618
-	 * @param int $permissions
619
-	 * @param string $password
620
-	 * @param string $publicUpload
621
-	 * @param string $expireDate
622
-	 * @return DataResponse
623
-	 * @throws OCSNotFoundException
624
-	 * @throws OCSBadRequestException
625
-	 * @throws OCSForbiddenException
626
-	 */
627
-	public function updateShare(
628
-		$id,
629
-		$permissions = null,
630
-		$password = null,
631
-		$publicUpload = null,
632
-		$expireDate = null
633
-	) {
634
-		try {
635
-			$share = $this->getShareById($id);
636
-		} catch (ShareNotFound $e) {
637
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
638
-		}
639
-
640
-		$this->lock($share->getNode());
641
-
642
-		if (!$this->canAccessShare($share, false)) {
643
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
644
-		}
645
-
646
-		/*
387
+            $existingShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0);
388
+            if (!empty($existingShares)) {
389
+                return new DataResponse($this->formatShare($existingShares[0]));
390
+            }
391
+
392
+            if ($publicUpload === 'true') {
393
+                // Check if public upload is allowed
394
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
395
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
396
+                }
397
+
398
+                // Public upload can only be set for folders
399
+                if ($path instanceof \OCP\Files\File) {
400
+                    throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
401
+                }
402
+
403
+                $share->setPermissions(
404
+                    \OCP\Constants::PERMISSION_READ |
405
+                    \OCP\Constants::PERMISSION_CREATE |
406
+                    \OCP\Constants::PERMISSION_UPDATE |
407
+                    \OCP\Constants::PERMISSION_DELETE
408
+                );
409
+            } else {
410
+                $share->setPermissions(\OCP\Constants::PERMISSION_READ);
411
+            }
412
+
413
+            // Set password
414
+            if ($password !== '') {
415
+                $share->setPassword($password);
416
+            }
417
+
418
+            //Expire date
419
+            if ($expireDate !== '') {
420
+                try {
421
+                    $expireDate = $this->parseDate($expireDate);
422
+                    $share->setExpirationDate($expireDate);
423
+                } catch (\Exception $e) {
424
+                    throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
425
+                }
426
+            }
427
+
428
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
429
+            if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
430
+                throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
431
+            }
432
+
433
+            $share->setSharedWith($shareWith);
434
+            $share->setPermissions($permissions);
435
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_EMAIL) {
436
+            if ($share->getNodeType() === 'file') {
437
+                $share->setPermissions(\OCP\Constants::PERMISSION_READ);
438
+            } else {
439
+                $share->setPermissions(
440
+                    \OCP\Constants::PERMISSION_READ |
441
+                    \OCP\Constants::PERMISSION_CREATE |
442
+                    \OCP\Constants::PERMISSION_UPDATE |
443
+                    \OCP\Constants::PERMISSION_DELETE);
444
+            }
445
+            $share->setSharedWith($shareWith);
446
+        } else {
447
+            throw new OCSBadRequestException($this->l->t('Unknown share type'));
448
+        }
449
+
450
+        $share->setShareType($shareType);
451
+        $share->setSharedBy($this->currentUser);
452
+
453
+        try {
454
+            $share = $this->shareManager->createShare($share);
455
+        } catch (GenericShareException $e) {
456
+            $code = $e->getCode() === 0 ? 403 : $e->getCode();
457
+            throw new OCSException($e->getHint(), $code);
458
+        } catch (\Exception $e) {
459
+            throw new OCSForbiddenException($e->getMessage());
460
+        }
461
+
462
+        $output = $this->formatShare($share);
463
+
464
+        return new DataResponse($output);
465
+    }
466
+
467
+    /**
468
+     * @param \OCP\Files\File|\OCP\Files\Folder $node
469
+     * @return DataResponse
470
+     */
471
+    private function getSharedWithMe($node = null) {
472
+        $userShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, -1, 0);
473
+        $groupShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0);
474
+
475
+        $shares = array_merge($userShares, $groupShares);
476
+
477
+        $shares = array_filter($shares, function (IShare $share) {
478
+            return $share->getShareOwner() !== $this->currentUser;
479
+        });
480
+
481
+        $formatted = [];
482
+        foreach ($shares as $share) {
483
+            if ($this->canAccessShare($share)) {
484
+                try {
485
+                    $formatted[] = $this->formatShare($share);
486
+                } catch (NotFoundException $e) {
487
+                    // Ignore this share
488
+                }
489
+            }
490
+        }
491
+
492
+        return new DataResponse($formatted);
493
+    }
494
+
495
+    /**
496
+     * @param \OCP\Files\Folder $folder
497
+     * @return DataResponse
498
+     * @throws OCSBadRequestException
499
+     */
500
+    private function getSharesInDir($folder) {
501
+        if (!($folder instanceof \OCP\Files\Folder)) {
502
+            throw new OCSBadRequestException($this->l->t('Not a directory'));
503
+        }
504
+
505
+        $nodes = $folder->getDirectoryListing();
506
+        /** @var \OCP\Share\IShare[] $shares */
507
+        $shares = [];
508
+        foreach ($nodes as $node) {
509
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0));
510
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
511
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0));
512
+            if($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
513
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
514
+            }
515
+            if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
516
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
517
+            }
518
+        }
519
+
520
+        $formatted = [];
521
+        foreach ($shares as $share) {
522
+            try {
523
+                $formatted[] = $this->formatShare($share);
524
+            } catch (NotFoundException $e) {
525
+                //Ignore this share
526
+            }
527
+        }
528
+
529
+        return new DataResponse($formatted);
530
+    }
531
+
532
+    /**
533
+     * The getShares function.
534
+     *
535
+     * @NoAdminRequired
536
+     *
537
+     * @param string $shared_with_me
538
+     * @param string $reshares
539
+     * @param string $subfiles
540
+     * @param string $path
541
+     *
542
+     * - Get shares by the current user
543
+     * - Get shares by the current user and reshares (?reshares=true)
544
+     * - Get shares with the current user (?shared_with_me=true)
545
+     * - Get shares for a specific path (?path=...)
546
+     * - Get all shares in a folder (?subfiles=true&path=..)
547
+     *
548
+     * @return DataResponse
549
+     * @throws OCSNotFoundException
550
+     */
551
+    public function getShares(
552
+        $shared_with_me = 'false',
553
+        $reshares = 'false',
554
+        $subfiles = 'false',
555
+        $path = null
556
+    ) {
557
+
558
+        if ($path !== null) {
559
+            $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
560
+            try {
561
+                $path = $userFolder->get($path);
562
+                $this->lock($path);
563
+            } catch (\OCP\Files\NotFoundException $e) {
564
+                throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
565
+            } catch (LockedException $e) {
566
+                throw new OCSNotFoundException($this->l->t('Could not lock path'));
567
+            }
568
+        }
569
+
570
+        if ($shared_with_me === 'true') {
571
+            $result = $this->getSharedWithMe($path);
572
+            return $result;
573
+        }
574
+
575
+        if ($subfiles === 'true') {
576
+            $result = $this->getSharesInDir($path);
577
+            return $result;
578
+        }
579
+
580
+        if ($reshares === 'true') {
581
+            $reshares = true;
582
+        } else {
583
+            $reshares = false;
584
+        }
585
+
586
+        // Get all shares
587
+        $userShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
588
+        $groupShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
589
+        $linkShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
590
+        if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
591
+            $mailShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
592
+        } else {
593
+            $mailShares = [];
594
+        }
595
+        $shares = array_merge($userShares, $groupShares, $linkShares, $mailShares);
596
+
597
+        if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
598
+            $federatedShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
599
+            $shares = array_merge($shares, $federatedShares);
600
+        }
601
+
602
+        $formatted = [];
603
+        foreach ($shares as $share) {
604
+            try {
605
+                $formatted[] = $this->formatShare($share, $path);
606
+            } catch (NotFoundException $e) {
607
+                //Ignore share
608
+            }
609
+        }
610
+
611
+        return new DataResponse($formatted);
612
+    }
613
+
614
+    /**
615
+     * @NoAdminRequired
616
+     *
617
+     * @param int $id
618
+     * @param int $permissions
619
+     * @param string $password
620
+     * @param string $publicUpload
621
+     * @param string $expireDate
622
+     * @return DataResponse
623
+     * @throws OCSNotFoundException
624
+     * @throws OCSBadRequestException
625
+     * @throws OCSForbiddenException
626
+     */
627
+    public function updateShare(
628
+        $id,
629
+        $permissions = null,
630
+        $password = null,
631
+        $publicUpload = null,
632
+        $expireDate = null
633
+    ) {
634
+        try {
635
+            $share = $this->getShareById($id);
636
+        } catch (ShareNotFound $e) {
637
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
638
+        }
639
+
640
+        $this->lock($share->getNode());
641
+
642
+        if (!$this->canAccessShare($share, false)) {
643
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
644
+        }
645
+
646
+        /*
647 647
 		 * expirationdate, password and publicUpload only make sense for link shares
648 648
 		 */
649
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
650
-			if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
651
-				throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
652
-			}
653
-
654
-			$newPermissions = null;
655
-			if ($publicUpload === 'true') {
656
-				$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
657
-			} else if ($publicUpload === 'false') {
658
-				$newPermissions = \OCP\Constants::PERMISSION_READ;
659
-			}
660
-
661
-			if ($permissions !== null) {
662
-				$newPermissions = (int)$permissions;
663
-			}
664
-
665
-			if ($newPermissions !== null &&
666
-				!in_array($newPermissions, [
667
-					\OCP\Constants::PERMISSION_READ,
668
-					\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE, // legacy
669
-					\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE, // correct
670
-					\OCP\Constants::PERMISSION_CREATE, // hidden file list
671
-					\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE, // allow to edit single files
672
-				])
673
-			) {
674
-				throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
675
-			}
676
-
677
-			if (
678
-				// legacy
679
-				$newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) ||
680
-				// correct
681
-				$newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
682
-			) {
683
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
684
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
685
-				}
686
-
687
-				if (!($share->getNode() instanceof \OCP\Files\Folder)) {
688
-					throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
689
-				}
690
-
691
-				// normalize to correct public upload permissions
692
-				$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
693
-			}
694
-
695
-			if ($newPermissions !== null) {
696
-				$share->setPermissions($newPermissions);
697
-				$permissions = $newPermissions;
698
-			}
699
-
700
-			if ($expireDate === '') {
701
-				$share->setExpirationDate(null);
702
-			} else if ($expireDate !== null) {
703
-				try {
704
-					$expireDate = $this->parseDate($expireDate);
705
-				} catch (\Exception $e) {
706
-					throw new OCSBadRequestException($e->getMessage());
707
-				}
708
-				$share->setExpirationDate($expireDate);
709
-			}
710
-
711
-			if ($password === '') {
712
-				$share->setPassword(null);
713
-			} else if ($password !== null) {
714
-				$share->setPassword($password);
715
-			}
716
-
717
-		} else {
718
-			// For other shares only permissions is valid.
719
-			if ($permissions === null) {
720
-				throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
721
-			} else {
722
-				$permissions = (int)$permissions;
723
-				$share->setPermissions($permissions);
724
-			}
725
-		}
726
-
727
-		if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
728
-			/* Check if this is an incomming share */
729
-			$incomingShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
730
-			$incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
731
-
732
-			/** @var \OCP\Share\IShare[] $incomingShares */
733
-			if (!empty($incomingShares)) {
734
-				$maxPermissions = 0;
735
-				foreach ($incomingShares as $incomingShare) {
736
-					$maxPermissions |= $incomingShare->getPermissions();
737
-				}
738
-
739
-				if ($share->getPermissions() & ~$maxPermissions) {
740
-					throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
741
-				}
742
-			}
743
-		}
744
-
745
-
746
-		try {
747
-			$share = $this->shareManager->updateShare($share);
748
-		} catch (\Exception $e) {
749
-			throw new OCSBadRequestException($e->getMessage());
750
-		}
751
-
752
-		return new DataResponse($this->formatShare($share));
753
-	}
754
-
755
-	/**
756
-	 * @param \OCP\Share\IShare $share
757
-	 * @return bool
758
-	 */
759
-	protected function canAccessShare(\OCP\Share\IShare $share, $checkGroups = true) {
760
-		// A file with permissions 0 can't be accessed by us. So Don't show it
761
-		if ($share->getPermissions() === 0) {
762
-			return false;
763
-		}
764
-
765
-		// Owner of the file and the sharer of the file can always get share
766
-		if ($share->getShareOwner() === $this->currentUser ||
767
-			$share->getSharedBy() === $this->currentUser
768
-		) {
769
-			return true;
770
-		}
771
-
772
-		// If the share is shared with you (or a group you are a member of)
773
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
774
-			$share->getSharedWith() === $this->currentUser
775
-		) {
776
-			return true;
777
-		}
778
-
779
-		if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
780
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
781
-			$user = $this->userManager->get($this->currentUser);
782
-			if ($user !== null && $sharedWith->inGroup($user)) {
783
-				return true;
784
-			}
785
-		}
786
-
787
-		return false;
788
-	}
789
-
790
-	/**
791
-	 * Make sure that the passed date is valid ISO 8601
792
-	 * So YYYY-MM-DD
793
-	 * If not throw an exception
794
-	 *
795
-	 * @param string $expireDate
796
-	 *
797
-	 * @throws \Exception
798
-	 * @return \DateTime
799
-	 */
800
-	private function parseDate($expireDate) {
801
-		try {
802
-			$date = new \DateTime($expireDate);
803
-		} catch (\Exception $e) {
804
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
805
-		}
806
-
807
-		if ($date === false) {
808
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
809
-		}
810
-
811
-		$date->setTime(0, 0, 0);
812
-
813
-		return $date;
814
-	}
815
-
816
-	/**
817
-	 * Since we have multiple providers but the OCS Share API v1 does
818
-	 * not support this we need to check all backends.
819
-	 *
820
-	 * @param string $id
821
-	 * @return \OCP\Share\IShare
822
-	 * @throws ShareNotFound
823
-	 */
824
-	private function getShareById($id) {
825
-		$share = null;
826
-
827
-		// First check if it is an internal share.
828
-		try {
829
-			$share = $this->shareManager->getShareById('ocinternal:' . $id);
830
-			return $share;
831
-		} catch (ShareNotFound $e) {
832
-			// Do nothing, just try the other share type
833
-		}
834
-
835
-		try {
836
-			if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
837
-				$share = $this->shareManager->getShareById('ocMailShare:' . $id);
838
-				return $share;
839
-			}
840
-		} catch (ShareNotFound $e) {
841
-			// Do nothing, just try the other share type
842
-		}
843
-
844
-		if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
845
-			throw new ShareNotFound();
846
-		}
847
-		$share = $this->shareManager->getShareById('ocFederatedSharing:' . $id);
848
-
849
-		return $share;
850
-	}
851
-
852
-	/**
853
-	 * Lock a Node
854
-	 *
855
-	 * @param \OCP\Files\Node $node
856
-	 */
857
-	private function lock(\OCP\Files\Node $node) {
858
-		$node->lock(ILockingProvider::LOCK_SHARED);
859
-		$this->lockedNode = $node;
860
-	}
861
-
862
-	/**
863
-	 * Cleanup the remaining locks
864
-	 */
865
-	public function cleanup() {
866
-		if ($this->lockedNode !== null) {
867
-			$this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
868
-		}
869
-	}
649
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
650
+            if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
651
+                throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
652
+            }
653
+
654
+            $newPermissions = null;
655
+            if ($publicUpload === 'true') {
656
+                $newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
657
+            } else if ($publicUpload === 'false') {
658
+                $newPermissions = \OCP\Constants::PERMISSION_READ;
659
+            }
660
+
661
+            if ($permissions !== null) {
662
+                $newPermissions = (int)$permissions;
663
+            }
664
+
665
+            if ($newPermissions !== null &&
666
+                !in_array($newPermissions, [
667
+                    \OCP\Constants::PERMISSION_READ,
668
+                    \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE, // legacy
669
+                    \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE, // correct
670
+                    \OCP\Constants::PERMISSION_CREATE, // hidden file list
671
+                    \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE, // allow to edit single files
672
+                ])
673
+            ) {
674
+                throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
675
+            }
676
+
677
+            if (
678
+                // legacy
679
+                $newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) ||
680
+                // correct
681
+                $newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
682
+            ) {
683
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
684
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
685
+                }
686
+
687
+                if (!($share->getNode() instanceof \OCP\Files\Folder)) {
688
+                    throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
689
+                }
690
+
691
+                // normalize to correct public upload permissions
692
+                $newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
693
+            }
694
+
695
+            if ($newPermissions !== null) {
696
+                $share->setPermissions($newPermissions);
697
+                $permissions = $newPermissions;
698
+            }
699
+
700
+            if ($expireDate === '') {
701
+                $share->setExpirationDate(null);
702
+            } else if ($expireDate !== null) {
703
+                try {
704
+                    $expireDate = $this->parseDate($expireDate);
705
+                } catch (\Exception $e) {
706
+                    throw new OCSBadRequestException($e->getMessage());
707
+                }
708
+                $share->setExpirationDate($expireDate);
709
+            }
710
+
711
+            if ($password === '') {
712
+                $share->setPassword(null);
713
+            } else if ($password !== null) {
714
+                $share->setPassword($password);
715
+            }
716
+
717
+        } else {
718
+            // For other shares only permissions is valid.
719
+            if ($permissions === null) {
720
+                throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
721
+            } else {
722
+                $permissions = (int)$permissions;
723
+                $share->setPermissions($permissions);
724
+            }
725
+        }
726
+
727
+        if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
728
+            /* Check if this is an incomming share */
729
+            $incomingShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
730
+            $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
731
+
732
+            /** @var \OCP\Share\IShare[] $incomingShares */
733
+            if (!empty($incomingShares)) {
734
+                $maxPermissions = 0;
735
+                foreach ($incomingShares as $incomingShare) {
736
+                    $maxPermissions |= $incomingShare->getPermissions();
737
+                }
738
+
739
+                if ($share->getPermissions() & ~$maxPermissions) {
740
+                    throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
741
+                }
742
+            }
743
+        }
744
+
745
+
746
+        try {
747
+            $share = $this->shareManager->updateShare($share);
748
+        } catch (\Exception $e) {
749
+            throw new OCSBadRequestException($e->getMessage());
750
+        }
751
+
752
+        return new DataResponse($this->formatShare($share));
753
+    }
754
+
755
+    /**
756
+     * @param \OCP\Share\IShare $share
757
+     * @return bool
758
+     */
759
+    protected function canAccessShare(\OCP\Share\IShare $share, $checkGroups = true) {
760
+        // A file with permissions 0 can't be accessed by us. So Don't show it
761
+        if ($share->getPermissions() === 0) {
762
+            return false;
763
+        }
764
+
765
+        // Owner of the file and the sharer of the file can always get share
766
+        if ($share->getShareOwner() === $this->currentUser ||
767
+            $share->getSharedBy() === $this->currentUser
768
+        ) {
769
+            return true;
770
+        }
771
+
772
+        // If the share is shared with you (or a group you are a member of)
773
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
774
+            $share->getSharedWith() === $this->currentUser
775
+        ) {
776
+            return true;
777
+        }
778
+
779
+        if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
780
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
781
+            $user = $this->userManager->get($this->currentUser);
782
+            if ($user !== null && $sharedWith->inGroup($user)) {
783
+                return true;
784
+            }
785
+        }
786
+
787
+        return false;
788
+    }
789
+
790
+    /**
791
+     * Make sure that the passed date is valid ISO 8601
792
+     * So YYYY-MM-DD
793
+     * If not throw an exception
794
+     *
795
+     * @param string $expireDate
796
+     *
797
+     * @throws \Exception
798
+     * @return \DateTime
799
+     */
800
+    private function parseDate($expireDate) {
801
+        try {
802
+            $date = new \DateTime($expireDate);
803
+        } catch (\Exception $e) {
804
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
805
+        }
806
+
807
+        if ($date === false) {
808
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
809
+        }
810
+
811
+        $date->setTime(0, 0, 0);
812
+
813
+        return $date;
814
+    }
815
+
816
+    /**
817
+     * Since we have multiple providers but the OCS Share API v1 does
818
+     * not support this we need to check all backends.
819
+     *
820
+     * @param string $id
821
+     * @return \OCP\Share\IShare
822
+     * @throws ShareNotFound
823
+     */
824
+    private function getShareById($id) {
825
+        $share = null;
826
+
827
+        // First check if it is an internal share.
828
+        try {
829
+            $share = $this->shareManager->getShareById('ocinternal:' . $id);
830
+            return $share;
831
+        } catch (ShareNotFound $e) {
832
+            // Do nothing, just try the other share type
833
+        }
834
+
835
+        try {
836
+            if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
837
+                $share = $this->shareManager->getShareById('ocMailShare:' . $id);
838
+                return $share;
839
+            }
840
+        } catch (ShareNotFound $e) {
841
+            // Do nothing, just try the other share type
842
+        }
843
+
844
+        if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
845
+            throw new ShareNotFound();
846
+        }
847
+        $share = $this->shareManager->getShareById('ocFederatedSharing:' . $id);
848
+
849
+        return $share;
850
+    }
851
+
852
+    /**
853
+     * Lock a Node
854
+     *
855
+     * @param \OCP\Files\Node $node
856
+     */
857
+    private function lock(\OCP\Files\Node $node) {
858
+        $node->lock(ILockingProvider::LOCK_SHARED);
859
+        $this->lockedNode = $node;
860
+    }
861
+
862
+    /**
863
+     * Cleanup the remaining locks
864
+     */
865
+    public function cleanup() {
866
+        if ($this->lockedNode !== null) {
867
+            $this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
868
+        }
869
+    }
870 870
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareesAPIController.php 1 patch
Indentation   +627 added lines, -627 removed lines patch added patch discarded remove patch
@@ -43,631 +43,631 @@
 block discarded – undo
43 43
 
44 44
 class ShareesAPIController extends OCSController {
45 45
 
46
-	/** @var IGroupManager */
47
-	protected $groupManager;
48
-
49
-	/** @var IUserManager */
50
-	protected $userManager;
51
-
52
-	/** @var IManager */
53
-	protected $contactsManager;
54
-
55
-	/** @var IConfig */
56
-	protected $config;
57
-
58
-	/** @var IUserSession */
59
-	protected $userSession;
60
-
61
-	/** @var IURLGenerator */
62
-	protected $urlGenerator;
63
-
64
-	/** @var ILogger */
65
-	protected $logger;
66
-
67
-	/** @var \OCP\Share\IManager */
68
-	protected $shareManager;
69
-
70
-	/** @var IClientService */
71
-	protected $clientService;
72
-
73
-	/** @var ICloudIdManager  */
74
-	protected $cloudIdManager;
75
-
76
-	/** @var bool */
77
-	protected $shareWithGroupOnly = false;
78
-
79
-	/** @var bool */
80
-	protected $shareeEnumeration = true;
81
-
82
-	/** @var int */
83
-	protected $offset = 0;
84
-
85
-	/** @var int */
86
-	protected $limit = 10;
87
-
88
-	/** @var array */
89
-	protected $result = [
90
-		'exact' => [
91
-			'users' => [],
92
-			'groups' => [],
93
-			'remotes' => [],
94
-			'emails' => [],
95
-		],
96
-		'users' => [],
97
-		'groups' => [],
98
-		'remotes' => [],
99
-		'emails' => [],
100
-		'lookup' => [],
101
-	];
102
-
103
-	protected $reachedEndFor = [];
104
-
105
-	/**
106
-	 * @param string $appName
107
-	 * @param IRequest $request
108
-	 * @param IGroupManager $groupManager
109
-	 * @param IUserManager $userManager
110
-	 * @param IManager $contactsManager
111
-	 * @param IConfig $config
112
-	 * @param IUserSession $userSession
113
-	 * @param IURLGenerator $urlGenerator
114
-	 * @param ILogger $logger
115
-	 * @param \OCP\Share\IManager $shareManager
116
-	 * @param IClientService $clientService
117
-	 * @param ICloudIdManager $cloudIdManager
118
-	 */
119
-	public function __construct($appName,
120
-								IRequest $request,
121
-								IGroupManager $groupManager,
122
-								IUserManager $userManager,
123
-								IManager $contactsManager,
124
-								IConfig $config,
125
-								IUserSession $userSession,
126
-								IURLGenerator $urlGenerator,
127
-								ILogger $logger,
128
-								\OCP\Share\IManager $shareManager,
129
-								IClientService $clientService,
130
-								ICloudIdManager $cloudIdManager
131
-	) {
132
-		parent::__construct($appName, $request);
133
-
134
-		$this->groupManager = $groupManager;
135
-		$this->userManager = $userManager;
136
-		$this->contactsManager = $contactsManager;
137
-		$this->config = $config;
138
-		$this->userSession = $userSession;
139
-		$this->urlGenerator = $urlGenerator;
140
-		$this->logger = $logger;
141
-		$this->shareManager = $shareManager;
142
-		$this->clientService = $clientService;
143
-		$this->cloudIdManager = $cloudIdManager;
144
-	}
145
-
146
-	/**
147
-	 * @param string $search
148
-	 */
149
-	protected function getUsers($search) {
150
-		$this->result['users'] = $this->result['exact']['users'] = $users = [];
151
-
152
-		$userGroups = [];
153
-		if ($this->shareWithGroupOnly) {
154
-			// Search in all the groups this user is part of
155
-			$userGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
156
-			foreach ($userGroups as $userGroup) {
157
-				$usersTmp = $this->groupManager->displayNamesInGroup($userGroup, $search, $this->limit, $this->offset);
158
-				foreach ($usersTmp as $uid => $userDisplayName) {
159
-					$users[$uid] = $userDisplayName;
160
-				}
161
-			}
162
-		} else {
163
-			// Search in all users
164
-			$usersTmp = $this->userManager->searchDisplayName($search, $this->limit, $this->offset);
165
-
166
-			foreach ($usersTmp as $user) {
167
-				$users[$user->getUID()] = $user->getDisplayName();
168
-			}
169
-		}
170
-
171
-		if (!$this->shareeEnumeration || sizeof($users) < $this->limit) {
172
-			$this->reachedEndFor[] = 'users';
173
-		}
174
-
175
-		$foundUserById = false;
176
-		$lowerSearch = strtolower($search);
177
-		foreach ($users as $uid => $userDisplayName) {
178
-			if (strtolower($uid) === $lowerSearch || strtolower($userDisplayName) === $lowerSearch) {
179
-				if (strtolower($uid) === $lowerSearch) {
180
-					$foundUserById = true;
181
-				}
182
-				$this->result['exact']['users'][] = [
183
-					'label' => $userDisplayName,
184
-					'value' => [
185
-						'shareType' => Share::SHARE_TYPE_USER,
186
-						'shareWith' => $uid,
187
-					],
188
-				];
189
-			} else {
190
-				$this->result['users'][] = [
191
-					'label' => $userDisplayName,
192
-					'value' => [
193
-						'shareType' => Share::SHARE_TYPE_USER,
194
-						'shareWith' => $uid,
195
-					],
196
-				];
197
-			}
198
-		}
199
-
200
-		if ($this->offset === 0 && !$foundUserById) {
201
-			// On page one we try if the search result has a direct hit on the
202
-			// user id and if so, we add that to the exact match list
203
-			$user = $this->userManager->get($search);
204
-			if ($user instanceof IUser) {
205
-				$addUser = true;
206
-
207
-				if ($this->shareWithGroupOnly) {
208
-					// Only add, if we have a common group
209
-					$commonGroups = array_intersect($userGroups, $this->groupManager->getUserGroupIds($user));
210
-					$addUser = !empty($commonGroups);
211
-				}
212
-
213
-				if ($addUser) {
214
-					array_push($this->result['exact']['users'], [
215
-						'label' => $user->getDisplayName(),
216
-						'value' => [
217
-							'shareType' => Share::SHARE_TYPE_USER,
218
-							'shareWith' => $user->getUID(),
219
-						],
220
-					]);
221
-				}
222
-			}
223
-		}
224
-
225
-		if (!$this->shareeEnumeration) {
226
-			$this->result['users'] = [];
227
-		}
228
-	}
229
-
230
-	/**
231
-	 * @param string $search
232
-	 */
233
-	protected function getGroups($search) {
234
-		$this->result['groups'] = $this->result['exact']['groups'] = [];
235
-
236
-		$groups = $this->groupManager->search($search, $this->limit, $this->offset);
237
-		$groupIds = array_map(function (IGroup $group) { return $group->getGID(); }, $groups);
238
-
239
-		if (!$this->shareeEnumeration || sizeof($groups) < $this->limit) {
240
-			$this->reachedEndFor[] = 'groups';
241
-		}
242
-
243
-		$userGroups =  [];
244
-		if (!empty($groups) && $this->shareWithGroupOnly) {
245
-			// Intersect all the groups that match with the groups this user is a member of
246
-			$userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
247
-			$userGroups = array_map(function (IGroup $group) { return $group->getGID(); }, $userGroups);
248
-			$groupIds = array_intersect($groupIds, $userGroups);
249
-		}
250
-
251
-		$lowerSearch = strtolower($search);
252
-		foreach ($groups as $group) {
253
-			// FIXME: use a more efficient approach
254
-			$gid = $group->getGID();
255
-			if (!in_array($gid, $groupIds)) {
256
-				continue;
257
-			}
258
-			if (strtolower($gid) === $lowerSearch || strtolower($group->getDisplayName()) === $lowerSearch) {
259
-				$this->result['exact']['groups'][] = [
260
-					'label' => $group->getDisplayName(),
261
-					'value' => [
262
-						'shareType' => Share::SHARE_TYPE_GROUP,
263
-						'shareWith' => $gid,
264
-					],
265
-				];
266
-			} else {
267
-				$this->result['groups'][] = [
268
-					'label' => $group->getDisplayName(),
269
-					'value' => [
270
-						'shareType' => Share::SHARE_TYPE_GROUP,
271
-						'shareWith' => $gid,
272
-					],
273
-				];
274
-			}
275
-		}
276
-
277
-		if ($this->offset === 0 && empty($this->result['exact']['groups'])) {
278
-			// On page one we try if the search result has a direct hit on the
279
-			// user id and if so, we add that to the exact match list
280
-			$group = $this->groupManager->get($search);
281
-			if ($group instanceof IGroup && (!$this->shareWithGroupOnly || in_array($group->getGID(), $userGroups))) {
282
-				array_push($this->result['exact']['groups'], [
283
-					'label' => $group->getDisplayName(),
284
-					'value' => [
285
-						'shareType' => Share::SHARE_TYPE_GROUP,
286
-						'shareWith' => $group->getGID(),
287
-					],
288
-				]);
289
-			}
290
-		}
291
-
292
-		if (!$this->shareeEnumeration) {
293
-			$this->result['groups'] = [];
294
-		}
295
-	}
296
-
297
-	/**
298
-	 * @param string $search
299
-	 * @return array
300
-	 */
301
-	protected function getRemote($search) {
302
-		$result = ['results' => [], 'exact' => []];
303
-
304
-		// Search in contacts
305
-		//@todo Pagination missing
306
-		$addressBookContacts = $this->contactsManager->search($search, ['CLOUD', 'FN']);
307
-		$result['exactIdMatch'] = false;
308
-		foreach ($addressBookContacts as $contact) {
309
-			if (isset($contact['isLocalSystemBook'])) {
310
-				continue;
311
-			}
312
-			if (isset($contact['CLOUD'])) {
313
-				$cloudIds = $contact['CLOUD'];
314
-				if (!is_array($cloudIds)) {
315
-					$cloudIds = [$cloudIds];
316
-				}
317
-				$lowerSearch = strtolower($search);
318
-				foreach ($cloudIds as $cloudId) {
319
-					list(, $serverUrl) = $this->splitUserRemote($cloudId);
320
-					if (strtolower($contact['FN']) === $lowerSearch || strtolower($cloudId) === $lowerSearch) {
321
-						if (strtolower($cloudId) === $lowerSearch) {
322
-							$result['exactIdMatch'] = true;
323
-						}
324
-						$result['exact'][] = [
325
-							'label' => $contact['FN'] . " ($cloudId)",
326
-							'value' => [
327
-								'shareType' => Share::SHARE_TYPE_REMOTE,
328
-								'shareWith' => $cloudId,
329
-								'server' => $serverUrl,
330
-							],
331
-						];
332
-					} else {
333
-						$result['results'][] = [
334
-							'label' => $contact['FN'] . " ($cloudId)",
335
-							'value' => [
336
-								'shareType' => Share::SHARE_TYPE_REMOTE,
337
-								'shareWith' => $cloudId,
338
-								'server' => $serverUrl,
339
-							],
340
-						];
341
-					}
342
-				}
343
-			}
344
-		}
345
-
346
-		if (!$this->shareeEnumeration) {
347
-			$result['results'] = [];
348
-		}
349
-
350
-		if (!$result['exactIdMatch'] && $this->cloudIdManager->isValidCloudId($search) && $this->offset === 0) {
351
-			$result['exact'][] = [
352
-				'label' => $search,
353
-				'value' => [
354
-					'shareType' => Share::SHARE_TYPE_REMOTE,
355
-					'shareWith' => $search,
356
-				],
357
-			];
358
-		}
359
-
360
-		$this->reachedEndFor[] = 'remotes';
361
-
362
-		return $result;
363
-	}
364
-
365
-	/**
366
-	 * split user and remote from federated cloud id
367
-	 *
368
-	 * @param string $address federated share address
369
-	 * @return array [user, remoteURL]
370
-	 * @throws \Exception
371
-	 */
372
-	public function splitUserRemote($address) {
373
-		try {
374
-			$cloudId = $this->cloudIdManager->resolveCloudId($address);
375
-			return [$cloudId->getUser(), $cloudId->getRemote()];
376
-		} catch (\InvalidArgumentException $e) {
377
-			throw new \Exception('Invalid Federated Cloud ID', 0, $e);
378
-		}
379
-	}
380
-
381
-	/**
382
-	 * Strips away a potential file names and trailing slashes:
383
-	 * - http://localhost
384
-	 * - http://localhost/
385
-	 * - http://localhost/index.php
386
-	 * - http://localhost/index.php/s/{shareToken}
387
-	 *
388
-	 * all return: http://localhost
389
-	 *
390
-	 * @param string $remote
391
-	 * @return string
392
-	 */
393
-	protected function fixRemoteURL($remote) {
394
-		$remote = str_replace('\\', '/', $remote);
395
-		if ($fileNamePosition = strpos($remote, '/index.php')) {
396
-			$remote = substr($remote, 0, $fileNamePosition);
397
-		}
398
-		$remote = rtrim($remote, '/');
399
-
400
-		return $remote;
401
-	}
402
-
403
-	/**
404
-	 * @NoAdminRequired
405
-	 *
406
-	 * @param string $search
407
-	 * @param string $itemType
408
-	 * @param int $page
409
-	 * @param int $perPage
410
-	 * @param int|int[] $shareType
411
-	 * @param bool $lookup
412
-	 * @return Http\DataResponse
413
-	 * @throws OCSBadRequestException
414
-	 */
415
-	public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) {
416
-		if ($perPage <= 0) {
417
-			throw new OCSBadRequestException('Invalid perPage argument');
418
-		}
419
-		if ($page <= 0) {
420
-			throw new OCSBadRequestException('Invalid page');
421
-		}
422
-
423
-		$shareTypes = [
424
-			Share::SHARE_TYPE_USER,
425
-		];
426
-
427
-		if ($itemType === 'file' || $itemType === 'folder') {
428
-			if ($this->shareManager->allowGroupSharing()) {
429
-				$shareTypes[] = Share::SHARE_TYPE_GROUP;
430
-			}
431
-
432
-			if ($this->isRemoteSharingAllowed($itemType)) {
433
-				$shareTypes[] = Share::SHARE_TYPE_REMOTE;
434
-			}
435
-
436
-			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
437
-				$shareTypes[] = Share::SHARE_TYPE_EMAIL;
438
-			}
439
-		} else {
440
-			$shareTypes[] = Share::SHARE_TYPE_GROUP;
441
-			$shareTypes[] = Share::SHARE_TYPE_EMAIL;
442
-		}
443
-
444
-		if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
445
-			$shareTypes = array_intersect($shareTypes, $_GET['shareType']);
446
-			sort($shareTypes);
447
-		} else if (is_numeric($shareType)) {
448
-			$shareTypes = array_intersect($shareTypes, [(int) $shareType]);
449
-			sort($shareTypes);
450
-		}
451
-
452
-		$this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
453
-		$this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
454
-		$this->limit = (int) $perPage;
455
-		$this->offset = $perPage * ($page - 1);
456
-
457
-		return $this->searchSharees($search, $itemType, $shareTypes, $page, $perPage, $lookup);
458
-	}
459
-
460
-	/**
461
-	 * Method to get out the static call for better testing
462
-	 *
463
-	 * @param string $itemType
464
-	 * @return bool
465
-	 */
466
-	protected function isRemoteSharingAllowed($itemType) {
467
-		try {
468
-			$backend = Share::getBackend($itemType);
469
-			return $backend->isShareTypeAllowed(Share::SHARE_TYPE_REMOTE);
470
-		} catch (\Exception $e) {
471
-			return false;
472
-		}
473
-	}
474
-
475
-	/**
476
-	 * Testable search function that does not need globals
477
-	 *
478
-	 * @param string $search
479
-	 * @param string $itemType
480
-	 * @param array $shareTypes
481
-	 * @param int $page
482
-	 * @param int $perPage
483
-	 * @param bool $lookup
484
-	 * @return Http\DataResponse
485
-	 * @throws OCSBadRequestException
486
-	 */
487
-	protected function searchSharees($search, $itemType, array $shareTypes, $page, $perPage, $lookup) {
488
-		// Verify arguments
489
-		if ($itemType === null) {
490
-			throw new OCSBadRequestException('Missing itemType');
491
-		}
492
-
493
-		// Get users
494
-		if (in_array(Share::SHARE_TYPE_USER, $shareTypes)) {
495
-			$this->getUsers($search);
496
-		}
497
-
498
-		// Get groups
499
-		if (in_array(Share::SHARE_TYPE_GROUP, $shareTypes)) {
500
-			$this->getGroups($search);
501
-		}
502
-
503
-		// Get remote
504
-		$remoteResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
505
-		if (in_array(Share::SHARE_TYPE_REMOTE, $shareTypes)) {
506
-			$remoteResults = $this->getRemote($search);
507
-		}
508
-
509
-		// Get emails
510
-		$mailResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
511
-		if (in_array(Share::SHARE_TYPE_EMAIL, $shareTypes)) {
512
-			$mailResults = $this->getEmail($search);
513
-		}
514
-
515
-		// Get from lookup server
516
-		if ($lookup) {
517
-			$this->getLookup($search);
518
-		}
519
-
520
-		// if we have a exact match, either for the federated cloud id or for the
521
-		// email address we only return the exact match. It is highly unlikely
522
-		// that the exact same email address and federated cloud id exists
523
-		if ($mailResults['exactIdMatch'] && !$remoteResults['exactIdMatch']) {
524
-			$this->result['emails'] = $mailResults['results'];
525
-			$this->result['exact']['emails'] = $mailResults['exact'];
526
-		} else if (!$mailResults['exactIdMatch'] && $remoteResults['exactIdMatch']) {
527
-			$this->result['remotes'] = $remoteResults['results'];
528
-			$this->result['exact']['remotes'] = $remoteResults['exact'];
529
-		} else {
530
-			$this->result['remotes'] = $remoteResults['results'];
531
-			$this->result['exact']['remotes'] = $remoteResults['exact'];
532
-			$this->result['emails'] = $mailResults['results'];
533
-			$this->result['exact']['emails'] = $mailResults['exact'];
534
-		}
535
-
536
-		$response = new Http\DataResponse($this->result);
537
-
538
-		if (sizeof($this->reachedEndFor) < 3) {
539
-			$response->addHeader('Link', $this->getPaginationLink($page, [
540
-				'search' => $search,
541
-				'itemType' => $itemType,
542
-				'shareType' => $shareTypes,
543
-				'perPage' => $perPage,
544
-			]));
545
-		}
546
-
547
-		return $response;
548
-	}
549
-
550
-	/**
551
-	 * @param string $search
552
-	 * @return array
553
-	 */
554
-	protected function getEmail($search) {
555
-		$result = ['results' => [], 'exact' => []];
556
-
557
-		// Search in contacts
558
-		//@todo Pagination missing
559
-		$addressBookContacts = $this->contactsManager->search($search, ['EMAIL', 'FN']);
560
-		$result['exactIdMatch'] = false;
561
-		foreach ($addressBookContacts as $contact) {
562
-			if (isset($contact['isLocalSystemBook'])) {
563
-				continue;
564
-			}
565
-			if (isset($contact['EMAIL'])) {
566
-				$emailAddresses = $contact['EMAIL'];
567
-				if (!is_array($emailAddresses)) {
568
-					$emailAddresses = [$emailAddresses];
569
-				}
570
-				foreach ($emailAddresses as $emailAddress) {
571
-					if (strtolower($contact['FN']) === strtolower($search) || strtolower($emailAddress) === strtolower($search)) {
572
-						if (strtolower($emailAddress) === strtolower($search)) {
573
-							$result['exactIdMatch'] = true;
574
-						}
575
-						$result['exact'][] = [
576
-							'label' => $contact['FN'] . " ($emailAddress)",
577
-							'value' => [
578
-								'shareType' => Share::SHARE_TYPE_EMAIL,
579
-								'shareWith' => $emailAddress,
580
-							],
581
-						];
582
-					} else {
583
-						$result['results'][] = [
584
-							'label' => $contact['FN'] . " ($emailAddress)",
585
-							'value' => [
586
-								'shareType' => Share::SHARE_TYPE_EMAIL,
587
-								'shareWith' => $emailAddress,
588
-							],
589
-						];
590
-					}
591
-				}
592
-			}
593
-		}
594
-
595
-		if (!$this->shareeEnumeration) {
596
-			$result['results'] = [];
597
-		}
598
-
599
-		if (!$result['exactIdMatch'] && filter_var($search, FILTER_VALIDATE_EMAIL)) {
600
-			$result['exact'][] = [
601
-				'label' => $search,
602
-				'value' => [
603
-					'shareType' => Share::SHARE_TYPE_EMAIL,
604
-					'shareWith' => $search,
605
-				],
606
-			];
607
-		}
608
-
609
-		$this->reachedEndFor[] = 'emails';
610
-
611
-		return $result;
612
-	}
613
-
614
-	protected function getLookup($search) {
615
-		$isEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
616
-		$result = [];
617
-
618
-		if($isEnabled === 'yes') {
619
-			try {
620
-				$client = $this->clientService->newClient();
621
-				$response = $client->get(
622
-					'https://lookup.nextcloud.com/users?search=' . urlencode($search),
623
-					[
624
-						'timeout' => 10,
625
-						'connect_timeout' => 3,
626
-					]
627
-				);
628
-
629
-				$body = json_decode($response->getBody(), true);
630
-
631
-				$result = [];
632
-				foreach ($body as $lookup) {
633
-					$result[] = [
634
-						'label' => $lookup['federationId'],
635
-						'value' => [
636
-							'shareType' => Share::SHARE_TYPE_REMOTE,
637
-							'shareWith' => $lookup['federationId'],
638
-						],
639
-						'extra' => $lookup,
640
-					];
641
-				}
642
-			} catch (\Exception $e) {}
643
-		}
644
-
645
-		$this->result['lookup'] = $result;
646
-	}
647
-
648
-	/**
649
-	 * Generates a bunch of pagination links for the current page
650
-	 *
651
-	 * @param int $page Current page
652
-	 * @param array $params Parameters for the URL
653
-	 * @return string
654
-	 */
655
-	protected function getPaginationLink($page, array $params) {
656
-		if ($this->isV2()) {
657
-			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
658
-		} else {
659
-			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
660
-		}
661
-		$params['page'] = $page + 1;
662
-		$link = '<' . $url . http_build_query($params) . '>; rel="next"';
663
-
664
-		return $link;
665
-	}
666
-
667
-	/**
668
-	 * @return bool
669
-	 */
670
-	protected function isV2() {
671
-		return $this->request->getScriptName() === '/ocs/v2.php';
672
-	}
46
+    /** @var IGroupManager */
47
+    protected $groupManager;
48
+
49
+    /** @var IUserManager */
50
+    protected $userManager;
51
+
52
+    /** @var IManager */
53
+    protected $contactsManager;
54
+
55
+    /** @var IConfig */
56
+    protected $config;
57
+
58
+    /** @var IUserSession */
59
+    protected $userSession;
60
+
61
+    /** @var IURLGenerator */
62
+    protected $urlGenerator;
63
+
64
+    /** @var ILogger */
65
+    protected $logger;
66
+
67
+    /** @var \OCP\Share\IManager */
68
+    protected $shareManager;
69
+
70
+    /** @var IClientService */
71
+    protected $clientService;
72
+
73
+    /** @var ICloudIdManager  */
74
+    protected $cloudIdManager;
75
+
76
+    /** @var bool */
77
+    protected $shareWithGroupOnly = false;
78
+
79
+    /** @var bool */
80
+    protected $shareeEnumeration = true;
81
+
82
+    /** @var int */
83
+    protected $offset = 0;
84
+
85
+    /** @var int */
86
+    protected $limit = 10;
87
+
88
+    /** @var array */
89
+    protected $result = [
90
+        'exact' => [
91
+            'users' => [],
92
+            'groups' => [],
93
+            'remotes' => [],
94
+            'emails' => [],
95
+        ],
96
+        'users' => [],
97
+        'groups' => [],
98
+        'remotes' => [],
99
+        'emails' => [],
100
+        'lookup' => [],
101
+    ];
102
+
103
+    protected $reachedEndFor = [];
104
+
105
+    /**
106
+     * @param string $appName
107
+     * @param IRequest $request
108
+     * @param IGroupManager $groupManager
109
+     * @param IUserManager $userManager
110
+     * @param IManager $contactsManager
111
+     * @param IConfig $config
112
+     * @param IUserSession $userSession
113
+     * @param IURLGenerator $urlGenerator
114
+     * @param ILogger $logger
115
+     * @param \OCP\Share\IManager $shareManager
116
+     * @param IClientService $clientService
117
+     * @param ICloudIdManager $cloudIdManager
118
+     */
119
+    public function __construct($appName,
120
+                                IRequest $request,
121
+                                IGroupManager $groupManager,
122
+                                IUserManager $userManager,
123
+                                IManager $contactsManager,
124
+                                IConfig $config,
125
+                                IUserSession $userSession,
126
+                                IURLGenerator $urlGenerator,
127
+                                ILogger $logger,
128
+                                \OCP\Share\IManager $shareManager,
129
+                                IClientService $clientService,
130
+                                ICloudIdManager $cloudIdManager
131
+    ) {
132
+        parent::__construct($appName, $request);
133
+
134
+        $this->groupManager = $groupManager;
135
+        $this->userManager = $userManager;
136
+        $this->contactsManager = $contactsManager;
137
+        $this->config = $config;
138
+        $this->userSession = $userSession;
139
+        $this->urlGenerator = $urlGenerator;
140
+        $this->logger = $logger;
141
+        $this->shareManager = $shareManager;
142
+        $this->clientService = $clientService;
143
+        $this->cloudIdManager = $cloudIdManager;
144
+    }
145
+
146
+    /**
147
+     * @param string $search
148
+     */
149
+    protected function getUsers($search) {
150
+        $this->result['users'] = $this->result['exact']['users'] = $users = [];
151
+
152
+        $userGroups = [];
153
+        if ($this->shareWithGroupOnly) {
154
+            // Search in all the groups this user is part of
155
+            $userGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
156
+            foreach ($userGroups as $userGroup) {
157
+                $usersTmp = $this->groupManager->displayNamesInGroup($userGroup, $search, $this->limit, $this->offset);
158
+                foreach ($usersTmp as $uid => $userDisplayName) {
159
+                    $users[$uid] = $userDisplayName;
160
+                }
161
+            }
162
+        } else {
163
+            // Search in all users
164
+            $usersTmp = $this->userManager->searchDisplayName($search, $this->limit, $this->offset);
165
+
166
+            foreach ($usersTmp as $user) {
167
+                $users[$user->getUID()] = $user->getDisplayName();
168
+            }
169
+        }
170
+
171
+        if (!$this->shareeEnumeration || sizeof($users) < $this->limit) {
172
+            $this->reachedEndFor[] = 'users';
173
+        }
174
+
175
+        $foundUserById = false;
176
+        $lowerSearch = strtolower($search);
177
+        foreach ($users as $uid => $userDisplayName) {
178
+            if (strtolower($uid) === $lowerSearch || strtolower($userDisplayName) === $lowerSearch) {
179
+                if (strtolower($uid) === $lowerSearch) {
180
+                    $foundUserById = true;
181
+                }
182
+                $this->result['exact']['users'][] = [
183
+                    'label' => $userDisplayName,
184
+                    'value' => [
185
+                        'shareType' => Share::SHARE_TYPE_USER,
186
+                        'shareWith' => $uid,
187
+                    ],
188
+                ];
189
+            } else {
190
+                $this->result['users'][] = [
191
+                    'label' => $userDisplayName,
192
+                    'value' => [
193
+                        'shareType' => Share::SHARE_TYPE_USER,
194
+                        'shareWith' => $uid,
195
+                    ],
196
+                ];
197
+            }
198
+        }
199
+
200
+        if ($this->offset === 0 && !$foundUserById) {
201
+            // On page one we try if the search result has a direct hit on the
202
+            // user id and if so, we add that to the exact match list
203
+            $user = $this->userManager->get($search);
204
+            if ($user instanceof IUser) {
205
+                $addUser = true;
206
+
207
+                if ($this->shareWithGroupOnly) {
208
+                    // Only add, if we have a common group
209
+                    $commonGroups = array_intersect($userGroups, $this->groupManager->getUserGroupIds($user));
210
+                    $addUser = !empty($commonGroups);
211
+                }
212
+
213
+                if ($addUser) {
214
+                    array_push($this->result['exact']['users'], [
215
+                        'label' => $user->getDisplayName(),
216
+                        'value' => [
217
+                            'shareType' => Share::SHARE_TYPE_USER,
218
+                            'shareWith' => $user->getUID(),
219
+                        ],
220
+                    ]);
221
+                }
222
+            }
223
+        }
224
+
225
+        if (!$this->shareeEnumeration) {
226
+            $this->result['users'] = [];
227
+        }
228
+    }
229
+
230
+    /**
231
+     * @param string $search
232
+     */
233
+    protected function getGroups($search) {
234
+        $this->result['groups'] = $this->result['exact']['groups'] = [];
235
+
236
+        $groups = $this->groupManager->search($search, $this->limit, $this->offset);
237
+        $groupIds = array_map(function (IGroup $group) { return $group->getGID(); }, $groups);
238
+
239
+        if (!$this->shareeEnumeration || sizeof($groups) < $this->limit) {
240
+            $this->reachedEndFor[] = 'groups';
241
+        }
242
+
243
+        $userGroups =  [];
244
+        if (!empty($groups) && $this->shareWithGroupOnly) {
245
+            // Intersect all the groups that match with the groups this user is a member of
246
+            $userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
247
+            $userGroups = array_map(function (IGroup $group) { return $group->getGID(); }, $userGroups);
248
+            $groupIds = array_intersect($groupIds, $userGroups);
249
+        }
250
+
251
+        $lowerSearch = strtolower($search);
252
+        foreach ($groups as $group) {
253
+            // FIXME: use a more efficient approach
254
+            $gid = $group->getGID();
255
+            if (!in_array($gid, $groupIds)) {
256
+                continue;
257
+            }
258
+            if (strtolower($gid) === $lowerSearch || strtolower($group->getDisplayName()) === $lowerSearch) {
259
+                $this->result['exact']['groups'][] = [
260
+                    'label' => $group->getDisplayName(),
261
+                    'value' => [
262
+                        'shareType' => Share::SHARE_TYPE_GROUP,
263
+                        'shareWith' => $gid,
264
+                    ],
265
+                ];
266
+            } else {
267
+                $this->result['groups'][] = [
268
+                    'label' => $group->getDisplayName(),
269
+                    'value' => [
270
+                        'shareType' => Share::SHARE_TYPE_GROUP,
271
+                        'shareWith' => $gid,
272
+                    ],
273
+                ];
274
+            }
275
+        }
276
+
277
+        if ($this->offset === 0 && empty($this->result['exact']['groups'])) {
278
+            // On page one we try if the search result has a direct hit on the
279
+            // user id and if so, we add that to the exact match list
280
+            $group = $this->groupManager->get($search);
281
+            if ($group instanceof IGroup && (!$this->shareWithGroupOnly || in_array($group->getGID(), $userGroups))) {
282
+                array_push($this->result['exact']['groups'], [
283
+                    'label' => $group->getDisplayName(),
284
+                    'value' => [
285
+                        'shareType' => Share::SHARE_TYPE_GROUP,
286
+                        'shareWith' => $group->getGID(),
287
+                    ],
288
+                ]);
289
+            }
290
+        }
291
+
292
+        if (!$this->shareeEnumeration) {
293
+            $this->result['groups'] = [];
294
+        }
295
+    }
296
+
297
+    /**
298
+     * @param string $search
299
+     * @return array
300
+     */
301
+    protected function getRemote($search) {
302
+        $result = ['results' => [], 'exact' => []];
303
+
304
+        // Search in contacts
305
+        //@todo Pagination missing
306
+        $addressBookContacts = $this->contactsManager->search($search, ['CLOUD', 'FN']);
307
+        $result['exactIdMatch'] = false;
308
+        foreach ($addressBookContacts as $contact) {
309
+            if (isset($contact['isLocalSystemBook'])) {
310
+                continue;
311
+            }
312
+            if (isset($contact['CLOUD'])) {
313
+                $cloudIds = $contact['CLOUD'];
314
+                if (!is_array($cloudIds)) {
315
+                    $cloudIds = [$cloudIds];
316
+                }
317
+                $lowerSearch = strtolower($search);
318
+                foreach ($cloudIds as $cloudId) {
319
+                    list(, $serverUrl) = $this->splitUserRemote($cloudId);
320
+                    if (strtolower($contact['FN']) === $lowerSearch || strtolower($cloudId) === $lowerSearch) {
321
+                        if (strtolower($cloudId) === $lowerSearch) {
322
+                            $result['exactIdMatch'] = true;
323
+                        }
324
+                        $result['exact'][] = [
325
+                            'label' => $contact['FN'] . " ($cloudId)",
326
+                            'value' => [
327
+                                'shareType' => Share::SHARE_TYPE_REMOTE,
328
+                                'shareWith' => $cloudId,
329
+                                'server' => $serverUrl,
330
+                            ],
331
+                        ];
332
+                    } else {
333
+                        $result['results'][] = [
334
+                            'label' => $contact['FN'] . " ($cloudId)",
335
+                            'value' => [
336
+                                'shareType' => Share::SHARE_TYPE_REMOTE,
337
+                                'shareWith' => $cloudId,
338
+                                'server' => $serverUrl,
339
+                            ],
340
+                        ];
341
+                    }
342
+                }
343
+            }
344
+        }
345
+
346
+        if (!$this->shareeEnumeration) {
347
+            $result['results'] = [];
348
+        }
349
+
350
+        if (!$result['exactIdMatch'] && $this->cloudIdManager->isValidCloudId($search) && $this->offset === 0) {
351
+            $result['exact'][] = [
352
+                'label' => $search,
353
+                'value' => [
354
+                    'shareType' => Share::SHARE_TYPE_REMOTE,
355
+                    'shareWith' => $search,
356
+                ],
357
+            ];
358
+        }
359
+
360
+        $this->reachedEndFor[] = 'remotes';
361
+
362
+        return $result;
363
+    }
364
+
365
+    /**
366
+     * split user and remote from federated cloud id
367
+     *
368
+     * @param string $address federated share address
369
+     * @return array [user, remoteURL]
370
+     * @throws \Exception
371
+     */
372
+    public function splitUserRemote($address) {
373
+        try {
374
+            $cloudId = $this->cloudIdManager->resolveCloudId($address);
375
+            return [$cloudId->getUser(), $cloudId->getRemote()];
376
+        } catch (\InvalidArgumentException $e) {
377
+            throw new \Exception('Invalid Federated Cloud ID', 0, $e);
378
+        }
379
+    }
380
+
381
+    /**
382
+     * Strips away a potential file names and trailing slashes:
383
+     * - http://localhost
384
+     * - http://localhost/
385
+     * - http://localhost/index.php
386
+     * - http://localhost/index.php/s/{shareToken}
387
+     *
388
+     * all return: http://localhost
389
+     *
390
+     * @param string $remote
391
+     * @return string
392
+     */
393
+    protected function fixRemoteURL($remote) {
394
+        $remote = str_replace('\\', '/', $remote);
395
+        if ($fileNamePosition = strpos($remote, '/index.php')) {
396
+            $remote = substr($remote, 0, $fileNamePosition);
397
+        }
398
+        $remote = rtrim($remote, '/');
399
+
400
+        return $remote;
401
+    }
402
+
403
+    /**
404
+     * @NoAdminRequired
405
+     *
406
+     * @param string $search
407
+     * @param string $itemType
408
+     * @param int $page
409
+     * @param int $perPage
410
+     * @param int|int[] $shareType
411
+     * @param bool $lookup
412
+     * @return Http\DataResponse
413
+     * @throws OCSBadRequestException
414
+     */
415
+    public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) {
416
+        if ($perPage <= 0) {
417
+            throw new OCSBadRequestException('Invalid perPage argument');
418
+        }
419
+        if ($page <= 0) {
420
+            throw new OCSBadRequestException('Invalid page');
421
+        }
422
+
423
+        $shareTypes = [
424
+            Share::SHARE_TYPE_USER,
425
+        ];
426
+
427
+        if ($itemType === 'file' || $itemType === 'folder') {
428
+            if ($this->shareManager->allowGroupSharing()) {
429
+                $shareTypes[] = Share::SHARE_TYPE_GROUP;
430
+            }
431
+
432
+            if ($this->isRemoteSharingAllowed($itemType)) {
433
+                $shareTypes[] = Share::SHARE_TYPE_REMOTE;
434
+            }
435
+
436
+            if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
437
+                $shareTypes[] = Share::SHARE_TYPE_EMAIL;
438
+            }
439
+        } else {
440
+            $shareTypes[] = Share::SHARE_TYPE_GROUP;
441
+            $shareTypes[] = Share::SHARE_TYPE_EMAIL;
442
+        }
443
+
444
+        if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
445
+            $shareTypes = array_intersect($shareTypes, $_GET['shareType']);
446
+            sort($shareTypes);
447
+        } else if (is_numeric($shareType)) {
448
+            $shareTypes = array_intersect($shareTypes, [(int) $shareType]);
449
+            sort($shareTypes);
450
+        }
451
+
452
+        $this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
453
+        $this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
454
+        $this->limit = (int) $perPage;
455
+        $this->offset = $perPage * ($page - 1);
456
+
457
+        return $this->searchSharees($search, $itemType, $shareTypes, $page, $perPage, $lookup);
458
+    }
459
+
460
+    /**
461
+     * Method to get out the static call for better testing
462
+     *
463
+     * @param string $itemType
464
+     * @return bool
465
+     */
466
+    protected function isRemoteSharingAllowed($itemType) {
467
+        try {
468
+            $backend = Share::getBackend($itemType);
469
+            return $backend->isShareTypeAllowed(Share::SHARE_TYPE_REMOTE);
470
+        } catch (\Exception $e) {
471
+            return false;
472
+        }
473
+    }
474
+
475
+    /**
476
+     * Testable search function that does not need globals
477
+     *
478
+     * @param string $search
479
+     * @param string $itemType
480
+     * @param array $shareTypes
481
+     * @param int $page
482
+     * @param int $perPage
483
+     * @param bool $lookup
484
+     * @return Http\DataResponse
485
+     * @throws OCSBadRequestException
486
+     */
487
+    protected function searchSharees($search, $itemType, array $shareTypes, $page, $perPage, $lookup) {
488
+        // Verify arguments
489
+        if ($itemType === null) {
490
+            throw new OCSBadRequestException('Missing itemType');
491
+        }
492
+
493
+        // Get users
494
+        if (in_array(Share::SHARE_TYPE_USER, $shareTypes)) {
495
+            $this->getUsers($search);
496
+        }
497
+
498
+        // Get groups
499
+        if (in_array(Share::SHARE_TYPE_GROUP, $shareTypes)) {
500
+            $this->getGroups($search);
501
+        }
502
+
503
+        // Get remote
504
+        $remoteResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
505
+        if (in_array(Share::SHARE_TYPE_REMOTE, $shareTypes)) {
506
+            $remoteResults = $this->getRemote($search);
507
+        }
508
+
509
+        // Get emails
510
+        $mailResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
511
+        if (in_array(Share::SHARE_TYPE_EMAIL, $shareTypes)) {
512
+            $mailResults = $this->getEmail($search);
513
+        }
514
+
515
+        // Get from lookup server
516
+        if ($lookup) {
517
+            $this->getLookup($search);
518
+        }
519
+
520
+        // if we have a exact match, either for the federated cloud id or for the
521
+        // email address we only return the exact match. It is highly unlikely
522
+        // that the exact same email address and federated cloud id exists
523
+        if ($mailResults['exactIdMatch'] && !$remoteResults['exactIdMatch']) {
524
+            $this->result['emails'] = $mailResults['results'];
525
+            $this->result['exact']['emails'] = $mailResults['exact'];
526
+        } else if (!$mailResults['exactIdMatch'] && $remoteResults['exactIdMatch']) {
527
+            $this->result['remotes'] = $remoteResults['results'];
528
+            $this->result['exact']['remotes'] = $remoteResults['exact'];
529
+        } else {
530
+            $this->result['remotes'] = $remoteResults['results'];
531
+            $this->result['exact']['remotes'] = $remoteResults['exact'];
532
+            $this->result['emails'] = $mailResults['results'];
533
+            $this->result['exact']['emails'] = $mailResults['exact'];
534
+        }
535
+
536
+        $response = new Http\DataResponse($this->result);
537
+
538
+        if (sizeof($this->reachedEndFor) < 3) {
539
+            $response->addHeader('Link', $this->getPaginationLink($page, [
540
+                'search' => $search,
541
+                'itemType' => $itemType,
542
+                'shareType' => $shareTypes,
543
+                'perPage' => $perPage,
544
+            ]));
545
+        }
546
+
547
+        return $response;
548
+    }
549
+
550
+    /**
551
+     * @param string $search
552
+     * @return array
553
+     */
554
+    protected function getEmail($search) {
555
+        $result = ['results' => [], 'exact' => []];
556
+
557
+        // Search in contacts
558
+        //@todo Pagination missing
559
+        $addressBookContacts = $this->contactsManager->search($search, ['EMAIL', 'FN']);
560
+        $result['exactIdMatch'] = false;
561
+        foreach ($addressBookContacts as $contact) {
562
+            if (isset($contact['isLocalSystemBook'])) {
563
+                continue;
564
+            }
565
+            if (isset($contact['EMAIL'])) {
566
+                $emailAddresses = $contact['EMAIL'];
567
+                if (!is_array($emailAddresses)) {
568
+                    $emailAddresses = [$emailAddresses];
569
+                }
570
+                foreach ($emailAddresses as $emailAddress) {
571
+                    if (strtolower($contact['FN']) === strtolower($search) || strtolower($emailAddress) === strtolower($search)) {
572
+                        if (strtolower($emailAddress) === strtolower($search)) {
573
+                            $result['exactIdMatch'] = true;
574
+                        }
575
+                        $result['exact'][] = [
576
+                            'label' => $contact['FN'] . " ($emailAddress)",
577
+                            'value' => [
578
+                                'shareType' => Share::SHARE_TYPE_EMAIL,
579
+                                'shareWith' => $emailAddress,
580
+                            ],
581
+                        ];
582
+                    } else {
583
+                        $result['results'][] = [
584
+                            'label' => $contact['FN'] . " ($emailAddress)",
585
+                            'value' => [
586
+                                'shareType' => Share::SHARE_TYPE_EMAIL,
587
+                                'shareWith' => $emailAddress,
588
+                            ],
589
+                        ];
590
+                    }
591
+                }
592
+            }
593
+        }
594
+
595
+        if (!$this->shareeEnumeration) {
596
+            $result['results'] = [];
597
+        }
598
+
599
+        if (!$result['exactIdMatch'] && filter_var($search, FILTER_VALIDATE_EMAIL)) {
600
+            $result['exact'][] = [
601
+                'label' => $search,
602
+                'value' => [
603
+                    'shareType' => Share::SHARE_TYPE_EMAIL,
604
+                    'shareWith' => $search,
605
+                ],
606
+            ];
607
+        }
608
+
609
+        $this->reachedEndFor[] = 'emails';
610
+
611
+        return $result;
612
+    }
613
+
614
+    protected function getLookup($search) {
615
+        $isEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
616
+        $result = [];
617
+
618
+        if($isEnabled === 'yes') {
619
+            try {
620
+                $client = $this->clientService->newClient();
621
+                $response = $client->get(
622
+                    'https://lookup.nextcloud.com/users?search=' . urlencode($search),
623
+                    [
624
+                        'timeout' => 10,
625
+                        'connect_timeout' => 3,
626
+                    ]
627
+                );
628
+
629
+                $body = json_decode($response->getBody(), true);
630
+
631
+                $result = [];
632
+                foreach ($body as $lookup) {
633
+                    $result[] = [
634
+                        'label' => $lookup['federationId'],
635
+                        'value' => [
636
+                            'shareType' => Share::SHARE_TYPE_REMOTE,
637
+                            'shareWith' => $lookup['federationId'],
638
+                        ],
639
+                        'extra' => $lookup,
640
+                    ];
641
+                }
642
+            } catch (\Exception $e) {}
643
+        }
644
+
645
+        $this->result['lookup'] = $result;
646
+    }
647
+
648
+    /**
649
+     * Generates a bunch of pagination links for the current page
650
+     *
651
+     * @param int $page Current page
652
+     * @param array $params Parameters for the URL
653
+     * @return string
654
+     */
655
+    protected function getPaginationLink($page, array $params) {
656
+        if ($this->isV2()) {
657
+            $url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
658
+        } else {
659
+            $url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
660
+        }
661
+        $params['page'] = $page + 1;
662
+        $link = '<' . $url . http_build_query($params) . '>; rel="next"';
663
+
664
+        return $link;
665
+    }
666
+
667
+    /**
668
+     * @return bool
669
+     */
670
+    protected function isV2() {
671
+        return $this->request->getScriptName() === '/ocs/v2.php';
672
+    }
673 673
 }
Please login to merge, or discard this patch.