Search sharees on lookup server when explicitly requested by user

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Christoph Wurst 2019-02-21 21:36:14 +01:00
parent a3d936fbb7
commit e930a0ccbe
No known key found for this signature in database
GPG key ID: CC42AC2A7F0E56D8
11 changed files with 172 additions and 69 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -92,6 +92,7 @@ class ShareesAPIController extends OCSController {
'lookup' => [],
'circles' => [],
'rooms' => [],
'lookupEnabled' => false,
];
protected $reachedEndFor = [];
@ -212,6 +213,7 @@ class ShareesAPIController extends OCSController {
$result['exact'] = array_merge($this->result['exact'], $result['exact']);
}
$this->result = array_merge($this->result, $result);
$this->result['lookupEnabled'] = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'yes') === 'yes';
$response = new DataResponse($this->result);
if ($hasMoreResults) {

View file

@ -38,6 +38,11 @@
opacity: .7;
margin-right: 7px;
}
.icon.search-globally {
width: 32px;
height: 32px;
margin-right: 0;
}
}
.shareTabView {

View file

@ -236,12 +236,13 @@ class ShareesAPIControllerTest extends TestCase {
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject $config */
$config = $this->createMock(IConfig::class);
$config->expects($this->exactly(2))
$config->expects($this->exactly(3))
->method('getAppValue')
->with('core', $this->anything(), $this->anything())
->with($this->anything(), $this->anything(), $this->anything())
->willReturnMap([
['core', 'shareapi_only_share_with_group_members', 'no', $apiSetting],
['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', $enumSetting],
['files_sharing', 'lookupServerEnabled', 'yes', 'yes'],
]);
$this->shareManager->expects($itemType === 'file' || $itemType === 'folder' ? $this->once() : $this->never())

Binary file not shown.

Binary file not shown.

View file

@ -32,6 +32,10 @@
/** @type {boolean} **/
_showLink: true,
_lookup: false,
_lookupAllowed: false,
/** @type {string} **/
tagName: 'div',
@ -125,24 +129,28 @@
/* trigger search after the field was re-selected */
onShareWithFieldFocus: function() {
this.$el.find('.shareWithField').autocomplete("search");
var $shareWithField = this.$el.find('.shareWithField');
$shareWithField.autocomplete("search", $shareWithField.val());
},
_getSuggestions: function(searchTerm, perPage, model) {
_getSuggestions: function(searchTerm, perPage, model, lookup) {
if (this._lastSuggestions &&
this._lastSuggestions.searchTerm === searchTerm &&
this._lastSuggestions.lookup === lookup &&
this._lastSuggestions.perPage === perPage &&
this._lastSuggestions.model === model) {
return this._lastSuggestions.promise;
}
var deferred = $.Deferred();
var view = this;
$.get(
OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees',
{
format: 'json',
search: searchTerm,
lookup: lookup,
perPage: perPage,
itemType: model.get('itemType')
},
@ -300,6 +308,7 @@
var remotes = result.ocs.data.remotes;
var remoteGroups = result.ocs.data.remote_groups;
var lookup = result.ocs.data.lookup;
var lookupEnabled = result.ocs.data.lookupEnabled;
var emails = [];
if (typeof(result.ocs.data.emails) !== 'undefined') {
emails = result.ocs.data.emails;
@ -365,8 +374,17 @@
lookup.length
)
);
if (!view._lookup && lookupEnabled) {
result.push(
{
label: t('core', 'Search globally'),
value: {},
lookup: true
}
)
}
deferred.resolve(result, exactMatches, moreResultsAvailable);
deferred.resolve(result, exactMatches, moreResultsAvailable, lookupEnabled);
} else {
deferred.reject(result.ocs.meta.message);
}
@ -377,6 +395,7 @@
this._lastSuggestions = {
searchTerm: searchTerm,
lookup: lookup,
perPage: perPage,
model: model,
promise: deferred.promise()
@ -641,14 +660,8 @@
var $shareWithField = $('.shareWithField');
this._getRecommendations(
view.model
).done(function(suggestions, exactMatches) {
view._pendingOperationsCount--;
if (view._pendingOperationsCount === 0) {
$loading.addClass('hidden');
$loading.removeClass('inlineblock');
$confirm.removeClass('hidden');
}
).done(function(suggestions) {
console.info('recommendations', suggestions);
if (suggestions.length > 0) {
$shareWithField
.autocomplete("option", "autoFocus", true);
@ -659,13 +672,6 @@
response();
}
}).fail(function(message) {
view._pendingOperationsCount--;
if (view._pendingOperationsCount === 0) {
$loading.addClass('hidden');
$loading.removeClass('inlineblock');
$confirm.removeClass('hidden');
}
console.error('could not load recommendations', message)
});
},
@ -674,6 +680,7 @@
// If nothing is entered we show recommendations instead of search
// results
if (search.term.length === 0) {
console.info(search.term, 'empty search term -> using recommendations');
this.recommendationHandler(response);
return;
}
@ -716,7 +723,8 @@
this._getSuggestions(
search.term.trim(),
perPage,
view.model
view.model,
view._lookup
).done(function(suggestions, exactMatches, moreResultsAvailable) {
view._pendingOperationsCount--;
if (view._pendingOperationsCount === 0) {
@ -747,7 +755,7 @@
.attr('data-original-title', title)
.tooltip('hide')
.tooltip({
placement: 'bottom',
placement: 'top',
trigger: 'manual'
})
.tooltip('fixTitle')
@ -818,6 +826,10 @@
insert.addClass('merged');
text = item.value.shareWith;
description = type;
} else if (item.lookup) {
text = item.label;
icon = false;
insert.append('<span class="icon icon-search search-globally"></span>');
} else {
var avatar = $("<div class='avatardiv'></div>").appendTo(insert);
if (item.value.shareType === OC.Share.SHARE_TYPE_USER || item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) {
@ -843,7 +855,9 @@
)
.appendTo(insert);
insert.attr('title', item.value.shareWith);
insert.append('<span class="icon '+icon+'" title="' + text + '"></span>');
if (icon) {
insert.append('<span class="icon ' + icon + '" title="' + text + '"></span>');
}
insert = $("<a>")
.append(insert);
return $("<li>")
@ -869,6 +883,18 @@
return false;
}
if (s.item.lookup) {
// Retrigger search but with global lookup this time
this._lookup = true;
var $shareWithField = this.$el.find('.shareWithField');
var val = $shareWithField.val();
setTimeout(function() {
console.debug('searching again, but globally. search term: ' + val);
$shareWithField.autocomplete("search", val);
}, 0);
return false;
}
e.preventDefault();
// Ensure that the keydown handler for the input field is not
// called; otherwise it would try to add the recipient again, which
@ -947,12 +973,11 @@
};
var perPage = parseInt(oc_config['sharing.maxAutocompleteResults'], 10) || 200;
var onlyExactMatches = true;
this._getSuggestions(
$shareWithField.val(),
perPage,
this.model,
onlyExactMatches
this._lookup
).done(function(suggestions, exactMatches) {
if (suggestions.length === 0) {
restoreUI();

View file

@ -350,7 +350,8 @@ describe('OC.Share.ShareDialogView', function() {
'groups': [],
'remotes': [],
'remote_groups': [],
'lookup': []
'lookup': [],
'lookupEnabled': true,
}
}
});
@ -365,7 +366,11 @@ describe('OC.Share.ShareDialogView', function() {
);
expect(doneStub.calledOnce).toEqual(true);
expect(doneStub.calledWithExactly([], [], false)).toEqual(true);
sinon.assert.calledWithExactly(doneStub, [{
label: t('core', 'Search globally'),
value: {},
lookup: true
}], [], false, true);
expect(failStub.called).toEqual(false);
});
@ -401,7 +406,8 @@ describe('OC.Share.ShareDialogView', function() {
'groups': [],
'remotes': [],
'remote_groups': [],
'lookup': []
'lookup': [],
'lookupEnabled': true,
}
}
});
@ -416,14 +422,20 @@ describe('OC.Share.ShareDialogView', function() {
);
expect(doneStub.calledOnce).toEqual(true);
expect(doneStub.calledWithExactly(
sinon.assert.calledWithExactly(doneStub,
[{
'label': 'bobby',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'}
},
{
label: t('core', 'Search globally'),
value: {},
lookup: true
}],
[],
false
)).toEqual(true);
false,
true
);
expect(failStub.called).toEqual(false);
});
it('single exact match', function() {
@ -458,7 +470,8 @@ describe('OC.Share.ShareDialogView', function() {
'groups': [],
'remotes': [],
'remote_groups': [],
'lookup': []
'lookup': [],
'lookupEnabled': true,
}
}
});
@ -473,17 +486,23 @@ describe('OC.Share.ShareDialogView', function() {
);
expect(doneStub.calledOnce).toEqual(true);
expect(doneStub.calledWithExactly(
sinon.assert.calledWithExactly(doneStub,
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
},
{
label: t('core', 'Search globally'),
value: {},
lookup: true
}],
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
}],
false
)).toEqual(true);
false,
true
);
expect(failStub.called).toEqual(false);
});
it('mixed matches', function() {
@ -549,7 +568,8 @@ describe('OC.Share.ShareDialogView', function() {
],
'remotes': [],
'remote_groups': [],
'lookup': []
'lookup': [],
'lookupEnabled': true
}
}
});
@ -564,7 +584,7 @@ describe('OC.Share.ShareDialogView', function() {
);
expect(doneStub.calledOnce).toEqual(true);
expect(doneStub.calledWithExactly(
sinon.assert.calledWithExactly(doneStub,
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
@ -580,6 +600,11 @@ describe('OC.Share.ShareDialogView', function() {
}, {
'label': 'bobfans',
'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'fans'}
},
{
label: t('core', 'Search globally'),
value: {},
lookup: true
}],
[{
'label': 'bob',
@ -588,8 +613,9 @@ describe('OC.Share.ShareDialogView', function() {
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'}
}],
false
)).toEqual(true);
false,
true
);
expect(failStub.called).toEqual(false);
});
@ -657,7 +683,8 @@ describe('OC.Share.ShareDialogView', function() {
],
'remotes': [],
'remote_groups': [],
'lookup': []
'lookup': [],
'lookupEnabled': true
}
}
});
@ -672,7 +699,7 @@ describe('OC.Share.ShareDialogView', function() {
);
expect(doneStub.calledOnce).toEqual(true);
expect(doneStub.calledWithExactly(
sinon.assert.calledWithExactly(doneStub,
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
@ -688,6 +715,11 @@ describe('OC.Share.ShareDialogView', function() {
}, {
'label': 'bobfans',
'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'fans'}
},
{
label: t('core', 'Search globally'),
value: {},
lookup: true
}],
[{
'label': 'bob',
@ -696,8 +728,9 @@ describe('OC.Share.ShareDialogView', function() {
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'}
}],
true,
true
)).toEqual(true);
);
expect(failStub.called).toEqual(false);
});
@ -733,7 +766,8 @@ describe('OC.Share.ShareDialogView', function() {
'groups': [],
'remotes': [],
'remote_groups': [],
'lookup': []
'lookup': [],
'lookupEnabled': true
}
}
});
@ -752,11 +786,18 @@ describe('OC.Share.ShareDialogView', function() {
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
}], [{
},
{
label: t('core', 'Search globally'),
value: {},
lookup: true
}],
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
}],
false
false,
true
)).toEqual(true);
expect(failStub.called).toEqual(false);
@ -769,17 +810,23 @@ describe('OC.Share.ShareDialogView', function() {
expect(failStub.called).toEqual(false);
expect(done2Stub.calledOnce).toEqual(true);
expect(done2Stub.calledWithExactly(
sinon.assert.calledWithExactly(doneStub,
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
},
{
label: t('core', 'Search globally'),
value: {},
lookup: true
}],
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
}],
false
)).toEqual(true);
false,
true
);
expect(fail2Stub.called).toEqual(false);
});
@ -815,7 +862,8 @@ describe('OC.Share.ShareDialogView', function() {
'groups': [],
'remotes': [],
'remote_groups': [],
'lookup': []
'lookup': [],
'lookupEnabled': true
}
}
});
@ -830,17 +878,23 @@ describe('OC.Share.ShareDialogView', function() {
);
expect(doneStub.calledOnce).toEqual(true);
expect(doneStub.calledWithExactly(
sinon.assert.calledWithExactly(doneStub,
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
},
{
label: t('core', 'Search globally'),
value: {},
lookup: true
}],
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
}],
false
)).toEqual(true);
false,
true
);
expect(failStub.called).toEqual(false);
var done2Stub = sinon.stub();
@ -880,17 +934,23 @@ describe('OC.Share.ShareDialogView', function() {
expect(fail2Stub.called).toEqual(false);
expect(done3Stub.calledOnce).toEqual(true);
expect(done3Stub.calledWithExactly(
sinon.assert.calledWithExactly(done3Stub,
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
},
{
label: t('core', 'Search globally'),
value: {},
lookup: true
}],
[{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
}],
false
)).toEqual(true);
false,
true
);
expect(fail3Stub.called).toEqual(false);
});
});
@ -944,7 +1004,8 @@ describe('OC.Share.ShareDialogView', function() {
'groups': [],
'remotes': [],
'remote_groups': [],
'lookup': []
'lookup': [],
'lookupEnabled': true
}
}
});
@ -953,13 +1014,17 @@ describe('OC.Share.ShareDialogView', function() {
{'Content-Type': 'application/json'},
jsonData
);
expect(response.calledWithExactly([{
sinon.assert.calledWithExactly(response, [{
'label': 'bob',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'}
}, {
'label': 'bobby',
'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'}
}])).toEqual(true);
}, {
label: t('core', 'Search globally'),
value: {},
lookup: true
}]);
expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
});
@ -1001,7 +1066,8 @@ describe('OC.Share.ShareDialogView', function() {
],
'remotes': [],
'remote_groups': [],
'lookup': []
'lookup': [],
'lookupEnabled': true
}
}
});
@ -1010,13 +1076,17 @@ describe('OC.Share.ShareDialogView', function() {
{'Content-Type': 'application/json'},
jsonData
);
expect(response.calledWithExactly([{
sinon.assert.calledWithExactly(response, [{
'label': 'group',
'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group'}
}, {
'label': 'group2',
'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group2'}
}])).toEqual(true);
}, {
label: t('core', 'Search globally'),
value: {},
lookup: true
}]);
expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
});

View file

@ -62,7 +62,7 @@ class LookupPlugin implements ISearchPlugin {
public function search($search, $limit, $offset, ISearchResult $searchResult) {
$isGlobalScaleEnabled = $this->config->getSystemValue('gs.enabled', false);
$isLookupServerEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no') === 'yes';
$isLookupServerEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'yes') === 'yes';
$hasInternetConnection = (bool)$this->config->getSystemValue('has_internet_connection', true);
// if case of Global Scale we always search the lookup server

View file

@ -90,7 +90,7 @@ class LookupPluginTest extends TestCase {
public function testSearchNoLookupServerURI() {
$this->config->expects($this->once())
->method('getAppValue')
->with('files_sharing', 'lookupServerEnabled', 'no')
->with('files_sharing', 'lookupServerEnabled', 'yes')
->willReturn('yes');
$this->config->expects($this->at(0))
->method('getSystemValue')
@ -118,7 +118,7 @@ class LookupPluginTest extends TestCase {
public function testSearchNoInternet() {
$this->config->expects($this->once())
->method('getAppValue')
->with('files_sharing', 'lookupServerEnabled', 'no')
->with('files_sharing', 'lookupServerEnabled', 'yes')
->willReturn('yes');
$this->config->expects($this->at(0))
->method('getSystemValue')
@ -154,7 +154,7 @@ class LookupPluginTest extends TestCase {
$this->config->expects($this->once())
->method('getAppValue')
->with('files_sharing', 'lookupServerEnabled', 'no')
->with('files_sharing', 'lookupServerEnabled', 'yes')
->willReturn('yes');
$this->config->expects($this->at(0))
->method('getSystemValue')
@ -213,7 +213,7 @@ class LookupPluginTest extends TestCase {
$this->config->expects($this->once())
->method('getAppValue')
->with('files_sharing', 'lookupServerEnabled', 'no')
->with('files_sharing', 'lookupServerEnabled', 'yes')
->willReturn($LookupEnabled ? 'yes' : 'no');
$this->config->expects($this->at(0))
->method('getSystemValue')
@ -267,7 +267,7 @@ class LookupPluginTest extends TestCase {
public function testSearchLookupServerDisabled() {
$this->config->expects($this->once())
->method('getAppValue')
->with('files_sharing', 'lookupServerEnabled', 'no')
->with('files_sharing', 'lookupServerEnabled', 'yes')
->willReturn('no');
/** @var ISearchResult|\PHPUnit_Framework_MockObject_MockObject $searchResult */