Skip to content

Commit 81d9305

Browse files
authored
feat(ACL): add includeACL flag for Query and fetching (#470)
1 parent 6590963 commit 81d9305

File tree

6 files changed

+83
-34
lines changed

6 files changed

+83
-34
lines changed

src/file.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const s3 = require('./uploader/s3');
55
const AVError = require('./error');
66
const AVRequest = require('./request').request;
77
const Promise = require('./promise');
8-
const { tap } = require('./utils');
8+
const { tap, transformFetchOptions } = require('./utils');
99
const debug = require('debug')('leancloud:file');
1010
const parseBase64 = require('./utils/parse-base64');
1111

@@ -521,14 +521,14 @@ module.exports = function(AV) {
521521
/**
522522
* fetch the file from server. If the server's representation of the
523523
* model differs from its current attributes, they will be overriden,
524-
* @param {AuthOptions} options AuthOptions plus 'keys' and 'include' option.
524+
* @param {Object} fetchOptions Optional options to set 'keys',
525+
* 'include' and 'includeACL' option.
526+
* @param {AuthOptions} options
525527
* @return {Promise} A promise that is fulfilled when the fetch
526528
* completes.
527529
*/
528-
fetch: function(options) {
529-
var options = null;
530-
531-
var request = AVRequest('files', null, this.id, 'GET', options);
530+
fetch: function(fetchOptions, options) {
531+
var request = AVRequest('files', null, this.id, 'GET', transformFetchOptions(fetchOptions), options);
532532
return request.then(this._finishFetch.bind(this));
533533
},
534534
_finishFetch: function(response) {

src/object.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -808,23 +808,17 @@ module.exports = function(AV) {
808808
* Fetch the model from the server. If the server's representation of the
809809
* model differs from its current attributes, they will be overriden,
810810
* triggering a <code>"change"</code> event.
811-
* @param {Object} fetchOptions Optional options to set 'keys' and
812-
* 'include' option.
811+
* @param {Object} fetchOptions Optional options to set 'keys',
812+
* 'include' and 'includeACL' option.
813813
* @param {AuthOptions} options
814814
* @return {Promise} A promise that is fulfilled when the fetch
815815
* completes.
816816
*/
817-
fetch: function(fetchOptions = {}, options) {
818-
if (_.isArray(fetchOptions.keys)) {
819-
fetchOptions.keys = fetchOptions.keys.join(',');
820-
}
821-
if (_.isArray(fetchOptions.include)) {
822-
fetchOptions.include = fetchOptions.include.join(',');
823-
}
817+
fetch: function(fetchOptions, options) {
824818

825819
var self = this;
826820
var request = AVRequest('classes', this.className, this.id, 'GET',
827-
fetchOptions, options);
821+
utils.transformFetchOptions(fetchOptions), options);
828822
return request.then(function(response) {
829823
self._finishFetch(self.parse(response), true);
830824
return self;

src/query.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ module.exports = function(AV) {
197197

198198
if (queryJSON.keys) fetchOptions.keys = queryJSON.keys;
199199
if (queryJSON.include) fetchOptions.include = queryJSON.include;
200+
if (queryJSON.includeACL) fetchOptions.includeACL = queryJSON.includeACL;
200201

201202
return obj.fetch(fetchOptions, options);
202203
},
@@ -216,6 +217,9 @@ module.exports = function(AV) {
216217
if (this._select.length > 0) {
217218
params.keys = this._select.join(",");
218219
}
220+
if (this._includeACL !== undefined) {
221+
params.returnACL = this._includeACL;
222+
}
219223
if (this._limit >= 0) {
220224
params.limit = this._limit;
221225
}
@@ -929,6 +933,16 @@ module.exports = function(AV) {
929933
return this;
930934
},
931935

936+
/**
937+
* Include the ACL.
938+
* @param {Boolean} [value=true] Whether to include the ACL
939+
* @return {AV.Query} Returns the query, so you can chain this call.
940+
*/
941+
includeACL: function(value = true) {
942+
this._includeACL = value;
943+
return this;
944+
},
945+
932946
/**
933947
* Restrict the fields of the returned AV.Objects to include only the
934948
* provided keys. If this is called multiple times, then all of the keys

src/utils/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ const ensureArray = target => {
1313
return [target];
1414
};
1515

16+
const transformFetchOptions = ({ keys, include, includeACL } = {}) => {
17+
const fetchOptions = {};
18+
if (_.isArray(keys)) {
19+
fetchOptions.keys = keys.join(',');
20+
}
21+
if (_.isArray(include)) {
22+
fetchOptions.include = include.join(',');
23+
}
24+
if (includeACL) {
25+
fetchOptions.returnACL = includeACL;
26+
}
27+
return fetchOptions;
28+
};
29+
1630
const getSessionToken = (authOptions) => {
1731
if (authOptions.sessionToken) {
1832
return authOptions.sessionToken;
@@ -29,6 +43,7 @@ const tap = interceptor => value => ((interceptor(value), value));
2943
module.exports = {
3044
isNullOrUndefined,
3145
ensureArray,
46+
transformFetchOptions,
3247
getSessionToken,
3348
tap,
3449
};

test/acl.js

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,42 @@
22

33
var GameScore = AV.Object.extend("GameScore");
44
describe("ObjectACL", function () {
5-
describe("*", function () {
6-
it("set * acl", function () {
7-
var gameScore = new GameScore();
8-
gameScore.set("score", 2);
9-
gameScore.set("playerName", "sdf");
10-
gameScore.set("cheatMode", false);
5+
it("set and fetch acl", function () {
6+
var gameScore = new GameScore();
7+
gameScore.set("score", 2);
8+
gameScore.set("playerName", "sdf");
9+
gameScore.set("cheatMode", false);
1110

12-
var postACL = new AV.ACL();
13-
postACL.setPublicReadAccess(true);
14-
postACL.setPublicWriteAccess(true);
11+
var postACL = new AV.ACL();
12+
postACL.setPublicReadAccess(true);
13+
postACL.setPublicWriteAccess(true);
1514

16-
postACL.setReadAccess("546", true);
17-
postACL.setReadAccess("56238", true);
18-
postACL.setWriteAccess("5a061", true);
19-
postACL.setRoleWriteAccess("r6", true);
20-
gameScore.setACL(postACL);
21-
return gameScore.save().then(result => {
22-
result.id.should.be.ok();
23-
return gameScore.destroy();
15+
postACL.setReadAccess("read-only", true);
16+
postACL.setWriteAccess("write-only", true);
17+
postACL.setRoleWriteAccess("write-only-role", true);
18+
gameScore.setACL(postACL);
19+
return gameScore.save().then(result => {
20+
result.id.should.be.ok();
21+
return AV.Object.createWithoutData('GameScore', result.id).fetch({
22+
includeACL: true,
2423
});
25-
});
24+
}).then(fetchedGameScore => {
25+
const acl = fetchedGameScore.getACL();
26+
acl.should.be.instanceOf(AV.ACL);
27+
acl.getPublicReadAccess().should.eql(true);
28+
acl.getPublicWriteAccess().should.eql(true);
29+
acl.getReadAccess('read-only').should.eql(true);
30+
acl.getWriteAccess('read-only').should.eql(false);
31+
acl.getReadAccess('write-only').should.eql(false);
32+
acl.getWriteAccess('write-only').should.eql(true);
33+
acl.getRoleReadAccess('write-only-role').should.eql(false);
34+
acl.getRoleWriteAccess('write-only-role').should.eql(true);
35+
}).then(
36+
() => gameScore.destroy(),
37+
error => {
38+
gameScore.destroy();
39+
throw error;
40+
}
41+
);
2642
});
2743
});

test/query.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,16 @@ describe('Queries', function () {
208208
});
209209
});
210210

211+
it('includeACL', function () {
212+
return new AV.Query(GameScore)
213+
.includeACL()
214+
.equalTo('objectId', this.gameScore.id)
215+
.find()
216+
.then(([gameScore]) => {
217+
gameScore.getACL().should.be.instanceOf(AV.ACL);
218+
});
219+
});
220+
211221
it('containsAll with an large array should not cause URI too long', () => {
212222
return new AV.Query(GameScore)
213223
.containsAll('arr', new Array(200).fill('contains-all-test'))

0 commit comments

Comments
 (0)