Merge pull request #23773 from owncloud/share_move_delete_user_hook
Migrate post_userDelete hook to share manager
This commit is contained in:
commit
0de15a86f0
|
@ -563,4 +563,21 @@ class FederatedShareProvider implements IShareProvider {
|
|||
return $nodes[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* A user is deleted from the system
|
||||
* So clean up the relevant shares.
|
||||
*
|
||||
* @param string $uid
|
||||
* @param int $shareType
|
||||
*/
|
||||
public function userDeleted($uid, $shareType) {
|
||||
//TODO: probabaly a good idea to send unshare info to remote servers
|
||||
|
||||
$qb = $this->dbConnection->getQueryBuilder();
|
||||
|
||||
$qb->delete('share')
|
||||
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)))
|
||||
->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -462,4 +462,52 @@ class FederatedShareProviderTest extends TestCase {
|
|||
$this->assertCount(1, $shares);
|
||||
$this->assertEquals('user2@server.com', $shares[0]->getSharedWith());
|
||||
}
|
||||
|
||||
public function dataDeleteUser() {
|
||||
return [
|
||||
['a', 'b', 'c', 'a', true],
|
||||
['a', 'b', 'c', 'b', false],
|
||||
// The recipient is non local.
|
||||
['a', 'b', 'c', 'c', false],
|
||||
['a', 'b', 'c', 'd', false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataDeleteUser
|
||||
*
|
||||
* @param string $owner The owner of the share (uid)
|
||||
* @param string $initiator The initiator of the share (uid)
|
||||
* @param string $recipient The recipient of the share (uid/gid/pass)
|
||||
* @param string $deletedUser The user that is deleted
|
||||
* @param bool $rowDeleted Is the row deleted in this setup
|
||||
*/
|
||||
public function testDeleteUser($owner, $initiator, $recipient, $deletedUser, $rowDeleted) {
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->insert('share')
|
||||
->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE))
|
||||
->setValue('uid_owner', $qb->createNamedParameter($owner))
|
||||
->setValue('uid_initiator', $qb->createNamedParameter($initiator))
|
||||
->setValue('share_with', $qb->createNamedParameter($recipient))
|
||||
->setValue('item_type', $qb->createNamedParameter('file'))
|
||||
->setValue('item_source', $qb->createNamedParameter(42))
|
||||
->setValue('file_source', $qb->createNamedParameter(42))
|
||||
->execute();
|
||||
|
||||
$id = $qb->getLastInsertId();
|
||||
|
||||
$this->provider->userDeleted($deletedUser, \OCP\Share::SHARE_TYPE_REMOTE);
|
||||
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from('share')
|
||||
->where(
|
||||
$qb->expr()->eq('id', $qb->createNamedParameter($id))
|
||||
);
|
||||
$cursor = $qb->execute();
|
||||
$data = $cursor->fetchAll();
|
||||
$cursor->closeCursor();
|
||||
|
||||
$this->assertCount($rowDeleted ? 0 : 1, $data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -777,7 +777,7 @@ class OC {
|
|||
*/
|
||||
public static function registerShareHooks() {
|
||||
if (\OC::$server->getSystemConfig()->getValue('installed')) {
|
||||
OC_Hook::connect('OC_User', 'post_deleteUser', 'OC\Share\Hooks', 'post_deleteUser');
|
||||
OC_Hook::connect('OC_User', 'post_deleteUser', 'OC\Share20\Hooks', 'post_deleteUser');
|
||||
OC_Hook::connect('OC_User', 'post_addToGroup', 'OC\Share\Hooks', 'post_addToGroup');
|
||||
OC_Hook::connect('OC_Group', 'pre_addToGroup', 'OC\Share\Hooks', 'pre_addToGroup');
|
||||
OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OC\Share\Hooks', 'post_removeFromGroup');
|
||||
|
|
|
@ -28,7 +28,6 @@ use OC\Share20\Exception\ProviderException;
|
|||
use OCP\Share\Exceptions\ShareNotFound;
|
||||
use OC\Share20\Exception\BackendError;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUserManager;
|
||||
|
@ -804,4 +803,68 @@ class DefaultShareProvider implements IShareProvider {
|
|||
return $share;
|
||||
}
|
||||
|
||||
/**
|
||||
* A user is deleted from the system
|
||||
* So clean up the relevant shares.
|
||||
*
|
||||
* @param string $uid
|
||||
* @param int $shareType
|
||||
*/
|
||||
public function userDeleted($uid, $shareType) {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
|
||||
$qb->delete('share');
|
||||
|
||||
if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
|
||||
/*
|
||||
* Delete all user shares that are owned by this user
|
||||
* or that are received by this user
|
||||
*/
|
||||
|
||||
$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)));
|
||||
|
||||
$qb->andWhere(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
|
||||
$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
|
||||
)
|
||||
);
|
||||
} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
|
||||
/*
|
||||
* Delete all group shares that are owned by this user
|
||||
* Or special user group shares that are received by this user
|
||||
*/
|
||||
$qb->where(
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
|
||||
$qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
|
||||
),
|
||||
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
|
||||
)
|
||||
);
|
||||
|
||||
$qb->orWhere(
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)),
|
||||
$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
|
||||
)
|
||||
);
|
||||
} else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
|
||||
/*
|
||||
* Delete all link shares owned by this user.
|
||||
* And all link shares initiated by this user (until #22327 is in)
|
||||
*/
|
||||
$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)));
|
||||
|
||||
$qb->andWhere(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
|
||||
$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$qb->execute();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Roeland Jago Douma <rullzer@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
namespace OC\Share20;
|
||||
|
||||
class Hooks {
|
||||
public static function post_deleteUser($arguments) {
|
||||
\OC::$server->getShareManager()->userDeleted($arguments['uid']);
|
||||
}
|
||||
}
|
|
@ -1018,6 +1018,18 @@ class Manager implements IManager {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function userDeleted($uid) {
|
||||
$types = [\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE];
|
||||
|
||||
foreach ($types as $type) {
|
||||
$provider = $this->factory->getProviderForType($type);
|
||||
$provider->userDeleted($uid, $type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access list to a path. This means
|
||||
* all the users and groups that can access a given path.
|
||||
|
|
|
@ -32,24 +32,6 @@ class Hooks extends \OC\Share\Constants {
|
|||
*/
|
||||
private static $updateTargets = array();
|
||||
|
||||
/**
|
||||
* Function that is called after a user is deleted. Cleans up the shares of that user.
|
||||
* @param array $arguments
|
||||
*/
|
||||
public static function post_deleteUser($arguments) {
|
||||
// Delete any items shared with the deleted user
|
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*share`'
|
||||
.' WHERE `share_with` = ? AND (`share_type` = ? OR `share_type` = ?)');
|
||||
$query->execute(array($arguments['uid'], self::SHARE_TYPE_USER, self::$shareTypeGroupUserUnique));
|
||||
// Delete any items the deleted user shared
|
||||
$query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*share` WHERE `uid_owner` = ?');
|
||||
$result = $query->execute(array($arguments['uid']));
|
||||
while ($item = $result->fetchRow()) {
|
||||
Helper::delete($item['id']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function that is called before a user is added to a group.
|
||||
* check if we need to create a unique target for the user
|
||||
|
|
|
@ -149,6 +149,17 @@ interface IManager {
|
|||
*/
|
||||
public function checkPassword(IShare $share, $password);
|
||||
|
||||
/**
|
||||
* The user with UID is deleted.
|
||||
* All share providers have to cleanup the shares with this user as well
|
||||
* as shares owned by this user.
|
||||
* Shares only initiated by this user are fine.
|
||||
*
|
||||
* @param string $uid
|
||||
* @since 9.1.0
|
||||
*/
|
||||
public function userDeleted($uid);
|
||||
|
||||
/**
|
||||
* Instantiates a new share object. This is to be passed to
|
||||
* createShare.
|
||||
|
|
|
@ -146,4 +146,14 @@ interface IShareProvider {
|
|||
* @since 9.0.0
|
||||
*/
|
||||
public function getShareByToken($token);
|
||||
|
||||
/**
|
||||
* A user is deleted from the system
|
||||
* So clean up the relevant shares.
|
||||
*
|
||||
* @param string $uid
|
||||
* @param int $shareType
|
||||
* @since 9.1.0
|
||||
*/
|
||||
public function userDeleted($uid, $shareType);
|
||||
}
|
||||
|
|
|
@ -1872,4 +1872,131 @@ class DefaultShareProviderTest extends \Test\TestCase {
|
|||
$share = $this->provider->getShareById($id, 'user0');
|
||||
$this->assertSame('/ultraNewTarget', $share->getTarget());
|
||||
}
|
||||
|
||||
public function dataDeleteUser() {
|
||||
return [
|
||||
[\OCP\Share::SHARE_TYPE_USER, 'a', 'b', 'c', 'a', true],
|
||||
[\OCP\Share::SHARE_TYPE_USER, 'a', 'b', 'c', 'b', false],
|
||||
[\OCP\Share::SHARE_TYPE_USER, 'a', 'b', 'c', 'c', true],
|
||||
[\OCP\Share::SHARE_TYPE_USER, 'a', 'b', 'c', 'd', false],
|
||||
[\OCP\Share::SHARE_TYPE_GROUP, 'a', 'b', 'c', 'a', true],
|
||||
[\OCP\Share::SHARE_TYPE_GROUP, 'a', 'b', 'c', 'b', false],
|
||||
// The group c is still valid but user c is deleted so group share stays
|
||||
[\OCP\Share::SHARE_TYPE_GROUP, 'a', 'b', 'c', 'c', false],
|
||||
[\OCP\Share::SHARE_TYPE_GROUP, 'a', 'b', 'c', 'd', false],
|
||||
[\OCP\Share::SHARE_TYPE_LINK, 'a', 'b', 'c', 'a', true],
|
||||
// To avoid invisible link shares delete initiated link shares as well (see #22327)
|
||||
[\OCP\Share::SHARE_TYPE_LINK, 'a', 'b', 'c', 'b', true],
|
||||
[\OCP\Share::SHARE_TYPE_LINK, 'a', 'b', 'c', 'c', false],
|
||||
[\OCP\Share::SHARE_TYPE_LINK, 'a', 'b', 'c', 'd', false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataDeleteUser
|
||||
*
|
||||
* @param int $type The shareType (user/group/link)
|
||||
* @param string $owner The owner of the share (uid)
|
||||
* @param string $initiator The initiator of the share (uid)
|
||||
* @param string $recipient The recipient of the share (uid/gid/pass)
|
||||
* @param string $deletedUser The user that is deleted
|
||||
* @param bool $rowDeleted Is the row deleted in this setup
|
||||
*/
|
||||
public function testDeleteUser($type, $owner, $initiator, $recipient, $deletedUser, $rowDeleted) {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$qb->insert('share')
|
||||
->setValue('share_type', $qb->createNamedParameter($type))
|
||||
->setValue('uid_owner', $qb->createNamedParameter($owner))
|
||||
->setValue('uid_initiator', $qb->createNamedParameter($initiator))
|
||||
->setValue('share_with', $qb->createNamedParameter($recipient))
|
||||
->setValue('item_type', $qb->createNamedParameter('file'))
|
||||
->setValue('item_source', $qb->createNamedParameter(42))
|
||||
->setValue('file_source', $qb->createNamedParameter(42))
|
||||
->execute();
|
||||
|
||||
$id = $qb->getLastInsertId();
|
||||
|
||||
$this->provider->userDeleted($deletedUser, $type);
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from('share')
|
||||
->where(
|
||||
$qb->expr()->eq('id', $qb->createNamedParameter($id))
|
||||
);
|
||||
$cursor = $qb->execute();
|
||||
$data = $cursor->fetchAll();
|
||||
$cursor->closeCursor();
|
||||
|
||||
$this->assertCount($rowDeleted ? 0 : 1, $data);
|
||||
}
|
||||
|
||||
public function dataDeleteUserGroup() {
|
||||
return [
|
||||
['a', 'b', 'c', 'a', true, true],
|
||||
['a', 'b', 'c', 'b', false, false],
|
||||
['a', 'b', 'c', 'c', false, true],
|
||||
['a', 'b', 'c', 'd', false, false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataDeleteUserGroup
|
||||
*
|
||||
* @param string $owner The owner of the share (uid)
|
||||
* @param string $initiator The initiator of the share (uid)
|
||||
* @param string $recipient The recipient of the usergroup share (uid)
|
||||
* @param string $deletedUser The user that is deleted
|
||||
* @param bool $groupShareDeleted
|
||||
* @param bool $userGroupShareDeleted
|
||||
*/
|
||||
public function testDeleteUserGroup($owner, $initiator, $recipient, $deletedUser, $groupShareDeleted, $userGroupShareDeleted) {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$qb->insert('share')
|
||||
->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP))
|
||||
->setValue('uid_owner', $qb->createNamedParameter($owner))
|
||||
->setValue('uid_initiator', $qb->createNamedParameter($initiator))
|
||||
->setValue('share_with', $qb->createNamedParameter('group'))
|
||||
->setValue('item_type', $qb->createNamedParameter('file'))
|
||||
->setValue('item_source', $qb->createNamedParameter(42))
|
||||
->setValue('file_source', $qb->createNamedParameter(42))
|
||||
->execute();
|
||||
$groupId = $qb->getLastInsertId();
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$qb->insert('share')
|
||||
->setValue('share_type', $qb->createNamedParameter(2))
|
||||
->setValue('uid_owner', $qb->createNamedParameter($owner))
|
||||
->setValue('uid_initiator', $qb->createNamedParameter($initiator))
|
||||
->setValue('share_with', $qb->createNamedParameter($recipient))
|
||||
->setValue('item_type', $qb->createNamedParameter('file'))
|
||||
->setValue('item_source', $qb->createNamedParameter(42))
|
||||
->setValue('file_source', $qb->createNamedParameter(42))
|
||||
->execute();
|
||||
$userGroupId = $qb->getLastInsertId();
|
||||
|
||||
$this->provider->userDeleted($deletedUser, \OCP\Share::SHARE_TYPE_GROUP);
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from('share')
|
||||
->where(
|
||||
$qb->expr()->eq('id', $qb->createNamedParameter($userGroupId))
|
||||
);
|
||||
$cursor = $qb->execute();
|
||||
$data = $cursor->fetchAll();
|
||||
$cursor->closeCursor();
|
||||
$this->assertCount($userGroupShareDeleted ? 0 : 1, $data);
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from('share')
|
||||
->where(
|
||||
$qb->expr()->eq('id', $qb->createNamedParameter($groupId))
|
||||
);
|
||||
$cursor = $qb->execute();
|
||||
$data = $cursor->fetchAll();
|
||||
$cursor->closeCursor();
|
||||
$this->assertCount($groupShareDeleted ? 0 : 1, $data);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue