Passed
Push — master ( 2ddf3c...43b333 )
by Lukas
16:47 queued 12s
created
lib/public/AppFramework/Db/QBMapper.php 2 patches
Indentation   +301 added lines, -301 removed lines patch added patch discarded remove patch
@@ -44,305 +44,305 @@
 block discarded – undo
44 44
  */
45 45
 abstract class QBMapper {
46 46
 
47
-	/** @var string */
48
-	protected $tableName;
49
-
50
-	/** @var string|class-string<T> */
51
-	protected $entityClass;
52
-
53
-	/** @var IDBConnection */
54
-	protected $db;
55
-
56
-	/**
57
-	 * @param IDBConnection $db Instance of the Db abstraction layer
58
-	 * @param string $tableName the name of the table. set this to allow entity
59
-	 * @param string|null $entityClass the name of the entity that the sql should be
60
-	 * @psalm-param class-string<T>|null $entityClass the name of the entity that the sql should be
61
-	 * mapped to queries without using sql
62
-	 * @since 14.0.0
63
-	 */
64
-	public function __construct(IDBConnection $db, string $tableName, string $entityClass = null) {
65
-		$this->db = $db;
66
-		$this->tableName = $tableName;
67
-
68
-		// if not given set the entity name to the class without the mapper part
69
-		// cache it here for later use since reflection is slow
70
-		if ($entityClass === null) {
71
-			$this->entityClass = str_replace('Mapper', '', \get_class($this));
72
-		} else {
73
-			$this->entityClass = $entityClass;
74
-		}
75
-	}
76
-
77
-
78
-	/**
79
-	 * @return string the table name
80
-	 * @since 14.0.0
81
-	 */
82
-	public function getTableName(): string {
83
-		return $this->tableName;
84
-	}
85
-
86
-
87
-	/**
88
-	 * Deletes an entity from the table
89
-	 * @param Entity $entity the entity that should be deleted
90
-	 * @psalm-param T $entity the entity that should be deleted
91
-	 * @return Entity the deleted entity
92
-	 * @psalm-return T the deleted entity
93
-	 * @since 14.0.0
94
-	 */
95
-	public function delete(Entity $entity): Entity {
96
-		$qb = $this->db->getQueryBuilder();
97
-
98
-		$idType = $this->getParameterTypeForProperty($entity, 'id');
99
-
100
-		$qb->delete($this->tableName)
101
-			->where(
102
-				$qb->expr()->eq('id', $qb->createNamedParameter($entity->getId(), $idType))
103
-			);
104
-		$qb->execute();
105
-		return $entity;
106
-	}
107
-
108
-
109
-	/**
110
-	 * Creates a new entry in the db from an entity
111
-	 * @param Entity $entity the entity that should be created
112
-	 * @psalm-param T $entity the entity that should be created
113
-	 * @return Entity the saved entity with the set id
114
-	 * @psalm-return T the saved entity with the set id
115
-	 * @since 14.0.0
116
-	 */
117
-	public function insert(Entity $entity): Entity {
118
-		// get updated fields to save, fields have to be set using a setter to
119
-		// be saved
120
-		$properties = $entity->getUpdatedFields();
121
-
122
-		$qb = $this->db->getQueryBuilder();
123
-		$qb->insert($this->tableName);
124
-
125
-		// build the fields
126
-		foreach ($properties as $property => $updated) {
127
-			$column = $entity->propertyToColumn($property);
128
-			$getter = 'get' . ucfirst($property);
129
-			$value = $entity->$getter();
130
-
131
-			$type = $this->getParameterTypeForProperty($entity, $property);
132
-			$qb->setValue($column, $qb->createNamedParameter($value, $type));
133
-		}
134
-
135
-		$qb->execute();
136
-
137
-		if ($entity->id === null) {
138
-			// When autoincrement is used id is always an int
139
-			$entity->setId($qb->getLastInsertId());
140
-		}
141
-
142
-		return $entity;
143
-	}
144
-
145
-	/**
146
-	 * Tries to creates a new entry in the db from an entity and
147
-	 * updates an existing entry if duplicate keys are detected
148
-	 * by the database
149
-	 *
150
-	 * @param Entity $entity the entity that should be created/updated
151
-	 * @psalm-param T $entity the entity that should be created/updated
152
-	 * @return Entity the saved entity with the (new) id
153
-	 * @psalm-return T the saved entity with the (new) id
154
-	 * @throws \InvalidArgumentException if entity has no id
155
-	 * @since 15.0.0
156
-	 */
157
-	public function insertOrUpdate(Entity $entity): Entity {
158
-		try {
159
-			return $this->insert($entity);
160
-		} catch (UniqueConstraintViolationException $ex) {
161
-			return $this->update($entity);
162
-		}
163
-	}
164
-
165
-	/**
166
-	 * Updates an entry in the db from an entity
167
-	 * @throws \InvalidArgumentException if entity has no id
168
-	 * @param Entity $entity the entity that should be created
169
-	 * @psalm-param T $entity the entity that should be created
170
-	 * @return Entity the saved entity with the set id
171
-	 * @psalm-return T the saved entity with the set id
172
-	 * @since 14.0.0
173
-	 */
174
-	public function update(Entity $entity): Entity {
175
-		// if entity wasn't changed it makes no sense to run a db query
176
-		$properties = $entity->getUpdatedFields();
177
-		if (\count($properties) === 0) {
178
-			return $entity;
179
-		}
180
-
181
-		// entity needs an id
182
-		$id = $entity->getId();
183
-		if ($id === null) {
184
-			throw new \InvalidArgumentException(
185
-				'Entity which should be updated has no id');
186
-		}
187
-
188
-		// get updated fields to save, fields have to be set using a setter to
189
-		// be saved
190
-		// do not update the id field
191
-		unset($properties['id']);
192
-
193
-		$qb = $this->db->getQueryBuilder();
194
-		$qb->update($this->tableName);
195
-
196
-		// build the fields
197
-		foreach ($properties as $property => $updated) {
198
-			$column = $entity->propertyToColumn($property);
199
-			$getter = 'get' . ucfirst($property);
200
-			$value = $entity->$getter();
201
-
202
-			$type = $this->getParameterTypeForProperty($entity, $property);
203
-			$qb->set($column, $qb->createNamedParameter($value, $type));
204
-		}
205
-
206
-		$idType = $this->getParameterTypeForProperty($entity, 'id');
207
-
208
-		$qb->where(
209
-			$qb->expr()->eq('id', $qb->createNamedParameter($id, $idType))
210
-		);
211
-		$qb->execute();
212
-
213
-		return $entity;
214
-	}
215
-
216
-	/**
217
-	 * Returns the type parameter for the QueryBuilder for a specific property
218
-	 * of the $entity
219
-	 *
220
-	 * @param Entity $entity   The entity to get the types from
221
-	 * @psalm-param T $entity
222
-	 * @param string $property The property of $entity to get the type for
223
-	 * @return int
224
-	 * @since 16.0.0
225
-	 */
226
-	protected function getParameterTypeForProperty(Entity $entity, string $property): int {
227
-		$types = $entity->getFieldTypes();
228
-
229
-		if (!isset($types[ $property ])) {
230
-			return IQueryBuilder::PARAM_STR;
231
-		}
232
-
233
-		switch ($types[ $property ]) {
234
-			case 'int':
235
-			case 'integer':
236
-				return IQueryBuilder::PARAM_INT;
237
-			case 'string':
238
-				return IQueryBuilder::PARAM_STR;
239
-			case 'bool':
240
-			case 'boolean':
241
-				return IQueryBuilder::PARAM_BOOL;
242
-			case 'blob':
243
-				return IQueryBuilder::PARAM_LOB;
244
-		}
245
-
246
-		return IQueryBuilder::PARAM_STR;
247
-	}
248
-
249
-	/**
250
-	 * Returns an db result and throws exceptions when there are more or less
251
-	 * results
252
-	 *
253
-	 * @see findEntity
254
-	 *
255
-	 * @param IQueryBuilder $query
256
-	 * @throws DoesNotExistException if the item does not exist
257
-	 * @throws MultipleObjectsReturnedException if more than one item exist
258
-	 * @return array the result as row
259
-	 * @since 14.0.0
260
-	 */
261
-	protected function findOneQuery(IQueryBuilder $query): array {
262
-		$cursor = $query->execute();
263
-
264
-		$row = $cursor->fetch();
265
-		if ($row === false) {
266
-			$cursor->closeCursor();
267
-			$msg = $this->buildDebugMessage(
268
-				'Did expect one result but found none when executing', $query
269
-			);
270
-			throw new DoesNotExistException($msg);
271
-		}
272
-
273
-		$row2 = $cursor->fetch();
274
-		$cursor->closeCursor();
275
-		if ($row2 !== false) {
276
-			$msg = $this->buildDebugMessage(
277
-				'Did not expect more than one result when executing', $query
278
-			);
279
-			throw new MultipleObjectsReturnedException($msg);
280
-		}
281
-
282
-		return $row;
283
-	}
284
-
285
-	/**
286
-	 * @param string $msg
287
-	 * @param IQueryBuilder $sql
288
-	 * @return string
289
-	 * @since 14.0.0
290
-	 */
291
-	private function buildDebugMessage(string $msg, IQueryBuilder $sql): string {
292
-		return $msg .
293
-			': query "' . $sql->getSQL() . '"; ';
294
-	}
295
-
296
-
297
-	/**
298
-	 * Creates an entity from a row. Automatically determines the entity class
299
-	 * from the current mapper name (MyEntityMapper -> MyEntity)
300
-	 *
301
-	 * @param array $row the row which should be converted to an entity
302
-	 * @return Entity the entity
303
-	 * @psalm-return T the entity
304
-	 * @since 14.0.0
305
-	 */
306
-	protected function mapRowToEntity(array $row): Entity {
307
-		return \call_user_func($this->entityClass .'::fromRow', $row);
308
-	}
309
-
310
-
311
-	/**
312
-	 * Runs a sql query and returns an array of entities
313
-	 *
314
-	 * @param IQueryBuilder $query
315
-	 * @return Entity[] all fetched entities
316
-	 * @psalm-return T[] all fetched entities
317
-	 * @since 14.0.0
318
-	 */
319
-	protected function findEntities(IQueryBuilder $query): array {
320
-		$cursor = $query->execute();
321
-
322
-		$entities = [];
323
-
324
-		while ($row = $cursor->fetch()) {
325
-			$entities[] = $this->mapRowToEntity($row);
326
-		}
327
-
328
-		$cursor->closeCursor();
329
-
330
-		return $entities;
331
-	}
332
-
333
-
334
-	/**
335
-	 * Returns an db result and throws exceptions when there are more or less
336
-	 * results
337
-	 *
338
-	 * @param IQueryBuilder $query
339
-	 * @throws DoesNotExistException if the item does not exist
340
-	 * @throws MultipleObjectsReturnedException if more than one item exist
341
-	 * @return Entity the entity
342
-	 * @psalm-return T the entity
343
-	 * @since 14.0.0
344
-	 */
345
-	protected function findEntity(IQueryBuilder $query): Entity {
346
-		return $this->mapRowToEntity($this->findOneQuery($query));
347
-	}
47
+    /** @var string */
48
+    protected $tableName;
49
+
50
+    /** @var string|class-string<T> */
51
+    protected $entityClass;
52
+
53
+    /** @var IDBConnection */
54
+    protected $db;
55
+
56
+    /**
57
+     * @param IDBConnection $db Instance of the Db abstraction layer
58
+     * @param string $tableName the name of the table. set this to allow entity
59
+     * @param string|null $entityClass the name of the entity that the sql should be
60
+     * @psalm-param class-string<T>|null $entityClass the name of the entity that the sql should be
61
+     * mapped to queries without using sql
62
+     * @since 14.0.0
63
+     */
64
+    public function __construct(IDBConnection $db, string $tableName, string $entityClass = null) {
65
+        $this->db = $db;
66
+        $this->tableName = $tableName;
67
+
68
+        // if not given set the entity name to the class without the mapper part
69
+        // cache it here for later use since reflection is slow
70
+        if ($entityClass === null) {
71
+            $this->entityClass = str_replace('Mapper', '', \get_class($this));
72
+        } else {
73
+            $this->entityClass = $entityClass;
74
+        }
75
+    }
76
+
77
+
78
+    /**
79
+     * @return string the table name
80
+     * @since 14.0.0
81
+     */
82
+    public function getTableName(): string {
83
+        return $this->tableName;
84
+    }
85
+
86
+
87
+    /**
88
+     * Deletes an entity from the table
89
+     * @param Entity $entity the entity that should be deleted
90
+     * @psalm-param T $entity the entity that should be deleted
91
+     * @return Entity the deleted entity
92
+     * @psalm-return T the deleted entity
93
+     * @since 14.0.0
94
+     */
95
+    public function delete(Entity $entity): Entity {
96
+        $qb = $this->db->getQueryBuilder();
97
+
98
+        $idType = $this->getParameterTypeForProperty($entity, 'id');
99
+
100
+        $qb->delete($this->tableName)
101
+            ->where(
102
+                $qb->expr()->eq('id', $qb->createNamedParameter($entity->getId(), $idType))
103
+            );
104
+        $qb->execute();
105
+        return $entity;
106
+    }
107
+
108
+
109
+    /**
110
+     * Creates a new entry in the db from an entity
111
+     * @param Entity $entity the entity that should be created
112
+     * @psalm-param T $entity the entity that should be created
113
+     * @return Entity the saved entity with the set id
114
+     * @psalm-return T the saved entity with the set id
115
+     * @since 14.0.0
116
+     */
117
+    public function insert(Entity $entity): Entity {
118
+        // get updated fields to save, fields have to be set using a setter to
119
+        // be saved
120
+        $properties = $entity->getUpdatedFields();
121
+
122
+        $qb = $this->db->getQueryBuilder();
123
+        $qb->insert($this->tableName);
124
+
125
+        // build the fields
126
+        foreach ($properties as $property => $updated) {
127
+            $column = $entity->propertyToColumn($property);
128
+            $getter = 'get' . ucfirst($property);
129
+            $value = $entity->$getter();
130
+
131
+            $type = $this->getParameterTypeForProperty($entity, $property);
132
+            $qb->setValue($column, $qb->createNamedParameter($value, $type));
133
+        }
134
+
135
+        $qb->execute();
136
+
137
+        if ($entity->id === null) {
138
+            // When autoincrement is used id is always an int
139
+            $entity->setId($qb->getLastInsertId());
140
+        }
141
+
142
+        return $entity;
143
+    }
144
+
145
+    /**
146
+     * Tries to creates a new entry in the db from an entity and
147
+     * updates an existing entry if duplicate keys are detected
148
+     * by the database
149
+     *
150
+     * @param Entity $entity the entity that should be created/updated
151
+     * @psalm-param T $entity the entity that should be created/updated
152
+     * @return Entity the saved entity with the (new) id
153
+     * @psalm-return T the saved entity with the (new) id
154
+     * @throws \InvalidArgumentException if entity has no id
155
+     * @since 15.0.0
156
+     */
157
+    public function insertOrUpdate(Entity $entity): Entity {
158
+        try {
159
+            return $this->insert($entity);
160
+        } catch (UniqueConstraintViolationException $ex) {
161
+            return $this->update($entity);
162
+        }
163
+    }
164
+
165
+    /**
166
+     * Updates an entry in the db from an entity
167
+     * @throws \InvalidArgumentException if entity has no id
168
+     * @param Entity $entity the entity that should be created
169
+     * @psalm-param T $entity the entity that should be created
170
+     * @return Entity the saved entity with the set id
171
+     * @psalm-return T the saved entity with the set id
172
+     * @since 14.0.0
173
+     */
174
+    public function update(Entity $entity): Entity {
175
+        // if entity wasn't changed it makes no sense to run a db query
176
+        $properties = $entity->getUpdatedFields();
177
+        if (\count($properties) === 0) {
178
+            return $entity;
179
+        }
180
+
181
+        // entity needs an id
182
+        $id = $entity->getId();
183
+        if ($id === null) {
184
+            throw new \InvalidArgumentException(
185
+                'Entity which should be updated has no id');
186
+        }
187
+
188
+        // get updated fields to save, fields have to be set using a setter to
189
+        // be saved
190
+        // do not update the id field
191
+        unset($properties['id']);
192
+
193
+        $qb = $this->db->getQueryBuilder();
194
+        $qb->update($this->tableName);
195
+
196
+        // build the fields
197
+        foreach ($properties as $property => $updated) {
198
+            $column = $entity->propertyToColumn($property);
199
+            $getter = 'get' . ucfirst($property);
200
+            $value = $entity->$getter();
201
+
202
+            $type = $this->getParameterTypeForProperty($entity, $property);
203
+            $qb->set($column, $qb->createNamedParameter($value, $type));
204
+        }
205
+
206
+        $idType = $this->getParameterTypeForProperty($entity, 'id');
207
+
208
+        $qb->where(
209
+            $qb->expr()->eq('id', $qb->createNamedParameter($id, $idType))
210
+        );
211
+        $qb->execute();
212
+
213
+        return $entity;
214
+    }
215
+
216
+    /**
217
+     * Returns the type parameter for the QueryBuilder for a specific property
218
+     * of the $entity
219
+     *
220
+     * @param Entity $entity   The entity to get the types from
221
+     * @psalm-param T $entity
222
+     * @param string $property The property of $entity to get the type for
223
+     * @return int
224
+     * @since 16.0.0
225
+     */
226
+    protected function getParameterTypeForProperty(Entity $entity, string $property): int {
227
+        $types = $entity->getFieldTypes();
228
+
229
+        if (!isset($types[ $property ])) {
230
+            return IQueryBuilder::PARAM_STR;
231
+        }
232
+
233
+        switch ($types[ $property ]) {
234
+            case 'int':
235
+            case 'integer':
236
+                return IQueryBuilder::PARAM_INT;
237
+            case 'string':
238
+                return IQueryBuilder::PARAM_STR;
239
+            case 'bool':
240
+            case 'boolean':
241
+                return IQueryBuilder::PARAM_BOOL;
242
+            case 'blob':
243
+                return IQueryBuilder::PARAM_LOB;
244
+        }
245
+
246
+        return IQueryBuilder::PARAM_STR;
247
+    }
248
+
249
+    /**
250
+     * Returns an db result and throws exceptions when there are more or less
251
+     * results
252
+     *
253
+     * @see findEntity
254
+     *
255
+     * @param IQueryBuilder $query
256
+     * @throws DoesNotExistException if the item does not exist
257
+     * @throws MultipleObjectsReturnedException if more than one item exist
258
+     * @return array the result as row
259
+     * @since 14.0.0
260
+     */
261
+    protected function findOneQuery(IQueryBuilder $query): array {
262
+        $cursor = $query->execute();
263
+
264
+        $row = $cursor->fetch();
265
+        if ($row === false) {
266
+            $cursor->closeCursor();
267
+            $msg = $this->buildDebugMessage(
268
+                'Did expect one result but found none when executing', $query
269
+            );
270
+            throw new DoesNotExistException($msg);
271
+        }
272
+
273
+        $row2 = $cursor->fetch();
274
+        $cursor->closeCursor();
275
+        if ($row2 !== false) {
276
+            $msg = $this->buildDebugMessage(
277
+                'Did not expect more than one result when executing', $query
278
+            );
279
+            throw new MultipleObjectsReturnedException($msg);
280
+        }
281
+
282
+        return $row;
283
+    }
284
+
285
+    /**
286
+     * @param string $msg
287
+     * @param IQueryBuilder $sql
288
+     * @return string
289
+     * @since 14.0.0
290
+     */
291
+    private function buildDebugMessage(string $msg, IQueryBuilder $sql): string {
292
+        return $msg .
293
+            ': query "' . $sql->getSQL() . '"; ';
294
+    }
295
+
296
+
297
+    /**
298
+     * Creates an entity from a row. Automatically determines the entity class
299
+     * from the current mapper name (MyEntityMapper -> MyEntity)
300
+     *
301
+     * @param array $row the row which should be converted to an entity
302
+     * @return Entity the entity
303
+     * @psalm-return T the entity
304
+     * @since 14.0.0
305
+     */
306
+    protected function mapRowToEntity(array $row): Entity {
307
+        return \call_user_func($this->entityClass .'::fromRow', $row);
308
+    }
309
+
310
+
311
+    /**
312
+     * Runs a sql query and returns an array of entities
313
+     *
314
+     * @param IQueryBuilder $query
315
+     * @return Entity[] all fetched entities
316
+     * @psalm-return T[] all fetched entities
317
+     * @since 14.0.0
318
+     */
319
+    protected function findEntities(IQueryBuilder $query): array {
320
+        $cursor = $query->execute();
321
+
322
+        $entities = [];
323
+
324
+        while ($row = $cursor->fetch()) {
325
+            $entities[] = $this->mapRowToEntity($row);
326
+        }
327
+
328
+        $cursor->closeCursor();
329
+
330
+        return $entities;
331
+    }
332
+
333
+
334
+    /**
335
+     * Returns an db result and throws exceptions when there are more or less
336
+     * results
337
+     *
338
+     * @param IQueryBuilder $query
339
+     * @throws DoesNotExistException if the item does not exist
340
+     * @throws MultipleObjectsReturnedException if more than one item exist
341
+     * @return Entity the entity
342
+     * @psalm-return T the entity
343
+     * @since 14.0.0
344
+     */
345
+    protected function findEntity(IQueryBuilder $query): Entity {
346
+        return $this->mapRowToEntity($this->findOneQuery($query));
347
+    }
348 348
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
 		// build the fields
126 126
 		foreach ($properties as $property => $updated) {
127 127
 			$column = $entity->propertyToColumn($property);
128
-			$getter = 'get' . ucfirst($property);
128
+			$getter = 'get'.ucfirst($property);
129 129
 			$value = $entity->$getter();
130 130
 
131 131
 			$type = $this->getParameterTypeForProperty($entity, $property);
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
 		// build the fields
197 197
 		foreach ($properties as $property => $updated) {
198 198
 			$column = $entity->propertyToColumn($property);
199
-			$getter = 'get' . ucfirst($property);
199
+			$getter = 'get'.ucfirst($property);
200 200
 			$value = $entity->$getter();
201 201
 
202 202
 			$type = $this->getParameterTypeForProperty($entity, $property);
@@ -226,11 +226,11 @@  discard block
 block discarded – undo
226 226
 	protected function getParameterTypeForProperty(Entity $entity, string $property): int {
227 227
 		$types = $entity->getFieldTypes();
228 228
 
229
-		if (!isset($types[ $property ])) {
229
+		if (!isset($types[$property])) {
230 230
 			return IQueryBuilder::PARAM_STR;
231 231
 		}
232 232
 
233
-		switch ($types[ $property ]) {
233
+		switch ($types[$property]) {
234 234
 			case 'int':
235 235
 			case 'integer':
236 236
 				return IQueryBuilder::PARAM_INT;
@@ -289,8 +289,8 @@  discard block
 block discarded – undo
289 289
 	 * @since 14.0.0
290 290
 	 */
291 291
 	private function buildDebugMessage(string $msg, IQueryBuilder $sql): string {
292
-		return $msg .
293
-			': query "' . $sql->getSQL() . '"; ';
292
+		return $msg.
293
+			': query "'.$sql->getSQL().'"; ';
294 294
 	}
295 295
 
296 296
 
@@ -304,7 +304,7 @@  discard block
 block discarded – undo
304 304
 	 * @since 14.0.0
305 305
 	 */
306 306
 	protected function mapRowToEntity(array $row): Entity {
307
-		return \call_user_func($this->entityClass .'::fromRow', $row);
307
+		return \call_user_func($this->entityClass.'::fromRow', $row);
308 308
 	}
309 309
 
310 310
 
Please login to merge, or discard this patch.
apps/sharebymail/lib/ShareByMailProvider.php 2 patches
Indentation   +1110 added lines, -1110 removed lines patch added patch discarded remove patch
@@ -71,1121 +71,1121 @@
 block discarded – undo
71 71
  */
72 72
 class ShareByMailProvider implements IShareProvider {
73 73
 
74
-	/** @var  IDBConnection */
75
-	private $dbConnection;
76
-
77
-	/** @var ILogger */
78
-	private $logger;
79
-
80
-	/** @var ISecureRandom */
81
-	private $secureRandom;
82
-
83
-	/** @var IUserManager */
84
-	private $userManager;
85
-
86
-	/** @var IRootFolder */
87
-	private $rootFolder;
88
-
89
-	/** @var IL10N */
90
-	private $l;
91
-
92
-	/** @var IMailer */
93
-	private $mailer;
94
-
95
-	/** @var IURLGenerator */
96
-	private $urlGenerator;
97
-
98
-	/** @var IManager  */
99
-	private $activityManager;
100
-
101
-	/** @var SettingsManager */
102
-	private $settingsManager;
103
-
104
-	/** @var Defaults */
105
-	private $defaults;
106
-
107
-	/** @var IHasher */
108
-	private $hasher;
109
-
110
-	/** @var IEventDispatcher */
111
-	private $eventDispatcher;
112
-
113
-	/**
114
-	 * Return the identifier of this provider.
115
-	 *
116
-	 * @return string Containing only [a-zA-Z0-9]
117
-	 */
118
-	public function identifier() {
119
-		return 'ocMailShare';
120
-	}
121
-
122
-	public function __construct(
123
-		IDBConnection $connection,
124
-		ISecureRandom $secureRandom,
125
-		IUserManager $userManager,
126
-		IRootFolder $rootFolder,
127
-		IL10N $l,
128
-		ILogger $logger,
129
-		IMailer $mailer,
130
-		IURLGenerator $urlGenerator,
131
-		IManager $activityManager,
132
-		SettingsManager $settingsManager,
133
-		Defaults $defaults,
134
-		IHasher $hasher,
135
-		IEventDispatcher $eventDispatcher
136
-	) {
137
-		$this->dbConnection = $connection;
138
-		$this->secureRandom = $secureRandom;
139
-		$this->userManager = $userManager;
140
-		$this->rootFolder = $rootFolder;
141
-		$this->l = $l;
142
-		$this->logger = $logger;
143
-		$this->mailer = $mailer;
144
-		$this->urlGenerator = $urlGenerator;
145
-		$this->activityManager = $activityManager;
146
-		$this->settingsManager = $settingsManager;
147
-		$this->defaults = $defaults;
148
-		$this->hasher = $hasher;
149
-		$this->eventDispatcher = $eventDispatcher;
150
-	}
151
-
152
-	/**
153
-	 * Share a path
154
-	 *
155
-	 * @param IShare $share
156
-	 * @return IShare The share object
157
-	 * @throws ShareNotFound
158
-	 * @throws \Exception
159
-	 */
160
-	public function create(IShare $share) {
161
-		$shareWith = $share->getSharedWith();
162
-		/*
74
+    /** @var  IDBConnection */
75
+    private $dbConnection;
76
+
77
+    /** @var ILogger */
78
+    private $logger;
79
+
80
+    /** @var ISecureRandom */
81
+    private $secureRandom;
82
+
83
+    /** @var IUserManager */
84
+    private $userManager;
85
+
86
+    /** @var IRootFolder */
87
+    private $rootFolder;
88
+
89
+    /** @var IL10N */
90
+    private $l;
91
+
92
+    /** @var IMailer */
93
+    private $mailer;
94
+
95
+    /** @var IURLGenerator */
96
+    private $urlGenerator;
97
+
98
+    /** @var IManager  */
99
+    private $activityManager;
100
+
101
+    /** @var SettingsManager */
102
+    private $settingsManager;
103
+
104
+    /** @var Defaults */
105
+    private $defaults;
106
+
107
+    /** @var IHasher */
108
+    private $hasher;
109
+
110
+    /** @var IEventDispatcher */
111
+    private $eventDispatcher;
112
+
113
+    /**
114
+     * Return the identifier of this provider.
115
+     *
116
+     * @return string Containing only [a-zA-Z0-9]
117
+     */
118
+    public function identifier() {
119
+        return 'ocMailShare';
120
+    }
121
+
122
+    public function __construct(
123
+        IDBConnection $connection,
124
+        ISecureRandom $secureRandom,
125
+        IUserManager $userManager,
126
+        IRootFolder $rootFolder,
127
+        IL10N $l,
128
+        ILogger $logger,
129
+        IMailer $mailer,
130
+        IURLGenerator $urlGenerator,
131
+        IManager $activityManager,
132
+        SettingsManager $settingsManager,
133
+        Defaults $defaults,
134
+        IHasher $hasher,
135
+        IEventDispatcher $eventDispatcher
136
+    ) {
137
+        $this->dbConnection = $connection;
138
+        $this->secureRandom = $secureRandom;
139
+        $this->userManager = $userManager;
140
+        $this->rootFolder = $rootFolder;
141
+        $this->l = $l;
142
+        $this->logger = $logger;
143
+        $this->mailer = $mailer;
144
+        $this->urlGenerator = $urlGenerator;
145
+        $this->activityManager = $activityManager;
146
+        $this->settingsManager = $settingsManager;
147
+        $this->defaults = $defaults;
148
+        $this->hasher = $hasher;
149
+        $this->eventDispatcher = $eventDispatcher;
150
+    }
151
+
152
+    /**
153
+     * Share a path
154
+     *
155
+     * @param IShare $share
156
+     * @return IShare The share object
157
+     * @throws ShareNotFound
158
+     * @throws \Exception
159
+     */
160
+    public function create(IShare $share) {
161
+        $shareWith = $share->getSharedWith();
162
+        /*
163 163
 		 * Check if file is not already shared with the remote user
164 164
 		 */
165
-		$alreadyShared = $this->getSharedWith($shareWith, IShare::TYPE_EMAIL, $share->getNode(), 1, 0);
166
-		if (!empty($alreadyShared)) {
167
-			$message = 'Sharing %1$s failed, this item is already shared with %2$s';
168
-			$message_t = $this->l->t('Sharing %1$s failed, this item is already shared with %2$s', [$share->getNode()->getName(), $shareWith]);
169
-			$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
170
-			throw new \Exception($message_t);
171
-		}
172
-
173
-		// if the admin enforces a password for all mail shares we create a
174
-		// random password and send it to the recipient
175
-		$password = $share->getPassword() ?: '';
176
-		$passwordEnforced = $this->settingsManager->enforcePasswordProtection();
177
-		if ($passwordEnforced && empty($password)) {
178
-			$password = $this->autoGeneratePassword($share);
179
-		}
180
-
181
-		if (!empty($password)) {
182
-			$share->setPassword($this->hasher->hash($password));
183
-		}
184
-
185
-		$shareId = $this->createMailShare($share);
186
-		$send = $this->sendPassword($share, $password);
187
-		if ($passwordEnforced && $send === false) {
188
-			$this->sendPasswordToOwner($share, $password);
189
-		}
190
-
191
-		$this->createShareActivity($share);
192
-		$data = $this->getRawShare($shareId);
193
-
194
-		return $this->createShareObject($data);
195
-	}
196
-
197
-	/**
198
-	 * auto generate password in case of password enforcement on mail shares
199
-	 *
200
-	 * @param IShare $share
201
-	 * @return string
202
-	 * @throws \Exception
203
-	 */
204
-	protected function autoGeneratePassword($share) {
205
-		$initiatorUser = $this->userManager->get($share->getSharedBy());
206
-		$initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
207
-		$allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
208
-
209
-		if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
210
-			throw new \Exception(
211
-				$this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
212
-			);
213
-		}
214
-
215
-		$passwordEvent = new GenerateSecurePasswordEvent();
216
-		$this->eventDispatcher->dispatchTyped($passwordEvent);
217
-
218
-		$password = $passwordEvent->getPassword();
219
-		if ($password === null) {
220
-			$password = $this->secureRandom->generate(8, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
221
-		}
222
-
223
-		return $password;
224
-	}
225
-
226
-	/**
227
-	 * create activity if a file/folder was shared by mail
228
-	 *
229
-	 * @param IShare $share
230
-	 * @param string $type
231
-	 */
232
-	protected function createShareActivity(IShare $share, string $type = 'share') {
233
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
234
-
235
-		$this->publishActivity(
236
-			$type === 'share' ? Activity::SUBJECT_SHARED_EMAIL_SELF : Activity::SUBJECT_UNSHARED_EMAIL_SELF,
237
-			[$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
238
-			$share->getSharedBy(),
239
-			$share->getNode()->getId(),
240
-			(string) $userFolder->getRelativePath($share->getNode()->getPath())
241
-		);
242
-
243
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
244
-			$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
245
-			$fileId = $share->getNode()->getId();
246
-			$nodes = $ownerFolder->getById($fileId);
247
-			$ownerPath = $nodes[0]->getPath();
248
-			$this->publishActivity(
249
-				$type === 'share' ? Activity::SUBJECT_SHARED_EMAIL_BY : Activity::SUBJECT_UNSHARED_EMAIL_BY,
250
-				[$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
251
-				$share->getShareOwner(),
252
-				$fileId,
253
-				(string) $ownerFolder->getRelativePath($ownerPath)
254
-			);
255
-		}
256
-	}
257
-
258
-	/**
259
-	 * create activity if a file/folder was shared by mail
260
-	 *
261
-	 * @param IShare $share
262
-	 * @param string $sharedWith
263
-	 * @param bool $sendToSelf
264
-	 */
265
-	protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
266
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
267
-
268
-		if ($sendToSelf) {
269
-			$this->publishActivity(
270
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
271
-				[$userFolder->getRelativePath($share->getNode()->getPath())],
272
-				$share->getSharedBy(),
273
-				$share->getNode()->getId(),
274
-				(string) $userFolder->getRelativePath($share->getNode()->getPath())
275
-			);
276
-		} else {
277
-			$this->publishActivity(
278
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
279
-				[$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
280
-				$share->getSharedBy(),
281
-				$share->getNode()->getId(),
282
-				(string) $userFolder->getRelativePath($share->getNode()->getPath())
283
-			);
284
-		}
285
-	}
286
-
287
-
288
-	/**
289
-	 * publish activity if a file/folder was shared by mail
290
-	 *
291
-	 * @param string $subject
292
-	 * @param array $parameters
293
-	 * @param string $affectedUser
294
-	 * @param int $fileId
295
-	 * @param string $filePath
296
-	 */
297
-	protected function publishActivity(string $subject, array $parameters, string $affectedUser, int $fileId, string $filePath) {
298
-		$event = $this->activityManager->generateEvent();
299
-		$event->setApp('sharebymail')
300
-			->setType('shared')
301
-			->setSubject($subject, $parameters)
302
-			->setAffectedUser($affectedUser)
303
-			->setObject('files', $fileId, $filePath);
304
-		$this->activityManager->publish($event);
305
-	}
306
-
307
-	/**
308
-	 * @param IShare $share
309
-	 * @return int
310
-	 * @throws \Exception
311
-	 */
312
-	protected function createMailShare(IShare $share) {
313
-		$share->setToken($this->generateToken());
314
-		$shareId = $this->addShareToDB(
315
-			$share->getNodeId(),
316
-			$share->getNodeType(),
317
-			$share->getSharedWith(),
318
-			$share->getSharedBy(),
319
-			$share->getShareOwner(),
320
-			$share->getPermissions(),
321
-			$share->getToken(),
322
-			$share->getPassword(),
323
-			$share->getSendPasswordByTalk(),
324
-			$share->getHideDownload(),
325
-			$share->getExpirationDate()
326
-		);
327
-
328
-		try {
329
-			$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
330
-				['token' => $share->getToken()]);
331
-			$this->sendMailNotification(
332
-				$share->getNode()->getName(),
333
-				$link,
334
-				$share->getSharedBy(),
335
-				$share->getSharedWith(),
336
-				$share->getExpirationDate()
337
-			);
338
-		} catch (HintException $hintException) {
339
-			$this->logger->logException($hintException, [
340
-				'message' => 'Failed to send share by mail.',
341
-				'level' => ILogger::ERROR,
342
-				'app' => 'sharebymail',
343
-			]);
344
-			$this->removeShareFromTable($shareId);
345
-			throw $hintException;
346
-		} catch (\Exception $e) {
347
-			$this->logger->logException($e, [
348
-				'message' => 'Failed to send share by mail.',
349
-				'level' => ILogger::ERROR,
350
-				'app' => 'sharebymail',
351
-			]);
352
-			$this->removeShareFromTable($shareId);
353
-			throw new HintException('Failed to send share by mail',
354
-				$this->l->t('Failed to send share by email'));
355
-		}
356
-
357
-		return $shareId;
358
-	}
359
-
360
-	/**
361
-	 * @param string $filename
362
-	 * @param string $link
363
-	 * @param string $initiator
364
-	 * @param string $shareWith
365
-	 * @param \DateTime|null $expiration
366
-	 * @throws \Exception If mail couldn't be sent
367
-	 */
368
-	protected function sendMailNotification($filename,
369
-											$link,
370
-											$initiator,
371
-											$shareWith,
372
-											\DateTime $expiration = null) {
373
-		$initiatorUser = $this->userManager->get($initiator);
374
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
375
-		$message = $this->mailer->createMessage();
376
-
377
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientNotification', [
378
-			'filename' => $filename,
379
-			'link' => $link,
380
-			'initiator' => $initiatorDisplayName,
381
-			'expiration' => $expiration,
382
-			'shareWith' => $shareWith,
383
-		]);
384
-
385
-		$emailTemplate->setSubject($this->l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]));
386
-		$emailTemplate->addHeader();
387
-		$emailTemplate->addHeading($this->l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
388
-		$text = $this->l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
389
-
390
-		$emailTemplate->addBodyText(
391
-			htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
392
-			$text
393
-		);
394
-		$emailTemplate->addBodyButton(
395
-			$this->l->t('Open »%s«', [$filename]),
396
-			$link
397
-		);
398
-
399
-		$message->setTo([$shareWith]);
400
-
401
-		// The "From" contains the sharers name
402
-		$instanceName = $this->defaults->getName();
403
-		$senderName = $instanceName;
404
-		if ($this->settingsManager->replyToInitiator()) {
405
-			$senderName = $this->l->t(
406
-				'%1$s via %2$s',
407
-				[
408
-					$initiatorDisplayName,
409
-					$instanceName
410
-				]
411
-			);
412
-		}
413
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
414
-
415
-		// The "Reply-To" is set to the sharer if an mail address is configured
416
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
417
-		$initiatorEmail = $initiatorUser->getEMailAddress();
418
-		if ($this->settingsManager->replyToInitiator() && $initiatorEmail !== null) {
419
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
420
-			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
421
-		} else {
422
-			$emailTemplate->addFooter();
423
-		}
424
-
425
-		$message->useTemplate($emailTemplate);
426
-		$this->mailer->send($message);
427
-	}
428
-
429
-	/**
430
-	 * send password to recipient of a mail share
431
-	 *
432
-	 * @param IShare $share
433
-	 * @param string $password
434
-	 * @return bool
435
-	 */
436
-	protected function sendPassword(IShare $share, $password) {
437
-		$filename = $share->getNode()->getName();
438
-		$initiator = $share->getSharedBy();
439
-		$shareWith = $share->getSharedWith();
440
-
441
-		if ($password === '' || $this->settingsManager->sendPasswordByMail() === false || $share->getSendPasswordByTalk()) {
442
-			return false;
443
-		}
444
-
445
-		$initiatorUser = $this->userManager->get($initiator);
446
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
447
-		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
448
-
449
-		$plainBodyPart = $this->l->t("%1\$s shared »%2\$s« with you.\nYou should have already received a separate mail with a link to access it.\n", [$initiatorDisplayName, $filename]);
450
-		$htmlBodyPart = $this->l->t('%1$s shared »%2$s« with you. You should have already received a separate mail with a link to access it.', [$initiatorDisplayName, $filename]);
451
-
452
-		$message = $this->mailer->createMessage();
453
-
454
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientPasswordNotification', [
455
-			'filename' => $filename,
456
-			'password' => $password,
457
-			'initiator' => $initiatorDisplayName,
458
-			'initiatorEmail' => $initiatorEmailAddress,
459
-			'shareWith' => $shareWith,
460
-		]);
461
-
462
-		$emailTemplate->setSubject($this->l->t('Password to access »%1$s« shared to you by %2$s', [$filename, $initiatorDisplayName]));
463
-		$emailTemplate->addHeader();
464
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
465
-		$emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
466
-		$emailTemplate->addBodyText($this->l->t('It is protected with the following password:'));
467
-		$emailTemplate->addBodyText($password);
468
-
469
-		// The "From" contains the sharers name
470
-		$instanceName = $this->defaults->getName();
471
-		$senderName = $instanceName;
472
-		if ($this->settingsManager->replyToInitiator()) {
473
-			$senderName = $this->l->t(
474
-				'%1$s via %2$s',
475
-				[
476
-					$initiatorDisplayName,
477
-					$instanceName
478
-				]
479
-			);
480
-		}
481
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
482
-		if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
483
-			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
484
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
485
-		} else {
486
-			$emailTemplate->addFooter();
487
-		}
488
-
489
-		$message->setTo([$shareWith]);
490
-		$message->useTemplate($emailTemplate);
491
-		$this->mailer->send($message);
492
-
493
-		$this->createPasswordSendActivity($share, $shareWith, false);
494
-
495
-		return true;
496
-	}
497
-
498
-	protected function sendNote(IShare $share) {
499
-		$recipient = $share->getSharedWith();
500
-
501
-
502
-		$filename = $share->getNode()->getName();
503
-		$initiator = $share->getSharedBy();
504
-		$note = $share->getNote();
505
-
506
-		$initiatorUser = $this->userManager->get($initiator);
507
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
508
-		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
509
-
510
-		$plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
511
-		$htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
512
-
513
-		$message = $this->mailer->createMessage();
514
-
515
-		$emailTemplate = $this->mailer->createEMailTemplate('shareByMail.sendNote');
516
-
517
-		$emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
518
-		$emailTemplate->addHeader();
519
-		$emailTemplate->addHeading(htmlspecialchars($htmlHeading), $plainHeading);
520
-		$emailTemplate->addBodyText(htmlspecialchars($note), $note);
521
-
522
-		$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
523
-			['token' => $share->getToken()]);
524
-		$emailTemplate->addBodyButton(
525
-			$this->l->t('Open »%s«', [$filename]),
526
-			$link
527
-		);
528
-
529
-		// The "From" contains the sharers name
530
-		$instanceName = $this->defaults->getName();
531
-		$senderName = $instanceName;
532
-		if ($this->settingsManager->replyToInitiator()) {
533
-			$senderName = $this->l->t(
534
-				'%1$s via %2$s',
535
-				[
536
-					$initiatorDisplayName,
537
-					$instanceName
538
-				]
539
-			);
540
-		}
541
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
542
-		if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
543
-			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
544
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
545
-		} else {
546
-			$emailTemplate->addFooter();
547
-		}
548
-
549
-		$message->setTo([$recipient]);
550
-		$message->useTemplate($emailTemplate);
551
-		$this->mailer->send($message);
552
-	}
553
-
554
-	/**
555
-	 * send auto generated password to the owner. This happens if the admin enforces
556
-	 * a password for mail shares and forbid to send the password by mail to the recipient
557
-	 *
558
-	 * @param IShare $share
559
-	 * @param string $password
560
-	 * @return bool
561
-	 * @throws \Exception
562
-	 */
563
-	protected function sendPasswordToOwner(IShare $share, $password) {
564
-		$filename = $share->getNode()->getName();
565
-		$initiator = $this->userManager->get($share->getSharedBy());
566
-		$initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
567
-		$initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
568
-		$shareWith = $share->getSharedWith();
569
-
570
-		if ($initiatorEMailAddress === null) {
571
-			throw new \Exception(
572
-				$this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
573
-			);
574
-		}
575
-
576
-		$bodyPart = $this->l->t('You just shared »%1$s« with %2$s. The share was already sent to the recipient. Due to the security policies defined by the administrator of %3$s each share needs to be protected by password and it is not allowed to send the password directly to the recipient. Therefore you need to forward the password manually to the recipient.', [$filename, $shareWith, $this->defaults->getName()]);
577
-
578
-		$message = $this->mailer->createMessage();
579
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.OwnerPasswordNotification', [
580
-			'filename' => $filename,
581
-			'password' => $password,
582
-			'initiator' => $initiatorDisplayName,
583
-			'initiatorEmail' => $initiatorEMailAddress,
584
-			'shareWith' => $shareWith,
585
-		]);
586
-
587
-		$emailTemplate->setSubject($this->l->t('Password to access »%1$s« shared by you with %2$s', [$filename, $shareWith]));
588
-		$emailTemplate->addHeader();
589
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
590
-		$emailTemplate->addBodyText($bodyPart);
591
-		$emailTemplate->addBodyText($this->l->t('This is the password:'));
592
-		$emailTemplate->addBodyText($password);
593
-		$emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
594
-		$emailTemplate->addFooter();
595
-
596
-		$instanceName = $this->defaults->getName();
597
-		$senderName = $this->l->t(
598
-			'%1$s via %2$s',
599
-			[
600
-				$initiatorDisplayName,
601
-				$instanceName
602
-			]
603
-		);
604
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
605
-		$message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
606
-		$message->useTemplate($emailTemplate);
607
-		$this->mailer->send($message);
608
-
609
-		$this->createPasswordSendActivity($share, $shareWith, true);
610
-
611
-		return true;
612
-	}
613
-
614
-	/**
615
-	 * generate share token
616
-	 *
617
-	 * @return string
618
-	 */
619
-	protected function generateToken($size = 15) {
620
-		$token = $this->secureRandom->generate($size, ISecureRandom::CHAR_HUMAN_READABLE);
621
-		return $token;
622
-	}
623
-
624
-	/**
625
-	 * Get all children of this share
626
-	 *
627
-	 * @param IShare $parent
628
-	 * @return IShare[]
629
-	 */
630
-	public function getChildren(IShare $parent) {
631
-		$children = [];
632
-
633
-		$qb = $this->dbConnection->getQueryBuilder();
634
-		$qb->select('*')
635
-			->from('share')
636
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
637
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
638
-			->orderBy('id');
639
-
640
-		$cursor = $qb->execute();
641
-		while ($data = $cursor->fetch()) {
642
-			$children[] = $this->createShareObject($data);
643
-		}
644
-		$cursor->closeCursor();
645
-
646
-		return $children;
647
-	}
648
-
649
-	/**
650
-	 * add share to the database and return the ID
651
-	 *
652
-	 * @param int $itemSource
653
-	 * @param string $itemType
654
-	 * @param string $shareWith
655
-	 * @param string $sharedBy
656
-	 * @param string $uidOwner
657
-	 * @param int $permissions
658
-	 * @param string $token
659
-	 * @param string $password
660
-	 * @param bool $sendPasswordByTalk
661
-	 * @param bool $hideDownload
662
-	 * @param \DateTime|null $expirationTime
663
-	 * @return int
664
-	 */
665
-	protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password, $sendPasswordByTalk, $hideDownload, $expirationTime) {
666
-		$qb = $this->dbConnection->getQueryBuilder();
667
-		$qb->insert('share')
668
-			->setValue('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL))
669
-			->setValue('item_type', $qb->createNamedParameter($itemType))
670
-			->setValue('item_source', $qb->createNamedParameter($itemSource))
671
-			->setValue('file_source', $qb->createNamedParameter($itemSource))
672
-			->setValue('share_with', $qb->createNamedParameter($shareWith))
673
-			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
674
-			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
675
-			->setValue('permissions', $qb->createNamedParameter($permissions))
676
-			->setValue('token', $qb->createNamedParameter($token))
677
-			->setValue('password', $qb->createNamedParameter($password))
678
-			->setValue('password_by_talk', $qb->createNamedParameter($sendPasswordByTalk, IQueryBuilder::PARAM_BOOL))
679
-			->setValue('stime', $qb->createNamedParameter(time()))
680
-			->setValue('hide_download', $qb->createNamedParameter((int)$hideDownload, IQueryBuilder::PARAM_INT));
681
-
682
-		if ($expirationTime !== null) {
683
-			$qb->setValue('expiration', $qb->createNamedParameter($expirationTime, IQueryBuilder::PARAM_DATE));
684
-		}
685
-
686
-		/*
165
+        $alreadyShared = $this->getSharedWith($shareWith, IShare::TYPE_EMAIL, $share->getNode(), 1, 0);
166
+        if (!empty($alreadyShared)) {
167
+            $message = 'Sharing %1$s failed, this item is already shared with %2$s';
168
+            $message_t = $this->l->t('Sharing %1$s failed, this item is already shared with %2$s', [$share->getNode()->getName(), $shareWith]);
169
+            $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
170
+            throw new \Exception($message_t);
171
+        }
172
+
173
+        // if the admin enforces a password for all mail shares we create a
174
+        // random password and send it to the recipient
175
+        $password = $share->getPassword() ?: '';
176
+        $passwordEnforced = $this->settingsManager->enforcePasswordProtection();
177
+        if ($passwordEnforced && empty($password)) {
178
+            $password = $this->autoGeneratePassword($share);
179
+        }
180
+
181
+        if (!empty($password)) {
182
+            $share->setPassword($this->hasher->hash($password));
183
+        }
184
+
185
+        $shareId = $this->createMailShare($share);
186
+        $send = $this->sendPassword($share, $password);
187
+        if ($passwordEnforced && $send === false) {
188
+            $this->sendPasswordToOwner($share, $password);
189
+        }
190
+
191
+        $this->createShareActivity($share);
192
+        $data = $this->getRawShare($shareId);
193
+
194
+        return $this->createShareObject($data);
195
+    }
196
+
197
+    /**
198
+     * auto generate password in case of password enforcement on mail shares
199
+     *
200
+     * @param IShare $share
201
+     * @return string
202
+     * @throws \Exception
203
+     */
204
+    protected function autoGeneratePassword($share) {
205
+        $initiatorUser = $this->userManager->get($share->getSharedBy());
206
+        $initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
207
+        $allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
208
+
209
+        if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
210
+            throw new \Exception(
211
+                $this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
212
+            );
213
+        }
214
+
215
+        $passwordEvent = new GenerateSecurePasswordEvent();
216
+        $this->eventDispatcher->dispatchTyped($passwordEvent);
217
+
218
+        $password = $passwordEvent->getPassword();
219
+        if ($password === null) {
220
+            $password = $this->secureRandom->generate(8, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
221
+        }
222
+
223
+        return $password;
224
+    }
225
+
226
+    /**
227
+     * create activity if a file/folder was shared by mail
228
+     *
229
+     * @param IShare $share
230
+     * @param string $type
231
+     */
232
+    protected function createShareActivity(IShare $share, string $type = 'share') {
233
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
234
+
235
+        $this->publishActivity(
236
+            $type === 'share' ? Activity::SUBJECT_SHARED_EMAIL_SELF : Activity::SUBJECT_UNSHARED_EMAIL_SELF,
237
+            [$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
238
+            $share->getSharedBy(),
239
+            $share->getNode()->getId(),
240
+            (string) $userFolder->getRelativePath($share->getNode()->getPath())
241
+        );
242
+
243
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
244
+            $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
245
+            $fileId = $share->getNode()->getId();
246
+            $nodes = $ownerFolder->getById($fileId);
247
+            $ownerPath = $nodes[0]->getPath();
248
+            $this->publishActivity(
249
+                $type === 'share' ? Activity::SUBJECT_SHARED_EMAIL_BY : Activity::SUBJECT_UNSHARED_EMAIL_BY,
250
+                [$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
251
+                $share->getShareOwner(),
252
+                $fileId,
253
+                (string) $ownerFolder->getRelativePath($ownerPath)
254
+            );
255
+        }
256
+    }
257
+
258
+    /**
259
+     * create activity if a file/folder was shared by mail
260
+     *
261
+     * @param IShare $share
262
+     * @param string $sharedWith
263
+     * @param bool $sendToSelf
264
+     */
265
+    protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
266
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
267
+
268
+        if ($sendToSelf) {
269
+            $this->publishActivity(
270
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
271
+                [$userFolder->getRelativePath($share->getNode()->getPath())],
272
+                $share->getSharedBy(),
273
+                $share->getNode()->getId(),
274
+                (string) $userFolder->getRelativePath($share->getNode()->getPath())
275
+            );
276
+        } else {
277
+            $this->publishActivity(
278
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
279
+                [$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
280
+                $share->getSharedBy(),
281
+                $share->getNode()->getId(),
282
+                (string) $userFolder->getRelativePath($share->getNode()->getPath())
283
+            );
284
+        }
285
+    }
286
+
287
+
288
+    /**
289
+     * publish activity if a file/folder was shared by mail
290
+     *
291
+     * @param string $subject
292
+     * @param array $parameters
293
+     * @param string $affectedUser
294
+     * @param int $fileId
295
+     * @param string $filePath
296
+     */
297
+    protected function publishActivity(string $subject, array $parameters, string $affectedUser, int $fileId, string $filePath) {
298
+        $event = $this->activityManager->generateEvent();
299
+        $event->setApp('sharebymail')
300
+            ->setType('shared')
301
+            ->setSubject($subject, $parameters)
302
+            ->setAffectedUser($affectedUser)
303
+            ->setObject('files', $fileId, $filePath);
304
+        $this->activityManager->publish($event);
305
+    }
306
+
307
+    /**
308
+     * @param IShare $share
309
+     * @return int
310
+     * @throws \Exception
311
+     */
312
+    protected function createMailShare(IShare $share) {
313
+        $share->setToken($this->generateToken());
314
+        $shareId = $this->addShareToDB(
315
+            $share->getNodeId(),
316
+            $share->getNodeType(),
317
+            $share->getSharedWith(),
318
+            $share->getSharedBy(),
319
+            $share->getShareOwner(),
320
+            $share->getPermissions(),
321
+            $share->getToken(),
322
+            $share->getPassword(),
323
+            $share->getSendPasswordByTalk(),
324
+            $share->getHideDownload(),
325
+            $share->getExpirationDate()
326
+        );
327
+
328
+        try {
329
+            $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
330
+                ['token' => $share->getToken()]);
331
+            $this->sendMailNotification(
332
+                $share->getNode()->getName(),
333
+                $link,
334
+                $share->getSharedBy(),
335
+                $share->getSharedWith(),
336
+                $share->getExpirationDate()
337
+            );
338
+        } catch (HintException $hintException) {
339
+            $this->logger->logException($hintException, [
340
+                'message' => 'Failed to send share by mail.',
341
+                'level' => ILogger::ERROR,
342
+                'app' => 'sharebymail',
343
+            ]);
344
+            $this->removeShareFromTable($shareId);
345
+            throw $hintException;
346
+        } catch (\Exception $e) {
347
+            $this->logger->logException($e, [
348
+                'message' => 'Failed to send share by mail.',
349
+                'level' => ILogger::ERROR,
350
+                'app' => 'sharebymail',
351
+            ]);
352
+            $this->removeShareFromTable($shareId);
353
+            throw new HintException('Failed to send share by mail',
354
+                $this->l->t('Failed to send share by email'));
355
+        }
356
+
357
+        return $shareId;
358
+    }
359
+
360
+    /**
361
+     * @param string $filename
362
+     * @param string $link
363
+     * @param string $initiator
364
+     * @param string $shareWith
365
+     * @param \DateTime|null $expiration
366
+     * @throws \Exception If mail couldn't be sent
367
+     */
368
+    protected function sendMailNotification($filename,
369
+                                            $link,
370
+                                            $initiator,
371
+                                            $shareWith,
372
+                                            \DateTime $expiration = null) {
373
+        $initiatorUser = $this->userManager->get($initiator);
374
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
375
+        $message = $this->mailer->createMessage();
376
+
377
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientNotification', [
378
+            'filename' => $filename,
379
+            'link' => $link,
380
+            'initiator' => $initiatorDisplayName,
381
+            'expiration' => $expiration,
382
+            'shareWith' => $shareWith,
383
+        ]);
384
+
385
+        $emailTemplate->setSubject($this->l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]));
386
+        $emailTemplate->addHeader();
387
+        $emailTemplate->addHeading($this->l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
388
+        $text = $this->l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
389
+
390
+        $emailTemplate->addBodyText(
391
+            htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
392
+            $text
393
+        );
394
+        $emailTemplate->addBodyButton(
395
+            $this->l->t('Open »%s«', [$filename]),
396
+            $link
397
+        );
398
+
399
+        $message->setTo([$shareWith]);
400
+
401
+        // The "From" contains the sharers name
402
+        $instanceName = $this->defaults->getName();
403
+        $senderName = $instanceName;
404
+        if ($this->settingsManager->replyToInitiator()) {
405
+            $senderName = $this->l->t(
406
+                '%1$s via %2$s',
407
+                [
408
+                    $initiatorDisplayName,
409
+                    $instanceName
410
+                ]
411
+            );
412
+        }
413
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
414
+
415
+        // The "Reply-To" is set to the sharer if an mail address is configured
416
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
417
+        $initiatorEmail = $initiatorUser->getEMailAddress();
418
+        if ($this->settingsManager->replyToInitiator() && $initiatorEmail !== null) {
419
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
420
+            $emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
421
+        } else {
422
+            $emailTemplate->addFooter();
423
+        }
424
+
425
+        $message->useTemplate($emailTemplate);
426
+        $this->mailer->send($message);
427
+    }
428
+
429
+    /**
430
+     * send password to recipient of a mail share
431
+     *
432
+     * @param IShare $share
433
+     * @param string $password
434
+     * @return bool
435
+     */
436
+    protected function sendPassword(IShare $share, $password) {
437
+        $filename = $share->getNode()->getName();
438
+        $initiator = $share->getSharedBy();
439
+        $shareWith = $share->getSharedWith();
440
+
441
+        if ($password === '' || $this->settingsManager->sendPasswordByMail() === false || $share->getSendPasswordByTalk()) {
442
+            return false;
443
+        }
444
+
445
+        $initiatorUser = $this->userManager->get($initiator);
446
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
447
+        $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
448
+
449
+        $plainBodyPart = $this->l->t("%1\$s shared »%2\$s« with you.\nYou should have already received a separate mail with a link to access it.\n", [$initiatorDisplayName, $filename]);
450
+        $htmlBodyPart = $this->l->t('%1$s shared »%2$s« with you. You should have already received a separate mail with a link to access it.', [$initiatorDisplayName, $filename]);
451
+
452
+        $message = $this->mailer->createMessage();
453
+
454
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientPasswordNotification', [
455
+            'filename' => $filename,
456
+            'password' => $password,
457
+            'initiator' => $initiatorDisplayName,
458
+            'initiatorEmail' => $initiatorEmailAddress,
459
+            'shareWith' => $shareWith,
460
+        ]);
461
+
462
+        $emailTemplate->setSubject($this->l->t('Password to access »%1$s« shared to you by %2$s', [$filename, $initiatorDisplayName]));
463
+        $emailTemplate->addHeader();
464
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
465
+        $emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
466
+        $emailTemplate->addBodyText($this->l->t('It is protected with the following password:'));
467
+        $emailTemplate->addBodyText($password);
468
+
469
+        // The "From" contains the sharers name
470
+        $instanceName = $this->defaults->getName();
471
+        $senderName = $instanceName;
472
+        if ($this->settingsManager->replyToInitiator()) {
473
+            $senderName = $this->l->t(
474
+                '%1$s via %2$s',
475
+                [
476
+                    $initiatorDisplayName,
477
+                    $instanceName
478
+                ]
479
+            );
480
+        }
481
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
482
+        if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
483
+            $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
484
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
485
+        } else {
486
+            $emailTemplate->addFooter();
487
+        }
488
+
489
+        $message->setTo([$shareWith]);
490
+        $message->useTemplate($emailTemplate);
491
+        $this->mailer->send($message);
492
+
493
+        $this->createPasswordSendActivity($share, $shareWith, false);
494
+
495
+        return true;
496
+    }
497
+
498
+    protected function sendNote(IShare $share) {
499
+        $recipient = $share->getSharedWith();
500
+
501
+
502
+        $filename = $share->getNode()->getName();
503
+        $initiator = $share->getSharedBy();
504
+        $note = $share->getNote();
505
+
506
+        $initiatorUser = $this->userManager->get($initiator);
507
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
508
+        $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
509
+
510
+        $plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
511
+        $htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
512
+
513
+        $message = $this->mailer->createMessage();
514
+
515
+        $emailTemplate = $this->mailer->createEMailTemplate('shareByMail.sendNote');
516
+
517
+        $emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
518
+        $emailTemplate->addHeader();
519
+        $emailTemplate->addHeading(htmlspecialchars($htmlHeading), $plainHeading);
520
+        $emailTemplate->addBodyText(htmlspecialchars($note), $note);
521
+
522
+        $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
523
+            ['token' => $share->getToken()]);
524
+        $emailTemplate->addBodyButton(
525
+            $this->l->t('Open »%s«', [$filename]),
526
+            $link
527
+        );
528
+
529
+        // The "From" contains the sharers name
530
+        $instanceName = $this->defaults->getName();
531
+        $senderName = $instanceName;
532
+        if ($this->settingsManager->replyToInitiator()) {
533
+            $senderName = $this->l->t(
534
+                '%1$s via %2$s',
535
+                [
536
+                    $initiatorDisplayName,
537
+                    $instanceName
538
+                ]
539
+            );
540
+        }
541
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
542
+        if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
543
+            $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
544
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
545
+        } else {
546
+            $emailTemplate->addFooter();
547
+        }
548
+
549
+        $message->setTo([$recipient]);
550
+        $message->useTemplate($emailTemplate);
551
+        $this->mailer->send($message);
552
+    }
553
+
554
+    /**
555
+     * send auto generated password to the owner. This happens if the admin enforces
556
+     * a password for mail shares and forbid to send the password by mail to the recipient
557
+     *
558
+     * @param IShare $share
559
+     * @param string $password
560
+     * @return bool
561
+     * @throws \Exception
562
+     */
563
+    protected function sendPasswordToOwner(IShare $share, $password) {
564
+        $filename = $share->getNode()->getName();
565
+        $initiator = $this->userManager->get($share->getSharedBy());
566
+        $initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
567
+        $initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
568
+        $shareWith = $share->getSharedWith();
569
+
570
+        if ($initiatorEMailAddress === null) {
571
+            throw new \Exception(
572
+                $this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
573
+            );
574
+        }
575
+
576
+        $bodyPart = $this->l->t('You just shared »%1$s« with %2$s. The share was already sent to the recipient. Due to the security policies defined by the administrator of %3$s each share needs to be protected by password and it is not allowed to send the password directly to the recipient. Therefore you need to forward the password manually to the recipient.', [$filename, $shareWith, $this->defaults->getName()]);
577
+
578
+        $message = $this->mailer->createMessage();
579
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.OwnerPasswordNotification', [
580
+            'filename' => $filename,
581
+            'password' => $password,
582
+            'initiator' => $initiatorDisplayName,
583
+            'initiatorEmail' => $initiatorEMailAddress,
584
+            'shareWith' => $shareWith,
585
+        ]);
586
+
587
+        $emailTemplate->setSubject($this->l->t('Password to access »%1$s« shared by you with %2$s', [$filename, $shareWith]));
588
+        $emailTemplate->addHeader();
589
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
590
+        $emailTemplate->addBodyText($bodyPart);
591
+        $emailTemplate->addBodyText($this->l->t('This is the password:'));
592
+        $emailTemplate->addBodyText($password);
593
+        $emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
594
+        $emailTemplate->addFooter();
595
+
596
+        $instanceName = $this->defaults->getName();
597
+        $senderName = $this->l->t(
598
+            '%1$s via %2$s',
599
+            [
600
+                $initiatorDisplayName,
601
+                $instanceName
602
+            ]
603
+        );
604
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
605
+        $message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
606
+        $message->useTemplate($emailTemplate);
607
+        $this->mailer->send($message);
608
+
609
+        $this->createPasswordSendActivity($share, $shareWith, true);
610
+
611
+        return true;
612
+    }
613
+
614
+    /**
615
+     * generate share token
616
+     *
617
+     * @return string
618
+     */
619
+    protected function generateToken($size = 15) {
620
+        $token = $this->secureRandom->generate($size, ISecureRandom::CHAR_HUMAN_READABLE);
621
+        return $token;
622
+    }
623
+
624
+    /**
625
+     * Get all children of this share
626
+     *
627
+     * @param IShare $parent
628
+     * @return IShare[]
629
+     */
630
+    public function getChildren(IShare $parent) {
631
+        $children = [];
632
+
633
+        $qb = $this->dbConnection->getQueryBuilder();
634
+        $qb->select('*')
635
+            ->from('share')
636
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
637
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
638
+            ->orderBy('id');
639
+
640
+        $cursor = $qb->execute();
641
+        while ($data = $cursor->fetch()) {
642
+            $children[] = $this->createShareObject($data);
643
+        }
644
+        $cursor->closeCursor();
645
+
646
+        return $children;
647
+    }
648
+
649
+    /**
650
+     * add share to the database and return the ID
651
+     *
652
+     * @param int $itemSource
653
+     * @param string $itemType
654
+     * @param string $shareWith
655
+     * @param string $sharedBy
656
+     * @param string $uidOwner
657
+     * @param int $permissions
658
+     * @param string $token
659
+     * @param string $password
660
+     * @param bool $sendPasswordByTalk
661
+     * @param bool $hideDownload
662
+     * @param \DateTime|null $expirationTime
663
+     * @return int
664
+     */
665
+    protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password, $sendPasswordByTalk, $hideDownload, $expirationTime) {
666
+        $qb = $this->dbConnection->getQueryBuilder();
667
+        $qb->insert('share')
668
+            ->setValue('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL))
669
+            ->setValue('item_type', $qb->createNamedParameter($itemType))
670
+            ->setValue('item_source', $qb->createNamedParameter($itemSource))
671
+            ->setValue('file_source', $qb->createNamedParameter($itemSource))
672
+            ->setValue('share_with', $qb->createNamedParameter($shareWith))
673
+            ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
674
+            ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
675
+            ->setValue('permissions', $qb->createNamedParameter($permissions))
676
+            ->setValue('token', $qb->createNamedParameter($token))
677
+            ->setValue('password', $qb->createNamedParameter($password))
678
+            ->setValue('password_by_talk', $qb->createNamedParameter($sendPasswordByTalk, IQueryBuilder::PARAM_BOOL))
679
+            ->setValue('stime', $qb->createNamedParameter(time()))
680
+            ->setValue('hide_download', $qb->createNamedParameter((int)$hideDownload, IQueryBuilder::PARAM_INT));
681
+
682
+        if ($expirationTime !== null) {
683
+            $qb->setValue('expiration', $qb->createNamedParameter($expirationTime, IQueryBuilder::PARAM_DATE));
684
+        }
685
+
686
+        /*
687 687
 		 * Added to fix https://github.com/owncloud/core/issues/22215
688 688
 		 * Can be removed once we get rid of ajax/share.php
689 689
 		 */
690
-		$qb->setValue('file_target', $qb->createNamedParameter(''));
691
-
692
-		$qb->execute();
693
-		return $qb->getLastInsertId();
694
-	}
695
-
696
-	/**
697
-	 * Update a share
698
-	 *
699
-	 * @param IShare $share
700
-	 * @param string|null $plainTextPassword
701
-	 * @return IShare The share object
702
-	 */
703
-	public function update(IShare $share, $plainTextPassword = null) {
704
-		$originalShare = $this->getShareById($share->getId());
705
-
706
-		// a real password was given
707
-		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
708
-
709
-		if ($validPassword && ($originalShare->getPassword() !== $share->getPassword() ||
710
-								($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()))) {
711
-			$this->sendPassword($share, $plainTextPassword);
712
-		}
713
-		/*
690
+        $qb->setValue('file_target', $qb->createNamedParameter(''));
691
+
692
+        $qb->execute();
693
+        return $qb->getLastInsertId();
694
+    }
695
+
696
+    /**
697
+     * Update a share
698
+     *
699
+     * @param IShare $share
700
+     * @param string|null $plainTextPassword
701
+     * @return IShare The share object
702
+     */
703
+    public function update(IShare $share, $plainTextPassword = null) {
704
+        $originalShare = $this->getShareById($share->getId());
705
+
706
+        // a real password was given
707
+        $validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
708
+
709
+        if ($validPassword && ($originalShare->getPassword() !== $share->getPassword() ||
710
+                                ($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()))) {
711
+            $this->sendPassword($share, $plainTextPassword);
712
+        }
713
+        /*
714 714
 		 * We allow updating the permissions and password of mail shares
715 715
 		 */
716
-		$qb = $this->dbConnection->getQueryBuilder();
717
-		$qb->update('share')
718
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
719
-			->set('permissions', $qb->createNamedParameter($share->getPermissions()))
720
-			->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
721
-			->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
722
-			->set('password', $qb->createNamedParameter($share->getPassword()))
723
-			->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
724
-			->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
725
-			->set('note', $qb->createNamedParameter($share->getNote()))
726
-			->set('hide_download', $qb->createNamedParameter((int)$share->getHideDownload(), IQueryBuilder::PARAM_INT))
727
-			->execute();
728
-
729
-		if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
730
-			$this->sendNote($share);
731
-		}
732
-
733
-		return $share;
734
-	}
735
-
736
-	/**
737
-	 * @inheritdoc
738
-	 */
739
-	public function move(IShare $share, $recipient) {
740
-		/**
741
-		 * nothing to do here, mail shares are only outgoing shares
742
-		 */
743
-		return $share;
744
-	}
745
-
746
-	/**
747
-	 * Delete a share (owner unShares the file)
748
-	 *
749
-	 * @param IShare $share
750
-	 */
751
-	public function delete(IShare $share) {
752
-		try {
753
-			$this->createShareActivity($share, 'unshare');
754
-		} catch (\Exception $e) {
755
-		}
756
-
757
-		$this->removeShareFromTable($share->getId());
758
-	}
759
-
760
-	/**
761
-	 * @inheritdoc
762
-	 */
763
-	public function deleteFromSelf(IShare $share, $recipient) {
764
-		// nothing to do here, mail shares are only outgoing shares
765
-	}
766
-
767
-	public function restore(IShare $share, string $recipient): IShare {
768
-		throw new GenericShareException('not implemented');
769
-	}
770
-
771
-	/**
772
-	 * @inheritdoc
773
-	 */
774
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
775
-		$qb = $this->dbConnection->getQueryBuilder();
776
-		$qb->select('*')
777
-			->from('share');
778
-
779
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
780
-
781
-		/**
782
-		 * Reshares for this user are shares where they are the owner.
783
-		 */
784
-		if ($reshares === false) {
785
-			//Special case for old shares created via the web UI
786
-			$or1 = $qb->expr()->andX(
787
-				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
788
-				$qb->expr()->isNull('uid_initiator')
789
-			);
790
-
791
-			$qb->andWhere(
792
-				$qb->expr()->orX(
793
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
794
-					$or1
795
-				)
796
-			);
797
-		} else {
798
-			$qb->andWhere(
799
-				$qb->expr()->orX(
800
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
801
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
802
-				)
803
-			);
804
-		}
805
-
806
-		if ($node !== null) {
807
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
808
-		}
809
-
810
-		if ($limit !== -1) {
811
-			$qb->setMaxResults($limit);
812
-		}
813
-
814
-		$qb->setFirstResult($offset);
815
-		$qb->orderBy('id');
816
-
817
-		$cursor = $qb->execute();
818
-		$shares = [];
819
-		while ($data = $cursor->fetch()) {
820
-			$shares[] = $this->createShareObject($data);
821
-		}
822
-		$cursor->closeCursor();
823
-
824
-		return $shares;
825
-	}
826
-
827
-	/**
828
-	 * @inheritdoc
829
-	 */
830
-	public function getShareById($id, $recipientId = null) {
831
-		$qb = $this->dbConnection->getQueryBuilder();
832
-
833
-		$qb->select('*')
834
-			->from('share')
835
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
836
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
837
-
838
-		$cursor = $qb->execute();
839
-		$data = $cursor->fetch();
840
-		$cursor->closeCursor();
841
-
842
-		if ($data === false) {
843
-			throw new ShareNotFound();
844
-		}
845
-
846
-		try {
847
-			$share = $this->createShareObject($data);
848
-		} catch (InvalidShare $e) {
849
-			throw new ShareNotFound();
850
-		}
851
-
852
-		return $share;
853
-	}
854
-
855
-	/**
856
-	 * Get shares for a given path
857
-	 *
858
-	 * @param \OCP\Files\Node $path
859
-	 * @return IShare[]
860
-	 */
861
-	public function getSharesByPath(Node $path) {
862
-		$qb = $this->dbConnection->getQueryBuilder();
863
-
864
-		$cursor = $qb->select('*')
865
-			->from('share')
866
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
867
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
868
-			->execute();
869
-
870
-		$shares = [];
871
-		while ($data = $cursor->fetch()) {
872
-			$shares[] = $this->createShareObject($data);
873
-		}
874
-		$cursor->closeCursor();
875
-
876
-		return $shares;
877
-	}
878
-
879
-	/**
880
-	 * @inheritdoc
881
-	 */
882
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
883
-		/** @var IShare[] $shares */
884
-		$shares = [];
885
-
886
-		//Get shares directly with this user
887
-		$qb = $this->dbConnection->getQueryBuilder();
888
-		$qb->select('*')
889
-			->from('share');
890
-
891
-		// Order by id
892
-		$qb->orderBy('id');
893
-
894
-		// Set limit and offset
895
-		if ($limit !== -1) {
896
-			$qb->setMaxResults($limit);
897
-		}
898
-		$qb->setFirstResult($offset);
899
-
900
-		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
901
-		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
902
-
903
-		// Filter by node if provided
904
-		if ($node !== null) {
905
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
906
-		}
907
-
908
-		$cursor = $qb->execute();
909
-
910
-		while ($data = $cursor->fetch()) {
911
-			$shares[] = $this->createShareObject($data);
912
-		}
913
-		$cursor->closeCursor();
914
-
915
-
916
-		return $shares;
917
-	}
918
-
919
-	/**
920
-	 * Get a share by token
921
-	 *
922
-	 * @param string $token
923
-	 * @return IShare
924
-	 * @throws ShareNotFound
925
-	 */
926
-	public function getShareByToken($token) {
927
-		$qb = $this->dbConnection->getQueryBuilder();
928
-
929
-		$cursor = $qb->select('*')
930
-			->from('share')
931
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
932
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
933
-			->execute();
934
-
935
-		$data = $cursor->fetch();
936
-
937
-		if ($data === false) {
938
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
939
-		}
940
-
941
-		try {
942
-			$share = $this->createShareObject($data);
943
-		} catch (InvalidShare $e) {
944
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
945
-		}
946
-
947
-		return $share;
948
-	}
949
-
950
-	/**
951
-	 * remove share from table
952
-	 *
953
-	 * @param string $shareId
954
-	 */
955
-	protected function removeShareFromTable($shareId) {
956
-		$qb = $this->dbConnection->getQueryBuilder();
957
-		$qb->delete('share')
958
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
959
-		$qb->execute();
960
-	}
961
-
962
-	/**
963
-	 * Create a share object from an database row
964
-	 *
965
-	 * @param array $data
966
-	 * @return IShare
967
-	 * @throws InvalidShare
968
-	 * @throws ShareNotFound
969
-	 */
970
-	protected function createShareObject($data) {
971
-		$share = new Share($this->rootFolder, $this->userManager);
972
-		$share->setId((int)$data['id'])
973
-			->setShareType((int)$data['share_type'])
974
-			->setPermissions((int)$data['permissions'])
975
-			->setTarget($data['file_target'])
976
-			->setMailSend((bool)$data['mail_send'])
977
-			->setNote($data['note'])
978
-			->setToken($data['token']);
979
-
980
-		$shareTime = new \DateTime();
981
-		$shareTime->setTimestamp((int)$data['stime']);
982
-		$share->setShareTime($shareTime);
983
-		$share->setSharedWith($data['share_with']);
984
-		$share->setPassword($data['password']);
985
-		$share->setSendPasswordByTalk((bool)$data['password_by_talk']);
986
-		$share->setHideDownload((bool)$data['hide_download']);
987
-
988
-		if ($data['uid_initiator'] !== null) {
989
-			$share->setShareOwner($data['uid_owner']);
990
-			$share->setSharedBy($data['uid_initiator']);
991
-		} else {
992
-			//OLD SHARE
993
-			$share->setSharedBy($data['uid_owner']);
994
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
995
-
996
-			$owner = $path->getOwner();
997
-			$share->setShareOwner($owner->getUID());
998
-		}
999
-
1000
-		if ($data['expiration'] !== null) {
1001
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
1002
-			if ($expiration !== false) {
1003
-				$share->setExpirationDate($expiration);
1004
-			}
1005
-		}
1006
-
1007
-		$share->setNodeId((int)$data['file_source']);
1008
-		$share->setNodeType($data['item_type']);
1009
-
1010
-		$share->setProviderId($this->identifier());
1011
-
1012
-		return $share;
1013
-	}
1014
-
1015
-	/**
1016
-	 * Get the node with file $id for $user
1017
-	 *
1018
-	 * @param string $userId
1019
-	 * @param int $id
1020
-	 * @return \OCP\Files\File|\OCP\Files\Folder
1021
-	 * @throws InvalidShare
1022
-	 */
1023
-	private function getNode($userId, $id) {
1024
-		try {
1025
-			$userFolder = $this->rootFolder->getUserFolder($userId);
1026
-		} catch (NoUserException $e) {
1027
-			throw new InvalidShare();
1028
-		}
1029
-
1030
-		$nodes = $userFolder->getById($id);
1031
-
1032
-		if (empty($nodes)) {
1033
-			throw new InvalidShare();
1034
-		}
1035
-
1036
-		return $nodes[0];
1037
-	}
1038
-
1039
-	/**
1040
-	 * A user is deleted from the system
1041
-	 * So clean up the relevant shares.
1042
-	 *
1043
-	 * @param string $uid
1044
-	 * @param int $shareType
1045
-	 */
1046
-	public function userDeleted($uid, $shareType) {
1047
-		$qb = $this->dbConnection->getQueryBuilder();
1048
-
1049
-		$qb->delete('share')
1050
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
1051
-			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
1052
-			->execute();
1053
-	}
1054
-
1055
-	/**
1056
-	 * This provider does not support group shares
1057
-	 *
1058
-	 * @param string $gid
1059
-	 */
1060
-	public function groupDeleted($gid) {
1061
-	}
1062
-
1063
-	/**
1064
-	 * This provider does not support group shares
1065
-	 *
1066
-	 * @param string $uid
1067
-	 * @param string $gid
1068
-	 */
1069
-	public function userDeletedFromGroup($uid, $gid) {
1070
-	}
1071
-
1072
-	/**
1073
-	 * get database row of a give share
1074
-	 *
1075
-	 * @param $id
1076
-	 * @return array
1077
-	 * @throws ShareNotFound
1078
-	 */
1079
-	protected function getRawShare($id) {
1080
-
1081
-		// Now fetch the inserted share and create a complete share object
1082
-		$qb = $this->dbConnection->getQueryBuilder();
1083
-		$qb->select('*')
1084
-			->from('share')
1085
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1086
-
1087
-		$cursor = $qb->execute();
1088
-		$data = $cursor->fetch();
1089
-		$cursor->closeCursor();
1090
-
1091
-		if ($data === false) {
1092
-			throw new ShareNotFound;
1093
-		}
1094
-
1095
-		return $data;
1096
-	}
1097
-
1098
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
1099
-		$qb = $this->dbConnection->getQueryBuilder();
1100
-		$qb->select('*')
1101
-			->from('share', 's')
1102
-			->andWhere($qb->expr()->orX(
1103
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1104
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1105
-			))
1106
-			->andWhere(
1107
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL))
1108
-			);
1109
-
1110
-		/**
1111
-		 * Reshares for this user are shares where they are the owner.
1112
-		 */
1113
-		if ($reshares === false) {
1114
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1115
-		} else {
1116
-			$qb->andWhere(
1117
-				$qb->expr()->orX(
1118
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1119
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1120
-				)
1121
-			);
1122
-		}
1123
-
1124
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1125
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1126
-
1127
-		$qb->orderBy('id');
1128
-
1129
-		$cursor = $qb->execute();
1130
-		$shares = [];
1131
-		while ($data = $cursor->fetch()) {
1132
-			$shares[$data['fileid']][] = $this->createShareObject($data);
1133
-		}
1134
-		$cursor->closeCursor();
1135
-
1136
-		return $shares;
1137
-	}
1138
-
1139
-	/**
1140
-	 * @inheritdoc
1141
-	 */
1142
-	public function getAccessList($nodes, $currentAccess) {
1143
-		$ids = [];
1144
-		foreach ($nodes as $node) {
1145
-			$ids[] = $node->getId();
1146
-		}
1147
-
1148
-		$qb = $this->dbConnection->getQueryBuilder();
1149
-		$qb->select('share_with')
1150
-			->from('share')
1151
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
1152
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1153
-			->andWhere($qb->expr()->orX(
1154
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1155
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1156
-			))
1157
-			->setMaxResults(1);
1158
-		$cursor = $qb->execute();
1159
-
1160
-		$mail = $cursor->fetch() !== false;
1161
-		$cursor->closeCursor();
1162
-
1163
-		return ['public' => $mail];
1164
-	}
1165
-
1166
-	public function getAllShares(): iterable {
1167
-		$qb = $this->dbConnection->getQueryBuilder();
1168
-
1169
-		$qb->select('*')
1170
-			->from('share')
1171
-			->where(
1172
-				$qb->expr()->orX(
1173
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_EMAIL))
1174
-				)
1175
-			);
1176
-
1177
-		$cursor = $qb->execute();
1178
-		while ($data = $cursor->fetch()) {
1179
-			try {
1180
-				$share = $this->createShareObject($data);
1181
-			} catch (InvalidShare $e) {
1182
-				continue;
1183
-			} catch (ShareNotFound $e) {
1184
-				continue;
1185
-			}
1186
-
1187
-			yield $share;
1188
-		}
1189
-		$cursor->closeCursor();
1190
-	}
716
+        $qb = $this->dbConnection->getQueryBuilder();
717
+        $qb->update('share')
718
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
719
+            ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
720
+            ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
721
+            ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
722
+            ->set('password', $qb->createNamedParameter($share->getPassword()))
723
+            ->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
724
+            ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
725
+            ->set('note', $qb->createNamedParameter($share->getNote()))
726
+            ->set('hide_download', $qb->createNamedParameter((int)$share->getHideDownload(), IQueryBuilder::PARAM_INT))
727
+            ->execute();
728
+
729
+        if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
730
+            $this->sendNote($share);
731
+        }
732
+
733
+        return $share;
734
+    }
735
+
736
+    /**
737
+     * @inheritdoc
738
+     */
739
+    public function move(IShare $share, $recipient) {
740
+        /**
741
+         * nothing to do here, mail shares are only outgoing shares
742
+         */
743
+        return $share;
744
+    }
745
+
746
+    /**
747
+     * Delete a share (owner unShares the file)
748
+     *
749
+     * @param IShare $share
750
+     */
751
+    public function delete(IShare $share) {
752
+        try {
753
+            $this->createShareActivity($share, 'unshare');
754
+        } catch (\Exception $e) {
755
+        }
756
+
757
+        $this->removeShareFromTable($share->getId());
758
+    }
759
+
760
+    /**
761
+     * @inheritdoc
762
+     */
763
+    public function deleteFromSelf(IShare $share, $recipient) {
764
+        // nothing to do here, mail shares are only outgoing shares
765
+    }
766
+
767
+    public function restore(IShare $share, string $recipient): IShare {
768
+        throw new GenericShareException('not implemented');
769
+    }
770
+
771
+    /**
772
+     * @inheritdoc
773
+     */
774
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
775
+        $qb = $this->dbConnection->getQueryBuilder();
776
+        $qb->select('*')
777
+            ->from('share');
778
+
779
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
780
+
781
+        /**
782
+         * Reshares for this user are shares where they are the owner.
783
+         */
784
+        if ($reshares === false) {
785
+            //Special case for old shares created via the web UI
786
+            $or1 = $qb->expr()->andX(
787
+                $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
788
+                $qb->expr()->isNull('uid_initiator')
789
+            );
790
+
791
+            $qb->andWhere(
792
+                $qb->expr()->orX(
793
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
794
+                    $or1
795
+                )
796
+            );
797
+        } else {
798
+            $qb->andWhere(
799
+                $qb->expr()->orX(
800
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
801
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
802
+                )
803
+            );
804
+        }
805
+
806
+        if ($node !== null) {
807
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
808
+        }
809
+
810
+        if ($limit !== -1) {
811
+            $qb->setMaxResults($limit);
812
+        }
813
+
814
+        $qb->setFirstResult($offset);
815
+        $qb->orderBy('id');
816
+
817
+        $cursor = $qb->execute();
818
+        $shares = [];
819
+        while ($data = $cursor->fetch()) {
820
+            $shares[] = $this->createShareObject($data);
821
+        }
822
+        $cursor->closeCursor();
823
+
824
+        return $shares;
825
+    }
826
+
827
+    /**
828
+     * @inheritdoc
829
+     */
830
+    public function getShareById($id, $recipientId = null) {
831
+        $qb = $this->dbConnection->getQueryBuilder();
832
+
833
+        $qb->select('*')
834
+            ->from('share')
835
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
836
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
837
+
838
+        $cursor = $qb->execute();
839
+        $data = $cursor->fetch();
840
+        $cursor->closeCursor();
841
+
842
+        if ($data === false) {
843
+            throw new ShareNotFound();
844
+        }
845
+
846
+        try {
847
+            $share = $this->createShareObject($data);
848
+        } catch (InvalidShare $e) {
849
+            throw new ShareNotFound();
850
+        }
851
+
852
+        return $share;
853
+    }
854
+
855
+    /**
856
+     * Get shares for a given path
857
+     *
858
+     * @param \OCP\Files\Node $path
859
+     * @return IShare[]
860
+     */
861
+    public function getSharesByPath(Node $path) {
862
+        $qb = $this->dbConnection->getQueryBuilder();
863
+
864
+        $cursor = $qb->select('*')
865
+            ->from('share')
866
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
867
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
868
+            ->execute();
869
+
870
+        $shares = [];
871
+        while ($data = $cursor->fetch()) {
872
+            $shares[] = $this->createShareObject($data);
873
+        }
874
+        $cursor->closeCursor();
875
+
876
+        return $shares;
877
+    }
878
+
879
+    /**
880
+     * @inheritdoc
881
+     */
882
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
883
+        /** @var IShare[] $shares */
884
+        $shares = [];
885
+
886
+        //Get shares directly with this user
887
+        $qb = $this->dbConnection->getQueryBuilder();
888
+        $qb->select('*')
889
+            ->from('share');
890
+
891
+        // Order by id
892
+        $qb->orderBy('id');
893
+
894
+        // Set limit and offset
895
+        if ($limit !== -1) {
896
+            $qb->setMaxResults($limit);
897
+        }
898
+        $qb->setFirstResult($offset);
899
+
900
+        $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
901
+        $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
902
+
903
+        // Filter by node if provided
904
+        if ($node !== null) {
905
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
906
+        }
907
+
908
+        $cursor = $qb->execute();
909
+
910
+        while ($data = $cursor->fetch()) {
911
+            $shares[] = $this->createShareObject($data);
912
+        }
913
+        $cursor->closeCursor();
914
+
915
+
916
+        return $shares;
917
+    }
918
+
919
+    /**
920
+     * Get a share by token
921
+     *
922
+     * @param string $token
923
+     * @return IShare
924
+     * @throws ShareNotFound
925
+     */
926
+    public function getShareByToken($token) {
927
+        $qb = $this->dbConnection->getQueryBuilder();
928
+
929
+        $cursor = $qb->select('*')
930
+            ->from('share')
931
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
932
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
933
+            ->execute();
934
+
935
+        $data = $cursor->fetch();
936
+
937
+        if ($data === false) {
938
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
939
+        }
940
+
941
+        try {
942
+            $share = $this->createShareObject($data);
943
+        } catch (InvalidShare $e) {
944
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
945
+        }
946
+
947
+        return $share;
948
+    }
949
+
950
+    /**
951
+     * remove share from table
952
+     *
953
+     * @param string $shareId
954
+     */
955
+    protected function removeShareFromTable($shareId) {
956
+        $qb = $this->dbConnection->getQueryBuilder();
957
+        $qb->delete('share')
958
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
959
+        $qb->execute();
960
+    }
961
+
962
+    /**
963
+     * Create a share object from an database row
964
+     *
965
+     * @param array $data
966
+     * @return IShare
967
+     * @throws InvalidShare
968
+     * @throws ShareNotFound
969
+     */
970
+    protected function createShareObject($data) {
971
+        $share = new Share($this->rootFolder, $this->userManager);
972
+        $share->setId((int)$data['id'])
973
+            ->setShareType((int)$data['share_type'])
974
+            ->setPermissions((int)$data['permissions'])
975
+            ->setTarget($data['file_target'])
976
+            ->setMailSend((bool)$data['mail_send'])
977
+            ->setNote($data['note'])
978
+            ->setToken($data['token']);
979
+
980
+        $shareTime = new \DateTime();
981
+        $shareTime->setTimestamp((int)$data['stime']);
982
+        $share->setShareTime($shareTime);
983
+        $share->setSharedWith($data['share_with']);
984
+        $share->setPassword($data['password']);
985
+        $share->setSendPasswordByTalk((bool)$data['password_by_talk']);
986
+        $share->setHideDownload((bool)$data['hide_download']);
987
+
988
+        if ($data['uid_initiator'] !== null) {
989
+            $share->setShareOwner($data['uid_owner']);
990
+            $share->setSharedBy($data['uid_initiator']);
991
+        } else {
992
+            //OLD SHARE
993
+            $share->setSharedBy($data['uid_owner']);
994
+            $path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
995
+
996
+            $owner = $path->getOwner();
997
+            $share->setShareOwner($owner->getUID());
998
+        }
999
+
1000
+        if ($data['expiration'] !== null) {
1001
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
1002
+            if ($expiration !== false) {
1003
+                $share->setExpirationDate($expiration);
1004
+            }
1005
+        }
1006
+
1007
+        $share->setNodeId((int)$data['file_source']);
1008
+        $share->setNodeType($data['item_type']);
1009
+
1010
+        $share->setProviderId($this->identifier());
1011
+
1012
+        return $share;
1013
+    }
1014
+
1015
+    /**
1016
+     * Get the node with file $id for $user
1017
+     *
1018
+     * @param string $userId
1019
+     * @param int $id
1020
+     * @return \OCP\Files\File|\OCP\Files\Folder
1021
+     * @throws InvalidShare
1022
+     */
1023
+    private function getNode($userId, $id) {
1024
+        try {
1025
+            $userFolder = $this->rootFolder->getUserFolder($userId);
1026
+        } catch (NoUserException $e) {
1027
+            throw new InvalidShare();
1028
+        }
1029
+
1030
+        $nodes = $userFolder->getById($id);
1031
+
1032
+        if (empty($nodes)) {
1033
+            throw new InvalidShare();
1034
+        }
1035
+
1036
+        return $nodes[0];
1037
+    }
1038
+
1039
+    /**
1040
+     * A user is deleted from the system
1041
+     * So clean up the relevant shares.
1042
+     *
1043
+     * @param string $uid
1044
+     * @param int $shareType
1045
+     */
1046
+    public function userDeleted($uid, $shareType) {
1047
+        $qb = $this->dbConnection->getQueryBuilder();
1048
+
1049
+        $qb->delete('share')
1050
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
1051
+            ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
1052
+            ->execute();
1053
+    }
1054
+
1055
+    /**
1056
+     * This provider does not support group shares
1057
+     *
1058
+     * @param string $gid
1059
+     */
1060
+    public function groupDeleted($gid) {
1061
+    }
1062
+
1063
+    /**
1064
+     * This provider does not support group shares
1065
+     *
1066
+     * @param string $uid
1067
+     * @param string $gid
1068
+     */
1069
+    public function userDeletedFromGroup($uid, $gid) {
1070
+    }
1071
+
1072
+    /**
1073
+     * get database row of a give share
1074
+     *
1075
+     * @param $id
1076
+     * @return array
1077
+     * @throws ShareNotFound
1078
+     */
1079
+    protected function getRawShare($id) {
1080
+
1081
+        // Now fetch the inserted share and create a complete share object
1082
+        $qb = $this->dbConnection->getQueryBuilder();
1083
+        $qb->select('*')
1084
+            ->from('share')
1085
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1086
+
1087
+        $cursor = $qb->execute();
1088
+        $data = $cursor->fetch();
1089
+        $cursor->closeCursor();
1090
+
1091
+        if ($data === false) {
1092
+            throw new ShareNotFound;
1093
+        }
1094
+
1095
+        return $data;
1096
+    }
1097
+
1098
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
1099
+        $qb = $this->dbConnection->getQueryBuilder();
1100
+        $qb->select('*')
1101
+            ->from('share', 's')
1102
+            ->andWhere($qb->expr()->orX(
1103
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1104
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1105
+            ))
1106
+            ->andWhere(
1107
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL))
1108
+            );
1109
+
1110
+        /**
1111
+         * Reshares for this user are shares where they are the owner.
1112
+         */
1113
+        if ($reshares === false) {
1114
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1115
+        } else {
1116
+            $qb->andWhere(
1117
+                $qb->expr()->orX(
1118
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1119
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1120
+                )
1121
+            );
1122
+        }
1123
+
1124
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1125
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1126
+
1127
+        $qb->orderBy('id');
1128
+
1129
+        $cursor = $qb->execute();
1130
+        $shares = [];
1131
+        while ($data = $cursor->fetch()) {
1132
+            $shares[$data['fileid']][] = $this->createShareObject($data);
1133
+        }
1134
+        $cursor->closeCursor();
1135
+
1136
+        return $shares;
1137
+    }
1138
+
1139
+    /**
1140
+     * @inheritdoc
1141
+     */
1142
+    public function getAccessList($nodes, $currentAccess) {
1143
+        $ids = [];
1144
+        foreach ($nodes as $node) {
1145
+            $ids[] = $node->getId();
1146
+        }
1147
+
1148
+        $qb = $this->dbConnection->getQueryBuilder();
1149
+        $qb->select('share_with')
1150
+            ->from('share')
1151
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
1152
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1153
+            ->andWhere($qb->expr()->orX(
1154
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1155
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1156
+            ))
1157
+            ->setMaxResults(1);
1158
+        $cursor = $qb->execute();
1159
+
1160
+        $mail = $cursor->fetch() !== false;
1161
+        $cursor->closeCursor();
1162
+
1163
+        return ['public' => $mail];
1164
+    }
1165
+
1166
+    public function getAllShares(): iterable {
1167
+        $qb = $this->dbConnection->getQueryBuilder();
1168
+
1169
+        $qb->select('*')
1170
+            ->from('share')
1171
+            ->where(
1172
+                $qb->expr()->orX(
1173
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_EMAIL))
1174
+                )
1175
+            );
1176
+
1177
+        $cursor = $qb->execute();
1178
+        while ($data = $cursor->fetch()) {
1179
+            try {
1180
+                $share = $this->createShareObject($data);
1181
+            } catch (InvalidShare $e) {
1182
+                continue;
1183
+            } catch (ShareNotFound $e) {
1184
+                continue;
1185
+            }
1186
+
1187
+            yield $share;
1188
+        }
1189
+        $cursor->closeCursor();
1190
+    }
1191 1191
 }
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -217,7 +217,7 @@  discard block
 block discarded – undo
217 217
 
218 218
 		$password = $passwordEvent->getPassword();
219 219
 		if ($password === null) {
220
-			$password = $this->secureRandom->generate(8, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
220
+			$password = $this->secureRandom->generate(8, ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS);
221 221
 		}
222 222
 
223 223
 		return $password;
@@ -388,7 +388,7 @@  discard block
 block discarded – undo
388 388
 		$text = $this->l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
389 389
 
390 390
 		$emailTemplate->addBodyText(
391
-			htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
391
+			htmlspecialchars($text.' '.$this->l->t('Click the button below to open it.')),
392 392
 			$text
393 393
 		);
394 394
 		$emailTemplate->addBodyButton(
@@ -417,7 +417,7 @@  discard block
 block discarded – undo
417 417
 		$initiatorEmail = $initiatorUser->getEMailAddress();
418 418
 		if ($this->settingsManager->replyToInitiator() && $initiatorEmail !== null) {
419 419
 			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
420
-			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
420
+			$emailTemplate->addFooter($instanceName.($this->defaults->getSlogan() !== '' ? ' - '.$this->defaults->getSlogan() : ''));
421 421
 		} else {
422 422
 			$emailTemplate->addFooter();
423 423
 		}
@@ -481,7 +481,7 @@  discard block
 block discarded – undo
481 481
 		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
482 482
 		if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
483 483
 			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
484
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
484
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
485 485
 		} else {
486 486
 			$emailTemplate->addFooter();
487 487
 		}
@@ -541,7 +541,7 @@  discard block
 block discarded – undo
541 541
 		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
542 542
 		if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
543 543
 			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
544
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
544
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
545 545
 		} else {
546 546
 			$emailTemplate->addFooter();
547 547
 		}
@@ -677,7 +677,7 @@  discard block
 block discarded – undo
677 677
 			->setValue('password', $qb->createNamedParameter($password))
678 678
 			->setValue('password_by_talk', $qb->createNamedParameter($sendPasswordByTalk, IQueryBuilder::PARAM_BOOL))
679 679
 			->setValue('stime', $qb->createNamedParameter(time()))
680
-			->setValue('hide_download', $qb->createNamedParameter((int)$hideDownload, IQueryBuilder::PARAM_INT));
680
+			->setValue('hide_download', $qb->createNamedParameter((int) $hideDownload, IQueryBuilder::PARAM_INT));
681 681
 
682 682
 		if ($expirationTime !== null) {
683 683
 			$qb->setValue('expiration', $qb->createNamedParameter($expirationTime, IQueryBuilder::PARAM_DATE));
@@ -723,7 +723,7 @@  discard block
 block discarded – undo
723 723
 			->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
724 724
 			->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
725 725
 			->set('note', $qb->createNamedParameter($share->getNote()))
726
-			->set('hide_download', $qb->createNamedParameter((int)$share->getHideDownload(), IQueryBuilder::PARAM_INT))
726
+			->set('hide_download', $qb->createNamedParameter((int) $share->getHideDownload(), IQueryBuilder::PARAM_INT))
727 727
 			->execute();
728 728
 
729 729
 		if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
@@ -969,21 +969,21 @@  discard block
 block discarded – undo
969 969
 	 */
970 970
 	protected function createShareObject($data) {
971 971
 		$share = new Share($this->rootFolder, $this->userManager);
972
-		$share->setId((int)$data['id'])
973
-			->setShareType((int)$data['share_type'])
974
-			->setPermissions((int)$data['permissions'])
972
+		$share->setId((int) $data['id'])
973
+			->setShareType((int) $data['share_type'])
974
+			->setPermissions((int) $data['permissions'])
975 975
 			->setTarget($data['file_target'])
976
-			->setMailSend((bool)$data['mail_send'])
976
+			->setMailSend((bool) $data['mail_send'])
977 977
 			->setNote($data['note'])
978 978
 			->setToken($data['token']);
979 979
 
980 980
 		$shareTime = new \DateTime();
981
-		$shareTime->setTimestamp((int)$data['stime']);
981
+		$shareTime->setTimestamp((int) $data['stime']);
982 982
 		$share->setShareTime($shareTime);
983 983
 		$share->setSharedWith($data['share_with']);
984 984
 		$share->setPassword($data['password']);
985
-		$share->setSendPasswordByTalk((bool)$data['password_by_talk']);
986
-		$share->setHideDownload((bool)$data['hide_download']);
985
+		$share->setSendPasswordByTalk((bool) $data['password_by_talk']);
986
+		$share->setHideDownload((bool) $data['hide_download']);
987 987
 
988 988
 		if ($data['uid_initiator'] !== null) {
989 989
 			$share->setShareOwner($data['uid_owner']);
@@ -991,7 +991,7 @@  discard block
 block discarded – undo
991 991
 		} else {
992 992
 			//OLD SHARE
993 993
 			$share->setSharedBy($data['uid_owner']);
994
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
994
+			$path = $this->getNode($share->getSharedBy(), (int) $data['file_source']);
995 995
 
996 996
 			$owner = $path->getOwner();
997 997
 			$share->setShareOwner($owner->getUID());
@@ -1004,7 +1004,7 @@  discard block
 block discarded – undo
1004 1004
 			}
1005 1005
 		}
1006 1006
 
1007
-		$share->setNodeId((int)$data['file_source']);
1007
+		$share->setNodeId((int) $data['file_source']);
1008 1008
 		$share->setNodeType($data['item_type']);
1009 1009
 
1010 1010
 		$share->setProviderId($this->identifier());
@@ -1121,7 +1121,7 @@  discard block
 block discarded – undo
1121 1121
 			);
1122 1122
 		}
1123 1123
 
1124
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1124
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1125 1125
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1126 1126
 
1127 1127
 		$qb->orderBy('id');
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/FederatedShareProvider.php 2 patches
Indentation   +1059 added lines, -1059 removed lines patch added patch discarded remove patch
@@ -61,1073 +61,1073 @@
 block discarded – undo
61 61
  * @package OCA\FederatedFileSharing
62 62
  */
63 63
 class FederatedShareProvider implements IShareProvider {
64
-	public const SHARE_TYPE_REMOTE = 6;
65
-
66
-	/** @var IDBConnection */
67
-	private $dbConnection;
68
-
69
-	/** @var AddressHandler */
70
-	private $addressHandler;
71
-
72
-	/** @var Notifications */
73
-	private $notifications;
74
-
75
-	/** @var TokenHandler */
76
-	private $tokenHandler;
77
-
78
-	/** @var IL10N */
79
-	private $l;
80
-
81
-	/** @var ILogger */
82
-	private $logger;
83
-
84
-	/** @var IRootFolder */
85
-	private $rootFolder;
86
-
87
-	/** @var IConfig */
88
-	private $config;
89
-
90
-	/** @var string */
91
-	private $externalShareTable = 'share_external';
92
-
93
-	/** @var IUserManager */
94
-	private $userManager;
95
-
96
-	/** @var ICloudIdManager */
97
-	private $cloudIdManager;
98
-
99
-	/** @var \OCP\GlobalScale\IConfig */
100
-	private $gsConfig;
101
-
102
-	/** @var ICloudFederationProviderManager */
103
-	private $cloudFederationProviderManager;
104
-
105
-	/** @var array list of supported share types */
106
-	private $supportedShareType = [IShare::TYPE_REMOTE_GROUP, IShare::TYPE_REMOTE, IShare::TYPE_CIRCLE];
107
-
108
-	/**
109
-	 * DefaultShareProvider constructor.
110
-	 *
111
-	 * @param IDBConnection $connection
112
-	 * @param AddressHandler $addressHandler
113
-	 * @param Notifications $notifications
114
-	 * @param TokenHandler $tokenHandler
115
-	 * @param IL10N $l10n
116
-	 * @param ILogger $logger
117
-	 * @param IRootFolder $rootFolder
118
-	 * @param IConfig $config
119
-	 * @param IUserManager $userManager
120
-	 * @param ICloudIdManager $cloudIdManager
121
-	 * @param \OCP\GlobalScale\IConfig $globalScaleConfig
122
-	 * @param ICloudFederationProviderManager $cloudFederationProviderManager
123
-	 */
124
-	public function __construct(
125
-			IDBConnection $connection,
126
-			AddressHandler $addressHandler,
127
-			Notifications $notifications,
128
-			TokenHandler $tokenHandler,
129
-			IL10N $l10n,
130
-			ILogger $logger,
131
-			IRootFolder $rootFolder,
132
-			IConfig $config,
133
-			IUserManager $userManager,
134
-			ICloudIdManager $cloudIdManager,
135
-			\OCP\GlobalScale\IConfig $globalScaleConfig,
136
-			ICloudFederationProviderManager $cloudFederationProviderManager
137
-	) {
138
-		$this->dbConnection = $connection;
139
-		$this->addressHandler = $addressHandler;
140
-		$this->notifications = $notifications;
141
-		$this->tokenHandler = $tokenHandler;
142
-		$this->l = $l10n;
143
-		$this->logger = $logger;
144
-		$this->rootFolder = $rootFolder;
145
-		$this->config = $config;
146
-		$this->userManager = $userManager;
147
-		$this->cloudIdManager = $cloudIdManager;
148
-		$this->gsConfig = $globalScaleConfig;
149
-		$this->cloudFederationProviderManager = $cloudFederationProviderManager;
150
-	}
151
-
152
-	/**
153
-	 * Return the identifier of this provider.
154
-	 *
155
-	 * @return string Containing only [a-zA-Z0-9]
156
-	 */
157
-	public function identifier() {
158
-		return 'ocFederatedSharing';
159
-	}
160
-
161
-	/**
162
-	 * Share a path
163
-	 *
164
-	 * @param IShare $share
165
-	 * @return IShare The share object
166
-	 * @throws ShareNotFound
167
-	 * @throws \Exception
168
-	 */
169
-	public function create(IShare $share) {
170
-		$shareWith = $share->getSharedWith();
171
-		$itemSource = $share->getNodeId();
172
-		$itemType = $share->getNodeType();
173
-		$permissions = $share->getPermissions();
174
-		$sharedBy = $share->getSharedBy();
175
-		$shareType = $share->getShareType();
176
-
177
-		if ($shareType === IShare::TYPE_REMOTE_GROUP &&
178
-			!$this->isOutgoingServer2serverGroupShareEnabled()
179
-		) {
180
-			$message = 'It is not allowed to send federated group shares from this server.';
181
-			$message_t = $this->l->t('It is not allowed to send federated group shares from this server.');
182
-			$this->logger->debug($message, ['app' => 'Federated File Sharing']);
183
-			throw new \Exception($message_t);
184
-		}
185
-
186
-		/*
64
+    public const SHARE_TYPE_REMOTE = 6;
65
+
66
+    /** @var IDBConnection */
67
+    private $dbConnection;
68
+
69
+    /** @var AddressHandler */
70
+    private $addressHandler;
71
+
72
+    /** @var Notifications */
73
+    private $notifications;
74
+
75
+    /** @var TokenHandler */
76
+    private $tokenHandler;
77
+
78
+    /** @var IL10N */
79
+    private $l;
80
+
81
+    /** @var ILogger */
82
+    private $logger;
83
+
84
+    /** @var IRootFolder */
85
+    private $rootFolder;
86
+
87
+    /** @var IConfig */
88
+    private $config;
89
+
90
+    /** @var string */
91
+    private $externalShareTable = 'share_external';
92
+
93
+    /** @var IUserManager */
94
+    private $userManager;
95
+
96
+    /** @var ICloudIdManager */
97
+    private $cloudIdManager;
98
+
99
+    /** @var \OCP\GlobalScale\IConfig */
100
+    private $gsConfig;
101
+
102
+    /** @var ICloudFederationProviderManager */
103
+    private $cloudFederationProviderManager;
104
+
105
+    /** @var array list of supported share types */
106
+    private $supportedShareType = [IShare::TYPE_REMOTE_GROUP, IShare::TYPE_REMOTE, IShare::TYPE_CIRCLE];
107
+
108
+    /**
109
+     * DefaultShareProvider constructor.
110
+     *
111
+     * @param IDBConnection $connection
112
+     * @param AddressHandler $addressHandler
113
+     * @param Notifications $notifications
114
+     * @param TokenHandler $tokenHandler
115
+     * @param IL10N $l10n
116
+     * @param ILogger $logger
117
+     * @param IRootFolder $rootFolder
118
+     * @param IConfig $config
119
+     * @param IUserManager $userManager
120
+     * @param ICloudIdManager $cloudIdManager
121
+     * @param \OCP\GlobalScale\IConfig $globalScaleConfig
122
+     * @param ICloudFederationProviderManager $cloudFederationProviderManager
123
+     */
124
+    public function __construct(
125
+            IDBConnection $connection,
126
+            AddressHandler $addressHandler,
127
+            Notifications $notifications,
128
+            TokenHandler $tokenHandler,
129
+            IL10N $l10n,
130
+            ILogger $logger,
131
+            IRootFolder $rootFolder,
132
+            IConfig $config,
133
+            IUserManager $userManager,
134
+            ICloudIdManager $cloudIdManager,
135
+            \OCP\GlobalScale\IConfig $globalScaleConfig,
136
+            ICloudFederationProviderManager $cloudFederationProviderManager
137
+    ) {
138
+        $this->dbConnection = $connection;
139
+        $this->addressHandler = $addressHandler;
140
+        $this->notifications = $notifications;
141
+        $this->tokenHandler = $tokenHandler;
142
+        $this->l = $l10n;
143
+        $this->logger = $logger;
144
+        $this->rootFolder = $rootFolder;
145
+        $this->config = $config;
146
+        $this->userManager = $userManager;
147
+        $this->cloudIdManager = $cloudIdManager;
148
+        $this->gsConfig = $globalScaleConfig;
149
+        $this->cloudFederationProviderManager = $cloudFederationProviderManager;
150
+    }
151
+
152
+    /**
153
+     * Return the identifier of this provider.
154
+     *
155
+     * @return string Containing only [a-zA-Z0-9]
156
+     */
157
+    public function identifier() {
158
+        return 'ocFederatedSharing';
159
+    }
160
+
161
+    /**
162
+     * Share a path
163
+     *
164
+     * @param IShare $share
165
+     * @return IShare The share object
166
+     * @throws ShareNotFound
167
+     * @throws \Exception
168
+     */
169
+    public function create(IShare $share) {
170
+        $shareWith = $share->getSharedWith();
171
+        $itemSource = $share->getNodeId();
172
+        $itemType = $share->getNodeType();
173
+        $permissions = $share->getPermissions();
174
+        $sharedBy = $share->getSharedBy();
175
+        $shareType = $share->getShareType();
176
+
177
+        if ($shareType === IShare::TYPE_REMOTE_GROUP &&
178
+            !$this->isOutgoingServer2serverGroupShareEnabled()
179
+        ) {
180
+            $message = 'It is not allowed to send federated group shares from this server.';
181
+            $message_t = $this->l->t('It is not allowed to send federated group shares from this server.');
182
+            $this->logger->debug($message, ['app' => 'Federated File Sharing']);
183
+            throw new \Exception($message_t);
184
+        }
185
+
186
+        /*
187 187
 		 * Check if file is not already shared with the remote user
188 188
 		 */
189
-		$alreadyShared = $this->getSharedWith($shareWith, IShare::TYPE_REMOTE, $share->getNode(), 1, 0);
190
-		$alreadySharedGroup = $this->getSharedWith($shareWith, IShare::TYPE_REMOTE_GROUP, $share->getNode(), 1, 0);
191
-		if (!empty($alreadyShared) || !empty($alreadySharedGroup)) {
192
-			$message = 'Sharing %1$s failed, because this item is already shared with %2$s';
193
-			$message_t = $this->l->t('Sharing %1$s failed, because this item is already shared with %2$s', [$share->getNode()->getName(), $shareWith]);
194
-			$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
195
-			throw new \Exception($message_t);
196
-		}
197
-
198
-
199
-		// don't allow federated shares if source and target server are the same
200
-		$cloudId = $this->cloudIdManager->resolveCloudId($shareWith);
201
-		$currentServer = $this->addressHandler->generateRemoteURL();
202
-		$currentUser = $sharedBy;
203
-		if ($this->addressHandler->compareAddresses($cloudId->getUser(), $cloudId->getRemote(), $currentUser, $currentServer)) {
204
-			$message = 'Not allowed to create a federated share with the same user.';
205
-			$message_t = $this->l->t('Not allowed to create a federated share with the same user');
206
-			$this->logger->debug($message, ['app' => 'Federated File Sharing']);
207
-			throw new \Exception($message_t);
208
-		}
209
-
210
-
211
-		$share->setSharedWith($cloudId->getId());
212
-
213
-		try {
214
-			$remoteShare = $this->getShareFromExternalShareTable($share);
215
-		} catch (ShareNotFound $e) {
216
-			$remoteShare = null;
217
-		}
218
-
219
-		if ($remoteShare) {
220
-			try {
221
-				$ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
222
-				$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time(), $shareType);
223
-				$share->setId($shareId);
224
-				[$token, $remoteId] = $this->askOwnerToReShare($shareWith, $share, $shareId);
225
-				// remote share was create successfully if we get a valid token as return
226
-				$send = is_string($token) && $token !== '';
227
-			} catch (\Exception $e) {
228
-				// fall back to old re-share behavior if the remote server
229
-				// doesn't support flat re-shares (was introduced with Nextcloud 9.1)
230
-				$this->removeShareFromTable($share);
231
-				$shareId = $this->createFederatedShare($share);
232
-			}
233
-			if ($send) {
234
-				$this->updateSuccessfulReshare($shareId, $token);
235
-				$this->storeRemoteId($shareId, $remoteId);
236
-			} else {
237
-				$this->removeShareFromTable($share);
238
-				$message_t = $this->l->t('File is already shared with %s', [$shareWith]);
239
-				throw new \Exception($message_t);
240
-			}
241
-		} else {
242
-			$shareId = $this->createFederatedShare($share);
243
-		}
244
-
245
-		$data = $this->getRawShare($shareId);
246
-		return $this->createShareObject($data);
247
-	}
248
-
249
-	/**
250
-	 * create federated share and inform the recipient
251
-	 *
252
-	 * @param IShare $share
253
-	 * @return int
254
-	 * @throws ShareNotFound
255
-	 * @throws \Exception
256
-	 */
257
-	protected function createFederatedShare(IShare $share) {
258
-		$token = $this->tokenHandler->generateToken();
259
-		$shareId = $this->addShareToDB(
260
-			$share->getNodeId(),
261
-			$share->getNodeType(),
262
-			$share->getSharedWith(),
263
-			$share->getSharedBy(),
264
-			$share->getShareOwner(),
265
-			$share->getPermissions(),
266
-			$token,
267
-			$share->getShareType()
268
-		);
269
-
270
-		$failure = false;
271
-
272
-		try {
273
-			$sharedByFederatedId = $share->getSharedBy();
274
-			if ($this->userManager->userExists($sharedByFederatedId)) {
275
-				$cloudId = $this->cloudIdManager->getCloudId($sharedByFederatedId, $this->addressHandler->generateRemoteURL());
276
-				$sharedByFederatedId = $cloudId->getId();
277
-			}
278
-			$ownerCloudId = $this->cloudIdManager->getCloudId($share->getShareOwner(), $this->addressHandler->generateRemoteURL());
279
-			$send = $this->notifications->sendRemoteShare(
280
-				$token,
281
-				$share->getSharedWith(),
282
-				$share->getNode()->getName(),
283
-				$shareId,
284
-				$share->getShareOwner(),
285
-				$ownerCloudId->getId(),
286
-				$share->getSharedBy(),
287
-				$sharedByFederatedId,
288
-				$share->getShareType()
289
-			);
290
-
291
-			if ($send === false) {
292
-				$failure = true;
293
-			}
294
-		} catch (\Exception $e) {
295
-			$this->logger->logException($e, [
296
-				'message' => 'Failed to notify remote server of federated share, removing share.',
297
-				'level' => ILogger::ERROR,
298
-				'app' => 'federatedfilesharing',
299
-			]);
300
-			$failure = true;
301
-		}
302
-
303
-		if ($failure) {
304
-			$this->removeShareFromTableById($shareId);
305
-			$message_t = $this->l->t('Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate.',
306
-				[$share->getNode()->getName(), $share->getSharedWith()]);
307
-			throw new \Exception($message_t);
308
-		}
309
-
310
-		return $shareId;
311
-	}
312
-
313
-	/**
314
-	 * @param string $shareWith
315
-	 * @param IShare $share
316
-	 * @param string $shareId internal share Id
317
-	 * @return array
318
-	 * @throws \Exception
319
-	 */
320
-	protected function askOwnerToReShare($shareWith, IShare $share, $shareId) {
321
-		$remoteShare = $this->getShareFromExternalShareTable($share);
322
-		$token = $remoteShare['share_token'];
323
-		$remoteId = $remoteShare['remote_id'];
324
-		$remote = $remoteShare['remote'];
325
-
326
-		[$token, $remoteId] = $this->notifications->requestReShare(
327
-			$token,
328
-			$remoteId,
329
-			$shareId,
330
-			$remote,
331
-			$shareWith,
332
-			$share->getPermissions(),
333
-			$share->getNode()->getName()
334
-		);
335
-
336
-		return [$token, $remoteId];
337
-	}
338
-
339
-	/**
340
-	 * get federated share from the share_external table but exclude mounted link shares
341
-	 *
342
-	 * @param IShare $share
343
-	 * @return array
344
-	 * @throws ShareNotFound
345
-	 */
346
-	protected function getShareFromExternalShareTable(IShare $share) {
347
-		$query = $this->dbConnection->getQueryBuilder();
348
-		$query->select('*')->from($this->externalShareTable)
349
-			->where($query->expr()->eq('user', $query->createNamedParameter($share->getShareOwner())))
350
-			->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($share->getTarget())));
351
-		$qResult = $query->execute();
352
-		$result = $qResult->fetchAll();
353
-		$qResult->closeCursor();
354
-
355
-		if (isset($result[0]) && (int)$result[0]['remote_id'] > 0) {
356
-			return $result[0];
357
-		}
358
-
359
-		throw new ShareNotFound('share not found in share_external table');
360
-	}
361
-
362
-	/**
363
-	 * add share to the database and return the ID
364
-	 *
365
-	 * @param int $itemSource
366
-	 * @param string $itemType
367
-	 * @param string $shareWith
368
-	 * @param string $sharedBy
369
-	 * @param string $uidOwner
370
-	 * @param int $permissions
371
-	 * @param string $token
372
-	 * @param int $shareType
373
-	 * @return int
374
-	 */
375
-	private function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $shareType) {
376
-		$qb = $this->dbConnection->getQueryBuilder();
377
-		$qb->insert('share')
378
-			->setValue('share_type', $qb->createNamedParameter($shareType))
379
-			->setValue('item_type', $qb->createNamedParameter($itemType))
380
-			->setValue('item_source', $qb->createNamedParameter($itemSource))
381
-			->setValue('file_source', $qb->createNamedParameter($itemSource))
382
-			->setValue('share_with', $qb->createNamedParameter($shareWith))
383
-			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
384
-			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
385
-			->setValue('permissions', $qb->createNamedParameter($permissions))
386
-			->setValue('token', $qb->createNamedParameter($token))
387
-			->setValue('stime', $qb->createNamedParameter(time()));
388
-
389
-		/*
189
+        $alreadyShared = $this->getSharedWith($shareWith, IShare::TYPE_REMOTE, $share->getNode(), 1, 0);
190
+        $alreadySharedGroup = $this->getSharedWith($shareWith, IShare::TYPE_REMOTE_GROUP, $share->getNode(), 1, 0);
191
+        if (!empty($alreadyShared) || !empty($alreadySharedGroup)) {
192
+            $message = 'Sharing %1$s failed, because this item is already shared with %2$s';
193
+            $message_t = $this->l->t('Sharing %1$s failed, because this item is already shared with %2$s', [$share->getNode()->getName(), $shareWith]);
194
+            $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
195
+            throw new \Exception($message_t);
196
+        }
197
+
198
+
199
+        // don't allow federated shares if source and target server are the same
200
+        $cloudId = $this->cloudIdManager->resolveCloudId($shareWith);
201
+        $currentServer = $this->addressHandler->generateRemoteURL();
202
+        $currentUser = $sharedBy;
203
+        if ($this->addressHandler->compareAddresses($cloudId->getUser(), $cloudId->getRemote(), $currentUser, $currentServer)) {
204
+            $message = 'Not allowed to create a federated share with the same user.';
205
+            $message_t = $this->l->t('Not allowed to create a federated share with the same user');
206
+            $this->logger->debug($message, ['app' => 'Federated File Sharing']);
207
+            throw new \Exception($message_t);
208
+        }
209
+
210
+
211
+        $share->setSharedWith($cloudId->getId());
212
+
213
+        try {
214
+            $remoteShare = $this->getShareFromExternalShareTable($share);
215
+        } catch (ShareNotFound $e) {
216
+            $remoteShare = null;
217
+        }
218
+
219
+        if ($remoteShare) {
220
+            try {
221
+                $ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
222
+                $shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time(), $shareType);
223
+                $share->setId($shareId);
224
+                [$token, $remoteId] = $this->askOwnerToReShare($shareWith, $share, $shareId);
225
+                // remote share was create successfully if we get a valid token as return
226
+                $send = is_string($token) && $token !== '';
227
+            } catch (\Exception $e) {
228
+                // fall back to old re-share behavior if the remote server
229
+                // doesn't support flat re-shares (was introduced with Nextcloud 9.1)
230
+                $this->removeShareFromTable($share);
231
+                $shareId = $this->createFederatedShare($share);
232
+            }
233
+            if ($send) {
234
+                $this->updateSuccessfulReshare($shareId, $token);
235
+                $this->storeRemoteId($shareId, $remoteId);
236
+            } else {
237
+                $this->removeShareFromTable($share);
238
+                $message_t = $this->l->t('File is already shared with %s', [$shareWith]);
239
+                throw new \Exception($message_t);
240
+            }
241
+        } else {
242
+            $shareId = $this->createFederatedShare($share);
243
+        }
244
+
245
+        $data = $this->getRawShare($shareId);
246
+        return $this->createShareObject($data);
247
+    }
248
+
249
+    /**
250
+     * create federated share and inform the recipient
251
+     *
252
+     * @param IShare $share
253
+     * @return int
254
+     * @throws ShareNotFound
255
+     * @throws \Exception
256
+     */
257
+    protected function createFederatedShare(IShare $share) {
258
+        $token = $this->tokenHandler->generateToken();
259
+        $shareId = $this->addShareToDB(
260
+            $share->getNodeId(),
261
+            $share->getNodeType(),
262
+            $share->getSharedWith(),
263
+            $share->getSharedBy(),
264
+            $share->getShareOwner(),
265
+            $share->getPermissions(),
266
+            $token,
267
+            $share->getShareType()
268
+        );
269
+
270
+        $failure = false;
271
+
272
+        try {
273
+            $sharedByFederatedId = $share->getSharedBy();
274
+            if ($this->userManager->userExists($sharedByFederatedId)) {
275
+                $cloudId = $this->cloudIdManager->getCloudId($sharedByFederatedId, $this->addressHandler->generateRemoteURL());
276
+                $sharedByFederatedId = $cloudId->getId();
277
+            }
278
+            $ownerCloudId = $this->cloudIdManager->getCloudId($share->getShareOwner(), $this->addressHandler->generateRemoteURL());
279
+            $send = $this->notifications->sendRemoteShare(
280
+                $token,
281
+                $share->getSharedWith(),
282
+                $share->getNode()->getName(),
283
+                $shareId,
284
+                $share->getShareOwner(),
285
+                $ownerCloudId->getId(),
286
+                $share->getSharedBy(),
287
+                $sharedByFederatedId,
288
+                $share->getShareType()
289
+            );
290
+
291
+            if ($send === false) {
292
+                $failure = true;
293
+            }
294
+        } catch (\Exception $e) {
295
+            $this->logger->logException($e, [
296
+                'message' => 'Failed to notify remote server of federated share, removing share.',
297
+                'level' => ILogger::ERROR,
298
+                'app' => 'federatedfilesharing',
299
+            ]);
300
+            $failure = true;
301
+        }
302
+
303
+        if ($failure) {
304
+            $this->removeShareFromTableById($shareId);
305
+            $message_t = $this->l->t('Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate.',
306
+                [$share->getNode()->getName(), $share->getSharedWith()]);
307
+            throw new \Exception($message_t);
308
+        }
309
+
310
+        return $shareId;
311
+    }
312
+
313
+    /**
314
+     * @param string $shareWith
315
+     * @param IShare $share
316
+     * @param string $shareId internal share Id
317
+     * @return array
318
+     * @throws \Exception
319
+     */
320
+    protected function askOwnerToReShare($shareWith, IShare $share, $shareId) {
321
+        $remoteShare = $this->getShareFromExternalShareTable($share);
322
+        $token = $remoteShare['share_token'];
323
+        $remoteId = $remoteShare['remote_id'];
324
+        $remote = $remoteShare['remote'];
325
+
326
+        [$token, $remoteId] = $this->notifications->requestReShare(
327
+            $token,
328
+            $remoteId,
329
+            $shareId,
330
+            $remote,
331
+            $shareWith,
332
+            $share->getPermissions(),
333
+            $share->getNode()->getName()
334
+        );
335
+
336
+        return [$token, $remoteId];
337
+    }
338
+
339
+    /**
340
+     * get federated share from the share_external table but exclude mounted link shares
341
+     *
342
+     * @param IShare $share
343
+     * @return array
344
+     * @throws ShareNotFound
345
+     */
346
+    protected function getShareFromExternalShareTable(IShare $share) {
347
+        $query = $this->dbConnection->getQueryBuilder();
348
+        $query->select('*')->from($this->externalShareTable)
349
+            ->where($query->expr()->eq('user', $query->createNamedParameter($share->getShareOwner())))
350
+            ->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($share->getTarget())));
351
+        $qResult = $query->execute();
352
+        $result = $qResult->fetchAll();
353
+        $qResult->closeCursor();
354
+
355
+        if (isset($result[0]) && (int)$result[0]['remote_id'] > 0) {
356
+            return $result[0];
357
+        }
358
+
359
+        throw new ShareNotFound('share not found in share_external table');
360
+    }
361
+
362
+    /**
363
+     * add share to the database and return the ID
364
+     *
365
+     * @param int $itemSource
366
+     * @param string $itemType
367
+     * @param string $shareWith
368
+     * @param string $sharedBy
369
+     * @param string $uidOwner
370
+     * @param int $permissions
371
+     * @param string $token
372
+     * @param int $shareType
373
+     * @return int
374
+     */
375
+    private function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $shareType) {
376
+        $qb = $this->dbConnection->getQueryBuilder();
377
+        $qb->insert('share')
378
+            ->setValue('share_type', $qb->createNamedParameter($shareType))
379
+            ->setValue('item_type', $qb->createNamedParameter($itemType))
380
+            ->setValue('item_source', $qb->createNamedParameter($itemSource))
381
+            ->setValue('file_source', $qb->createNamedParameter($itemSource))
382
+            ->setValue('share_with', $qb->createNamedParameter($shareWith))
383
+            ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
384
+            ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
385
+            ->setValue('permissions', $qb->createNamedParameter($permissions))
386
+            ->setValue('token', $qb->createNamedParameter($token))
387
+            ->setValue('stime', $qb->createNamedParameter(time()));
388
+
389
+        /*
390 390
 		 * Added to fix https://github.com/owncloud/core/issues/22215
391 391
 		 * Can be removed once we get rid of ajax/share.php
392 392
 		 */
393
-		$qb->setValue('file_target', $qb->createNamedParameter(''));
394
-
395
-		$qb->execute();
396
-		return $qb->getLastInsertId();
397
-	}
398
-
399
-	/**
400
-	 * Update a share
401
-	 *
402
-	 * @param IShare $share
403
-	 * @return IShare The share object
404
-	 */
405
-	public function update(IShare $share) {
406
-		/*
393
+        $qb->setValue('file_target', $qb->createNamedParameter(''));
394
+
395
+        $qb->execute();
396
+        return $qb->getLastInsertId();
397
+    }
398
+
399
+    /**
400
+     * Update a share
401
+     *
402
+     * @param IShare $share
403
+     * @return IShare The share object
404
+     */
405
+    public function update(IShare $share) {
406
+        /*
407 407
 		 * We allow updating the permissions of federated shares
408 408
 		 */
409
-		$qb = $this->dbConnection->getQueryBuilder();
410
-		$qb->update('share')
411
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
412
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
413
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
414
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
415
-				->execute();
416
-
417
-		// send the updated permission to the owner/initiator, if they are not the same
418
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
419
-			$this->sendPermissionUpdate($share);
420
-		}
421
-
422
-		return $share;
423
-	}
424
-
425
-	/**
426
-	 * send the updated permission to the owner/initiator, if they are not the same
427
-	 *
428
-	 * @param IShare $share
429
-	 * @throws ShareNotFound
430
-	 * @throws \OC\HintException
431
-	 */
432
-	protected function sendPermissionUpdate(IShare $share) {
433
-		$remoteId = $this->getRemoteId($share);
434
-		// if the local user is the owner we send the permission change to the initiator
435
-		if ($this->userManager->userExists($share->getShareOwner())) {
436
-			[, $remote] = $this->addressHandler->splitUserRemote($share->getSharedBy());
437
-		} else { // ... if not we send the permission change to the owner
438
-			[, $remote] = $this->addressHandler->splitUserRemote($share->getShareOwner());
439
-		}
440
-		$this->notifications->sendPermissionChange($remote, $remoteId, $share->getToken(), $share->getPermissions());
441
-	}
442
-
443
-
444
-	/**
445
-	 * update successful reShare with the correct token
446
-	 *
447
-	 * @param int $shareId
448
-	 * @param string $token
449
-	 */
450
-	protected function updateSuccessfulReShare($shareId, $token) {
451
-		$query = $this->dbConnection->getQueryBuilder();
452
-		$query->update('share')
453
-			->where($query->expr()->eq('id', $query->createNamedParameter($shareId)))
454
-			->set('token', $query->createNamedParameter($token))
455
-			->execute();
456
-	}
457
-
458
-	/**
459
-	 * store remote ID in federated reShare table
460
-	 *
461
-	 * @param $shareId
462
-	 * @param $remoteId
463
-	 */
464
-	public function storeRemoteId(int $shareId, string $remoteId): void {
465
-		$query = $this->dbConnection->getQueryBuilder();
466
-		$query->insert('federated_reshares')
467
-			->values(
468
-				[
469
-					'share_id' => $query->createNamedParameter($shareId),
470
-					'remote_id' => $query->createNamedParameter($remoteId),
471
-				]
472
-			);
473
-		$query->execute();
474
-	}
475
-
476
-	/**
477
-	 * get share ID on remote server for federated re-shares
478
-	 *
479
-	 * @param IShare $share
480
-	 * @return string
481
-	 * @throws ShareNotFound
482
-	 */
483
-	public function getRemoteId(IShare $share): string {
484
-		$query = $this->dbConnection->getQueryBuilder();
485
-		$query->select('remote_id')->from('federated_reshares')
486
-			->where($query->expr()->eq('share_id', $query->createNamedParameter((int)$share->getId())));
487
-		$result = $query->execute();
488
-		$data = $result->fetch();
489
-		$result->closeCursor();
490
-
491
-		if (!is_array($data) || !isset($data['remote_id'])) {
492
-			throw new ShareNotFound();
493
-		}
494
-
495
-		return (string)$data['remote_id'];
496
-	}
497
-
498
-	/**
499
-	 * @inheritdoc
500
-	 */
501
-	public function move(IShare $share, $recipient) {
502
-		/*
409
+        $qb = $this->dbConnection->getQueryBuilder();
410
+        $qb->update('share')
411
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
412
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
413
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
414
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
415
+                ->execute();
416
+
417
+        // send the updated permission to the owner/initiator, if they are not the same
418
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
419
+            $this->sendPermissionUpdate($share);
420
+        }
421
+
422
+        return $share;
423
+    }
424
+
425
+    /**
426
+     * send the updated permission to the owner/initiator, if they are not the same
427
+     *
428
+     * @param IShare $share
429
+     * @throws ShareNotFound
430
+     * @throws \OC\HintException
431
+     */
432
+    protected function sendPermissionUpdate(IShare $share) {
433
+        $remoteId = $this->getRemoteId($share);
434
+        // if the local user is the owner we send the permission change to the initiator
435
+        if ($this->userManager->userExists($share->getShareOwner())) {
436
+            [, $remote] = $this->addressHandler->splitUserRemote($share->getSharedBy());
437
+        } else { // ... if not we send the permission change to the owner
438
+            [, $remote] = $this->addressHandler->splitUserRemote($share->getShareOwner());
439
+        }
440
+        $this->notifications->sendPermissionChange($remote, $remoteId, $share->getToken(), $share->getPermissions());
441
+    }
442
+
443
+
444
+    /**
445
+     * update successful reShare with the correct token
446
+     *
447
+     * @param int $shareId
448
+     * @param string $token
449
+     */
450
+    protected function updateSuccessfulReShare($shareId, $token) {
451
+        $query = $this->dbConnection->getQueryBuilder();
452
+        $query->update('share')
453
+            ->where($query->expr()->eq('id', $query->createNamedParameter($shareId)))
454
+            ->set('token', $query->createNamedParameter($token))
455
+            ->execute();
456
+    }
457
+
458
+    /**
459
+     * store remote ID in federated reShare table
460
+     *
461
+     * @param $shareId
462
+     * @param $remoteId
463
+     */
464
+    public function storeRemoteId(int $shareId, string $remoteId): void {
465
+        $query = $this->dbConnection->getQueryBuilder();
466
+        $query->insert('federated_reshares')
467
+            ->values(
468
+                [
469
+                    'share_id' => $query->createNamedParameter($shareId),
470
+                    'remote_id' => $query->createNamedParameter($remoteId),
471
+                ]
472
+            );
473
+        $query->execute();
474
+    }
475
+
476
+    /**
477
+     * get share ID on remote server for federated re-shares
478
+     *
479
+     * @param IShare $share
480
+     * @return string
481
+     * @throws ShareNotFound
482
+     */
483
+    public function getRemoteId(IShare $share): string {
484
+        $query = $this->dbConnection->getQueryBuilder();
485
+        $query->select('remote_id')->from('federated_reshares')
486
+            ->where($query->expr()->eq('share_id', $query->createNamedParameter((int)$share->getId())));
487
+        $result = $query->execute();
488
+        $data = $result->fetch();
489
+        $result->closeCursor();
490
+
491
+        if (!is_array($data) || !isset($data['remote_id'])) {
492
+            throw new ShareNotFound();
493
+        }
494
+
495
+        return (string)$data['remote_id'];
496
+    }
497
+
498
+    /**
499
+     * @inheritdoc
500
+     */
501
+    public function move(IShare $share, $recipient) {
502
+        /*
503 503
 		 * This function does nothing yet as it is just for outgoing
504 504
 		 * federated shares.
505 505
 		 */
506
-		return $share;
507
-	}
508
-
509
-	/**
510
-	 * Get all children of this share
511
-	 *
512
-	 * @param IShare $parent
513
-	 * @return IShare[]
514
-	 */
515
-	public function getChildren(IShare $parent) {
516
-		$children = [];
517
-
518
-		$qb = $this->dbConnection->getQueryBuilder();
519
-		$qb->select('*')
520
-			->from('share')
521
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
522
-			->andWhere($qb->expr()->in('share_type', $qb->createNamedParameter($this->supportedShareType, IQueryBuilder::PARAM_INT_ARRAY)))
523
-			->orderBy('id');
524
-
525
-		$cursor = $qb->execute();
526
-		while ($data = $cursor->fetch()) {
527
-			$children[] = $this->createShareObject($data);
528
-		}
529
-		$cursor->closeCursor();
530
-
531
-		return $children;
532
-	}
533
-
534
-	/**
535
-	 * Delete a share (owner unShares the file)
536
-	 *
537
-	 * @param IShare $share
538
-	 * @throws ShareNotFound
539
-	 * @throws \OC\HintException
540
-	 */
541
-	public function delete(IShare $share) {
542
-		[, $remote] = $this->addressHandler->splitUserRemote($share->getSharedWith());
543
-
544
-		// if the local user is the owner we can send the unShare request directly...
545
-		if ($this->userManager->userExists($share->getShareOwner())) {
546
-			$this->notifications->sendRemoteUnShare($remote, $share->getId(), $share->getToken());
547
-			$this->revokeShare($share, true);
548
-		} else { // ... if not we need to correct ID for the unShare request
549
-			$remoteId = $this->getRemoteId($share);
550
-			$this->notifications->sendRemoteUnShare($remote, $remoteId, $share->getToken());
551
-			$this->revokeShare($share, false);
552
-		}
553
-
554
-		// only remove the share when all messages are send to not lose information
555
-		// about the share to early
556
-		$this->removeShareFromTable($share);
557
-	}
558
-
559
-	/**
560
-	 * in case of a re-share we need to send the other use (initiator or owner)
561
-	 * a message that the file was unshared
562
-	 *
563
-	 * @param IShare $share
564
-	 * @param bool $isOwner the user can either be the owner or the user who re-sahred it
565
-	 * @throws ShareNotFound
566
-	 * @throws \OC\HintException
567
-	 */
568
-	protected function revokeShare($share, $isOwner) {
569
-		if ($this->userManager->userExists($share->getShareOwner()) && $this->userManager->userExists($share->getSharedBy())) {
570
-			// If both the owner and the initiator of the share are local users we don't have to notify anybody else
571
-			return;
572
-		}
573
-
574
-		// also send a unShare request to the initiator, if this is a different user than the owner
575
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
576
-			if ($isOwner) {
577
-				[, $remote] = $this->addressHandler->splitUserRemote($share->getSharedBy());
578
-			} else {
579
-				[, $remote] = $this->addressHandler->splitUserRemote($share->getShareOwner());
580
-			}
581
-			$remoteId = $this->getRemoteId($share);
582
-			$this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken());
583
-		}
584
-	}
585
-
586
-	/**
587
-	 * remove share from table
588
-	 *
589
-	 * @param IShare $share
590
-	 */
591
-	public function removeShareFromTable(IShare $share) {
592
-		$this->removeShareFromTableById($share->getId());
593
-	}
594
-
595
-	/**
596
-	 * remove share from table
597
-	 *
598
-	 * @param string $shareId
599
-	 */
600
-	private function removeShareFromTableById($shareId) {
601
-		$qb = $this->dbConnection->getQueryBuilder();
602
-		$qb->delete('share')
603
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)))
604
-			->andWhere($qb->expr()->neq('share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE)));
605
-		$qb->execute();
606
-
607
-		$qb->delete('federated_reshares')
608
-			->where($qb->expr()->eq('share_id', $qb->createNamedParameter($shareId)));
609
-		$qb->execute();
610
-	}
611
-
612
-	/**
613
-	 * @inheritdoc
614
-	 */
615
-	public function deleteFromSelf(IShare $share, $recipient) {
616
-		// nothing to do here. Technically deleteFromSelf in the context of federated
617
-		// shares is a umount of an external storage. This is handled here
618
-		// apps/files_sharing/lib/external/manager.php
619
-		// TODO move this code over to this app
620
-	}
621
-
622
-	public function restore(IShare $share, string $recipient): IShare {
623
-		throw new GenericShareException('not implemented');
624
-	}
625
-
626
-
627
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
628
-		$qb = $this->dbConnection->getQueryBuilder();
629
-		$qb->select('*')
630
-			->from('share', 's')
631
-			->andWhere($qb->expr()->orX(
632
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
633
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
634
-			))
635
-			->andWhere(
636
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_REMOTE))
637
-			);
638
-
639
-		/**
640
-		 * Reshares for this user are shares where they are the owner.
641
-		 */
642
-		if ($reshares === false) {
643
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
644
-		} else {
645
-			$qb->andWhere(
646
-				$qb->expr()->orX(
647
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
648
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
649
-				)
650
-			);
651
-		}
652
-
653
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
654
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
655
-
656
-		$qb->orderBy('id');
657
-
658
-		$cursor = $qb->execute();
659
-		$shares = [];
660
-		while ($data = $cursor->fetch()) {
661
-			$shares[$data['fileid']][] = $this->createShareObject($data);
662
-		}
663
-		$cursor->closeCursor();
664
-
665
-		return $shares;
666
-	}
667
-
668
-	/**
669
-	 * @inheritdoc
670
-	 */
671
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
672
-		$qb = $this->dbConnection->getQueryBuilder();
673
-		$qb->select('*')
674
-			->from('share');
675
-
676
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
677
-
678
-		/**
679
-		 * Reshares for this user are shares where they are the owner.
680
-		 */
681
-		if ($reshares === false) {
682
-			//Special case for old shares created via the web UI
683
-			$or1 = $qb->expr()->andX(
684
-				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
685
-				$qb->expr()->isNull('uid_initiator')
686
-			);
687
-
688
-			$qb->andWhere(
689
-				$qb->expr()->orX(
690
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
691
-					$or1
692
-				)
693
-			);
694
-		} else {
695
-			$qb->andWhere(
696
-				$qb->expr()->orX(
697
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
698
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
699
-				)
700
-			);
701
-		}
702
-
703
-		if ($node !== null) {
704
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
705
-		}
706
-
707
-		if ($limit !== -1) {
708
-			$qb->setMaxResults($limit);
709
-		}
710
-
711
-		$qb->setFirstResult($offset);
712
-		$qb->orderBy('id');
713
-
714
-		$cursor = $qb->execute();
715
-		$shares = [];
716
-		while ($data = $cursor->fetch()) {
717
-			$shares[] = $this->createShareObject($data);
718
-		}
719
-		$cursor->closeCursor();
720
-
721
-		return $shares;
722
-	}
723
-
724
-	/**
725
-	 * @inheritdoc
726
-	 */
727
-	public function getShareById($id, $recipientId = null) {
728
-		$qb = $this->dbConnection->getQueryBuilder();
729
-
730
-		$qb->select('*')
731
-			->from('share')
732
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
733
-			->andWhere($qb->expr()->in('share_type', $qb->createNamedParameter($this->supportedShareType, IQueryBuilder::PARAM_INT_ARRAY)));
734
-
735
-		$cursor = $qb->execute();
736
-		$data = $cursor->fetch();
737
-		$cursor->closeCursor();
738
-
739
-		if ($data === false) {
740
-			throw new ShareNotFound('Can not find share with ID: ' . $id);
741
-		}
742
-
743
-		try {
744
-			$share = $this->createShareObject($data);
745
-		} catch (InvalidShare $e) {
746
-			throw new ShareNotFound();
747
-		}
748
-
749
-		return $share;
750
-	}
751
-
752
-	/**
753
-	 * Get shares for a given path
754
-	 *
755
-	 * @param \OCP\Files\Node $path
756
-	 * @return IShare[]
757
-	 */
758
-	public function getSharesByPath(Node $path) {
759
-		$qb = $this->dbConnection->getQueryBuilder();
760
-
761
-		// get federated user shares
762
-		$cursor = $qb->select('*')
763
-			->from('share')
764
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
765
-			->andWhere($qb->expr()->in('share_type', $qb->createNamedParameter($this->supportedShareType, IQueryBuilder::PARAM_INT_ARRAY)))
766
-			->execute();
767
-
768
-		$shares = [];
769
-		while ($data = $cursor->fetch()) {
770
-			$shares[] = $this->createShareObject($data);
771
-		}
772
-		$cursor->closeCursor();
773
-
774
-		return $shares;
775
-	}
776
-
777
-	/**
778
-	 * @inheritdoc
779
-	 */
780
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
781
-		/** @var IShare[] $shares */
782
-		$shares = [];
783
-
784
-		//Get shares directly with this user
785
-		$qb = $this->dbConnection->getQueryBuilder();
786
-		$qb->select('*')
787
-			->from('share');
788
-
789
-		// Order by id
790
-		$qb->orderBy('id');
791
-
792
-		// Set limit and offset
793
-		if ($limit !== -1) {
794
-			$qb->setMaxResults($limit);
795
-		}
796
-		$qb->setFirstResult($offset);
797
-
798
-		$qb->where($qb->expr()->in('share_type', $qb->createNamedParameter($this->supportedShareType, IQueryBuilder::PARAM_INT_ARRAY)));
799
-		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
800
-
801
-		// Filter by node if provided
802
-		if ($node !== null) {
803
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
804
-		}
805
-
806
-		$cursor = $qb->execute();
807
-
808
-		while ($data = $cursor->fetch()) {
809
-			$shares[] = $this->createShareObject($data);
810
-		}
811
-		$cursor->closeCursor();
812
-
813
-
814
-		return $shares;
815
-	}
816
-
817
-	/**
818
-	 * Get a share by token
819
-	 *
820
-	 * @param string $token
821
-	 * @return IShare
822
-	 * @throws ShareNotFound
823
-	 */
824
-	public function getShareByToken($token) {
825
-		$qb = $this->dbConnection->getQueryBuilder();
826
-
827
-		$cursor = $qb->select('*')
828
-			->from('share')
829
-			->where($qb->expr()->in('share_type', $qb->createNamedParameter($this->supportedShareType, IQueryBuilder::PARAM_INT_ARRAY)))
830
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
831
-			->execute();
832
-
833
-		$data = $cursor->fetch();
834
-
835
-		if ($data === false) {
836
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
837
-		}
838
-
839
-		try {
840
-			$share = $this->createShareObject($data);
841
-		} catch (InvalidShare $e) {
842
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
843
-		}
844
-
845
-		return $share;
846
-	}
847
-
848
-	/**
849
-	 * get database row of a give share
850
-	 *
851
-	 * @param $id
852
-	 * @return array
853
-	 * @throws ShareNotFound
854
-	 */
855
-	private function getRawShare($id) {
856
-
857
-		// Now fetch the inserted share and create a complete share object
858
-		$qb = $this->dbConnection->getQueryBuilder();
859
-		$qb->select('*')
860
-			->from('share')
861
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
862
-
863
-		$cursor = $qb->execute();
864
-		$data = $cursor->fetch();
865
-		$cursor->closeCursor();
866
-
867
-		if ($data === false) {
868
-			throw new ShareNotFound;
869
-		}
870
-
871
-		return $data;
872
-	}
873
-
874
-	/**
875
-	 * Create a share object from an database row
876
-	 *
877
-	 * @param array $data
878
-	 * @return IShare
879
-	 * @throws InvalidShare
880
-	 * @throws ShareNotFound
881
-	 */
882
-	private function createShareObject($data) {
883
-		$share = new Share($this->rootFolder, $this->userManager);
884
-		$share->setId((int)$data['id'])
885
-			->setShareType((int)$data['share_type'])
886
-			->setPermissions((int)$data['permissions'])
887
-			->setTarget($data['file_target'])
888
-			->setMailSend((bool)$data['mail_send'])
889
-			->setToken($data['token']);
890
-
891
-		$shareTime = new \DateTime();
892
-		$shareTime->setTimestamp((int)$data['stime']);
893
-		$share->setShareTime($shareTime);
894
-		$share->setSharedWith($data['share_with']);
895
-
896
-		if ($data['uid_initiator'] !== null) {
897
-			$share->setShareOwner($data['uid_owner']);
898
-			$share->setSharedBy($data['uid_initiator']);
899
-		} else {
900
-			//OLD SHARE
901
-			$share->setSharedBy($data['uid_owner']);
902
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
903
-
904
-			$owner = $path->getOwner();
905
-			$share->setShareOwner($owner->getUID());
906
-		}
907
-
908
-		$share->setNodeId((int)$data['file_source']);
909
-		$share->setNodeType($data['item_type']);
910
-
911
-		$share->setProviderId($this->identifier());
912
-
913
-		return $share;
914
-	}
915
-
916
-	/**
917
-	 * Get the node with file $id for $user
918
-	 *
919
-	 * @param string $userId
920
-	 * @param int $id
921
-	 * @return \OCP\Files\File|\OCP\Files\Folder
922
-	 * @throws InvalidShare
923
-	 */
924
-	private function getNode($userId, $id) {
925
-		try {
926
-			$userFolder = $this->rootFolder->getUserFolder($userId);
927
-		} catch (NotFoundException $e) {
928
-			throw new InvalidShare();
929
-		}
930
-
931
-		$nodes = $userFolder->getById($id);
932
-
933
-		if (empty($nodes)) {
934
-			throw new InvalidShare();
935
-		}
936
-
937
-		return $nodes[0];
938
-	}
939
-
940
-	/**
941
-	 * A user is deleted from the system
942
-	 * So clean up the relevant shares.
943
-	 *
944
-	 * @param string $uid
945
-	 * @param int $shareType
946
-	 */
947
-	public function userDeleted($uid, $shareType) {
948
-		//TODO: probabaly a good idea to send unshare info to remote servers
949
-
950
-		$qb = $this->dbConnection->getQueryBuilder();
951
-
952
-		$qb->delete('share')
953
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_REMOTE)))
954
-			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
955
-			->execute();
956
-	}
957
-
958
-	/**
959
-	 * This provider does not handle groups
960
-	 *
961
-	 * @param string $gid
962
-	 */
963
-	public function groupDeleted($gid) {
964
-		// We don't handle groups here
965
-	}
966
-
967
-	/**
968
-	 * This provider does not handle groups
969
-	 *
970
-	 * @param string $uid
971
-	 * @param string $gid
972
-	 */
973
-	public function userDeletedFromGroup($uid, $gid) {
974
-		// We don't handle groups here
975
-	}
976
-
977
-	/**
978
-	 * check if users from other Nextcloud instances are allowed to mount public links share by this instance
979
-	 *
980
-	 * @return bool
981
-	 */
982
-	public function isOutgoingServer2serverShareEnabled() {
983
-		if ($this->gsConfig->onlyInternalFederation()) {
984
-			return false;
985
-		}
986
-		$result = $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes');
987
-		return ($result === 'yes');
988
-	}
989
-
990
-	/**
991
-	 * check if users are allowed to mount public links from other Nextclouds
992
-	 *
993
-	 * @return bool
994
-	 */
995
-	public function isIncomingServer2serverShareEnabled() {
996
-		if ($this->gsConfig->onlyInternalFederation()) {
997
-			return false;
998
-		}
999
-		$result = $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes');
1000
-		return ($result === 'yes');
1001
-	}
1002
-
1003
-
1004
-	/**
1005
-	 * check if users from other Nextcloud instances are allowed to send federated group shares
1006
-	 *
1007
-	 * @return bool
1008
-	 */
1009
-	public function isOutgoingServer2serverGroupShareEnabled() {
1010
-		if ($this->gsConfig->onlyInternalFederation()) {
1011
-			return false;
1012
-		}
1013
-		$result = $this->config->getAppValue('files_sharing', 'outgoing_server2server_group_share_enabled', 'no');
1014
-		return ($result === 'yes');
1015
-	}
1016
-
1017
-	/**
1018
-	 * check if users are allowed to receive federated group shares
1019
-	 *
1020
-	 * @return bool
1021
-	 */
1022
-	public function isIncomingServer2serverGroupShareEnabled() {
1023
-		if ($this->gsConfig->onlyInternalFederation()) {
1024
-			return false;
1025
-		}
1026
-		$result = $this->config->getAppValue('files_sharing', 'incoming_server2server_group_share_enabled', 'no');
1027
-		return ($result === 'yes');
1028
-	}
1029
-
1030
-	/**
1031
-	 * check if federated group sharing is supported, therefore the OCM API need to be enabled
1032
-	 *
1033
-	 * @return bool
1034
-	 */
1035
-	public function isFederatedGroupSharingSupported() {
1036
-		return $this->cloudFederationProviderManager->isReady();
1037
-	}
1038
-
1039
-	/**
1040
-	 * Check if querying sharees on the lookup server is enabled
1041
-	 *
1042
-	 * @return bool
1043
-	 */
1044
-	public function isLookupServerQueriesEnabled() {
1045
-		// in a global scale setup we should always query the lookup server
1046
-		if ($this->gsConfig->isGlobalScaleEnabled()) {
1047
-			return true;
1048
-		}
1049
-		$result = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'yes');
1050
-		return ($result === 'yes');
1051
-	}
1052
-
1053
-
1054
-	/**
1055
-	 * Check if it is allowed to publish user specific data to the lookup server
1056
-	 *
1057
-	 * @return bool
1058
-	 */
1059
-	public function isLookupServerUploadEnabled() {
1060
-		// in a global scale setup the admin is responsible to keep the lookup server up-to-date
1061
-		if ($this->gsConfig->isGlobalScaleEnabled()) {
1062
-			return false;
1063
-		}
1064
-		$result = $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes');
1065
-		return ($result === 'yes');
1066
-	}
1067
-
1068
-	/**
1069
-	 * @inheritdoc
1070
-	 */
1071
-	public function getAccessList($nodes, $currentAccess) {
1072
-		$ids = [];
1073
-		foreach ($nodes as $node) {
1074
-			$ids[] = $node->getId();
1075
-		}
1076
-
1077
-		$qb = $this->dbConnection->getQueryBuilder();
1078
-		$qb->select('share_with', 'token', 'file_source')
1079
-			->from('share')
1080
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_REMOTE)))
1081
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1082
-			->andWhere($qb->expr()->orX(
1083
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1084
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1085
-			));
1086
-		$cursor = $qb->execute();
1087
-
1088
-		if ($currentAccess === false) {
1089
-			$remote = $cursor->fetch() !== false;
1090
-			$cursor->closeCursor();
1091
-
1092
-			return ['remote' => $remote];
1093
-		}
1094
-
1095
-		$remote = [];
1096
-		while ($row = $cursor->fetch()) {
1097
-			$remote[$row['share_with']] = [
1098
-				'node_id' => $row['file_source'],
1099
-				'token' => $row['token'],
1100
-			];
1101
-		}
1102
-		$cursor->closeCursor();
1103
-
1104
-		return ['remote' => $remote];
1105
-	}
1106
-
1107
-	public function getAllShares(): iterable {
1108
-		$qb = $this->dbConnection->getQueryBuilder();
1109
-
1110
-		$qb->select('*')
1111
-			->from('share')
1112
-			->where(
1113
-				$qb->expr()->orX(
1114
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_REMOTE)),
1115
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_REMOTE_GROUP))
1116
-				)
1117
-			);
1118
-
1119
-		$cursor = $qb->execute();
1120
-		while ($data = $cursor->fetch()) {
1121
-			try {
1122
-				$share = $this->createShareObject($data);
1123
-			} catch (InvalidShare $e) {
1124
-				continue;
1125
-			} catch (ShareNotFound $e) {
1126
-				continue;
1127
-			}
1128
-
1129
-			yield $share;
1130
-		}
1131
-		$cursor->closeCursor();
1132
-	}
506
+        return $share;
507
+    }
508
+
509
+    /**
510
+     * Get all children of this share
511
+     *
512
+     * @param IShare $parent
513
+     * @return IShare[]
514
+     */
515
+    public function getChildren(IShare $parent) {
516
+        $children = [];
517
+
518
+        $qb = $this->dbConnection->getQueryBuilder();
519
+        $qb->select('*')
520
+            ->from('share')
521
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
522
+            ->andWhere($qb->expr()->in('share_type', $qb->createNamedParameter($this->supportedShareType, IQueryBuilder::PARAM_INT_ARRAY)))
523
+            ->orderBy('id');
524
+
525
+        $cursor = $qb->execute();
526
+        while ($data = $cursor->fetch()) {
527
+            $children[] = $this->createShareObject($data);
528
+        }
529
+        $cursor->closeCursor();
530
+
531
+        return $children;
532
+    }
533
+
534
+    /**
535
+     * Delete a share (owner unShares the file)
536
+     *
537
+     * @param IShare $share
538
+     * @throws ShareNotFound
539
+     * @throws \OC\HintException
540
+     */
541
+    public function delete(IShare $share) {
542
+        [, $remote] = $this->addressHandler->splitUserRemote($share->getSharedWith());
543
+
544
+        // if the local user is the owner we can send the unShare request directly...
545
+        if ($this->userManager->userExists($share->getShareOwner())) {
546
+            $this->notifications->sendRemoteUnShare($remote, $share->getId(), $share->getToken());
547
+            $this->revokeShare($share, true);
548
+        } else { // ... if not we need to correct ID for the unShare request
549
+            $remoteId = $this->getRemoteId($share);
550
+            $this->notifications->sendRemoteUnShare($remote, $remoteId, $share->getToken());
551
+            $this->revokeShare($share, false);
552
+        }
553
+
554
+        // only remove the share when all messages are send to not lose information
555
+        // about the share to early
556
+        $this->removeShareFromTable($share);
557
+    }
558
+
559
+    /**
560
+     * in case of a re-share we need to send the other use (initiator or owner)
561
+     * a message that the file was unshared
562
+     *
563
+     * @param IShare $share
564
+     * @param bool $isOwner the user can either be the owner or the user who re-sahred it
565
+     * @throws ShareNotFound
566
+     * @throws \OC\HintException
567
+     */
568
+    protected function revokeShare($share, $isOwner) {
569
+        if ($this->userManager->userExists($share->getShareOwner()) && $this->userManager->userExists($share->getSharedBy())) {
570
+            // If both the owner and the initiator of the share are local users we don't have to notify anybody else
571
+            return;
572
+        }
573
+
574
+        // also send a unShare request to the initiator, if this is a different user than the owner
575
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
576
+            if ($isOwner) {
577
+                [, $remote] = $this->addressHandler->splitUserRemote($share->getSharedBy());
578
+            } else {
579
+                [, $remote] = $this->addressHandler->splitUserRemote($share->getShareOwner());
580
+            }
581
+            $remoteId = $this->getRemoteId($share);
582
+            $this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken());
583
+        }
584
+    }
585
+
586
+    /**
587
+     * remove share from table
588
+     *
589
+     * @param IShare $share
590
+     */
591
+    public function removeShareFromTable(IShare $share) {
592
+        $this->removeShareFromTableById($share->getId());
593
+    }
594
+
595
+    /**
596
+     * remove share from table
597
+     *
598
+     * @param string $shareId
599
+     */
600
+    private function removeShareFromTableById($shareId) {
601
+        $qb = $this->dbConnection->getQueryBuilder();
602
+        $qb->delete('share')
603
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)))
604
+            ->andWhere($qb->expr()->neq('share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE)));
605
+        $qb->execute();
606
+
607
+        $qb->delete('federated_reshares')
608
+            ->where($qb->expr()->eq('share_id', $qb->createNamedParameter($shareId)));
609
+        $qb->execute();
610
+    }
611
+
612
+    /**
613
+     * @inheritdoc
614
+     */
615
+    public function deleteFromSelf(IShare $share, $recipient) {
616
+        // nothing to do here. Technically deleteFromSelf in the context of federated
617
+        // shares is a umount of an external storage. This is handled here
618
+        // apps/files_sharing/lib/external/manager.php
619
+        // TODO move this code over to this app
620
+    }
621
+
622
+    public function restore(IShare $share, string $recipient): IShare {
623
+        throw new GenericShareException('not implemented');
624
+    }
625
+
626
+
627
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
628
+        $qb = $this->dbConnection->getQueryBuilder();
629
+        $qb->select('*')
630
+            ->from('share', 's')
631
+            ->andWhere($qb->expr()->orX(
632
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
633
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
634
+            ))
635
+            ->andWhere(
636
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_REMOTE))
637
+            );
638
+
639
+        /**
640
+         * Reshares for this user are shares where they are the owner.
641
+         */
642
+        if ($reshares === false) {
643
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
644
+        } else {
645
+            $qb->andWhere(
646
+                $qb->expr()->orX(
647
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
648
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
649
+                )
650
+            );
651
+        }
652
+
653
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
654
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
655
+
656
+        $qb->orderBy('id');
657
+
658
+        $cursor = $qb->execute();
659
+        $shares = [];
660
+        while ($data = $cursor->fetch()) {
661
+            $shares[$data['fileid']][] = $this->createShareObject($data);
662
+        }
663
+        $cursor->closeCursor();
664
+
665
+        return $shares;
666
+    }
667
+
668
+    /**
669
+     * @inheritdoc
670
+     */
671
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
672
+        $qb = $this->dbConnection->getQueryBuilder();
673
+        $qb->select('*')
674
+            ->from('share');
675
+
676
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
677
+
678
+        /**
679
+         * Reshares for this user are shares where they are the owner.
680
+         */
681
+        if ($reshares === false) {
682
+            //Special case for old shares created via the web UI
683
+            $or1 = $qb->expr()->andX(
684
+                $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
685
+                $qb->expr()->isNull('uid_initiator')
686
+            );
687
+
688
+            $qb->andWhere(
689
+                $qb->expr()->orX(
690
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
691
+                    $or1
692
+                )
693
+            );
694
+        } else {
695
+            $qb->andWhere(
696
+                $qb->expr()->orX(
697
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
698
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
699
+                )
700
+            );
701
+        }
702
+
703
+        if ($node !== null) {
704
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
705
+        }
706
+
707
+        if ($limit !== -1) {
708
+            $qb->setMaxResults($limit);
709
+        }
710
+
711
+        $qb->setFirstResult($offset);
712
+        $qb->orderBy('id');
713
+
714
+        $cursor = $qb->execute();
715
+        $shares = [];
716
+        while ($data = $cursor->fetch()) {
717
+            $shares[] = $this->createShareObject($data);
718
+        }
719
+        $cursor->closeCursor();
720
+
721
+        return $shares;
722
+    }
723
+
724
+    /**
725
+     * @inheritdoc
726
+     */
727
+    public function getShareById($id, $recipientId = null) {
728
+        $qb = $this->dbConnection->getQueryBuilder();
729
+
730
+        $qb->select('*')
731
+            ->from('share')
732
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
733
+            ->andWhere($qb->expr()->in('share_type', $qb->createNamedParameter($this->supportedShareType, IQueryBuilder::PARAM_INT_ARRAY)));
734
+
735
+        $cursor = $qb->execute();
736
+        $data = $cursor->fetch();
737
+        $cursor->closeCursor();
738
+
739
+        if ($data === false) {
740
+            throw new ShareNotFound('Can not find share with ID: ' . $id);
741
+        }
742
+
743
+        try {
744
+            $share = $this->createShareObject($data);
745
+        } catch (InvalidShare $e) {
746
+            throw new ShareNotFound();
747
+        }
748
+
749
+        return $share;
750
+    }
751
+
752
+    /**
753
+     * Get shares for a given path
754
+     *
755
+     * @param \OCP\Files\Node $path
756
+     * @return IShare[]
757
+     */
758
+    public function getSharesByPath(Node $path) {
759
+        $qb = $this->dbConnection->getQueryBuilder();
760
+
761
+        // get federated user shares
762
+        $cursor = $qb->select('*')
763
+            ->from('share')
764
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
765
+            ->andWhere($qb->expr()->in('share_type', $qb->createNamedParameter($this->supportedShareType, IQueryBuilder::PARAM_INT_ARRAY)))
766
+            ->execute();
767
+
768
+        $shares = [];
769
+        while ($data = $cursor->fetch()) {
770
+            $shares[] = $this->createShareObject($data);
771
+        }
772
+        $cursor->closeCursor();
773
+
774
+        return $shares;
775
+    }
776
+
777
+    /**
778
+     * @inheritdoc
779
+     */
780
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
781
+        /** @var IShare[] $shares */
782
+        $shares = [];
783
+
784
+        //Get shares directly with this user
785
+        $qb = $this->dbConnection->getQueryBuilder();
786
+        $qb->select('*')
787
+            ->from('share');
788
+
789
+        // Order by id
790
+        $qb->orderBy('id');
791
+
792
+        // Set limit and offset
793
+        if ($limit !== -1) {
794
+            $qb->setMaxResults($limit);
795
+        }
796
+        $qb->setFirstResult($offset);
797
+
798
+        $qb->where($qb->expr()->in('share_type', $qb->createNamedParameter($this->supportedShareType, IQueryBuilder::PARAM_INT_ARRAY)));
799
+        $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
800
+
801
+        // Filter by node if provided
802
+        if ($node !== null) {
803
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
804
+        }
805
+
806
+        $cursor = $qb->execute();
807
+
808
+        while ($data = $cursor->fetch()) {
809
+            $shares[] = $this->createShareObject($data);
810
+        }
811
+        $cursor->closeCursor();
812
+
813
+
814
+        return $shares;
815
+    }
816
+
817
+    /**
818
+     * Get a share by token
819
+     *
820
+     * @param string $token
821
+     * @return IShare
822
+     * @throws ShareNotFound
823
+     */
824
+    public function getShareByToken($token) {
825
+        $qb = $this->dbConnection->getQueryBuilder();
826
+
827
+        $cursor = $qb->select('*')
828
+            ->from('share')
829
+            ->where($qb->expr()->in('share_type', $qb->createNamedParameter($this->supportedShareType, IQueryBuilder::PARAM_INT_ARRAY)))
830
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
831
+            ->execute();
832
+
833
+        $data = $cursor->fetch();
834
+
835
+        if ($data === false) {
836
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
837
+        }
838
+
839
+        try {
840
+            $share = $this->createShareObject($data);
841
+        } catch (InvalidShare $e) {
842
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
843
+        }
844
+
845
+        return $share;
846
+    }
847
+
848
+    /**
849
+     * get database row of a give share
850
+     *
851
+     * @param $id
852
+     * @return array
853
+     * @throws ShareNotFound
854
+     */
855
+    private function getRawShare($id) {
856
+
857
+        // Now fetch the inserted share and create a complete share object
858
+        $qb = $this->dbConnection->getQueryBuilder();
859
+        $qb->select('*')
860
+            ->from('share')
861
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
862
+
863
+        $cursor = $qb->execute();
864
+        $data = $cursor->fetch();
865
+        $cursor->closeCursor();
866
+
867
+        if ($data === false) {
868
+            throw new ShareNotFound;
869
+        }
870
+
871
+        return $data;
872
+    }
873
+
874
+    /**
875
+     * Create a share object from an database row
876
+     *
877
+     * @param array $data
878
+     * @return IShare
879
+     * @throws InvalidShare
880
+     * @throws ShareNotFound
881
+     */
882
+    private function createShareObject($data) {
883
+        $share = new Share($this->rootFolder, $this->userManager);
884
+        $share->setId((int)$data['id'])
885
+            ->setShareType((int)$data['share_type'])
886
+            ->setPermissions((int)$data['permissions'])
887
+            ->setTarget($data['file_target'])
888
+            ->setMailSend((bool)$data['mail_send'])
889
+            ->setToken($data['token']);
890
+
891
+        $shareTime = new \DateTime();
892
+        $shareTime->setTimestamp((int)$data['stime']);
893
+        $share->setShareTime($shareTime);
894
+        $share->setSharedWith($data['share_with']);
895
+
896
+        if ($data['uid_initiator'] !== null) {
897
+            $share->setShareOwner($data['uid_owner']);
898
+            $share->setSharedBy($data['uid_initiator']);
899
+        } else {
900
+            //OLD SHARE
901
+            $share->setSharedBy($data['uid_owner']);
902
+            $path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
903
+
904
+            $owner = $path->getOwner();
905
+            $share->setShareOwner($owner->getUID());
906
+        }
907
+
908
+        $share->setNodeId((int)$data['file_source']);
909
+        $share->setNodeType($data['item_type']);
910
+
911
+        $share->setProviderId($this->identifier());
912
+
913
+        return $share;
914
+    }
915
+
916
+    /**
917
+     * Get the node with file $id for $user
918
+     *
919
+     * @param string $userId
920
+     * @param int $id
921
+     * @return \OCP\Files\File|\OCP\Files\Folder
922
+     * @throws InvalidShare
923
+     */
924
+    private function getNode($userId, $id) {
925
+        try {
926
+            $userFolder = $this->rootFolder->getUserFolder($userId);
927
+        } catch (NotFoundException $e) {
928
+            throw new InvalidShare();
929
+        }
930
+
931
+        $nodes = $userFolder->getById($id);
932
+
933
+        if (empty($nodes)) {
934
+            throw new InvalidShare();
935
+        }
936
+
937
+        return $nodes[0];
938
+    }
939
+
940
+    /**
941
+     * A user is deleted from the system
942
+     * So clean up the relevant shares.
943
+     *
944
+     * @param string $uid
945
+     * @param int $shareType
946
+     */
947
+    public function userDeleted($uid, $shareType) {
948
+        //TODO: probabaly a good idea to send unshare info to remote servers
949
+
950
+        $qb = $this->dbConnection->getQueryBuilder();
951
+
952
+        $qb->delete('share')
953
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_REMOTE)))
954
+            ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
955
+            ->execute();
956
+    }
957
+
958
+    /**
959
+     * This provider does not handle groups
960
+     *
961
+     * @param string $gid
962
+     */
963
+    public function groupDeleted($gid) {
964
+        // We don't handle groups here
965
+    }
966
+
967
+    /**
968
+     * This provider does not handle groups
969
+     *
970
+     * @param string $uid
971
+     * @param string $gid
972
+     */
973
+    public function userDeletedFromGroup($uid, $gid) {
974
+        // We don't handle groups here
975
+    }
976
+
977
+    /**
978
+     * check if users from other Nextcloud instances are allowed to mount public links share by this instance
979
+     *
980
+     * @return bool
981
+     */
982
+    public function isOutgoingServer2serverShareEnabled() {
983
+        if ($this->gsConfig->onlyInternalFederation()) {
984
+            return false;
985
+        }
986
+        $result = $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes');
987
+        return ($result === 'yes');
988
+    }
989
+
990
+    /**
991
+     * check if users are allowed to mount public links from other Nextclouds
992
+     *
993
+     * @return bool
994
+     */
995
+    public function isIncomingServer2serverShareEnabled() {
996
+        if ($this->gsConfig->onlyInternalFederation()) {
997
+            return false;
998
+        }
999
+        $result = $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes');
1000
+        return ($result === 'yes');
1001
+    }
1002
+
1003
+
1004
+    /**
1005
+     * check if users from other Nextcloud instances are allowed to send federated group shares
1006
+     *
1007
+     * @return bool
1008
+     */
1009
+    public function isOutgoingServer2serverGroupShareEnabled() {
1010
+        if ($this->gsConfig->onlyInternalFederation()) {
1011
+            return false;
1012
+        }
1013
+        $result = $this->config->getAppValue('files_sharing', 'outgoing_server2server_group_share_enabled', 'no');
1014
+        return ($result === 'yes');
1015
+    }
1016
+
1017
+    /**
1018
+     * check if users are allowed to receive federated group shares
1019
+     *
1020
+     * @return bool
1021
+     */
1022
+    public function isIncomingServer2serverGroupShareEnabled() {
1023
+        if ($this->gsConfig->onlyInternalFederation()) {
1024
+            return false;
1025
+        }
1026
+        $result = $this->config->getAppValue('files_sharing', 'incoming_server2server_group_share_enabled', 'no');
1027
+        return ($result === 'yes');
1028
+    }
1029
+
1030
+    /**
1031
+     * check if federated group sharing is supported, therefore the OCM API need to be enabled
1032
+     *
1033
+     * @return bool
1034
+     */
1035
+    public function isFederatedGroupSharingSupported() {
1036
+        return $this->cloudFederationProviderManager->isReady();
1037
+    }
1038
+
1039
+    /**
1040
+     * Check if querying sharees on the lookup server is enabled
1041
+     *
1042
+     * @return bool
1043
+     */
1044
+    public function isLookupServerQueriesEnabled() {
1045
+        // in a global scale setup we should always query the lookup server
1046
+        if ($this->gsConfig->isGlobalScaleEnabled()) {
1047
+            return true;
1048
+        }
1049
+        $result = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'yes');
1050
+        return ($result === 'yes');
1051
+    }
1052
+
1053
+
1054
+    /**
1055
+     * Check if it is allowed to publish user specific data to the lookup server
1056
+     *
1057
+     * @return bool
1058
+     */
1059
+    public function isLookupServerUploadEnabled() {
1060
+        // in a global scale setup the admin is responsible to keep the lookup server up-to-date
1061
+        if ($this->gsConfig->isGlobalScaleEnabled()) {
1062
+            return false;
1063
+        }
1064
+        $result = $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes');
1065
+        return ($result === 'yes');
1066
+    }
1067
+
1068
+    /**
1069
+     * @inheritdoc
1070
+     */
1071
+    public function getAccessList($nodes, $currentAccess) {
1072
+        $ids = [];
1073
+        foreach ($nodes as $node) {
1074
+            $ids[] = $node->getId();
1075
+        }
1076
+
1077
+        $qb = $this->dbConnection->getQueryBuilder();
1078
+        $qb->select('share_with', 'token', 'file_source')
1079
+            ->from('share')
1080
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_REMOTE)))
1081
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1082
+            ->andWhere($qb->expr()->orX(
1083
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1084
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1085
+            ));
1086
+        $cursor = $qb->execute();
1087
+
1088
+        if ($currentAccess === false) {
1089
+            $remote = $cursor->fetch() !== false;
1090
+            $cursor->closeCursor();
1091
+
1092
+            return ['remote' => $remote];
1093
+        }
1094
+
1095
+        $remote = [];
1096
+        while ($row = $cursor->fetch()) {
1097
+            $remote[$row['share_with']] = [
1098
+                'node_id' => $row['file_source'],
1099
+                'token' => $row['token'],
1100
+            ];
1101
+        }
1102
+        $cursor->closeCursor();
1103
+
1104
+        return ['remote' => $remote];
1105
+    }
1106
+
1107
+    public function getAllShares(): iterable {
1108
+        $qb = $this->dbConnection->getQueryBuilder();
1109
+
1110
+        $qb->select('*')
1111
+            ->from('share')
1112
+            ->where(
1113
+                $qb->expr()->orX(
1114
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_REMOTE)),
1115
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_REMOTE_GROUP))
1116
+                )
1117
+            );
1118
+
1119
+        $cursor = $qb->execute();
1120
+        while ($data = $cursor->fetch()) {
1121
+            try {
1122
+                $share = $this->createShareObject($data);
1123
+            } catch (InvalidShare $e) {
1124
+                continue;
1125
+            } catch (ShareNotFound $e) {
1126
+                continue;
1127
+            }
1128
+
1129
+            yield $share;
1130
+        }
1131
+        $cursor->closeCursor();
1132
+    }
1133 1133
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
 		if ($remoteShare) {
220 220
 			try {
221 221
 				$ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
222
-				$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time(), $shareType);
222
+				$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_'.time(), $shareType);
223 223
 				$share->setId($shareId);
224 224
 				[$token, $remoteId] = $this->askOwnerToReShare($shareWith, $share, $shareId);
225 225
 				// remote share was create successfully if we get a valid token as return
@@ -352,7 +352,7 @@  discard block
 block discarded – undo
352 352
 		$result = $qResult->fetchAll();
353 353
 		$qResult->closeCursor();
354 354
 
355
-		if (isset($result[0]) && (int)$result[0]['remote_id'] > 0) {
355
+		if (isset($result[0]) && (int) $result[0]['remote_id'] > 0) {
356 356
 			return $result[0];
357 357
 		}
358 358
 
@@ -483,7 +483,7 @@  discard block
 block discarded – undo
483 483
 	public function getRemoteId(IShare $share): string {
484 484
 		$query = $this->dbConnection->getQueryBuilder();
485 485
 		$query->select('remote_id')->from('federated_reshares')
486
-			->where($query->expr()->eq('share_id', $query->createNamedParameter((int)$share->getId())));
486
+			->where($query->expr()->eq('share_id', $query->createNamedParameter((int) $share->getId())));
487 487
 		$result = $query->execute();
488 488
 		$data = $result->fetch();
489 489
 		$result->closeCursor();
@@ -492,7 +492,7 @@  discard block
 block discarded – undo
492 492
 			throw new ShareNotFound();
493 493
 		}
494 494
 
495
-		return (string)$data['remote_id'];
495
+		return (string) $data['remote_id'];
496 496
 	}
497 497
 
498 498
 	/**
@@ -650,7 +650,7 @@  discard block
 block discarded – undo
650 650
 			);
651 651
 		}
652 652
 
653
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
653
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
654 654
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
655 655
 
656 656
 		$qb->orderBy('id');
@@ -737,7 +737,7 @@  discard block
 block discarded – undo
737 737
 		$cursor->closeCursor();
738 738
 
739 739
 		if ($data === false) {
740
-			throw new ShareNotFound('Can not find share with ID: ' . $id);
740
+			throw new ShareNotFound('Can not find share with ID: '.$id);
741 741
 		}
742 742
 
743 743
 		try {
@@ -881,15 +881,15 @@  discard block
 block discarded – undo
881 881
 	 */
882 882
 	private function createShareObject($data) {
883 883
 		$share = new Share($this->rootFolder, $this->userManager);
884
-		$share->setId((int)$data['id'])
885
-			->setShareType((int)$data['share_type'])
886
-			->setPermissions((int)$data['permissions'])
884
+		$share->setId((int) $data['id'])
885
+			->setShareType((int) $data['share_type'])
886
+			->setPermissions((int) $data['permissions'])
887 887
 			->setTarget($data['file_target'])
888
-			->setMailSend((bool)$data['mail_send'])
888
+			->setMailSend((bool) $data['mail_send'])
889 889
 			->setToken($data['token']);
890 890
 
891 891
 		$shareTime = new \DateTime();
892
-		$shareTime->setTimestamp((int)$data['stime']);
892
+		$shareTime->setTimestamp((int) $data['stime']);
893 893
 		$share->setShareTime($shareTime);
894 894
 		$share->setSharedWith($data['share_with']);
895 895
 
@@ -899,13 +899,13 @@  discard block
 block discarded – undo
899 899
 		} else {
900 900
 			//OLD SHARE
901 901
 			$share->setSharedBy($data['uid_owner']);
902
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
902
+			$path = $this->getNode($share->getSharedBy(), (int) $data['file_source']);
903 903
 
904 904
 			$owner = $path->getOwner();
905 905
 			$share->setShareOwner($owner->getUID());
906 906
 		}
907 907
 
908
-		$share->setNodeId((int)$data['file_source']);
908
+		$share->setNodeId((int) $data['file_source']);
909 909
 		$share->setNodeType($data['item_type']);
910 910
 
911 911
 		$share->setProviderId($this->identifier());
Please login to merge, or discard this patch.