Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate post_groupDelete hook to share manager #23841

Merged
merged 1 commit into from
Apr 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions apps/federatedfilesharing/lib/federatedshareprovider.php
Original file line number Diff line number Diff line change
Expand Up @@ -580,4 +580,14 @@ public function userDeleted($uid, $shareType) {
->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
->execute();
}

/**
* This provider does not handle groups
*
* @param string $gid
*/
public function groupDeleted($gid) {
// We don't handle groups here
return;
}
}
2 changes: 1 addition & 1 deletion lib/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ public static function registerShareHooks() {
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');
OC_Hook::connect('OC_User', 'post_deleteGroup', 'OC\Share\Hooks', 'post_deleteGroup');
OC_Hook::connect('OC_User', 'post_deleteGroup', 'OC\Share20\Hooks', 'post_deleteGroup');
}
}

Expand Down
43 changes: 43 additions & 0 deletions lib/private/Share20/DefaultShareProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -867,4 +867,47 @@ public function userDeleted($uid, $shareType) {

$qb->execute();
}

/**
* Delete all shares received by this group. As well as any custom group
* shares for group members.
*
* @param string $gid
*/
public function groupDeleted($gid) {
/*
* First delete all custom group shares for group members
*/
$qb = $this->dbConn->getQueryBuilder();
$qb->select('id')
->from('share')
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));

$cursor = $qb->execute();
$ids = [];
while($row = $cursor->fetch()) {
$ids[] = (int)$row['id'];
}
$cursor->closeCursor();

if (!empty($ids)) {
$chunks = array_chunk($ids, 100);
foreach ($chunks as $chunk) {
$qb->delete('share')
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
$qb->execute();
}
}

/*
* Now delete all the group shares
*/
$qb = $this->dbConn->getQueryBuilder();
$qb->delete('share')
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
$qb->execute();
}
}
4 changes: 4 additions & 0 deletions lib/private/Share20/Hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ class Hooks {
public static function post_deleteUser($arguments) {
\OC::$server->getShareManager()->userDeleted($arguments['uid']);
}

public static function post_deleteGroup($arguments) {
\OC::$server->getShareManager()->groupDeleted($arguments['gid']);
}
}
8 changes: 8 additions & 0 deletions lib/private/Share20/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,14 @@ public function userDeleted($uid) {
}
}

/**
* @inheritdoc
*/
public function groupDeleted($gid) {
$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
$provider->groupDeleted($gid);
}

/**
* Get access list to a path. This means
* all the users and groups that can access a given path.
Expand Down
13 changes: 0 additions & 13 deletions lib/private/share/hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,17 +161,4 @@ public static function post_removeFromGroup($arguments) {
}
}
}

/**
* Function that is called after a group is removed. Cleans up the shares to that group.
* @param array $arguments
*/
public static function post_deleteGroup($arguments) {
$sql = 'SELECT `id` FROM `*PREFIX*share` WHERE `share_type` = ? AND `share_with` = ?';
$result = \OC_DB::executeAudited($sql, array(self::SHARE_TYPE_GROUP, $arguments['gid']));
while ($item = $result->fetchRow()) {
Helper::delete($item['id']);
}
}

}
9 changes: 9 additions & 0 deletions lib/public/Share/IManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ public function checkPassword(IShare $share, $password);
*/
public function userDeleted($uid);

/**
* The group with $gid is deleted
* We need to clear up all shares to this group
*
* @param $gid
* @since 9.1.0
*/
public function groupDeleted($gid);

/**
* Instantiates a new share object. This is to be passed to
* createShare.
Expand Down
10 changes: 10 additions & 0 deletions lib/public/Share/IShareProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,14 @@ public function getShareByToken($token);
* @since 9.1.0
*/
public function userDeleted($uid, $shareType);

/**
* A group is deleted from the system.
* We have to clean up all shares to this group.
* Providers not handling group shares should just return
*
* @param string $gid
* @since 9.1.0
*/
public function groupDeleted($gid);
}
94 changes: 94 additions & 0 deletions tests/lib/share20/defaultshareprovidertest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1999,4 +1999,98 @@ public function testDeleteUserGroup($owner, $initiator, $recipient, $deletedUser
$cursor->closeCursor();
$this->assertCount($groupShareDeleted ? 0 : 1, $data);
}

public function dataGroupDeleted() {
return [
[
[
'type' => \OCP\Share::SHARE_TYPE_USER,
'recipient' => 'user',
'children' => []
], 'group', false
],
[
[
'type' => \OCP\Share::SHARE_TYPE_USER,
'recipient' => 'user',
'children' => []
], 'user', false
],
[
[
'type' => \OCP\Share::SHARE_TYPE_LINK,
'recipient' => 'user',
'children' => []
], 'group', false
],
[
[
'type' => \OCP\Share::SHARE_TYPE_GROUP,
'recipient' => 'group1',
'children' => [
'foo',
'bar'
]
], 'group2', false
],
[
[
'type' => \OCP\Share::SHARE_TYPE_GROUP,
'recipient' => 'group1',
'children' => [
'foo',
'bar'
]
], 'group1', true
],
];
}

/**
* @dataProvider dataGroupDeleted
*
* @param $shares
* @param $groupToDelete
* @param $shouldBeDeleted
*/
public function testGroupDeleted($shares, $groupToDelete, $shouldBeDeleted) {
$qb = $this->dbConn->getQueryBuilder();
$qb->insert('share')
->setValue('share_type', $qb->createNamedParameter($shares['type']))
->setValue('uid_owner', $qb->createNamedParameter('owner'))
->setValue('uid_initiator', $qb->createNamedParameter('initiator'))
->setValue('share_with', $qb->createNamedParameter($shares['recipient']))
->setValue('item_type', $qb->createNamedParameter('file'))
->setValue('item_source', $qb->createNamedParameter(42))
->setValue('file_source', $qb->createNamedParameter(42))
->execute();
$ids = [$qb->getLastInsertId()];

foreach ($shares['children'] as $child) {
$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($child))
->setValue('item_type', $qb->createNamedParameter('file'))
->setValue('item_source', $qb->createNamedParameter(42))
->setValue('file_source', $qb->createNamedParameter(42))
->setValue('parent', $qb->createNamedParameter($ids[0]))
->execute();
$ids[] = $qb->getLastInsertId();
}

$this->provider->groupDeleted($groupToDelete);

$qb = $this->dbConn->getQueryBuilder();
$cursor = $qb->select('*')
->from('share')
->where($qb->expr()->in('id', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
->execute();
$data = $cursor->fetchAll();
$cursor->closeCursor();

$this->assertCount($shouldBeDeleted ? 0 : count($ids), $data);
}
}