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