Skip to content

Commit 9a19f53

Browse files
authored
Merge pull request #1325 from nextcloud/backport/1317/stable10
[stable10] fix(FaceRoot): Fix duplicate prevention
2 parents d96aaac + b934ede commit 9a19f53

File tree

4 files changed

+46
-6
lines changed

4 files changed

+46
-6
lines changed

lib/Dav/Faces/FaceRoot.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
use OCA\Recognize\Db\FaceDetection;
1313
use OCA\Recognize\Db\FaceDetectionMapper;
1414
use OCP\AppFramework\Db\DoesNotExistException;
15+
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
16+
use OCP\DB\Exception;
1517
use OCP\Files\IRootFolder;
1618
use OCP\IPreview;
1719
use OCP\ITagManager;
@@ -57,10 +59,12 @@ public function getName() {
5759
*/
5860
public function setName($name) {
5961
try {
60-
$this->clusterMapper->findByUserAndTitle($this->user->getUID(), $name);
62+
$this->clusterMapper->findByUserAndTitle($this->user->getUID(), basename($name));
6163
throw new Forbidden('Not allowed to create duplicate names');
6264
} catch (DoesNotExistException $e) {
6365
// pass
66+
} catch (MultipleObjectsReturnedException|Exception $e) {
67+
throw $e;
6468
}
6569
$this->cluster->setTitle(basename($name));
6670
$this->clusterMapper->update($this->cluster);

lib/Dav/Faces/FacesHome.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,15 @@ public function setName($name) {
5050
}
5151

5252
public function createDirectory($name) {
53+
if ($this->childExists(basename($name))) {
54+
throw new Forbidden('Not allowed to create duplicate names');
55+
}
56+
if (preg_match('/^[0-9]+$/', basename($name), $matches) != false) {
57+
throw new Forbidden('Not allowed to use numbers as names');
58+
}
5359
$entity = new FaceCluster();
5460
$entity->setUserId($this->user->getUID());
55-
$entity->setTitle($name);
61+
$entity->setTitle(basename($name));
5662
$this->faceClusterMapper->insert($entity);
5763
}
5864

@@ -90,9 +96,9 @@ public function getChild($name) : FaceRoot {
9096
* @throws \OCP\DB\Exception
9197
*/
9298
public function getChildren(): array {
93-
$clusters = $this->faceClusterMapper->findByUserId($this->user->getUID());
94-
$clusters = array_values(array_filter($clusters, fn ($cluster) => count($this->faceDetectionMapper->findByClusterId($cluster->getId())) > 0));
9599
if (count($this->children) === 0) {
100+
$clusters = $this->faceClusterMapper->findByUserId($this->user->getUID());
101+
$clusters = array_values(array_filter($clusters, fn ($cluster) => count($this->faceDetectionMapper->findByClusterId($cluster->getId())) > 0));
96102
$this->children = array_map(function (FaceCluster $cluster) {
97103
return new FaceRoot($this->faceClusterMapper, $cluster, $this->user, $this->faceDetectionMapper, $this->rootFolder, $this->tagManager, $this->previewManager);
98104
}, $clusters);

lib/Dav/Faces/PropFindPlugin.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@
1010
use \OCA\DAV\Connector\Sabre\FilesPlugin;
1111
use \OCA\DAV\Connector\Sabre\TagsPlugin;
1212
use OCA\DAV\Connector\Sabre\File;
13+
use OCA\Recognize\Db\FaceClusterMapper;
1314
use OCA\Recognize\Db\FaceDetectionMapper;
1415
use OCA\Recognize\Db\FaceDetectionWithTitle;
16+
use OCP\AppFramework\Db\DoesNotExistException;
17+
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
18+
use OCP\DB\Exception;
1519
use OCP\Files\DavUtil;
1620
use OCP\IPreview;
21+
use Sabre\DAV\Exception\Forbidden;
1722
use Sabre\DAV\INode;
1823
use Sabre\DAV\PropFind;
1924
use Sabre\DAV\Server;
@@ -31,13 +36,15 @@ final class PropFindPlugin extends ServerPlugin {
3136
public function __construct(
3237
private FaceDetectionMapper $faceDetectionMapper,
3338
private IPreview $previewManager,
39+
private FaceClusterMapper $faceClusterMapper,
3440
) {
3541
}
3642

3743
public function initialize(Server $server) {
3844
$this->server = $server;
3945

4046
$this->server->on('propFind', [$this, 'propFind']);
47+
$this->server->on('beforeMove', [$this, 'beforeMove']);
4148
}
4249

4350

@@ -87,4 +94,23 @@ public function propFind(PropFind $propFind, INode $node) {
8794
});
8895
}
8996
}
97+
98+
public function beforeMove($source, $target) {
99+
// recognize/{userId}/faces/{name}
100+
if (str_starts_with($source, 'recognize') && str_starts_with($target, 'recognize')) {
101+
$sourceParts = explode('/', $source);
102+
$targetParts = explode('/', $target);
103+
if ($sourceParts[2] === 'faces' && $targetParts[2] === 'faces' && count($sourceParts) === 4 && count($targetParts) === 4) {
104+
try {
105+
$this->faceClusterMapper->findByUserAndTitle($targetParts[1], $targetParts[3]);
106+
throw new Forbidden('The target node already exists and cannot be overwritten');
107+
} catch (DoesNotExistException $e) {
108+
return true;
109+
} catch (MultipleObjectsReturnedException|Exception $e) {
110+
throw $e;
111+
}
112+
}
113+
}
114+
return true;
115+
}
90116
}

lib/Db/FaceClusterMapper.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,18 @@ public function findByUserAndTitle(string $userId, string $title) : Entity {
5858
$qb = $this->db->getQueryBuilder();
5959
$qb->select(FaceCluster::$columns)
6060
->from('recognize_face_clusters')
61-
->where($qb->expr()->eq('user_id', $qb->createPositionalParameter($userId)))
62-
->andWhere($qb->expr()->orX(
61+
->where($qb->expr()->eq('user_id', $qb->createPositionalParameter($userId)));
62+
if (preg_match('/^[0-9]+$/', $title, $matches) != false) {
63+
$qb->andWhere($qb->expr()->orX(
6364
$qb->expr()->eq('title', $qb->createPositionalParameter($title)),
6465
$qb->expr()->andX(
6566
$qb->expr()->eq('title', $qb->createPositionalParameter('')),
6667
$qb->expr()->eq('id', $qb->createPositionalParameter((int) $title, IQueryBuilder::PARAM_INT))
6768
)
6869
));
70+
} else {
71+
$qb->andWhere($qb->expr()->eq('title', $qb->createPositionalParameter($title)));
72+
}
6973
return $this->findEntity($qb);
7074
}
7175

0 commit comments

Comments
 (0)