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/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 131
# -*- coding: utf-8 -*- # Copyright 2014 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. """Tests for signurl command.""" from __future__ import absolute_import from __future__ import print_function from __future__ import division from __future__ import unicode_literals from datetime import datetime from datetime import timedelta import os import pkgutil import boto import gslib.commands.signurl from gslib.commands.signurl import HAVE_OPENSSL from gslib.commands.signurl import HAVE_CRYPTO from gslib.exception import CommandException from gslib.gcs_json_api import GcsJsonApi from gslib.iamcredentials_api import IamcredentailsApi from gslib.impersonation_credentials import ImpersonationCredentials import gslib.tests.testcase as testcase from gslib.tests.testcase.integration_testcase import (SkipForS3, SkipForXML) from gslib.tests.util import ObjectToURI as suri from gslib.tests.util import SetBotoConfigForTest from gslib.tests.util import SetEnvironmentForTest from gslib.tests.util import unittest import gslib.tests.signurl_signatures as sigs from oauth2client import client from oauth2client.service_account import ServiceAccountCredentials from six import add_move, MovedModule add_move(MovedModule('mock', 'mock', 'unittest.mock')) from six.moves import mock SERVICE_ACCOUNT = boto.config.get_value('GSUtil', 'test_impersonate_service_account') TEST_EMAIL = 'test%40developer.gserviceaccount.com' # pylint: disable=protected-access @unittest.skipUnless(HAVE_OPENSSL, 'signurl requires pyopenssl.') @SkipForS3('Signed URLs are only supported for gs:// URLs.') class TestSignUrl(testcase.GsUtilIntegrationTestCase): """Integration tests for signurl command.""" def _GetJSONKsFile(self): if not hasattr(self, 'json_ks_file'): # Dummy json keystore constructed from test.p12. contents = pkgutil.get_data('gslib', 'tests/test_data/test.json') self.json_ks_file = self.CreateTempFile(contents=contents) return self.json_ks_file def _GetKsFile(self): if not hasattr(self, 'ks_file'): # Dummy pkcs12 keystore generated with the command # openssl req -new -passout pass:notasecret -batch \ # -x509 -keyout signed_url_test.key -out signed_url_test.pem \ # -subj '/CN=test.apps.googleusercontent.com' # && # openssl pkcs12 -export -passin pass:notasecret \ # -passout pass:notasecret -inkey signed_url_test.key \ # -in signed_url_test.pem -out test.p12 # && # rm signed_url_test.key signed_url_test.pem contents = pkgutil.get_data('gslib', 'tests/test_data/test.p12') self.ks_file = self.CreateTempFile(contents=contents) return self.ks_file def testSignUrlInvalidDuration(self): """Tests signurl fails with out of bounds value for valid duration.""" if self._use_gcloud_storage: expected_status = 2 else: expected_status = 1 stderr = self.RunGsUtil(['signurl', '-d', '123d', 'ks_file', 'gs://uri'], return_stderr=True, expected_status=expected_status) if self._use_gcloud_storage: self.assertIn('value must be less than or equal to 7d', stderr) else: self.assertIn('CommandException: Max valid duration allowed is 7 days', stderr) def testSignUrlInvalidDurationWithUseServiceAccount(self): """Tests signurl with -u flag fails duration > 12 hours.""" stderr = self.RunGsUtil(['signurl', '-d', '13h', '-u', 'gs://uri'], return_stderr=True, expected_status=1) self.assertIn('CommandException: Max valid duration allowed is 12:00:00', stderr) @unittest.skipUnless(not HAVE_CRYPTO, 'signurl requires crypto to decode .p12 keys') def testSignUrlRaiseErrorForP12KeysWithoutCrypto(self): bucket_uri = self.CreateBucket() object_uri = self.CreateObject(bucket_uri=bucket_uri, contents=b'z') cmd = [ 'signurl', '-p', 'notasecret', '-m', 'PUT', self._GetKsFile(), suri(object_uri) ] stderr = self.RunGsUtil(cmd, return_stderr=1, expected_status=1) self.assertIn('CommandException: pyca/cryptography is not available. Either install it, or please consider using the .json keyfile', stderr) @unittest.skipUnless(HAVE_CRYPTO, 'signurl requires crypto to decode .p12 keys.') def testSignUrlOutputP12(self): """Tests signurl output of a sample object with pkcs12 keystore.""" bucket_uri = self.CreateBucket() object_uri = self.CreateObject(bucket_uri=bucket_uri, contents=b'z') cmd = [ 'signurl', '-p', 'notasecret', '-m', 'PUT', self._GetKsFile(), suri(object_uri) ] stdout = self.RunGsUtil(cmd, return_stdout=True) self.assertIn('x-goog-credential=test.apps.googleusercontent.com', stdout) self.assertIn('x-goog-expires=3600', stdout) self.assertIn('%2Fus-central1%2F', stdout) self.assertIn('\tPUT\t', stdout) def testSignUrlOutputJSON(self): """Tests signurl output of a sample object with JSON keystore.""" bucket_uri = self.CreateBucket() object_uri = self.CreateObject(bucket_uri=bucket_uri, contents=b'z') cmd = ['signurl', '-m', 'PUT', self._GetJSONKsFile(), suri(object_uri)] stdout = self.RunGsUtil(cmd, return_stdout=True) self.assertIn('x-goog-credential=' + TEST_EMAIL, stdout) self.assertIn('x-goog-expires=3600', stdout) self.assertIn('%2Fus-central1%2F', stdout) self.assertIn('\tPUT\t', stdout) def testSignUrlWithJSONKeyFileAndObjectGeneration(self): """Tests signurl output of a sample object version with JSON keystore.""" bucket_uri = self.CreateBucket(versioning_enabled=True) object_uri = self.CreateObject(bucket_uri=bucket_uri, contents=b'z') cmd = ['signurl', self._GetJSONKsFile(), object_uri.version_specific_uri] stdout = self.RunGsUtil(cmd, return_stdout=True) self.assertIn('x-goog-credential=' + TEST_EMAIL, stdout) self.assertIn('generation=' + object_uri.generation, stdout) def testSignUrlWithURLEncodeRequiredChars(self): objs = [ 'gs://example.org/test 1', 'gs://example.org/test/test 2', 'gs://example.org/Аудиоарi хив' ] expected_partial_urls = [ 'https://storage.googleapis.com/example.org/test%201?x-goog-signature=', ('https://storage.googleapis.com/example.org/test/test%202' '?x-goog-signature='), ('https://storage.googleapis.com/example.org/%D0%90%D1%83%D0%B4%D0%B8%D' '0%BE%D0%B0%D1%80i%20%D1%85%D0%B8%D0%B2?x-goog-signature=') ] self.assertEqual(len(objs), len(expected_partial_urls)) cmd_args = [ 'signurl', '-m', 'PUT', '-r', 'us', self._GetJSONKsFile() ] cmd_args.extend(objs) stdout = self.RunGsUtil(cmd_args, return_stdout=True) lines = stdout.split('\n') # Header, signed urls, trailing newline. self.assertEqual(len(lines), len(objs) + 2) # Strip the header line to make the indices line up. lines = lines[1:] for obj, line, partial_url in zip(objs, lines, expected_partial_urls): self.assertIn(obj, line) self.assertIn(partial_url, line) self.assertIn('x-goog-credential='+TEST_EMAIL, line) self.assertIn('%2Fus%2F', stdout) def testSignUrlWithWildcard(self): objs = ['test1', 'test2', 'test3'] obj_urls = [] bucket = self.CreateBucket() for obj_name in objs: obj_urls.append( self.CreateObject(bucket_uri=bucket, object_name=obj_name, contents=b'')) stdout = self.RunGsUtil( ['signurl', self._GetJSONKsFile(), suri(bucket) + '/*'], return_stdout=True) # Header, 3 signed urls, trailing newline self.assertEqual(len(stdout.split('\n')), 5) for obj_url in obj_urls: self.assertIn(suri(obj_url), stdout) @unittest.skipUnless(SERVICE_ACCOUNT, 'Test requires test_impersonate_service_account.') @SkipForS3('Tests only uses gs credentials.') @SkipForXML('Tests only run on JSON API.') def testSignUrlWithServiceAccount(self): with SetBotoConfigForTest([('Credentials', 'gs_impersonate_service_account', SERVICE_ACCOUNT)]): stdout, stderr = self.RunGsUtil( ['signurl', '-r', 'us-east1', '-u', 'gs://pub'], return_stdout=True, return_stderr=True) # The signed url returned in stdout relies on current time. # We are not able to mock the datetime here because RunGsUtil creates # a separate process and runs the command. self.assertIn('https://storage.googleapis.com/pub', stdout) self.assertIn('All API calls will be executed as [%s]' % SERVICE_ACCOUNT, stderr) def testSignUrlOfNonObjectUrl(self): """Tests the signurl output of a non-existent file.""" self.RunGsUtil(['signurl', self._GetJSONKsFile(), 'gs://'], expected_status=1) self.RunGsUtil(['signurl', 'file://tmp/abc', 'gs://bucket'], expected_status=1) @unittest.skipUnless(HAVE_OPENSSL, 'signurl requires pyopenssl.') class UnitTestSignUrl(testcase.GsUtilUnitTestCase): """Unit tests for the signurl command.""" # Helpful for comparing mismatched signed URLs that would be truncated. # https://stackoverflow.com/questions/14493670/how-to-set-self-maxdiff-in-nose-to-get-full-diff-output maxDiff = None def setUp(self): super(UnitTestSignUrl, self).setUp() ks_contents = pkgutil.get_data('gslib', 'tests/test_data/test.p12') self.key, self.client_email = gslib.commands.signurl._ReadKeystore( ks_contents, 'notasecret') def fake_now(): return datetime(1900, 1, 1, 0, 5, 55) gslib.utils.signurl_helper._NowUTC = fake_now def _get_mock_api_delegator(self): mock_api_delegator = self.MakeGsUtilApi() # The MAkeGsUtilAPi maps apiclass.gs.JSON to BotoTranslation # instead of GcsJsonApi # Issue https://github.com/GoogleCloudPlatform/gsutil/issues/970 # SignUrl relies on the GcsJsonApi so we are replacing the mapping here. mock_api_delegator.api_map['apiclass']['gs']['JSON'] = GcsJsonApi return mock_api_delegator def testDurationSpec(self): tests = [ ('1h', timedelta(hours=1)), ('2d', timedelta(days=2)), ('5D', timedelta(days=5)), ('35s', timedelta(seconds=35)), ('1h', timedelta(hours=1)), ('33', timedelta(hours=33)), ('22m', timedelta(minutes=22)), ('3.7', None), ('27Z', None), ] for inp, expected in tests: try: td = gslib.commands.signurl._DurationToTimeDelta(inp) self.assertEqual(td, expected) except CommandException: if expected is not None: self.fail('{0} failed to parse') def testSignPutUsingKeyFile(self): """Tests the _GenSignedUrl function with a PUT method using Key file.""" expected = sigs.TEST_SIGN_PUT_SIG duration = timedelta(seconds=3600) with SetBotoConfigForTest([('Credentials', 'gs_host', 'storage.googleapis.com')]): signed_url = gslib.commands.signurl._GenSignedUrl( self.key, api=None, use_service_account=False, provider='gs', client_id=self.client_email, method='RESUMABLE', gcs_path='test/test.txt', duration=duration, logger=self.logger, region='us-east', content_type='') self.assertEqual(expected, signed_url) @SkipForS3('Tests only uses gs credentials.') @SkipForXML('Tests only run on JSON API.') def testSignPutUsingServiceAccount(self): """Tests the _GenSignedUrl function PUT method with service account.""" expected = sigs.TEST_SIGN_URL_PUT_WITH_SERVICE_ACCOUNT duration = timedelta(seconds=3600) mock_api_delegator = self._get_mock_api_delegator() json_api = mock_api_delegator._GetApi('gs') # patch a service account credentials mock_credentials = mock.Mock(spec=ServiceAccountCredentials) mock_credentials.service_account_email = 'fake_service_account_email' mock_credentials.sign_blob.return_value = ('fake_key', b'fake_signature') json_api.credentials = mock_credentials with SetBotoConfigForTest([('Credentials', 'gs_host', 'storage.googleapis.com')]): signed_url = gslib.commands.signurl._GenSignedUrl( None, api=mock_api_delegator, use_service_account=True, provider='gs', client_id=self.client_email, method='PUT', gcs_path='test/test.txt', duration=duration, logger=self.logger, region='us-east1', content_type='') self.assertEqual(expected, signed_url) mock_credentials.sign_blob.assert_called_once_with( b'GOOG4-RSA-SHA256\n19000101T000555Z\n19000101/us-east1/storage/' b'goog4_request\n7f110b30eeca7fdd8846e876bceee85384d8e4c7388b359' b'6544b1b503f9e2320') @SkipForS3('Tests only uses gs credentials.') @SkipForXML('Tests only run on JSON API.') def testSignUrlWithIncorrectAccountType(self): """Tests the _GenSignedUrl with incorrect account type. Test that GenSignedUrl function with 'use_service_account' set to True and a service account not used for credentials raises an error. """ expected = sigs.TEST_SIGN_URL_PUT_WITH_SERVICE_ACCOUNT duration = timedelta(seconds=3600) mock_api_delegator = self._get_mock_api_delegator() json_api = mock_api_delegator._GetApi('gs') # patch a service account credentials mock_credentials = mock.Mock(spec=client.OAuth2Credentials) mock_credentials.service_account_email = 'fake_service_account_email' json_api.credentials = mock_credentials with SetBotoConfigForTest([('Credentials', 'gs_host', 'storage.googleapis.com')]): self.assertRaises(CommandException, gslib.commands.signurl._GenSignedUrl, None, api=mock_api_delegator, use_service_account=True, provider='gs', client_id=self.client_email, method='PUT', gcs_path='test/test.txt', duration=duration, logger=self.logger, region='us-east1', content_type='') @SkipForS3('Tests only uses gs credentials.') @SkipForXML('Tests only run on JSON API.') @mock.patch('gslib.iamcredentials_api.apitools_client') @mock.patch('gslib.iamcredentials_api.apitools_messages') def testSignPutUsingImersonatedServiceAccount(self, mock_api_messages, mock_apiclient): """Tests the _GenSignedUrl function PUT method with impersonation. Test _GenSignedUrl function using an impersonated service account. """ expected = sigs.TEST_SIGN_URL_PUT_WITH_SERVICE_ACCOUNT duration = timedelta(seconds=3600) mock_api_delegator = self._get_mock_api_delegator() json_api = mock_api_delegator._GetApi('gs') # A mock object of type ImpersonationCredentials. mock_credentials = mock.Mock(spec=ImpersonationCredentials) api_client_obj = mock.Mock() mock_apiclient.IamcredentialsV1.return_value = api_client_obj # The api_client.IamcredntialsV1 get's in IamCredentialsApi's init mock_iam_cred_api = IamcredentailsApi(credentials=mock.Mock()) mock_credentials.api = mock_iam_cred_api mock_credentials.service_account_id = 'fake_service_account_email' # Mock the response and assign it as a return value for the SignBlob func. mock_resp = mock.Mock() mock_resp.signedBlob = b'fake_signature' api_client_obj.projects_serviceAccounts.SignBlob.return_value = mock_resp json_api.credentials = mock_credentials with SetBotoConfigForTest([('Credentials', 'gs_host', 'storage.googleapis.com')]): signed_url = gslib.commands.signurl._GenSignedUrl( None, api=mock_api_delegator, use_service_account=True, provider='gs', client_id=self.client_email, method='PUT', gcs_path='test/test.txt', duration=duration, logger=self.logger, region='us-east1', content_type='') self.assertEqual(expected, signed_url) mock_api_messages.SignBlobRequest.assert_called_once_with( payload=b'GOOG4-RSA-SHA256\n19000101T000555Z\n19000101/us-east1' b'/storage/goog4_request\n7f110b30eeca7fdd8846e876bceee' b'85384d8e4c7388b3596544b1b503f9e2320') def testSignResumableWithKeyFile(self): """Tests _GenSignedUrl using key file with a RESUMABLE method.""" expected = sigs.TEST_SIGN_RESUMABLE class MockLogger(object): def __init__(self): self.warning_issued = False def warn(self, unused_msg): self.warning_issued = True mock_logger = MockLogger() duration = timedelta(seconds=3600) with SetBotoConfigForTest([('Credentials', 'gs_host', 'storage.googleapis.com')]): signed_url = gslib.commands.signurl._GenSignedUrl( self.key, api=None, use_service_account=False, provider='gs', client_id=self.client_email, method='RESUMABLE', gcs_path='test/test.txt', duration=duration, logger=mock_logger, region='us-east', content_type='') self.assertEqual(expected, signed_url) # Resumable uploads with no content-type should issue a warning. self.assertTrue(mock_logger.warning_issued) mock_logger2 = MockLogger() with SetBotoConfigForTest([('Credentials', 'gs_host', 'storage.googleapis.com')]): signed_url = gslib.commands.signurl._GenSignedUrl( self.key, api=None, use_service_account=False, provider='gs', client_id=self.client_email, method='RESUMABLE', gcs_path='test/test.txt', duration=duration, logger=mock_logger2, region='us-east', content_type='image/jpeg') # No warning, since content type was included. self.assertFalse(mock_logger2.warning_issued) def testSignurlPutContentypeUsingKeyFile(self): """Tests _GenSignedUrl using key file with a PUT method and content type.""" expected = sigs.TEST_SIGN_URL_PUT_CONTENT duration = timedelta(seconds=3600) with SetBotoConfigForTest([('Credentials', 'gs_host', 'storage.googleapis.com')]): signed_url = gslib.commands.signurl._GenSignedUrl( self.key, api=None, use_service_account=False, provider='gs', client_id=self.client_email, method='PUT', gcs_path='test/test.txt', duration=duration, logger=self.logger, region='eu', content_type='text/plain') self.assertEqual(expected, signed_url) def testSignurlGetUsingKeyFile(self): """Tests the _GenSignedUrl function using key file with a GET method.""" expected = sigs.TEST_SIGN_URL_GET duration = timedelta(seconds=0) with SetBotoConfigForTest([('Credentials', 'gs_host', 'storage.googleapis.com')]): signed_url = gslib.commands.signurl._GenSignedUrl( self.key, api=None, use_service_account=False, provider='gs', client_id=self.client_email, method='GET', gcs_path='test/test.txt', duration=duration, logger=self.logger, region='asia', content_type='') self.assertEqual(expected, signed_url) def testSignurlGetWithJSONKeyUsingKeyFile(self): """Tests _GenSignedUrl with a GET method and the test JSON private key.""" expected = sigs.TEST_SIGN_URL_GET_WITH_JSON_KEY json_contents = pkgutil.get_data('gslib', 'tests/test_data/test.json').decode() key, client_email = gslib.commands.signurl._ReadJSONKeystore(json_contents) duration = timedelta(seconds=0) with SetBotoConfigForTest([('Credentials', 'gs_host', 'storage.googleapis.com')]): signed_url = gslib.commands.signurl._GenSignedUrl( key, api=None, use_service_account=False, provider='gs', client_id=client_email, method='GET', gcs_path='test/test.txt', duration=duration, logger=self.logger, region='asia', content_type='') self.assertEqual(expected, signed_url) def testSignurlGetWithUserProject(self): """Tests the _GenSignedUrl function with a userproject.""" expected = sigs.TEST_SIGN_URL_GET_USERPROJECT duration = timedelta(seconds=0) with SetBotoConfigForTest([('Credentials', 'gs_host', 'storage.googleapis.com')]): signed_url = gslib.commands.signurl._GenSignedUrl( self.key, api=None, use_service_account=False, provider='gs', client_id=self.client_email, method='GET', gcs_path='test/test.txt', duration=duration, logger=self.logger, region='asia', content_type='', billing_project='myproject') self.assertEqual(expected, signed_url) @unittest.skipUnless(HAVE_OPENSSL, 'signurl requires pyopenssl.') class UnitTestSignUrlWithShim(testcase.ShimUnitTestBase): def testShimTranslatesFlags(self): key_contents = pkgutil.get_data('gslib', 'tests/test_data/test.json') key_path = self.CreateTempFile(contents=key_contents) with SetBotoConfigForTest([('GSUtil', 'use_gcloud_storage', 'True'), ('GSUtil', 'hidden_shim_mode', 'dry_run')]): with SetEnvironmentForTest({ 'CLOUDSDK_CORE_PASS_CREDENTIALS_TO_GSUTIL': 'True', 'CLOUDSDK_ROOT_DIR': 'fake_dir', }): mock_log_handler = self.RunCommand('signurl', [ '-d', '2m', '-m', 'RESUMABLE', '-r', 'US', '-b', 'project', '-c', 'application/octet-stream', key_path, 'gs://bucket/object' ], return_log_handler=True) info_lines = '\n'.join(mock_log_handler.messages['info']) self.assertIn( 'storage sign-url' ' --format=csv[separator="\\t"](resource:label="URL", http_verb:label="HTTP Method", expiration:label="Expiration", signed_url:label="Signed URL")' ' --private-key-file={}' ' --headers=x-goog-resumable=start' ' --duration 120s' ' --http-verb POST' ' --region US' ' --query-params userProject=project' ' --headers content-type=application/octet-stream' ' gs://bucket/object'.format(key_path), info_lines) def testShimTranslatesFlagsWithP12Key(self): key_contents = pkgutil.get_data('gslib', 'tests/test_data/test.p12') key_path = self.CreateTempFile(contents=key_contents) key_password = 'notasecret' with SetBotoConfigForTest([('GSUtil', 'use_gcloud_storage', 'True'), ('GSUtil', 'hidden_shim_mode', 'dry_run')]): with SetEnvironmentForTest({ 'CLOUDSDK_CORE_PASS_CREDENTIALS_TO_GSUTIL': 'True', 'CLOUDSDK_ROOT_DIR': 'fake_dir', }): mock_log_handler = self.RunCommand('signurl', [ '-d', '2m', '-m', 'RESUMABLE', '-p', key_password, '-r', 'US', '-b', 'project', '-c', 'application/octet-stream', key_path, 'gs://bucket/object' ], return_log_handler=True) info_lines = '\n'.join(mock_log_handler.messages['info']) self.assertIn( 'storage sign-url' ' --format=csv[separator="\\t"](resource:label="URL", http_verb:label="HTTP Method", expiration:label="Expiration", signed_url:label="Signed URL")' ' --private-key-file={}' ' --headers=x-goog-resumable=start' ' --duration 120s' ' --http-verb POST' ' --private-key-password {}' ' --region US' ' --query-params userProject=project' ' --headers content-type=application/octet-stream' ' gs://bucket/object'.format(key_path, key_password), info_lines)