Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/google/cloud/storage/acl.py: 41%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

202 statements  

1# Copyright 2014 Google LLC 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15"""Manage access to objects and buckets.""" 

16 

17from google.cloud.storage._helpers import _add_generation_match_parameters 

18from google.cloud.storage._opentelemetry_tracing import create_trace_span 

19from google.cloud.storage.constants import _DEFAULT_TIMEOUT 

20from google.cloud.storage.retry import DEFAULT_RETRY 

21from google.cloud.storage.retry import DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED 

22 

23 

24class _ACLEntity(object): 

25 """Class representing a set of roles for an entity. 

26 

27 This is a helper class that you likely won't ever construct 

28 outside of using the factor methods on the :class:`ACL` object. 

29 

30 :type entity_type: str 

31 :param entity_type: The type of entity (ie, 'group' or 'user'). 

32 

33 :type identifier: str 

34 :param identifier: (Optional) The ID or e-mail of the entity. For the special 

35 entity types (like 'allUsers'). 

36 """ 

37 

38 READER_ROLE = "READER" 

39 WRITER_ROLE = "WRITER" 

40 OWNER_ROLE = "OWNER" 

41 

42 def __init__(self, entity_type, identifier=None): 

43 self.identifier = identifier 

44 self.roles = set([]) 

45 self.type = entity_type 

46 

47 def __str__(self): 

48 if not self.identifier: 

49 return str(self.type) 

50 else: 

51 return "{acl.type}-{acl.identifier}".format(acl=self) 

52 

53 def __repr__(self): 

54 return f"<ACL Entity: {self} ({', '.join(self.roles)})>" 

55 

56 def get_roles(self): 

57 """Get the list of roles permitted by this entity. 

58 

59 :rtype: list of strings 

60 :returns: The list of roles associated with this entity. 

61 """ 

62 return self.roles 

63 

64 def grant(self, role): 

65 """Add a role to the entity. 

66 

67 :type role: str 

68 :param role: The role to add to the entity. 

69 """ 

70 self.roles.add(role) 

71 

72 def revoke(self, role): 

73 """Remove a role from the entity. 

74 

75 :type role: str 

76 :param role: The role to remove from the entity. 

77 """ 

78 if role in self.roles: 

79 self.roles.remove(role) 

80 

81 def grant_read(self): 

82 """Grant read access to the current entity.""" 

83 self.grant(_ACLEntity.READER_ROLE) 

84 

85 def grant_write(self): 

86 """Grant write access to the current entity.""" 

87 self.grant(_ACLEntity.WRITER_ROLE) 

88 

89 def grant_owner(self): 

90 """Grant owner access to the current entity.""" 

91 self.grant(_ACLEntity.OWNER_ROLE) 

92 

93 def revoke_read(self): 

94 """Revoke read access from the current entity.""" 

95 self.revoke(_ACLEntity.READER_ROLE) 

96 

97 def revoke_write(self): 

98 """Revoke write access from the current entity.""" 

99 self.revoke(_ACLEntity.WRITER_ROLE) 

100 

101 def revoke_owner(self): 

102 """Revoke owner access from the current entity.""" 

103 self.revoke(_ACLEntity.OWNER_ROLE) 

104 

105 

106class ACL(object): 

107 """Container class representing a list of access controls.""" 

108 

109 _URL_PATH_ELEM = "acl" 

110 _PREDEFINED_QUERY_PARAM = "predefinedAcl" 

111 

112 PREDEFINED_XML_ACLS = { 

113 # XML API name -> JSON API name 

114 "project-private": "projectPrivate", 

115 "public-read": "publicRead", 

116 "public-read-write": "publicReadWrite", 

117 "authenticated-read": "authenticatedRead", 

118 "bucket-owner-read": "bucketOwnerRead", 

119 "bucket-owner-full-control": "bucketOwnerFullControl", 

120 } 

121 

122 PREDEFINED_JSON_ACLS = frozenset( 

123 [ 

124 "private", 

125 "projectPrivate", 

126 "publicRead", 

127 "publicReadWrite", 

128 "authenticatedRead", 

129 "bucketOwnerRead", 

130 "bucketOwnerFullControl", 

131 ] 

132 ) 

133 """See 

134 https://cloud.google.com/storage/docs/access-control/lists#predefined-acl 

135 """ 

136 

137 loaded = False 

138 

139 # Subclasses must override to provide these attributes (typically, 

140 # as properties). 

141 reload_path = None 

142 save_path = None 

143 user_project = None 

144 

145 def __init__(self): 

146 self.entities = {} 

147 

148 def _ensure_loaded(self, timeout=_DEFAULT_TIMEOUT): 

149 """Load if not already loaded. 

150 

151 :type timeout: float or tuple 

152 :param timeout: 

153 (Optional) The amount of time, in seconds, to wait 

154 for the server response. See: :ref:`configuring_timeouts` 

155 """ 

156 if not self.loaded: 

157 self.reload(timeout=timeout) 

158 

159 @classmethod 

160 def validate_predefined(cls, predefined): 

161 """Ensures predefined is in list of predefined json values 

162 

163 :type predefined: str 

164 :param predefined: name of a predefined acl 

165 

166 :type predefined: str 

167 :param predefined: validated JSON name of predefined acl 

168 

169 :raises: :exc: `ValueError`: If predefined is not a valid acl 

170 """ 

171 predefined = cls.PREDEFINED_XML_ACLS.get(predefined, predefined) 

172 if predefined and predefined not in cls.PREDEFINED_JSON_ACLS: 

173 raise ValueError(f"Invalid predefined ACL: {predefined}") 

174 return predefined 

175 

176 def reset(self): 

177 """Remove all entities from the ACL, and clear the ``loaded`` flag.""" 

178 self.entities.clear() 

179 self.loaded = False 

180 

181 def __iter__(self): 

182 self._ensure_loaded() 

183 

184 for entity in self.entities.values(): 

185 for role in entity.get_roles(): 

186 if role: 

187 yield {"entity": str(entity), "role": role} 

188 

189 def entity_from_dict(self, entity_dict): 

190 """Build an _ACLEntity object from a dictionary of data. 

191 

192 An entity is a mutable object that represents a list of roles 

193 belonging to either a user or group or the special types for all 

194 users and all authenticated users. 

195 

196 :type entity_dict: dict 

197 :param entity_dict: Dictionary full of data from an ACL lookup. 

198 

199 :rtype: :class:`_ACLEntity` 

200 :returns: An Entity constructed from the dictionary. 

201 """ 

202 entity = entity_dict["entity"] 

203 role = entity_dict["role"] 

204 

205 if entity == "allUsers": 

206 entity = self.all() 

207 

208 elif entity == "allAuthenticatedUsers": 

209 entity = self.all_authenticated() 

210 

211 elif "-" in entity: 

212 entity_type, identifier = entity.split("-", 1) 

213 entity = self.entity(entity_type=entity_type, identifier=identifier) 

214 

215 if not isinstance(entity, _ACLEntity): 

216 raise ValueError(f"Invalid dictionary: {entity_dict}") 

217 

218 entity.grant(role) 

219 return entity 

220 

221 def has_entity(self, entity): 

222 """Returns whether or not this ACL has any entries for an entity. 

223 

224 :type entity: :class:`_ACLEntity` 

225 :param entity: The entity to check for existence in this ACL. 

226 

227 :rtype: bool 

228 :returns: True of the entity exists in the ACL. 

229 """ 

230 self._ensure_loaded() 

231 return str(entity) in self.entities 

232 

233 def get_entity(self, entity, default=None): 

234 """Gets an entity object from the ACL. 

235 

236 :type entity: :class:`_ACLEntity` or string 

237 :param entity: The entity to get lookup in the ACL. 

238 

239 :type default: anything 

240 :param default: This value will be returned if the entity 

241 doesn't exist. 

242 

243 :rtype: :class:`_ACLEntity` 

244 :returns: The corresponding entity or the value provided 

245 to ``default``. 

246 """ 

247 self._ensure_loaded() 

248 return self.entities.get(str(entity), default) 

249 

250 def add_entity(self, entity): 

251 """Add an entity to the ACL. 

252 

253 :type entity: :class:`_ACLEntity` 

254 :param entity: The entity to add to this ACL. 

255 """ 

256 self._ensure_loaded() 

257 self.entities[str(entity)] = entity 

258 

259 def entity(self, entity_type, identifier=None): 

260 """Factory method for creating an Entity. 

261 

262 If an entity with the same type and identifier already exists, 

263 this will return a reference to that entity. If not, it will 

264 create a new one and add it to the list of known entities for 

265 this ACL. 

266 

267 :type entity_type: str 

268 :param entity_type: The type of entity to create 

269 (ie, ``user``, ``group``, etc) 

270 

271 :type identifier: str 

272 :param identifier: The ID of the entity (if applicable). 

273 This can be either an ID or an e-mail address. 

274 

275 :rtype: :class:`_ACLEntity` 

276 :returns: A new Entity or a reference to an existing identical entity. 

277 """ 

278 entity = _ACLEntity(entity_type=entity_type, identifier=identifier) 

279 if self.has_entity(entity): 

280 entity = self.get_entity(entity) 

281 else: 

282 self.add_entity(entity) 

283 return entity 

284 

285 def user(self, identifier): 

286 """Factory method for a user Entity. 

287 

288 :type identifier: str 

289 :param identifier: An id or e-mail for this particular user. 

290 

291 :rtype: :class:`_ACLEntity` 

292 :returns: An Entity corresponding to this user. 

293 """ 

294 return self.entity("user", identifier=identifier) 

295 

296 def group(self, identifier): 

297 """Factory method for a group Entity. 

298 

299 :type identifier: str 

300 :param identifier: An id or e-mail for this particular group. 

301 

302 :rtype: :class:`_ACLEntity` 

303 :returns: An Entity corresponding to this group. 

304 """ 

305 return self.entity("group", identifier=identifier) 

306 

307 def domain(self, domain): 

308 """Factory method for a domain Entity. 

309 

310 :type domain: str 

311 :param domain: The domain for this entity. 

312 

313 :rtype: :class:`_ACLEntity` 

314 :returns: An entity corresponding to this domain. 

315 """ 

316 return self.entity("domain", identifier=domain) 

317 

318 def all(self): 

319 """Factory method for an Entity representing all users. 

320 

321 :rtype: :class:`_ACLEntity` 

322 :returns: An entity representing all users. 

323 """ 

324 return self.entity("allUsers") 

325 

326 def all_authenticated(self): 

327 """Factory method for an Entity representing all authenticated users. 

328 

329 :rtype: :class:`_ACLEntity` 

330 :returns: An entity representing all authenticated users. 

331 """ 

332 return self.entity("allAuthenticatedUsers") 

333 

334 def get_entities(self): 

335 """Get a list of all Entity objects. 

336 

337 :rtype: list of :class:`_ACLEntity` objects 

338 :returns: A list of all Entity objects. 

339 """ 

340 self._ensure_loaded() 

341 return list(self.entities.values()) 

342 

343 @property 

344 def client(self): 

345 """Abstract getter for the object client.""" 

346 raise NotImplementedError 

347 

348 def _require_client(self, client): 

349 """Check client or verify over-ride. 

350 

351 :type client: :class:`~google.cloud.storage.client.Client` or 

352 ``NoneType`` 

353 :param client: the client to use. If not passed, falls back to the 

354 ``client`` stored on the current ACL. 

355 

356 :rtype: :class:`google.cloud.storage.client.Client` 

357 :returns: The client passed in or the currently bound client. 

358 """ 

359 if client is None: 

360 client = self.client 

361 return client 

362 

363 def reload(self, client=None, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY): 

364 """Reload the ACL data from Cloud Storage. 

365 

366 If :attr:`user_project` is set, bills the API request to that project. 

367 

368 :type client: :class:`~google.cloud.storage.client.Client` or 

369 ``NoneType`` 

370 :param client: (Optional) The client to use. If not passed, falls back 

371 to the ``client`` stored on the ACL's parent. 

372 :type timeout: float or tuple 

373 :param timeout: 

374 (Optional) The amount of time, in seconds, to wait 

375 for the server response. See: :ref:`configuring_timeouts` 

376 

377 :type retry: :class:`~google.api_core.retry.Retry` 

378 :param retry: 

379 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

380 """ 

381 with create_trace_span(name="Storage.ACL.reload"): 

382 path = self.reload_path 

383 client = self._require_client(client) 

384 query_params = {} 

385 

386 if self.user_project is not None: 

387 query_params["userProject"] = self.user_project 

388 

389 self.entities.clear() 

390 

391 found = client._get_resource( 

392 path, 

393 query_params=query_params, 

394 timeout=timeout, 

395 retry=retry, 

396 ) 

397 self.loaded = True 

398 

399 for entry in found.get("items", ()): 

400 self.add_entity(self.entity_from_dict(entry)) 

401 

402 def _save( 

403 self, 

404 acl, 

405 predefined, 

406 client, 

407 if_generation_match=None, 

408 if_generation_not_match=None, 

409 if_metageneration_match=None, 

410 if_metageneration_not_match=None, 

411 timeout=_DEFAULT_TIMEOUT, 

412 retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED, 

413 ): 

414 """Helper for :meth:`save` and :meth:`save_predefined`. 

415 

416 :type acl: :class:`google.cloud.storage.acl.ACL`, or a compatible list. 

417 :param acl: The ACL object to save. If left blank, this will save 

418 current entries. 

419 

420 :type predefined: str 

421 :param predefined: An identifier for a predefined ACL. Must be one of the 

422 keys in :attr:`PREDEFINED_JSON_ACLS` If passed, `acl` must be None. 

423 

424 :type client: :class:`~google.cloud.storage.client.Client` or 

425 ``NoneType`` 

426 :param client: (Optional) The client to use. If not passed, falls back 

427 to the ``client`` stored on the ACL's parent. 

428 

429 :type if_generation_match: long 

430 :param if_generation_match: 

431 (Optional) See :ref:`using-if-generation-match` 

432 

433 :type if_generation_not_match: long 

434 :param if_generation_not_match: 

435 (Optional) See :ref:`using-if-generation-not-match` 

436 

437 :type if_metageneration_match: long 

438 :param if_metageneration_match: 

439 (Optional) See :ref:`using-if-metageneration-match` 

440 

441 :type if_metageneration_not_match: long 

442 :param if_metageneration_not_match: 

443 (Optional) See :ref:`using-if-metageneration-not-match` 

444 

445 :type timeout: float or tuple 

446 :param timeout: 

447 (Optional) The amount of time, in seconds, to wait 

448 for the server response. See: :ref:`configuring_timeouts` 

449 

450 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

451 :param retry: 

452 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

453 """ 

454 client = self._require_client(client) 

455 query_params = {"projection": "full"} 

456 

457 if predefined is not None: 

458 acl = [] 

459 query_params[self._PREDEFINED_QUERY_PARAM] = predefined 

460 

461 if self.user_project is not None: 

462 query_params["userProject"] = self.user_project 

463 

464 _add_generation_match_parameters( 

465 query_params, 

466 if_generation_match=if_generation_match, 

467 if_generation_not_match=if_generation_not_match, 

468 if_metageneration_match=if_metageneration_match, 

469 if_metageneration_not_match=if_metageneration_not_match, 

470 ) 

471 

472 path = self.save_path 

473 

474 result = client._patch_resource( 

475 path, 

476 {self._URL_PATH_ELEM: list(acl)}, 

477 query_params=query_params, 

478 timeout=timeout, 

479 retry=retry, 

480 ) 

481 

482 self.entities.clear() 

483 

484 for entry in result.get(self._URL_PATH_ELEM, ()): 

485 self.add_entity(self.entity_from_dict(entry)) 

486 

487 self.loaded = True 

488 

489 def save( 

490 self, 

491 acl=None, 

492 client=None, 

493 if_generation_match=None, 

494 if_generation_not_match=None, 

495 if_metageneration_match=None, 

496 if_metageneration_not_match=None, 

497 timeout=_DEFAULT_TIMEOUT, 

498 retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED, 

499 ): 

500 """Save this ACL for the current bucket. 

501 

502 If :attr:`user_project` is set, bills the API request to that project. 

503 

504 :type acl: :class:`google.cloud.storage.acl.ACL`, or a compatible list. 

505 :param acl: The ACL object to save. If left blank, this will save 

506 current entries. 

507 

508 :type client: :class:`~google.cloud.storage.client.Client` or 

509 ``NoneType`` 

510 :param client: (Optional) The client to use. If not passed, falls back 

511 to the ``client`` stored on the ACL's parent. 

512 

513 :type if_generation_match: long 

514 :param if_generation_match: 

515 (Optional) See :ref:`using-if-generation-match` 

516 

517 :type if_generation_not_match: long 

518 :param if_generation_not_match: 

519 (Optional) See :ref:`using-if-generation-not-match` 

520 

521 :type if_metageneration_match: long 

522 :param if_metageneration_match: 

523 (Optional) See :ref:`using-if-metageneration-match` 

524 

525 :type if_metageneration_not_match: long 

526 :param if_metageneration_not_match: 

527 (Optional) See :ref:`using-if-metageneration-not-match` 

528 

529 :type timeout: float or tuple 

530 :param timeout: 

531 (Optional) The amount of time, in seconds, to wait 

532 for the server response. See: :ref:`configuring_timeouts` 

533 

534 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

535 :param retry: 

536 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

537 """ 

538 with create_trace_span(name="Storage.ACL.save"): 

539 if acl is None: 

540 acl = self 

541 save_to_backend = acl.loaded 

542 else: 

543 save_to_backend = True 

544 

545 if save_to_backend: 

546 self._save( 

547 acl, 

548 None, 

549 client, 

550 if_generation_match=if_generation_match, 

551 if_generation_not_match=if_generation_not_match, 

552 if_metageneration_match=if_metageneration_match, 

553 if_metageneration_not_match=if_metageneration_not_match, 

554 timeout=timeout, 

555 retry=retry, 

556 ) 

557 

558 def save_predefined( 

559 self, 

560 predefined, 

561 client=None, 

562 if_generation_match=None, 

563 if_generation_not_match=None, 

564 if_metageneration_match=None, 

565 if_metageneration_not_match=None, 

566 timeout=_DEFAULT_TIMEOUT, 

567 retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED, 

568 ): 

569 """Save this ACL for the current bucket using a predefined ACL. 

570 

571 If :attr:`user_project` is set, bills the API request to that project. 

572 

573 :type predefined: str 

574 :param predefined: An identifier for a predefined ACL. Must be one 

575 of the keys in :attr:`PREDEFINED_JSON_ACLS` 

576 or :attr:`PREDEFINED_XML_ACLS` (which will be 

577 aliased to the corresponding JSON name). 

578 If passed, `acl` must be None. 

579 

580 :type client: :class:`~google.cloud.storage.client.Client` or 

581 ``NoneType`` 

582 :param client: (Optional) The client to use. If not passed, falls back 

583 to the ``client`` stored on the ACL's parent. 

584 

585 :type if_generation_match: long 

586 :param if_generation_match: 

587 (Optional) See :ref:`using-if-generation-match` 

588 

589 :type if_generation_not_match: long 

590 :param if_generation_not_match: 

591 (Optional) See :ref:`using-if-generation-not-match` 

592 

593 :type if_metageneration_match: long 

594 :param if_metageneration_match: 

595 (Optional) See :ref:`using-if-metageneration-match` 

596 

597 :type if_metageneration_not_match: long 

598 :param if_metageneration_not_match: 

599 (Optional) See :ref:`using-if-metageneration-not-match` 

600 

601 :type timeout: float or tuple 

602 :param timeout: 

603 (Optional) The amount of time, in seconds, to wait 

604 for the server response. See: :ref:`configuring_timeouts` 

605 

606 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

607 :param retry: 

608 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

609 """ 

610 with create_trace_span(name="Storage.ACL.savePredefined"): 

611 predefined = self.validate_predefined(predefined) 

612 self._save( 

613 None, 

614 predefined, 

615 client, 

616 if_generation_match=if_generation_match, 

617 if_generation_not_match=if_generation_not_match, 

618 if_metageneration_match=if_metageneration_match, 

619 if_metageneration_not_match=if_metageneration_not_match, 

620 timeout=timeout, 

621 retry=retry, 

622 ) 

623 

624 def clear( 

625 self, 

626 client=None, 

627 if_generation_match=None, 

628 if_generation_not_match=None, 

629 if_metageneration_match=None, 

630 if_metageneration_not_match=None, 

631 timeout=_DEFAULT_TIMEOUT, 

632 retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED, 

633 ): 

634 """Remove all ACL entries. 

635 

636 If :attr:`user_project` is set, bills the API request to that project. 

637 

638 Note that this won't actually remove *ALL* the rules, but it 

639 will remove all the non-default rules. In short, you'll still 

640 have access to a bucket that you created even after you clear 

641 ACL rules with this method. 

642 

643 :type client: :class:`~google.cloud.storage.client.Client` or 

644 ``NoneType`` 

645 :param client: (Optional) The client to use. If not passed, falls back 

646 to the ``client`` stored on the ACL's parent. 

647 

648 :type if_generation_match: long 

649 :param if_generation_match: 

650 (Optional) See :ref:`using-if-generation-match` 

651 

652 :type if_generation_not_match: long 

653 :param if_generation_not_match: 

654 (Optional) See :ref:`using-if-generation-not-match` 

655 

656 :type if_metageneration_match: long 

657 :param if_metageneration_match: 

658 (Optional) See :ref:`using-if-metageneration-match` 

659 

660 :type if_metageneration_not_match: long 

661 :param if_metageneration_not_match: 

662 (Optional) See :ref:`using-if-metageneration-not-match` 

663 

664 :type timeout: float or tuple 

665 :param timeout: 

666 (Optional) The amount of time, in seconds, to wait 

667 for the server response. See: :ref:`configuring_timeouts` 

668 

669 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

670 :param retry: 

671 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

672 """ 

673 with create_trace_span(name="Storage.ACL.clear"): 

674 self.save( 

675 [], 

676 client=client, 

677 if_generation_match=if_generation_match, 

678 if_generation_not_match=if_generation_not_match, 

679 if_metageneration_match=if_metageneration_match, 

680 if_metageneration_not_match=if_metageneration_not_match, 

681 timeout=timeout, 

682 retry=retry, 

683 ) 

684 

685 

686class BucketACL(ACL): 

687 """An ACL specifically for a bucket. 

688 

689 :type bucket: :class:`google.cloud.storage.bucket.Bucket` 

690 :param bucket: The bucket to which this ACL relates. 

691 """ 

692 

693 def __init__(self, bucket): 

694 super(BucketACL, self).__init__() 

695 self.bucket = bucket 

696 

697 @property 

698 def client(self): 

699 """The client bound to this ACL's bucket.""" 

700 return self.bucket.client 

701 

702 @property 

703 def reload_path(self): 

704 """Compute the path for GET API requests for this ACL.""" 

705 return f"{self.bucket.path}/{self._URL_PATH_ELEM}" 

706 

707 @property 

708 def save_path(self): 

709 """Compute the path for PATCH API requests for this ACL.""" 

710 return self.bucket.path 

711 

712 @property 

713 def user_project(self): 

714 """Compute the user project charged for API requests for this ACL.""" 

715 return self.bucket.user_project 

716 

717 

718class DefaultObjectACL(BucketACL): 

719 """A class representing the default object ACL for a bucket.""" 

720 

721 _URL_PATH_ELEM = "defaultObjectAcl" 

722 _PREDEFINED_QUERY_PARAM = "predefinedDefaultObjectAcl" 

723 

724 

725class ObjectACL(ACL): 

726 """An ACL specifically for a Cloud Storage object / blob. 

727 

728 :type blob: :class:`google.cloud.storage.blob.Blob` 

729 :param blob: The blob that this ACL corresponds to. 

730 """ 

731 

732 def __init__(self, blob): 

733 super(ObjectACL, self).__init__() 

734 self.blob = blob 

735 

736 @property 

737 def client(self): 

738 """The client bound to this ACL's blob.""" 

739 return self.blob.client 

740 

741 @property 

742 def reload_path(self): 

743 """Compute the path for GET API requests for this ACL.""" 

744 return f"{self.blob.path}/acl" 

745 

746 @property 

747 def save_path(self): 

748 """Compute the path for PATCH API requests for this ACL.""" 

749 return self.blob.path 

750 

751 @property 

752 def user_project(self): 

753 """Compute the user project charged for API requests for this ACL.""" 

754 return self.blob.user_project 

755 

756 def save( 

757 self, 

758 acl=None, 

759 client=None, 

760 if_generation_match=None, 

761 if_generation_not_match=None, 

762 if_metageneration_match=None, 

763 if_metageneration_not_match=None, 

764 timeout=_DEFAULT_TIMEOUT, 

765 retry=DEFAULT_RETRY, 

766 ): 

767 """Save this ACL for the current object. 

768 

769 If :attr:`user_project` is set, bills the API request to that project. 

770 

771 :type acl: :class:`google.cloud.storage.acl.ACL`, or a compatible list. 

772 :param acl: The ACL object to save. If left blank, this will save 

773 current entries. 

774 

775 :type client: :class:`~google.cloud.storage.client.Client` or 

776 ``NoneType`` 

777 :param client: (Optional) The client to use. If not passed, falls back 

778 to the ``client`` stored on the ACL's parent. 

779 

780 :type if_generation_match: long 

781 :param if_generation_match: 

782 (Optional) See :ref:`using-if-generation-match` 

783 

784 :type if_generation_not_match: long 

785 :param if_generation_not_match: 

786 (Optional) See :ref:`using-if-generation-not-match` 

787 

788 :type if_metageneration_match: long 

789 :param if_metageneration_match: 

790 (Optional) See :ref:`using-if-metageneration-match` 

791 

792 :type if_metageneration_not_match: long 

793 :param if_metageneration_not_match: 

794 (Optional) See :ref:`using-if-metageneration-not-match` 

795 

796 :type timeout: float or tuple 

797 :param timeout: 

798 (Optional) The amount of time, in seconds, to wait 

799 for the server response. See: :ref:`configuring_timeouts` 

800 

801 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

802 :param retry: 

803 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

804 """ 

805 super().save( 

806 acl=acl, 

807 client=client, 

808 if_generation_match=if_generation_match, 

809 if_generation_not_match=if_generation_not_match, 

810 if_metageneration_match=if_metageneration_match, 

811 if_metageneration_not_match=if_metageneration_not_match, 

812 timeout=timeout, 

813 retry=retry, 

814 ) 

815 

816 def save_predefined( 

817 self, 

818 predefined, 

819 client=None, 

820 if_generation_match=None, 

821 if_generation_not_match=None, 

822 if_metageneration_match=None, 

823 if_metageneration_not_match=None, 

824 timeout=_DEFAULT_TIMEOUT, 

825 retry=DEFAULT_RETRY, 

826 ): 

827 """Save this ACL for the current object using a predefined ACL. 

828 

829 If :attr:`user_project` is set, bills the API request to that project. 

830 

831 :type predefined: str 

832 :param predefined: An identifier for a predefined ACL. Must be one 

833 of the keys in :attr:`PREDEFINED_JSON_ACLS` 

834 or :attr:`PREDEFINED_XML_ACLS` (which will be 

835 aliased to the corresponding JSON name). 

836 If passed, `acl` must be None. 

837 

838 :type client: :class:`~google.cloud.storage.client.Client` or 

839 ``NoneType`` 

840 :param client: (Optional) The client to use. If not passed, falls back 

841 to the ``client`` stored on the ACL's parent. 

842 

843 :type if_generation_match: long 

844 :param if_generation_match: 

845 (Optional) See :ref:`using-if-generation-match` 

846 

847 :type if_generation_not_match: long 

848 :param if_generation_not_match: 

849 (Optional) See :ref:`using-if-generation-not-match` 

850 

851 :type if_metageneration_match: long 

852 :param if_metageneration_match: 

853 (Optional) See :ref:`using-if-metageneration-match` 

854 

855 :type if_metageneration_not_match: long 

856 :param if_metageneration_not_match: 

857 (Optional) See :ref:`using-if-metageneration-not-match` 

858 

859 :type timeout: float or tuple 

860 :param timeout: 

861 (Optional) The amount of time, in seconds, to wait 

862 for the server response. See: :ref:`configuring_timeouts` 

863 

864 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

865 :param retry: 

866 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

867 """ 

868 super().save_predefined( 

869 predefined=predefined, 

870 client=client, 

871 if_generation_match=if_generation_match, 

872 if_generation_not_match=if_generation_not_match, 

873 if_metageneration_match=if_metageneration_match, 

874 if_metageneration_not_match=if_metageneration_not_match, 

875 timeout=timeout, 

876 retry=retry, 

877 ) 

878 

879 def clear( 

880 self, 

881 client=None, 

882 if_generation_match=None, 

883 if_generation_not_match=None, 

884 if_metageneration_match=None, 

885 if_metageneration_not_match=None, 

886 timeout=_DEFAULT_TIMEOUT, 

887 retry=DEFAULT_RETRY, 

888 ): 

889 """Remove all ACL entries. 

890 

891 If :attr:`user_project` is set, bills the API request to that project. 

892 

893 Note that this won't actually remove *ALL* the rules, but it 

894 will remove all the non-default rules. In short, you'll still 

895 have access to a bucket that you created even after you clear 

896 ACL rules with this method. 

897 

898 :type client: :class:`~google.cloud.storage.client.Client` or 

899 ``NoneType`` 

900 :param client: (Optional) The client to use. If not passed, falls back 

901 to the ``client`` stored on the ACL's parent. 

902 

903 :type if_generation_match: long 

904 :param if_generation_match: 

905 (Optional) See :ref:`using-if-generation-match` 

906 

907 :type if_generation_not_match: long 

908 :param if_generation_not_match: 

909 (Optional) See :ref:`using-if-generation-not-match` 

910 

911 :type if_metageneration_match: long 

912 :param if_metageneration_match: 

913 (Optional) See :ref:`using-if-metageneration-match` 

914 

915 :type if_metageneration_not_match: long 

916 :param if_metageneration_not_match: 

917 (Optional) See :ref:`using-if-metageneration-not-match` 

918 

919 :type timeout: float or tuple 

920 :param timeout: 

921 (Optional) The amount of time, in seconds, to wait 

922 for the server response. See: :ref:`configuring_timeouts` 

923 

924 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy 

925 :param retry: 

926 (Optional) How to retry the RPC. See: :ref:`configuring_retries` 

927 """ 

928 super().clear( 

929 client=client, 

930 if_generation_match=if_generation_match, 

931 if_generation_not_match=if_generation_not_match, 

932 if_metageneration_match=if_metageneration_match, 

933 if_metageneration_not_match=if_metageneration_not_match, 

934 timeout=timeout, 

935 retry=retry, 

936 )