1 | ;
|
2 | // Copyright 2019 Google LLC
|
3 | //
|
4 | // Licensed under the Apache License, Version 2.0 (the "License");
|
5 | // you may not use this file except in compliance with the License.
|
6 | // You may obtain a copy of the License at
|
7 | //
|
8 | // http://www.apache.org/licenses/LICENSE-2.0
|
9 | //
|
10 | // Unless required by applicable law or agreed to in writing, software
|
11 | // distributed under the License is distributed on an "AS IS" BASIS,
|
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 | // See the License for the specific language governing permissions and
|
14 | // limitations under the License.
|
15 | Object.defineProperty(exports, "__esModule", { value: true });
|
16 | exports.AclRoleAccessorMethods = exports.Acl = void 0;
|
17 | const promisify_1 = require("@google-cloud/promisify");
|
18 | const arrify = require("arrify");
|
19 | /**
|
20 | * Attach functionality to a {@link Storage.acl} instance. This will add an
|
21 | * object for each role group (owners, readers, and writers), with each object
|
22 | * containing methods to add or delete a type of entity.
|
23 | *
|
24 | * As an example, here are a few methods that are created.
|
25 | *
|
26 | * myBucket.acl.readers.deleteGroup('groupId', function(err) {});
|
27 | *
|
28 | * myBucket.acl.owners.addUser('email@example.com', function(err, acl) {});
|
29 | *
|
30 | * myBucket.acl.writers.addDomain('example.com', function(err, acl) {});
|
31 | *
|
32 | * @private
|
33 | */
|
34 | class AclRoleAccessorMethods {
|
35 | constructor() {
|
36 | this.owners = {};
|
37 | this.readers = {};
|
38 | this.writers = {};
|
39 | /**
|
40 | * An object of convenience methods to add or delete owner ACL permissions
|
41 | * for a given entity.
|
42 | *
|
43 | * The supported methods include:
|
44 | *
|
45 | * - `myFile.acl.owners.addAllAuthenticatedUsers`
|
46 | * - `myFile.acl.owners.deleteAllAuthenticatedUsers`
|
47 | * - `myFile.acl.owners.addAllUsers`
|
48 | * - `myFile.acl.owners.deleteAllUsers`
|
49 | * - `myFile.acl.owners.addDomain`
|
50 | * - `myFile.acl.owners.deleteDomain`
|
51 | * - `myFile.acl.owners.addGroup`
|
52 | * - `myFile.acl.owners.deleteGroup`
|
53 | * - `myFile.acl.owners.addProject`
|
54 | * - `myFile.acl.owners.deleteProject`
|
55 | * - `myFile.acl.owners.addUser`
|
56 | * - `myFile.acl.owners.deleteUser`
|
57 | *
|
58 | * @name Acl#owners
|
59 | *
|
60 | * @example
|
61 | * const storage = require('@google-cloud/storage')();
|
62 | * const myBucket = storage.bucket('my-bucket');
|
63 | * const myFile = myBucket.file('my-file');
|
64 | *
|
65 | * //-
|
66 | * // Add a user as an owner of a file.
|
67 | * //-
|
68 | * const myBucket = gcs.bucket('my-bucket');
|
69 | * const myFile = myBucket.file('my-file');
|
70 | * myFile.acl.owners.addUser('email@example.com', function(err, aclObject)
|
71 | * {});
|
72 | *
|
73 | * //-
|
74 | * // For reference, the above command is the same as running the following.
|
75 | * //-
|
76 | * myFile.acl.add({
|
77 | * entity: 'user-email@example.com',
|
78 | * role: gcs.acl.OWNER_ROLE
|
79 | * }, function(err, aclObject) {});
|
80 | *
|
81 | * //-
|
82 | * // If the callback is omitted, we'll return a Promise.
|
83 | * //-
|
84 | * myFile.acl.owners.addUser('email@example.com').then(function(data) {
|
85 | * const aclObject = data[0];
|
86 | * const apiResponse = data[1];
|
87 | * });
|
88 | */
|
89 | this.owners = {};
|
90 | /**
|
91 | * An object of convenience methods to add or delete reader ACL permissions
|
92 | * for a given entity.
|
93 | *
|
94 | * The supported methods include:
|
95 | *
|
96 | * - `myFile.acl.readers.addAllAuthenticatedUsers`
|
97 | * - `myFile.acl.readers.deleteAllAuthenticatedUsers`
|
98 | * - `myFile.acl.readers.addAllUsers`
|
99 | * - `myFile.acl.readers.deleteAllUsers`
|
100 | * - `myFile.acl.readers.addDomain`
|
101 | * - `myFile.acl.readers.deleteDomain`
|
102 | * - `myFile.acl.readers.addGroup`
|
103 | * - `myFile.acl.readers.deleteGroup`
|
104 | * - `myFile.acl.readers.addProject`
|
105 | * - `myFile.acl.readers.deleteProject`
|
106 | * - `myFile.acl.readers.addUser`
|
107 | * - `myFile.acl.readers.deleteUser`
|
108 | *
|
109 | * @name Acl#readers
|
110 | *
|
111 | * @example
|
112 | * const storage = require('@google-cloud/storage')();
|
113 | * const myBucket = storage.bucket('my-bucket');
|
114 | * const myFile = myBucket.file('my-file');
|
115 | *
|
116 | * //-
|
117 | * // Add a user as a reader of a file.
|
118 | * //-
|
119 | * myFile.acl.readers.addUser('email@example.com', function(err, aclObject)
|
120 | * {});
|
121 | *
|
122 | * //-
|
123 | * // For reference, the above command is the same as running the following.
|
124 | * //-
|
125 | * myFile.acl.add({
|
126 | * entity: 'user-email@example.com',
|
127 | * role: gcs.acl.READER_ROLE
|
128 | * }, function(err, aclObject) {});
|
129 | *
|
130 | * //-
|
131 | * // If the callback is omitted, we'll return a Promise.
|
132 | * //-
|
133 | * myFile.acl.readers.addUser('email@example.com').then(function(data) {
|
134 | * const aclObject = data[0];
|
135 | * const apiResponse = data[1];
|
136 | * });
|
137 | */
|
138 | this.readers = {};
|
139 | /**
|
140 | * An object of convenience methods to add or delete writer ACL permissions
|
141 | * for a given entity.
|
142 | *
|
143 | * The supported methods include:
|
144 | *
|
145 | * - `myFile.acl.writers.addAllAuthenticatedUsers`
|
146 | * - `myFile.acl.writers.deleteAllAuthenticatedUsers`
|
147 | * - `myFile.acl.writers.addAllUsers`
|
148 | * - `myFile.acl.writers.deleteAllUsers`
|
149 | * - `myFile.acl.writers.addDomain`
|
150 | * - `myFile.acl.writers.deleteDomain`
|
151 | * - `myFile.acl.writers.addGroup`
|
152 | * - `myFile.acl.writers.deleteGroup`
|
153 | * - `myFile.acl.writers.addProject`
|
154 | * - `myFile.acl.writers.deleteProject`
|
155 | * - `myFile.acl.writers.addUser`
|
156 | * - `myFile.acl.writers.deleteUser`
|
157 | *
|
158 | * @name Acl#writers
|
159 | *
|
160 | * @example
|
161 | * const storage = require('@google-cloud/storage')();
|
162 | * const myBucket = storage.bucket('my-bucket');
|
163 | * const myFile = myBucket.file('my-file');
|
164 | *
|
165 | * //-
|
166 | * // Add a user as a writer of a file.
|
167 | * //-
|
168 | * myFile.acl.writers.addUser('email@example.com', function(err, aclObject)
|
169 | * {});
|
170 | *
|
171 | * //-
|
172 | * // For reference, the above command is the same as running the following.
|
173 | * //-
|
174 | * myFile.acl.add({
|
175 | * entity: 'user-email@example.com',
|
176 | * role: gcs.acl.WRITER_ROLE
|
177 | * }, function(err, aclObject) {});
|
178 | *
|
179 | * //-
|
180 | * // If the callback is omitted, we'll return a Promise.
|
181 | * //-
|
182 | * myFile.acl.writers.addUser('email@example.com').then(function(data) {
|
183 | * const aclObject = data[0];
|
184 | * const apiResponse = data[1];
|
185 | * });
|
186 | */
|
187 | this.writers = {};
|
188 | AclRoleAccessorMethods.roles.forEach(this._assignAccessMethods.bind(this));
|
189 | }
|
190 | _assignAccessMethods(role) {
|
191 | const accessMethods = AclRoleAccessorMethods.accessMethods;
|
192 | const entities = AclRoleAccessorMethods.entities;
|
193 | const roleGroup = role.toLowerCase() + 's';
|
194 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
195 | this[roleGroup] = entities.reduce((acc, entity) => {
|
196 | const isPrefix = entity.charAt(entity.length - 1) === '-';
|
197 | accessMethods.forEach(accessMethod => {
|
198 | let method = accessMethod + entity[0].toUpperCase() + entity.substr(1);
|
199 | if (isPrefix) {
|
200 | method = method.replace('-', '');
|
201 | }
|
202 | // Wrap the parent accessor method (e.g. `add` or `delete`) to avoid the
|
203 | // more complex API of specifying an `entity` and `role`.
|
204 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
205 | acc[method] = (entityId, options, callback) => {
|
206 | let apiEntity;
|
207 | if (typeof options === 'function') {
|
208 | callback = options;
|
209 | options = {};
|
210 | }
|
211 | if (isPrefix) {
|
212 | apiEntity = entity + entityId;
|
213 | }
|
214 | else {
|
215 | // If the entity is not a prefix, it is a special entity group
|
216 | // that does not require further details. The accessor methods
|
217 | // only accept a callback.
|
218 | apiEntity = entity;
|
219 | callback = entityId;
|
220 | }
|
221 | options = Object.assign({
|
222 | entity: apiEntity,
|
223 | role,
|
224 | }, options);
|
225 | const args = [options];
|
226 | if (typeof callback === 'function') {
|
227 | args.push(callback);
|
228 | }
|
229 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
230 | return this[accessMethod].apply(this, args);
|
231 | };
|
232 | });
|
233 | return acc;
|
234 | }, {});
|
235 | }
|
236 | }
|
237 | exports.AclRoleAccessorMethods = AclRoleAccessorMethods;
|
238 | AclRoleAccessorMethods.accessMethods = ['add', 'delete'];
|
239 | AclRoleAccessorMethods.entities = [
|
240 | // Special entity groups that do not require further specification.
|
241 | 'allAuthenticatedUsers',
|
242 | 'allUsers',
|
243 | // Entity groups that require specification, e.g. `user-email@example.com`.
|
244 | 'domain-',
|
245 | 'group-',
|
246 | 'project-',
|
247 | 'user-',
|
248 | ];
|
249 | AclRoleAccessorMethods.roles = ['OWNER', 'READER', 'WRITER'];
|
250 | /**
|
251 | * Cloud Storage uses access control lists (ACLs) to manage object and
|
252 | * bucket access. ACLs are the mechanism you use to share objects with other
|
253 | * users and allow other users to access your buckets and objects.
|
254 | *
|
255 | * An ACL consists of one or more entries, where each entry grants permissions
|
256 | * to an entity. Permissions define the actions that can be performed against an
|
257 | * object or bucket (for example, `READ` or `WRITE`); the entity defines who the
|
258 | * permission applies to (for example, a specific user or group of users).
|
259 | *
|
260 | * Where an `entity` value is accepted, we follow the format the Cloud Storage
|
261 | * API expects.
|
262 | *
|
263 | * Refer to
|
264 | * https://cloud.google.com/storage/docs/json_api/v1/defaultObjectAccessControls
|
265 | * for the most up-to-date values.
|
266 | *
|
267 | * - `user-userId`
|
268 | * - `user-email`
|
269 | * - `group-groupId`
|
270 | * - `group-email`
|
271 | * - `domain-domain`
|
272 | * - `project-team-projectId`
|
273 | * - `allUsers`
|
274 | * - `allAuthenticatedUsers`
|
275 | *
|
276 | * Examples:
|
277 | *
|
278 | * - The user "liz@example.com" would be `user-liz@example.com`.
|
279 | * - The group "example@googlegroups.com" would be
|
280 | * `group-example@googlegroups.com`.
|
281 | * - To refer to all members of the Google Apps for Business domain
|
282 | * "example.com", the entity would be `domain-example.com`.
|
283 | *
|
284 | * For more detailed information, see
|
285 | * [About Access Control Lists](http://goo.gl/6qBBPO).
|
286 | *
|
287 | * @constructor Acl
|
288 | * @mixin
|
289 | * @param {object} options Configuration options.
|
290 | */
|
291 | class Acl extends AclRoleAccessorMethods {
|
292 | constructor(options) {
|
293 | super();
|
294 | this.pathPrefix = options.pathPrefix;
|
295 | this.request_ = options.request;
|
296 | }
|
297 | /**
|
298 | * @typedef {array} AddAclResponse
|
299 | * @property {object} 0 The Acl Objects.
|
300 | * @property {object} 1 The full API response.
|
301 | */
|
302 | /**
|
303 | * @callback AddAclCallback
|
304 | * @param {?Error} err Request error, if any.
|
305 | * @param {object} acl The Acl Objects.
|
306 | * @param {object} apiResponse The full API response.
|
307 | */
|
308 | /**
|
309 | * Add access controls on a {@link Bucket} or {@link File}.
|
310 | *
|
311 | * @see [BucketAccessControls: insert API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/insert}
|
312 | * @see [ObjectAccessControls: insert API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/insert}
|
313 | *
|
314 | * @param {object} options Configuration options.
|
315 | * @param {string} options.entity Whose permissions will be added.
|
316 | * @param {string} options.role Permissions allowed for the defined entity.
|
317 | * See {@link https://cloud.google.com/storage/docs/access-control Access
|
318 | * Control}.
|
319 | * @param {number} [options.generation] **File Objects Only** Select a specific
|
320 | * revision of this file (as opposed to the latest version, the default).
|
321 | * @param {string} [options.userProject] The ID of the project which will be
|
322 | * billed for the request.
|
323 | * @param {AddAclCallback} [callback] Callback function.
|
324 | * @returns {Promise<AddAclResponse>}
|
325 | *
|
326 | * @example
|
327 | * const storage = require('@google-cloud/storage')();
|
328 | * const myBucket = storage.bucket('my-bucket');
|
329 | * const myFile = myBucket.file('my-file');
|
330 | *
|
331 | * const options = {
|
332 | * entity: 'user-useremail@example.com',
|
333 | * role: gcs.acl.OWNER_ROLE
|
334 | * };
|
335 | *
|
336 | * myBucket.acl.add(options, function(err, aclObject, apiResponse) {});
|
337 | *
|
338 | * //-
|
339 | * // For file ACL operations, you can also specify a `generation` property.
|
340 | * // Here is how you would grant ownership permissions to a user on a
|
341 | * specific
|
342 | * // revision of a file.
|
343 | * //-
|
344 | * myFile.acl.add({
|
345 | * entity: 'user-useremail@example.com',
|
346 | * role: gcs.acl.OWNER_ROLE,
|
347 | * generation: 1
|
348 | * }, function(err, aclObject, apiResponse) {});
|
349 | *
|
350 | * //-
|
351 | * // If the callback is omitted, we'll return a Promise.
|
352 | * //-
|
353 | * myBucket.acl.add(options).then(function(data) {
|
354 | * const aclObject = data[0];
|
355 | * const apiResponse = data[1];
|
356 | * });
|
357 | *
|
358 | * @example <caption>include:samples/acl.js</caption>
|
359 | * region_tag:storage_add_file_owner
|
360 | * Example of adding an owner to a file:
|
361 | *
|
362 | * @example <caption>include:samples/acl.js</caption>
|
363 | * region_tag:storage_add_bucket_owner
|
364 | * Example of adding an owner to a bucket:
|
365 | *
|
366 | * @example <caption>include:samples/acl.js</caption>
|
367 | * region_tag:storage_add_bucket_default_owner
|
368 | * Example of adding a default owner to a bucket:
|
369 | */
|
370 | add(options, callback) {
|
371 | const query = {};
|
372 | if (options.generation) {
|
373 | query.generation = options.generation;
|
374 | }
|
375 | if (options.userProject) {
|
376 | query.userProject = options.userProject;
|
377 | }
|
378 | this.request({
|
379 | method: 'POST',
|
380 | uri: '',
|
381 | qs: query,
|
382 | json: {
|
383 | entity: options.entity,
|
384 | role: options.role.toUpperCase(),
|
385 | },
|
386 | }, (err, resp) => {
|
387 | if (err) {
|
388 | callback(err, null, resp);
|
389 | return;
|
390 | }
|
391 | callback(null, this.makeAclObject_(resp), resp);
|
392 | });
|
393 | }
|
394 | /**
|
395 | * @typedef {array} RemoveAclResponse
|
396 | * @property {object} 0 The full API response.
|
397 | */
|
398 | /**
|
399 | * @callback RemoveAclCallback
|
400 | * @param {?Error} err Request error, if any.
|
401 | * @param {object} apiResponse The full API response.
|
402 | */
|
403 | /**
|
404 | * Delete access controls on a {@link Bucket} or {@link File}.
|
405 | *
|
406 | * @see [BucketAccessControls: delete API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/delete}
|
407 | * @see [ObjectAccessControls: delete API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/delete}
|
408 | *
|
409 | * @param {object} options Configuration object.
|
410 | * @param {string} options.entity Whose permissions will be revoked.
|
411 | * @param {int} [options.generation] **File Objects Only** Select a specific
|
412 | * revision of this file (as opposed to the latest version, the default).
|
413 | * @param {string} [options.userProject] The ID of the project which will be
|
414 | * billed for the request.
|
415 | * @param {RemoveAclCallback} callback The callback function.
|
416 | * @returns {Promise<RemoveAclResponse>}
|
417 | *
|
418 | * @example
|
419 | * const storage = require('@google-cloud/storage')();
|
420 | * const myBucket = storage.bucket('my-bucket');
|
421 | * const myFile = myBucket.file('my-file');
|
422 | *
|
423 | * myBucket.acl.delete({
|
424 | * entity: 'user-useremail@example.com'
|
425 | * }, function(err, apiResponse) {});
|
426 | *
|
427 | * //-
|
428 | * // For file ACL operations, you can also specify a `generation` property.
|
429 | * //-
|
430 | * myFile.acl.delete({
|
431 | * entity: 'user-useremail@example.com',
|
432 | * generation: 1
|
433 | * }, function(err, apiResponse) {});
|
434 | *
|
435 | * //-
|
436 | * // If the callback is omitted, we'll return a Promise.
|
437 | * //-
|
438 | * myFile.acl.delete().then(function(data) {
|
439 | * const apiResponse = data[0];
|
440 | * });
|
441 | *
|
442 | * @example <caption>include:samples/acl.js</caption>
|
443 | * region_tag:storage_remove_bucket_owner
|
444 | * Example of removing an owner from a bucket:
|
445 | *
|
446 | * @example <caption>include:samples/acl.js</caption>
|
447 | * region_tag:storage_remove_bucket_default_owner
|
448 | * Example of removing a default owner from a bucket:
|
449 | *
|
450 | * @example <caption>include:samples/acl.js</caption>
|
451 | * region_tag:storage_remove_file_owner
|
452 | * Example of removing an owner from a bucket:
|
453 | */
|
454 | delete(options, callback) {
|
455 | const query = {};
|
456 | if (options.generation) {
|
457 | query.generation = options.generation;
|
458 | }
|
459 | if (options.userProject) {
|
460 | query.userProject = options.userProject;
|
461 | }
|
462 | this.request({
|
463 | method: 'DELETE',
|
464 | uri: '/' + encodeURIComponent(options.entity),
|
465 | qs: query,
|
466 | }, (err, resp) => {
|
467 | callback(err, resp);
|
468 | });
|
469 | }
|
470 | /**
|
471 | * @typedef {array} GetAclResponse
|
472 | * @property {object|object[]} 0 Single or array of Acl Objects.
|
473 | * @property {object} 1 The full API response.
|
474 | */
|
475 | /**
|
476 | * @callback GetAclCallback
|
477 | * @param {?Error} err Request error, if any.
|
478 | * @param {object|object[]} acl Single or array of Acl Objects.
|
479 | * @param {object} apiResponse The full API response.
|
480 | */
|
481 | /**
|
482 | * Get access controls on a {@link Bucket} or {@link File}. If
|
483 | * an entity is omitted, you will receive an array of all applicable access
|
484 | * controls.
|
485 | *
|
486 | * @see [BucketAccessControls: get API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/get}
|
487 | * @see [ObjectAccessControls: get API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/get}
|
488 | *
|
489 | * @param {object|function} [options] Configuration options. If you want to
|
490 | * receive a list of all access controls, pass the callback function as
|
491 | * the only argument.
|
492 | * @param {string} [options.entity] Whose permissions will be fetched.
|
493 | * @param {number} [options.generation] **File Objects Only** Select a specific
|
494 | * revision of this file (as opposed to the latest version, the default).
|
495 | * @param {string} [options.userProject] The ID of the project which will be
|
496 | * billed for the request.
|
497 | * @param {GetAclCallback} [callback] Callback function.
|
498 | * @returns {Promise<GetAclResponse>}
|
499 | *
|
500 | * @example
|
501 | * const storage = require('@google-cloud/storage')();
|
502 | * const myBucket = storage.bucket('my-bucket');
|
503 | * const myFile = myBucket.file('my-file');
|
504 | *
|
505 | * myBucket.acl.get({
|
506 | * entity: 'user-useremail@example.com'
|
507 | * }, function(err, aclObject, apiResponse) {});
|
508 | *
|
509 | * //-
|
510 | * // Get all access controls.
|
511 | * //-
|
512 | * myBucket.acl.get(function(err, aclObjects, apiResponse) {
|
513 | * // aclObjects = [
|
514 | * // {
|
515 | * // entity: 'user-useremail@example.com',
|
516 | * // role: 'owner'
|
517 | * // }
|
518 | * // ]
|
519 | * });
|
520 | *
|
521 | * //-
|
522 | * // For file ACL operations, you can also specify a `generation` property.
|
523 | * //-
|
524 | * myFile.acl.get({
|
525 | * entity: 'user-useremail@example.com',
|
526 | * generation: 1
|
527 | * }, function(err, aclObject, apiResponse) {});
|
528 | *
|
529 | * //-
|
530 | * // If the callback is omitted, we'll return a Promise.
|
531 | * //-
|
532 | * myBucket.acl.get().then(function(data) {
|
533 | * const aclObject = data[0];
|
534 | * const apiResponse = data[1];
|
535 | * });
|
536 | *
|
537 | * @example <caption>include:samples/acl.js</caption>
|
538 | * region_tag:storage_print_file_acl
|
539 | * Example of printing a file's ACL:
|
540 | *
|
541 | * @example <caption>include:samples/acl.js</caption>
|
542 | * region_tag:storage_print_file_acl_for_user
|
543 | * Example of printing a file's ACL for a specific user:
|
544 | *
|
545 | * @example <caption>include:samples/acl.js</caption>
|
546 | * region_tag:storage_print_bucket_acl
|
547 | * Example of printing a bucket's ACL:
|
548 | *
|
549 | * @example <caption>include:samples/acl.js</caption>
|
550 | * region_tag:storage_print_bucket_acl_for_user
|
551 | * Example of printing a bucket's ACL for a specific user:
|
552 | */
|
553 | get(optionsOrCallback, cb) {
|
554 | const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : null;
|
555 | const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
|
556 | let path = '';
|
557 | const query = {};
|
558 | if (options) {
|
559 | path = '/' + encodeURIComponent(options.entity);
|
560 | if (options.generation) {
|
561 | query.generation = options.generation;
|
562 | }
|
563 | if (options.userProject) {
|
564 | query.userProject = options.userProject;
|
565 | }
|
566 | }
|
567 | this.request({
|
568 | uri: path,
|
569 | qs: query,
|
570 | }, (err, resp) => {
|
571 | if (err) {
|
572 | callback(err, null, resp);
|
573 | return;
|
574 | }
|
575 | let results;
|
576 | if (resp.items) {
|
577 | results = arrify(resp.items).map(this.makeAclObject_);
|
578 | }
|
579 | else {
|
580 | results = this.makeAclObject_(resp);
|
581 | }
|
582 | callback(null, results, resp);
|
583 | });
|
584 | }
|
585 | /**
|
586 | * @typedef {array} UpdateAclResponse
|
587 | * @property {object} 0 The updated Acl Objects.
|
588 | * @property {object} 1 The full API response.
|
589 | */
|
590 | /**
|
591 | * @callback UpdateAclCallback
|
592 | * @param {?Error} err Request error, if any.
|
593 | * @param {object} acl The updated Acl Objects.
|
594 | * @param {object} apiResponse The full API response.
|
595 | */
|
596 | /**
|
597 | * Update access controls on a {@link Bucket} or {@link File}.
|
598 | *
|
599 | * @see [BucketAccessControls: update API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/update}
|
600 | * @see [ObjectAccessControls: update API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/update}
|
601 | *
|
602 | * @param {object} options Configuration options.
|
603 | * @param {string} options.entity Whose permissions will be updated.
|
604 | * @param {string} options.role Permissions allowed for the defined entity.
|
605 | * See {@link Storage.acl}.
|
606 | * @param {number} [options.generation] **File Objects Only** Select a specific
|
607 | * revision of this file (as opposed to the latest version, the default).
|
608 | * @param {string} [options.userProject] The ID of the project which will be
|
609 | * billed for the request.
|
610 | * @param {UpdateAclCallback} [callback] Callback function.
|
611 | * @returns {Promise<UpdateAclResponse>}
|
612 | *
|
613 | * @example
|
614 | * const storage = require('@google-cloud/storage')();
|
615 | * const myBucket = storage.bucket('my-bucket');
|
616 | * const myFile = myBucket.file('my-file');
|
617 | *
|
618 | * const options = {
|
619 | * entity: 'user-useremail@example.com',
|
620 | * role: gcs.acl.WRITER_ROLE
|
621 | * };
|
622 | *
|
623 | * myBucket.acl.update(options, function(err, aclObject, apiResponse) {});
|
624 | *
|
625 | * //-
|
626 | * // For file ACL operations, you can also specify a `generation` property.
|
627 | * //-
|
628 | * myFile.acl.update({
|
629 | * entity: 'user-useremail@example.com',
|
630 | * role: gcs.acl.WRITER_ROLE,
|
631 | * generation: 1
|
632 | * }, function(err, aclObject, apiResponse) {});
|
633 | *
|
634 | * //-
|
635 | * // If the callback is omitted, we'll return a Promise.
|
636 | * //-
|
637 | * myFile.acl.update(options).then(function(data) {
|
638 | * const aclObject = data[0];
|
639 | * const apiResponse = data[1];
|
640 | * });
|
641 | */
|
642 | update(options, callback) {
|
643 | const query = {};
|
644 | if (options.generation) {
|
645 | query.generation = options.generation;
|
646 | }
|
647 | if (options.userProject) {
|
648 | query.userProject = options.userProject;
|
649 | }
|
650 | this.request({
|
651 | method: 'PUT',
|
652 | uri: '/' + encodeURIComponent(options.entity),
|
653 | qs: query,
|
654 | json: {
|
655 | role: options.role.toUpperCase(),
|
656 | },
|
657 | }, (err, resp) => {
|
658 | if (err) {
|
659 | callback(err, null, resp);
|
660 | return;
|
661 | }
|
662 | callback(null, this.makeAclObject_(resp), resp);
|
663 | });
|
664 | }
|
665 | /**
|
666 | * Transform API responses to a consistent object format.
|
667 | *
|
668 | * @private
|
669 | */
|
670 | makeAclObject_(accessControlObject) {
|
671 | const obj = {
|
672 | entity: accessControlObject.entity,
|
673 | role: accessControlObject.role,
|
674 | };
|
675 | if (accessControlObject.projectTeam) {
|
676 | obj.projectTeam = accessControlObject.projectTeam;
|
677 | }
|
678 | return obj;
|
679 | }
|
680 | /**
|
681 | * Patch requests up to the bucket's request object.
|
682 | *
|
683 | * @private
|
684 | *
|
685 | * @param {string} method Action.
|
686 | * @param {string} path Request path.
|
687 | * @param {*} query Request query object.
|
688 | * @param {*} body Request body contents.
|
689 | * @param {function} callback Callback function.
|
690 | */
|
691 | request(reqOpts, callback) {
|
692 | reqOpts.uri = this.pathPrefix + reqOpts.uri;
|
693 | this.request_(reqOpts, callback);
|
694 | }
|
695 | }
|
696 | exports.Acl = Acl;
|
697 | /*! Developer Documentation
|
698 | *
|
699 | * All async methods (except for streams) will return a Promise in the event
|
700 | * that a callback is omitted.
|
701 | */
|
702 | promisify_1.promisifyAll(Acl, {
|
703 | exclude: ['request'],
|
704 | });
|
705 | //# sourceMappingURL=acl.js.map |
\ | No newline at end of file |