diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index dd07adceac..4cebf7962e 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -117,22 +117,95 @@ var $loading = this.$el.find('.shareWithLoading'); $loading.removeClass('hidden'); $loading.addClass('inlineblock'); - $.get(OC.filePath('core', 'ajax', 'share.php'), { - fetch: 'getShareWith', - search: search.term.trim(), - limit: 200, - itemShares: OC.Share.itemShares, - itemType: view.model.get('itemType') - }, function (result) { - $loading.addClass('hidden'); - $loading.removeClass('inlineblock'); - if (result.status == 'success' && result.data.length > 0) { - $('.shareWithField').autocomplete("option", "autoFocus", true); - response(result.data); - } else { - response(); + $.get( + OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees', + { + format: 'json', + search: search.term.trim(), + perPage: 200, + itemType: view.model.get('itemType') + }, + function (result) { + $loading.addClass('hidden'); + $loading.removeClass('inlineblock'); + if (result.ocs.meta.statuscode == 100) { + var users = result.ocs.data.exact.users.concat(result.ocs.data.users); + var groups = result.ocs.data.exact.groups.concat(result.ocs.data.groups); + var remotes = result.ocs.data.exact.remotes.concat(result.ocs.data.remotes); + + var usersLength; + var groupsLength; + var remotesLength; + + var i, j; + + //Filter out the current user + usersLength = users.length; + for (i = 0 ; i < usersLength; i++) { + if (users[i].value.shareWith === OC.currentUser) { + users.splice(i, 1); + break; + } + } + + // Filter out the owner of the share + if (view.model.hasReshare()) { + usersLength = users.length; + for (i = 0 ; i < usersLength; i++) { + if (users[i].value.shareWith === view.model.getReshareOwner()) { + users.splice(i, 1); + break; + } + } + } + + var shares = view.model.get('shares'); + var sharesLength = shares.length; + + // Now filter out all sharees that are already shared with + for (i = 0; i < sharesLength; i++) { + var share = shares[i]; + + if (share.share_type === OC.Share.SHARE_TYPE_USER) { + usersLength = users.length; + for (j = 0; j < usersLength; j++) { + if (users[j].value.shareWith === share.share_with) { + users.splice(j, 1); + break; + } + } + } else if (share.share_type === OC.Share.SHARE_TYPE_GROUP) { + groupsLength = groups.length; + for (j = 0; j < groupsLength; j++) { + if (groups[j].value.shareWith === share.share_with) { + groups.splice(j, 1); + break; + } + } + } else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE) { + remotesLength = remotes.length; + for (j = 0; j < remotesLength; j++) { + if (remotes[j].value.shareWith === share.share_with) { + remotes.splice(j, 1); + break; + } + } + } + } + + var suggestions = users.concat(groups).concat(remotes); + + if (suggestions.length > 0) { + $('.shareWithField').autocomplete("option", "autoFocus", true); + response(suggestions); + } else { + response(); + } + } else { + response(); + } } - }).fail(function () { + ).fail(function() { $loading.addClass('hidden'); $loading.removeClass('inlineblock'); OC.Notification.show(t('core', 'An error occured. Please try again')); diff --git a/core/js/tests/specs/sharedialogviewSpec.js b/core/js/tests/specs/sharedialogviewSpec.js index bfd3d98786..63cfe5299a 100644 --- a/core/js/tests/specs/sharedialogviewSpec.js +++ b/core/js/tests/specs/sharedialogviewSpec.js @@ -702,6 +702,7 @@ describe('OC.Share.ShareDialogView', function() { }); }); }); + describe('remote sharing', function() { it('shows remote share info when allowed', function() { configModel.set({ @@ -724,23 +725,336 @@ describe('OC.Share.ShareDialogView', function() { var response = sinon.stub(); dialog.autocompleteHandler({term: 'bob'}, response); var jsonData = JSON.stringify({ - "data": [{"label": "bob", "value": {"shareType": 0, "shareWith": "test"}}], - "status": "success" + 'ocs' : { + 'meta' : { + 'status' : 'success', + 'statuscode' : 100, + 'message' : null + }, + 'data' : { + 'exact' : { + 'users' : [], + 'groups' : [], + 'remotes': [] + }, + 'users' : [{'label': 'bob', 'value': {'shareType': 0, 'shareWith': 'test'}}], + 'groups' : [], + 'remotes': [] + } + } }); fakeServer.requests[0].respond( 200, {'Content-Type': 'application/json'}, jsonData ); - expect(response.calledWithExactly(JSON.parse(jsonData).data)).toEqual(true); + expect(response.calledWithExactly(JSON.parse(jsonData).ocs.data.users)).toEqual(true); expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); }); + describe('filter out', function() { + it('the current user', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'bob'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': 0, + 'shareWith': OC.currentUser + } + }, + { + 'label': 'bobby', + 'value': { + 'shareType': 0, + 'shareWith': 'imbob' + } + } + ], + 'groups': [], + 'remotes': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'bobby', + 'value': {'shareType': 0, 'shareWith': 'imbob'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('the share owner', function () { + shareModel.set({ + reshare: { + uid_owner: 'user1' + }, + shares: [], + permissions: OC.PERMISSION_READ + }); + + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'bob'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': 0, + 'shareWith': 'user1' + } + }, + { + 'label': 'bobby', + 'value': { + 'shareType': 0, + 'shareWith': 'imbob' + } + } + ], + 'groups': [], + 'remotes': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'bobby', + 'value': {'shareType': 0, 'shareWith': 'imbob'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + describe('already shared with', function () { + beforeEach(function() { + shareModel.set({ + reshare: {}, + shares: [{ + id: 100, + item_source: 123, + permissions: 31, + share_type: OC.Share.SHARE_TYPE_USER, + share_with: 'user1', + share_with_displayname: 'User One' + },{ + id: 101, + item_source: 123, + permissions: 31, + share_type: OC.Share.SHARE_TYPE_GROUP, + share_with: 'group', + share_with_displayname: 'group' + },{ + id: 102, + item_source: 123, + permissions: 31, + share_type: OC.Share.SHARE_TYPE_REMOTE, + share_with: 'foo@bar.com/baz', + share_with_displayname: 'foo@bar.com/baz' + + }] + }); + }); + + it('users', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'bob'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [ + { + 'label': 'bob', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'user1' + } + }, + { + 'label': 'bobby', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_USER, + 'shareWith': 'imbob' + } + } + ], + 'groups': [], + 'remotes': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'bobby', + 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('groups', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'group'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [ + { + 'label': 'group', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'group' + } + }, + { + 'label': 'group2', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_GROUP, + 'shareWith': 'group2' + } + } + ], + 'remotes': [] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'group2', + 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group2'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + + it('remotes', function () { + dialog.render(); + var response = sinon.stub(); + dialog.autocompleteHandler({term: 'bob'}, response); + var jsonData = JSON.stringify({ + 'ocs': { + 'meta': { + 'status': 'success', + 'statuscode': 100, + 'message': null + }, + 'data': { + 'exact': { + 'users': [], + 'groups': [], + 'remotes': [] + }, + 'users': [], + 'groups': [], + 'remotes': [ + { + 'label': 'foo@bar.com/baz', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_REMOTE, + 'shareWith': 'foo@bar.com/baz' + } + }, + { + 'label': 'foo2@bar.com/baz', + 'value': { + 'shareType': OC.Share.SHARE_TYPE_REMOTE, + 'shareWith': 'foo2@bar.com/baz' + } + } + ] + } + } + }); + fakeServer.requests[0].respond( + 200, + {'Content-Type': 'application/json'}, + jsonData + ); + expect(response.calledWithExactly([{ + 'label': 'foo2@bar.com/baz', + 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo2@bar.com/baz'} + }])).toEqual(true); + expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); + }); + }); + }); + it('gracefully handles successful ajax call with failure content', function () { dialog.render(); var response = sinon.stub(); dialog.autocompleteHandler({term: 'bob'}, response); - var jsonData = JSON.stringify({"status": "failure"}); + var jsonData = JSON.stringify({ + 'ocs' : { + 'meta' : { + 'status': 'failure', + 'statuscode': 400 + } + } + }); fakeServer.requests[0].respond( 200, {'Content-Type': 'application/json'},