Completed
Push — master ( 46e8fe...37177d )
by Thomas
11:43
created

Backend::deleteAllSharesByUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 7
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 7
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Joas Schilling <[email protected]>
4
 * @author Lukas Reschke <[email protected]>
5
 * @author Thomas Müller <[email protected]>
6
 *
7
 * @copyright Copyright (c) 2016, ownCloud GmbH.
8
 * @license AGPL-3.0
9
 *
10
 * This code is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License, version 3,
12
 * as published by the Free Software Foundation.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License, version 3,
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
21
 *
22
 */
23
24
namespace OCA\DAV\DAV\Sharing;
25
26
use OCA\DAV\Connector\Sabre\Principal;
27
use OCP\IDBConnection;
28
29
class Backend {
30
31
	/** @var IDBConnection */
32
	private $db;
33
	/** @var Principal */
34
	private $principalBackend;
35
	/** @var string */
36
	private $resourceType;
37
38
	const ACCESS_OWNER = 1;
39
	const ACCESS_READ_WRITE = 2;
40
	const ACCESS_READ = 3;
41
42
	/**
43
	 * @param IDBConnection $db
44
	 * @param Principal $principalBackend
45
	 * @param string $resourceType
46
	 */
47
	public function __construct(IDBConnection $db, Principal $principalBackend, $resourceType) {
48
		$this->db = $db;
49
		$this->principalBackend = $principalBackend;
50
		$this->resourceType = $resourceType;
51
	}
52
53
	/**
54
	 * @param IShareable $shareable
55
	 * @param string[] $add
56
	 * @param string[] $remove
57
	 */
58
	public function updateShares($shareable, $add, $remove) {
59
		foreach($add as $element) {
60
			$this->shareWith($shareable, $element);
61
		}
62
		foreach($remove as $element) {
63
			$this->unshare($shareable, $element);
64
		}
65
	}
66
67
	/**
68
	 * @param IShareable $shareable
69
	 * @param string $element
70
	 */
71
	private function shareWith($shareable, $element) {
72
		$user = $element['href'];
73
		$parts = explode(':', $user, 2);
74
		if ($parts[0] !== 'principal') {
75
			return;
76
		}
77
78
		// don't share with owner
79
		if ($shareable->getOwner() === $parts[1]) {
80
			return;
81
		}
82
83
		// remove the share if it already exists
84
		$this->unshare($shareable, $element['href']);
85
		$access = self::ACCESS_READ;
86
		if (isset($element['readOnly'])) {
87
			$access = $element['readOnly'] ? self::ACCESS_READ : self::ACCESS_READ_WRITE;
88
		}
89
90
		$query = $this->db->getQueryBuilder();
91
		$query->insert('dav_shares')
92
			->values([
93
				'principaluri' => $query->createNamedParameter($parts[1]),
94
				'type' => $query->createNamedParameter($this->resourceType),
95
				'access' => $query->createNamedParameter($access),
96
				'resourceid' => $query->createNamedParameter($shareable->getResourceId())
97
			]);
98
		$query->execute();
99
	}
100
101
	/**
102
	 * @param $resourceId
103
	 */
104 View Code Duplication
	public function deleteAllShares($resourceId) {
105
		$query = $this->db->getQueryBuilder();
106
		$query->delete('dav_shares')
107
			->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId)))
108
			->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType)))
109
			->execute();
110
	}
111
112 View Code Duplication
	public function deleteAllSharesByUser($principaluri) {
113
		$query = $this->db->getQueryBuilder();
114
		$query->delete('dav_shares')
115
			->where($query->expr()->eq('principaluri', $query->createNamedParameter($principaluri)))
116
			->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType)))
117
			->execute();
118
	}
119
120
	/**
121
	 * @param IShareable $shareable
122
	 * @param string $element
123
	 */
124
	private function unshare($shareable, $element) {
125
		$parts = explode(':', $element, 2);
126
		if ($parts[0] !== 'principal') {
127
			return;
128
		}
129
130
		// don't share with owner
131
		if ($shareable->getOwner() === $parts[1]) {
132
			return;
133
		}
134
135
		$query = $this->db->getQueryBuilder();
136
		$query->delete('dav_shares')
137
			->where($query->expr()->eq('resourceid', $query->createNamedParameter($shareable->getResourceId())))
138
			->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType)))
139
			->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($parts[1])))
140
		;
141
		$query->execute();
142
	}
143
144
	/**
145
	 * Returns the list of people whom this resource is shared with.
146
	 *
147
	 * Every element in this array should have the following properties:
148
	 *   * href - Often a mailto: address
149
	 *   * commonName - Optional, for example a first + last name
150
	 *   * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
151
	 *   * readOnly - boolean
152
	 *   * summary - Optional, a description for the share
153
	 *
154
	 * @param int $resourceId
155
	 * @return array
156
	 */
157
	public function getShares($resourceId) {
158
		$query = $this->db->getQueryBuilder();
159
		$result = $query->select(['principaluri', 'access'])
160
			->from('dav_shares')
161
			->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId)))
162
			->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType)))
163
			->execute();
164
165
		$shares = [];
166
		while($row = $result->fetch()) {
167
			$p = $this->principalBackend->getPrincipalByPath($row['principaluri']);
168
			$shares[]= [
169
				'href' => "principal:${row['principaluri']}",
170
				'commonName' => isset($p['{DAV:}displayname']) ? $p['{DAV:}displayname'] : '',
171
				'status' => 1,
172
				'readOnly' => ($row['access'] == self::ACCESS_READ),
173
				'{http://owncloud.org/ns}principal' => $row['principaluri'],
174
				'{http://owncloud.org/ns}group-share' => is_null($p)
175
			];
176
		}
177
178
		return $shares;
179
	}
180
181
	/**
182
	 * For shared resources the sharee is set in the ACL of the resource
183
	 *
184
	 * @param int $resourceId
185
	 * @param array $acl
186
	 * @return array
187
	 */
188
	public function applyShareAcl($resourceId, $acl) {
189
190
		$shares = $this->getShares($resourceId);
191
		foreach ($shares as $share) {
192
			$acl[] = [
193
				'privilege' => '{DAV:}read',
194
				'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'],
195
				'protected' => true,
196
			];
197
			if (!$share['readOnly']) {
198
				$acl[] = [
199
					'privilege' => '{DAV:}write',
200
					'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'],
201
					'protected' => true,
202
				];
203
			} else if ($this->resourceType === 'calendar') {
204
				// Allow changing the properties of read only calendars,
205
				// so users can change the visibility.
206
				$acl[] = [
207
					'privilege' => '{DAV:}write-properties',
208
					'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'],
209
					'protected' => true,
210
				];
211
			}
212
		}
213
		return $acl;
214
	}
215
}
216