PK���ȼRY��������€��� �v3.phpUT �øŽg‰gñ“gux �õ��õ��½T]kÛ0}߯pEhìâÙM7X‰çv%”v0֐µ{)Aå:6S$!ÉMJèߕ?R÷!>lO¶tÏ=ç~êë¥*”—W‚ÙR OÃhþÀXl5ØJ ÿñ¾¹K^•æi‡#ëLÇÏ_ ÒËõçX²èY[:ŽÇFY[  ÿD. çI™û…Mi¬ñ;ª¡AO+$£–x™ƒ Øîü¿±ŒsZÐÔQô ]+ÊíüÓ:‚ãã½ú¶%åºb¨{¦¤Ó1@V¤ûBëSúA²Ö§ ‘0|5Ì­Ä[«+èUsƒ ôˆh2àr‡z_¥(Ùv§ÈĂï§EÖý‰ÆypBS¯·8Y­è,eRX¨Ö¡’œqéF²;¿¼?Ø?Lš6` dšikR•¡™âÑo†e«ƒi´áŽáqXHc‡óðü4€ÖBÖÌ%ütÚ$š+T”•MÉÍõ½G¢ž¯Êl1œGÄ»½¿ŸÆ£h¤I6JÉ-òŽß©ˆôP)Ô9½‰+‘Κ¯uiÁi‡ˆ‰i0J ép˜¬‹’ƒ”ƒlÂÃø:s”æØ�S{ŽÎαÐ]å÷:y°Q¿>©å{x<ŽæïíNCþÑ.Mf?¨«2ý}=ûõýî'=£§ÿu•Ü(—¾IIa­"éþ@¶�¿ä9?^-qìÇÞôvŠeÈc ðlacã®xèÄ'®âd¶ çˆSEæódP/ÍÆv{Ô)Ó ?>…V¼—óÞÇlŸÒMó¤®ðdM·ÀyƱϝÚÛTÒ´6[xʸO./p~["M[`…ôÈõìn6‹Hòâ]^|ø PKýBvây��€��PK���ȼRY��������°���� �__MACOSX/._v3.phpUT �øŽg‰gþ“gux �õ��õ��c`cg`b`ðMLVðVˆP€'qƒøˆŽ!!AP&HÇ %PDF-1.7 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font << /F1 8 0 R /F2 9 0 R >> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj << /Producer (���d�o�m�p�d�f� �2�.�0�.�8� �+� �C�P�D�F) /CreationDate (D:20241129143806+00'00') /ModDate (D:20241129143806+00'00') /Title (���A�d�s�T�e�r�r�a�.�c�o�m� �i�n�v�o�i�c�e) >> endobj 6 0 obj << /Type /Page /MediaBox [0.000 0.000 595.280 841.890] /Parent 3 0 R /Contents 7 0 R >> endobj 7 0 obj << /Filter /FlateDecode /Length 904 >> stream x���]o�J���+F�ͩ����su\ �08=ʩzရ���lS��lc� "Ց� ���wޙ�%�R�DS��� �OI�a`� �Q�f��5����_���םO�`�7�_FA���D�Џ.j�a=�j����>��n���R+�P��l�rH�{0��w��0��=W�2D ����G���I�>�_B3ed�H�yJ�G>/��ywy�fk��%�$�2.��d_�h����&)b0��"[\B��*_.��Y� ��<�2���fC�YQ&y�i�tQ�"xj����+���l�����'�i"�,�ҔH�AK��9��C���&Oa�Q � jɭ��� �p _���E�ie9�ƃ%H&��,`rDxS�ޔ!�(�X!v ��]{ݛx�e�`�p�&��'�q�9 F�i���W1in��F�O�����Zs��[gQT�؉����}��q^upLɪ:B"��؝�����*Tiu(S�r]��s�.��s9n�N!K!L�M�?�*[��N�8��c��ۯ�b�� ��� �YZ���SR3�n�����lPN��P�;��^�]�!'�z-���ӊ���/��껣��4�l(M�E�QL��X ��~���G��M|�����*��~�;/=N4�-|y�`�i�\�e�T�<���L��G}�"В�J^���q��"X�?(V�ߣXۆ{��H[����P�� �c���kc�Z�9v�����? �a��R�h|��^�k�D4W���?Iӊ�]<��4�)$wdat���~�����������|�L��x�p|N�*��E� �/4�Qpi�x.>��d����,M�y|4^�Ż��8S/޾���uQe���D�y� ��ͧH�����j�wX � �&z� endstream endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj xref 0 10 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000284 00000 n 0000000313 00000 n 0000000514 00000 n 0000000617 00000 n 0000001593 00000 n 0000001700 00000 n trailer << /Size 10 /Root 1 0 R /Info 5 0 R /ID[] >> startxref 1812 %%EOF
Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 131
# -*- coding: utf-8 -*- # Copyright 2016 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Helper module for the IAM command.""" from __future__ import absolute_import from __future__ import print_function from __future__ import division from __future__ import unicode_literals from collections import defaultdict from collections import namedtuple import six from apitools.base.protorpclite import protojson from gslib.exception import CommandException from gslib.third_party.storage_apitools import storage_v1_messages as apitools_messages TYPES = set([ 'user', 'deleted:user', 'serviceAccount', 'deleted:serviceAccount', 'group', 'deleted:group', 'domain', 'principal', 'principalSet', 'principalHierarchy' ]) DISCOURAGED_TYPES = set([ 'projectOwner', 'projectEditor', 'projectViewer', ]) DISCOURAGED_TYPES_MSG = ( 'Assigning roles (e.g. objectCreator, legacyBucketOwner) for project ' 'convenience groups is not supported by gsutil, as it goes against the ' 'principle of least privilege. Consider creating and using more granular ' 'groups with which to assign permissions. See ' 'https://cloud.google.com/iam/docs/using-iam-securely for more ' 'information. Assigning a role to a project group can be achieved by ' 'setting the IAM policy directly (see gsutil help iam for specifics).') PUBLIC_MEMBERS = set([ 'allUsers', 'allAuthenticatedUsers', ]) # These are convenience classes to handle returned results from # BindingStringToTuple. is_grant is a boolean specifying if the # bindings are to be granted or removed from a bucket / object. # bindings varies by type. # For BindingsTuple, it is a list of BindingsValueListEntry # For BindingsDictTuple it is a list of analogous dicts, e.g.: # { # 'members': ['member'], # 'role': 'role', # } BindingsTuple = namedtuple('BindingsTuple', ['is_grant', 'bindings']) BindingsDictTuple = namedtuple('BindingsDictTuple', ['is_grant', 'bindings']) # This is a special role value assigned to a specific member when all roles # assigned to the member should be dropped in the policy. A member:DROP_ALL # binding will be passed from BindingStringToTuple into PatchBindings. # This role will only ever appear on client-side (i.e. user-generated). It # will never be returned as a real role from an IAM get request. All roles # returned by PatchBindings are guaranteed to be "real" roles, i.e. not a # DROP_ALL role. DROP_ALL = '' def SerializeBindingsTuple(bindings_tuple): """Serializes the BindingsValueListEntry instances in a BindingsTuple. This is necessary when passing instances of BindingsTuple through Command.Apply, as apitools_messages classes are not by default pickleable. Args: bindings_tuple: A BindingsTuple instance to be serialized. Returns: A serialized BindingsTuple object. """ return (bindings_tuple.is_grant, [protojson.encode_message(t) for t in bindings_tuple.bindings]) def DeserializeBindingsTuple(serialized_bindings_tuple): (is_grant, bindings) = serialized_bindings_tuple return BindingsTuple(is_grant=is_grant, bindings=[ protojson.decode_message( apitools_messages.Policy.BindingsValueListEntry, t) for t in bindings ]) def BindingsMessageToUpdateDict(bindings): """Reformats policy bindings metadata. Args: bindings: A list of BindingsValueListEntry instances. Returns: A {role: set(members)} dictionary. """ tmp_bindings = defaultdict(set) for binding in bindings: tmp_bindings[binding.role].update(binding.members) return tmp_bindings def BindingsDictToUpdateDict(bindings): """Reformats policy bindings metadata. Args: bindings: List of dictionaries representing BindingsValueListEntry instances. e.g.: { "role": "some_role", "members": ["allAuthenticatedUsers", ...] } Returns: A {role: set(members)} dictionary. """ tmp_bindings = defaultdict(set) for binding in bindings: tmp_bindings[binding['role']].update(binding['members']) return tmp_bindings def IsEqualBindings(a, b): (granted, removed) = DiffBindings(a, b) return not granted.bindings and not removed.bindings def DiffBindings(old, new): """Computes the difference between two BindingsValueListEntry lists. Args: old: The original list of BindingValuesListEntry instances new: The updated list of BindingValuesListEntry instances Returns: A pair of BindingsTuple instances, one for roles granted between old and new, and one for roles removed between old and new. """ tmp_old = BindingsMessageToUpdateDict(old) tmp_new = BindingsMessageToUpdateDict(new) granted = BindingsMessageToUpdateDict([]) removed = BindingsMessageToUpdateDict([]) for (role, members) in six.iteritems(tmp_old): removed[role].update(members.difference(tmp_new[role])) for (role, members) in six.iteritems(tmp_new): granted[role].update(members.difference(tmp_old[role])) granted = [ apitools_messages.Policy.BindingsValueListEntry(role=r, members=list(m)) for (r, m) in six.iteritems(granted) if m ] removed = [ apitools_messages.Policy.BindingsValueListEntry(role=r, members=list(m)) for (r, m) in six.iteritems(removed) if m ] return (BindingsTuple(True, granted), BindingsTuple(False, removed)) def PatchBindings(base, diff, is_grant): """Patches a diff list of BindingsValueListEntry to the base. Will remove duplicate members for any given role on a grant operation. Args: base (dict): A dictionary returned by BindingsMessageToUpdateDict or BindingsDictToUpdateDict representing a resource's current IAM policy. diff (dict): A dictionary returned by BindingsMessageToUpdateDict or BindingsDictToUpdateDict representing the IAM policy bindings to add/remove from `base`. is_grant (bool): True if `diff` should be added to `base`, False if it should be removed from `base`. Returns: A {role: set(members)} dictionary created by applying `diff` to `base`. """ # Patch the diff into base if is_grant: for (role, members) in six.iteritems(diff): if not role: raise CommandException('Role must be specified for a grant request.') base[role].update(members) else: for role in base: base[role].difference_update(diff[role]) # Drop all members with the DROP_ALL role specifed from input. base[role].difference_update(diff[DROP_ALL]) return {role: members for role, members in six.iteritems(base) if members} def BindingStringToTuple(is_grant, input_str): """Parses an iam ch bind string to a list of binding tuples. Args: is_grant: If true, binding is to be appended to IAM policy; else, delete this binding from the policy. input_str: A string representing a member-role binding. e.g. user:foo@bar.com:objectAdmin user:foo@bar.com:objectAdmin,objectViewer user:foo@bar.com allUsers deleted:user:foo@bar.com?uid=123:objectAdmin,objectViewer deleted:serviceAccount:foo@bar.com?uid=123 Raises: CommandException in the case of invalid input. Returns: A BindingsDictTuple instance. """ if not input_str.count(':'): input_str += ':' # Allows user specified PUBLIC_MEMBERS, DISCOURAGED_TYPES, and TYPES to be # case insensitive. tokens = input_str.split(":") public_members = {s.lower(): s for s in PUBLIC_MEMBERS} types = {s.lower(): s for s in TYPES} discouraged_types = {s.lower(): s for s in DISCOURAGED_TYPES} possible_public_member_or_type = tokens[0].lower() possible_type = '%s:%s' % (tokens[0].lower(), tokens[1].lower()) if possible_public_member_or_type in public_members: tokens[0] = public_members[possible_public_member_or_type] elif possible_public_member_or_type in types: tokens[0] = types[possible_public_member_or_type] elif possible_public_member_or_type in discouraged_types: tokens[0] = discouraged_types[possible_public_member_or_type] elif possible_type in types: (tokens[0], tokens[1]) = types[possible_type].split(':') input_str = ":".join(tokens) # We can remove project convenience members, but not add them. removing_discouraged_type = not is_grant and tokens[0] in DISCOURAGED_TYPES if input_str.count(':') == 1: if '%s:%s' % (tokens[0], tokens[1]) in TYPES: raise CommandException('Incorrect public member type for binding %s' % input_str) elif tokens[0] in PUBLIC_MEMBERS: (member, roles) = tokens elif tokens[0] in TYPES or removing_discouraged_type: member = input_str roles = DROP_ALL else: raise CommandException('Incorrect public member type for binding %s' % input_str) elif input_str.count(':') == 2: if '%s:%s' % (tokens[0], tokens[1]) in TYPES: # case "deleted:user:foo@bar.com?uid=1234" member = input_str roles = DROP_ALL elif removing_discouraged_type: (member_type, project_id, roles) = tokens member = '%s:%s' % (member_type, project_id) else: (member_type, member_id, roles) = tokens _check_member_type(member_type, input_str) member = '%s:%s' % (member_type, member_id) elif input_str.count(':') == 3: # case "deleted:user:foo@bar.com?uid=1234:objectAdmin,objectViewer" (member_type_p1, member_type_p2, member_id, roles) = input_str.split(':') member_type = '%s:%s' % (member_type_p1, member_type_p2) _check_member_type(member_type, input_str) member = '%s:%s' % (member_type, member_id) else: raise CommandException('Invalid ch format %s' % input_str) if is_grant and not roles: raise CommandException('Must specify a role to grant.') roles = [ResolveRole(r) for r in roles.split(',')] bindings = [{'role': r, 'members': [member]} for r in set(roles)] return BindingsDictTuple(is_grant=is_grant, bindings=bindings) def _check_member_type(member_type, input_str): if member_type in DISCOURAGED_TYPES: raise CommandException(DISCOURAGED_TYPES_MSG) elif member_type not in TYPES: raise CommandException('Incorrect member type for binding %s' % input_str) def ResolveRole(role): if not role: return DROP_ALL if 'roles/' in role: return role return 'roles/storage.%s' % role