Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Show sharing recommendations
Signed-off-by: Christoph Wurst <[email protected]>
  • Loading branch information
ChristophWurst authored and rullzer committed Feb 25, 2019
commit f3023aaa85b8a168d55bd962a241e439e61105d9
4 changes: 2 additions & 2 deletions apps/accessibility/js/accessibility.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/accessibility/js/accessibility.js.map

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions apps/files_sharing/appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@
'url' => '/api/v1/sharees',
'verb' => 'GET',
],
[
'name' => 'ShareesAPI#findRecommended',
'url' => '/api/v1/sharees_recommended',
'verb' => 'GET',
],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document this in the docs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/*
* Remote Shares
*/
Expand Down
158 changes: 157 additions & 1 deletion apps/files_sharing/lib/Controller/ShareesAPIController.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,29 @@
*/
namespace OCA\Files_Sharing\Controller;

use function array_filter;
use function array_slice;
use function array_values;
use Generator;
use OC\Collaboration\Collaborators\SearchResult;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSBadRequestException;
use OCP\AppFramework\OCSController;
use OCP\Collaboration\Collaborators\ISearch;
use OCP\Collaboration\Collaborators\ISearchResult;
use OCP\Collaboration\Collaborators\SearchResultType;
use OCP\IRequest;
use OCP\IConfig;
use OCP\IURLGenerator;
use OCP\Share;
use OCP\Share\IManager;
use function usort;

class ShareesAPIController extends OCSController {

/** @var userId */
protected $userId;

/** @var IConfig */
protected $config;

Expand Down Expand Up @@ -87,6 +99,7 @@ class ShareesAPIController extends OCSController {
private $collaboratorSearch;

/**
* @param string $UserId
* @param string $appName
* @param IRequest $request
* @param IConfig $config
Expand All @@ -95,6 +108,7 @@ class ShareesAPIController extends OCSController {
* @param ISearch $collaboratorSearch
*/
public function __construct(
$UserId,
string $appName,
IRequest $request,
IConfig $config,
Expand All @@ -103,7 +117,7 @@ public function __construct(
ISearch $collaboratorSearch
) {
parent::__construct($appName, $request);

$this->userId = $UserId;
$this->config = $config;
$this->urlGenerator = $urlGenerator;
$this->shareManager = $shareManager;
Expand Down Expand Up @@ -212,6 +226,148 @@ public function search(string $search = '', string $itemType = null, int $page =
return $response;
}

/**
* @param string $user
* @param int $shareType
*
* @return Generator<array<string>>
*/
private function getAllShareesByType(string $user, int $shareType): Generator {
$offset = 0;
$pageSize = 50;

while (count($page = $this->shareManager->getSharesBy(
$user,
$shareType,
null,
false,
$pageSize,
$offset
))) {
foreach ($page as $share) {
yield [$share->getSharedWith(), $share->getSharedWithDisplayName() ?? $share->getSharedWith()];
}

$offset += $pageSize;
}
}

private function sortShareesByFrequency(array $sharees): array {
usort($sharees, function(array $s1, array $s2) {
return $s2['count'] - $s1['count'];
});
return $sharees;
}

private $searchResultTypeMap = [
Share::SHARE_TYPE_USER => 'users',
Share::SHARE_TYPE_GROUP => 'groups',
Share::SHARE_TYPE_REMOTE => 'remotes',
Share::SHARE_TYPE_REMOTE_GROUP => 'remote_groups',
Share::SHARE_TYPE_EMAIL => 'emails',
];

private function getAllSharees(string $user, array $shareTypes): ISearchResult {
$result = [];
foreach ($shareTypes as $shareType) {
$sharees = $this->getAllShareesByType($user, $shareType);
$shareTypeResults = [];
foreach ($sharees as list($sharee, $displayname)) {
if (!isset($this->searchResultTypeMap[$shareType])) {
continue;
}

if (!isset($shareTypeResults[$sharee])) {
$shareTypeResults[$sharee] = [
'count' => 1,
'label' => $displayname,
'value' => [
'shareType' => $shareType,
'shareWith' => $sharee,
],
];
} else {
$shareTypeResults[$sharee]['count']++;
}
}
$result = array_merge($result, array_values($shareTypeResults));
}

$top5 = array_slice(
$this->sortShareesByFrequency($result),
0,
5
);

$searchResult = new SearchResult();
foreach ($this->searchResultTypeMap as $int => $str) {
$searchResult->addResultSet(new SearchResultType($str), [], []);
foreach ($top5 as $x) {
if ($x['value']['shareType'] === $int) {
$searchResult->addResultSet(new SearchResultType($str), [], [$x]);
}
}
}
return $searchResult;
}

/**
* @NoAdminRequired
*
* @param string $itemType
* @return DataResponse
* @throws OCSBadRequestException
*/
public function findRecommended(string $itemType = null, $shareType = null): DataResponse {
$shareTypes = [
Share::SHARE_TYPE_USER,
];

if ($itemType === null) {
throw new OCSBadRequestException('Missing itemType');
} elseif ($itemType === 'file' || $itemType === 'folder') {
if ($this->shareManager->allowGroupSharing()) {
$shareTypes[] = Share::SHARE_TYPE_GROUP;
}

if ($this->isRemoteSharingAllowed($itemType)) {
$shareTypes[] = Share::SHARE_TYPE_REMOTE;
}

if ($this->isRemoteGroupSharingAllowed($itemType)) {
$shareTypes[] = Share::SHARE_TYPE_REMOTE_GROUP;
}

if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
$shareTypes[] = Share::SHARE_TYPE_EMAIL;
}

if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_ROOM)) {
$shareTypes[] = Share::SHARE_TYPE_ROOM;
}
} else {
$shareTypes[] = Share::SHARE_TYPE_GROUP;
$shareTypes[] = Share::SHARE_TYPE_EMAIL;
}

// FIXME: DI
if (\OC::$server->getAppManager()->isEnabledForUser('circles') && class_exists('\OCA\Circles\ShareByCircleProvider')) {
$shareTypes[] = Share::SHARE_TYPE_CIRCLE;
}

if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
$shareTypes = array_intersect($shareTypes, $_GET['shareType']);
sort($shareTypes);
} else if (is_numeric($shareType)) {
$shareTypes = array_intersect($shareTypes, [(int) $shareType]);
sort($shareTypes);
}

return new DataResponse(
$this->getAllSharees($this->userId, $shareTypes)->asArray()
);
}

/**
* Method to get out the static call for better testing
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class ShareesAPIControllerTest extends TestCase {
/** @var ShareesAPIController */
protected $sharees;

/** @var string */
protected $uid;

/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
protected $request;

Expand All @@ -62,6 +65,7 @@ class ShareesAPIControllerTest extends TestCase {
protected function setUp() {
parent::setUp();

$this->uid = 'test123';
$this->request = $this->createMock(IRequest::class);
$this->shareManager = $this->createMock(IManager::class);

Expand All @@ -74,6 +78,7 @@ protected function setUp() {
$this->collaboratorSearch = $this->createMock(ISearch::class);

$this->sharees = new ShareesAPIController(
$this->uid,
'files_sharing',
$this->request,
$configMock,
Expand Down Expand Up @@ -243,6 +248,8 @@ public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEn
->method('allowGroupSharing')
->willReturn($allowGroupSharing);

/** @var string */
$uid = 'test123';
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject $request */
$request = $this->createMock(IRequest::class);
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject $urlGenerator */
Expand All @@ -251,6 +258,7 @@ public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEn
/** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */
$sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController')
->setConstructorArgs([
$uid,
'files_sharing',
$request,
$config,
Expand Down Expand Up @@ -335,6 +343,8 @@ public function testSearchInvalid($getData, $message) {
$config->expects($this->never())
->method('getAppValue');

/** @var string */
$uid = 'test123';
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject $request */
$request = $this->createMock(IRequest::class);
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject $urlGenerator */
Expand All @@ -343,6 +353,7 @@ public function testSearchInvalid($getData, $message) {
/** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */
$sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController')
->setConstructorArgs([
$uid,
'files_sharing',
$request,
$config,
Expand Down
16 changes: 5 additions & 11 deletions apps/twofactor_backupcodes/js/settings.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/twofactor_backupcodes/js/settings.js.map

Large diffs are not rendered by default.

Loading