in gslib/commands/signurl.py [0:0]
def RunCommand(self):
"""Command entry point for signurl command."""
if not HAVE_OPENSSL:
raise CommandException(
'The signurl command requires the pyopenssl library (try pip '
'install pyopenssl or easy_install pyopenssl)')
method, delta, content_type, passwd, region, use_service_account, billing_project = (
self._ParseAndCheckSubOpts())
arg_start_index = 0 if use_service_account else 1
storage_urls = self._EnumerateStorageUrls(self.args[arg_start_index:])
region_cache = {}
key = None
if not use_service_account:
try:
key, client_email = _ReadJSONKeystore(
open(self.args[0], 'rb').read(), passwd)
except ValueError:
# Ignore and try parsing as a pkcs12.
if not passwd:
passwd = getpass.getpass('Keystore password:')
try:
key, client_email = _ReadKeystore(
open(self.args[0], 'rb').read(), passwd)
except ValueError:
raise CommandException('Unable to parse private key from {0}'.format(
self.args[0]))
else:
client_email = self.gsutil_api.GetServiceAccountId(provider='gs')
print('URL\tHTTP Method\tExpiration\tSigned URL')
for url in storage_urls:
if url.scheme != 'gs':
raise CommandException('Can only create signed urls from gs:// urls')
if url.IsBucket():
if region == _AUTO_DETECT_REGION:
raise CommandException('Generating signed URLs for creating buckets'
' requires a region be specified via the -r '
'option. Run `gsutil help signurl` for more '
'information about the \'-r\' option.')
gcs_path = url.bucket_name
if method == 'RESUMABLE':
raise CommandException('Resumable signed URLs require an object '
'name.')
else:
# Need to URL encode the object name as Google Cloud Storage does when
# computing the string to sign when checking the signature.
gcs_path = '{0}/{1}'.format(
url.bucket_name,
urllib.parse.quote(url.object_name.encode(constants.UTF8),
safe=b'/~'))
if region == _AUTO_DETECT_REGION:
if url.bucket_name in region_cache:
bucket_region = region_cache[url.bucket_name]
else:
try:
_, bucket = self.GetSingleBucketUrlFromArg(
'gs://{}'.format(url.bucket_name), bucket_fields=['location'])
except Exception as e:
raise CommandException(
'{}: Failed to auto-detect location for bucket \'{}\'. Please '
'ensure you have storage.buckets.get permission on the bucket '
'or specify the bucket\'s location using the \'-r\' option.'.
format(e.__class__.__name__, url.bucket_name))
bucket_region = bucket.location.lower()
region_cache[url.bucket_name] = bucket_region
else:
bucket_region = region
final_url = _GenSignedUrl(key=key,
api=self.gsutil_api,
use_service_account=use_service_account,
provider=url.scheme,
client_id=client_email,
method=method,
duration=delta,
gcs_path=gcs_path,
generation=url.generation,
logger=self.logger,
region=bucket_region,
content_type=content_type,
billing_project=billing_project,
string_to_sign_debug=True)
expiration = calendar.timegm((datetime.now(tz=timezone.utc).replace(tzinfo=None) + delta).utctimetuple())
expiration_dt = datetime.fromtimestamp(expiration)
time_str = expiration_dt.strftime('%Y-%m-%d %H:%M:%S')
# TODO(PY3-ONLY): Delete this if block.
if six.PY2:
time_str = time_str.decode(constants.UTF8)
url_info_str = '{0}\t{1}\t{2}\t{3}'.format(url.url_string, method,
time_str, final_url)
# TODO(PY3-ONLY): Delete this if block.
if six.PY2:
url_info_str = url_info_str.encode(constants.UTF8)
print(url_info_str)
response_code = self._ProbeObjectAccessWithClient(
key, use_service_account, url.scheme, client_email, gcs_path,
url.generation, self.logger, bucket_region, billing_project)
if response_code == 404:
if url.IsBucket() and method != 'PUT':
raise CommandException(
'Bucket {0} does not exist. Please create a bucket with '
'that name before a creating signed URL to access it.'.format(
url))
else:
if method != 'PUT' and method != 'RESUMABLE':
raise CommandException(
'Object {0} does not exist. Please create/upload an object '
'with that name before a creating signed URL to access it.'.
format(url))
elif response_code == 403:
self.logger.warn(
'%s does not have permissions on %s, using this link will likely '
'result in a 403 error until at least READ permissions are granted',
client_email or 'The account', url)
return 0