google-cloud-storage 1.26.2 → 1.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e3be983e4030e7bf8ecdbf4b6c4e0af49cf5bd6c26874d656446e8222a34e05e
4
- data.tar.gz: 5cb3efb8d5fb429f11cab27251e2aeaffc27ad452559bedb655be9812ef15dbf
3
+ metadata.gz: c1c5fde2ed35606723e05c787ff96fd6ec31d7e06015e09bcac8dc0bc4b9ae05
4
+ data.tar.gz: bf1391389ff711934df5302f65cdf6136bad14b0a00865728da8fe3b549b3cbe
5
5
  SHA512:
6
- metadata.gz: ddfc78d9663e563e52b23f44edf41bebc1b2935218fd3fb227d5ad055e50802e2298465b8f6560961e5dbafd34471782951870b09453a664193dd6c3fc8ca534
7
- data.tar.gz: 9fc5ff1f8ff4cf037e39bb6fb6b30f459d74c77adc08222bdbd3c6637b00c450a42b9563fed33ca1ac8cf4a6be7624c453d85fba82b643ae83e8c4c7390137e0
6
+ metadata.gz: 1e7d9a97562357737322928a56f093ed42bc8f8015a06723c5e403c402367a89f56604eeefb2bbbf289a7dce5b84ee055f76f3d6ef6df6d987f7f05ed5eed5fe
7
+ data.tar.gz: 67046c8397a7e7fabf7b0a4d4e6501417ba815b55267e641a0ab51cdb233641e699348629a021763724aaca623e25a901395d77453b78fbc90ae67d4efca17b1
@@ -102,8 +102,14 @@ To configure your system for this, simply:
102
102
  2. Authenticate using OAuth 2.0 `$ gcloud auth login`
103
103
  3. Write code as if already authenticated.
104
104
 
105
- **NOTE:** This is _not_ recommended for running in production. The Cloud SDK
106
- *should* only be used during development.
105
+ **NOTE:** The use of Cloud SDK credentials is _not_ recommended for running in
106
+ production. The Cloud SDK *should* only be used during development.
107
+
108
+ **NOTE:** The use of Cloud SDK credentials may not support certain methods such as
109
+ those that produce
110
+ [signed URLs](https://cloud.google.com/storage/docs/access-control/signed-urls) and
111
+ post objects. For these methods, authentication using a service account JSON key file
112
+ is required.
107
113
 
108
114
  [gce-how-to]: https://cloud.google.com/compute/docs/authentication#using
109
115
  [dev-console]: https://console.cloud.google.com/project
@@ -1,5 +1,22 @@
1
1
  # Release History
2
2
 
3
+ ### 1.27.0 / 2020-07-29
4
+
5
+ #### Features
6
+
7
+ * Add support for signing URLs with IAMCredentials SignBlob API
8
+ * Add signer parameter accepting Procs to the following methods:
9
+ * Project#signed_url
10
+ * Bucket#generate_signed_post_policy_v4
11
+ * Bucket#post_object
12
+ * Bucket#signed_url
13
+ * File#signed_url
14
+ * Update signer aliases signing_key and private_key to similarly support Procs
15
+
16
+ #### Documentation
17
+
18
+ * Update documentation of SignedUrlUnavailable
19
+
3
20
  ### 1.26.2 / 2020-05-28
4
21
 
5
22
  #### Documentation
@@ -1406,7 +1406,7 @@ module Google
1406
1406
  # A {SignedUrlUnavailable} is raised if the service account credentials
1407
1407
  # are missing. Service account credentials are acquired by following the
1408
1408
  # steps in [Service Account Authentication](
1409
- # https://cloud.google.com/storage/docs/authentication#service_accounts).
1409
+ # https://cloud.google.com/iam/docs/service-accounts).
1410
1410
  #
1411
1411
  # @see https://cloud.google.com/storage/docs/access-control/signed-urls
1412
1412
  # Signed URLs guide
@@ -1433,10 +1433,22 @@ module Google
1433
1433
  # use the signed URL.
1434
1434
  # @param [String] issuer Service Account's Client Email.
1435
1435
  # @param [String] client_email Service Account's Client Email.
1436
- # @param [OpenSSL::PKey::RSA, String] signing_key Service Account's
1437
- # Private Key.
1438
- # @param [OpenSSL::PKey::RSA, String] private_key Service Account's
1439
- # Private Key.
1436
+ # @param [OpenSSL::PKey::RSA, String, Proc] signing_key Service Account's
1437
+ # Private Key or a Proc that accepts a single String parameter and returns a
1438
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1439
+ # @param [OpenSSL::PKey::RSA, String, Proc] private_key Service Account's
1440
+ # Private Key or a Proc that accepts a single String parameter and returns a
1441
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1442
+ # @param [OpenSSL::PKey::RSA, String, Proc] signer Service Account's
1443
+ # Private Key or a Proc that accepts a single String parameter and returns a
1444
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1445
+ #
1446
+ # When using this method in environments such as GAE Flexible Environment,
1447
+ # GKE, or Cloud Functions where the private key is unavailable, it may be
1448
+ # necessary to provide a Proc (or lambda) via the signer parameter. This
1449
+ # Proc should return a signature created using a RPC call to the
1450
+ # [Service Account Credentials signBlob](https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob)
1451
+ # method as shown in the example below.
1440
1452
  # @param [Hash] query Query string parameters to include in the signed
1441
1453
  # URL. The given parameters are not verified by the signature.
1442
1454
  #
@@ -1462,7 +1474,12 @@ module Google
1462
1474
  # to create. Must be one of `:v2` or `:v4`. The default value is
1463
1475
  # `:v2`.
1464
1476
  #
1465
- # @return [String]
1477
+ # @return [String] The signed URL.
1478
+ #
1479
+ # @raise [SignedUrlUnavailable] If the service account credentials
1480
+ # are missing. Service account credentials are acquired by following the
1481
+ # steps in [Service Account Authentication](
1482
+ # https://cloud.google.com/iam/docs/service-accounts).
1466
1483
  #
1467
1484
  # @example
1468
1485
  # require "google/cloud/storage"
@@ -1493,6 +1510,40 @@ module Google
1493
1510
  # issuer: "service-account@gcloud.com",
1494
1511
  # signing_key: key
1495
1512
  #
1513
+ # @example Using Cloud IAMCredentials signBlob to create the signature:
1514
+ # require "google/cloud/storage"
1515
+ # require "google/apis/iamcredentials_v1"
1516
+ # require "googleauth"
1517
+ #
1518
+ # # Issuer is the service account email that the Signed URL will be signed with
1519
+ # # and any permission granted in the Signed URL must be granted to the
1520
+ # # Google Service Account.
1521
+ # issuer = "service-account@project-id.iam.gserviceaccount.com"
1522
+ #
1523
+ # # Create a lambda that accepts the string_to_sign
1524
+ # signer = lambda do |string_to_sign|
1525
+ # IAMCredentials = Google::Apis::IamcredentialsV1
1526
+ # iam_client = IAMCredentials::IAMCredentialsService.new
1527
+ #
1528
+ # # Get the environment configured authorization
1529
+ # scopes = ["https://www.googleapis.com/auth/iam"]
1530
+ # iam_client.authorization = Google::Auth.get_application_default scopes
1531
+ #
1532
+ # request = {
1533
+ # "payload": string_to_sign,
1534
+ # }
1535
+ # resource = "projects/-/serviceAccounts/#{issuer}"
1536
+ # response = iam_client.sign_service_account_blob resource, request, {}
1537
+ # response.signed_blob
1538
+ # end
1539
+ #
1540
+ # storage = Google::Cloud::Storage.new
1541
+ #
1542
+ # bucket_name = "my-todo-app"
1543
+ # file_path = "avatars/heidi/400x400.png"
1544
+ # url = storage.signed_url bucket_name, file_path,
1545
+ # method: "GET", issuer: issuer,
1546
+ # signer: signer
1496
1547
  # @example Using the `headers` option:
1497
1548
  # require "google/cloud/storage"
1498
1549
  #
@@ -1538,6 +1589,7 @@ module Google
1538
1589
  client_email: nil,
1539
1590
  signing_key: nil,
1540
1591
  private_key: nil,
1592
+ signer: nil,
1541
1593
  query: nil,
1542
1594
  scheme: "HTTPS",
1543
1595
  virtual_hosted_style: nil,
@@ -1547,30 +1599,32 @@ module Google
1547
1599
  version ||= :v2
1548
1600
  case version.to_sym
1549
1601
  when :v2
1550
- signer = File::SignerV2.from_bucket self, path
1551
- signer.signed_url method: method,
1552
- expires: expires,
1553
- headers: headers,
1554
- content_type: content_type,
1555
- content_md5: content_md5,
1556
- issuer: issuer,
1557
- client_email: client_email,
1558
- signing_key: signing_key,
1559
- private_key: private_key,
1560
- query: query
1602
+ sign = File::SignerV2.from_bucket self, path
1603
+ sign.signed_url method: method,
1604
+ expires: expires,
1605
+ headers: headers,
1606
+ content_type: content_type,
1607
+ content_md5: content_md5,
1608
+ issuer: issuer,
1609
+ client_email: client_email,
1610
+ signing_key: signing_key,
1611
+ private_key: private_key,
1612
+ signer: signer,
1613
+ query: query
1561
1614
  when :v4
1562
- signer = File::SignerV4.from_bucket self, path
1563
- signer.signed_url method: method,
1564
- expires: expires,
1565
- headers: headers,
1566
- issuer: issuer,
1567
- client_email: client_email,
1568
- signing_key: signing_key,
1569
- private_key: private_key,
1570
- query: query,
1571
- scheme: scheme,
1572
- virtual_hosted_style: virtual_hosted_style,
1573
- bucket_bound_hostname: bucket_bound_hostname
1615
+ sign = File::SignerV4.from_bucket self, path
1616
+ sign.signed_url method: method,
1617
+ expires: expires,
1618
+ headers: headers,
1619
+ issuer: issuer,
1620
+ client_email: client_email,
1621
+ signing_key: signing_key,
1622
+ private_key: private_key,
1623
+ signer: signer,
1624
+ query: query,
1625
+ scheme: scheme,
1626
+ virtual_hosted_style: virtual_hosted_style,
1627
+ bucket_bound_hostname: bucket_bound_hostname
1574
1628
  else
1575
1629
  raise ArgumentError, "version '#{version}' not supported"
1576
1630
  end
@@ -1591,7 +1645,7 @@ module Google
1591
1645
  # A {SignedUrlUnavailable} is raised if the service account credentials
1592
1646
  # are missing. Service account credentials are acquired by following the
1593
1647
  # steps in [Service Account Authentication](
1594
- # https://cloud.google.com/storage/docs/authentication#service_accounts).
1648
+ # https://cloud.google.com/iam/docs/service-accounts).
1595
1649
  #
1596
1650
  # @see https://cloud.google.com/storage/docs/xml-api/post-object
1597
1651
  #
@@ -1608,12 +1662,28 @@ module Google
1608
1662
  # for more information.
1609
1663
  # @param [String] issuer Service Account's Client Email.
1610
1664
  # @param [String] client_email Service Account's Client Email.
1611
- # @param [OpenSSL::PKey::RSA, String] signing_key Service Account's
1612
- # Private Key.
1613
- # @param [OpenSSL::PKey::RSA, String] private_key Service Account's
1614
- # Private Key.
1665
+ # @param [OpenSSL::PKey::RSA, String, Proc] signing_key Service Account's
1666
+ # Private Key or a Proc that accepts a single String parameter and returns a
1667
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1668
+ # @param [OpenSSL::PKey::RSA, String, Proc] private_key Service Account's
1669
+ # Private Key or a Proc that accepts a single String parameter and returns a
1670
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1671
+ # @param [OpenSSL::PKey::RSA, String, Proc] signer Service Account's
1672
+ # Private Key or a Proc that accepts a single String parameter and returns a
1673
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1674
+ #
1675
+ # When using this method in environments such as GAE Flexible Environment,
1676
+ # GKE, or Cloud Functions where the private key is unavailable, it may be
1677
+ # necessary to provide a Proc (or lambda) via the signer parameter. This
1678
+ # Proc should return a signature created using a RPC call to the
1679
+ # [Service Account Credentials signBlob](https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob)
1680
+ # method as shown in the example below.
1681
+ # @return [PostObject] An object containing the URL, fields, and values needed to upload files via html forms.
1615
1682
  #
1616
- # @return [PostObject]
1683
+ # @raise [SignedUrlUnavailable] If the service account credentials
1684
+ # are missing. Service account credentials are acquired by following the
1685
+ # steps in [Service Account Authentication](
1686
+ # https://cloud.google.com/iam/docs/service-accounts).
1617
1687
  #
1618
1688
  # @example
1619
1689
  # require "google/cloud/storage"
@@ -1673,19 +1743,61 @@ module Google
1673
1743
  # post.fields[:signature] #=> "ABC...XYZ="
1674
1744
  # post.fields[:policy] #=> "ABC...XYZ="
1675
1745
  #
1746
+ # @example Using Cloud IAMCredentials signBlob to create the signature:
1747
+ # require "google/cloud/storage"
1748
+ # require "google/apis/iamcredentials_v1"
1749
+ # require "googleauth"
1750
+ #
1751
+ # # Issuer is the service account email that the Signed URL will be signed with
1752
+ # # and any permission granted in the Signed URL must be granted to the
1753
+ # # Google Service Account.
1754
+ # issuer = "service-account@project-id.iam.gserviceaccount.com"
1755
+ #
1756
+ # # Create a lambda that accepts the string_to_sign
1757
+ # signer = lambda do |string_to_sign|
1758
+ # IAMCredentials = Google::Apis::IamcredentialsV1
1759
+ # iam_client = IAMCredentials::IAMCredentialsService.new
1760
+ #
1761
+ # # Get the environment configured authorization
1762
+ # scopes = ["https://www.googleapis.com/auth/iam"]
1763
+ # iam_client.authorization = Google::Auth.get_application_default scopes
1764
+ #
1765
+ # request = {
1766
+ # "payload": string_to_sign,
1767
+ # }
1768
+ # resource = "projects/-/serviceAccounts/#{issuer}"
1769
+ # response = iam_client.sign_service_account_blob resource, request, {}
1770
+ # response.signed_blob
1771
+ # end
1772
+ #
1773
+ # storage = Google::Cloud::Storage.new
1774
+ #
1775
+ # bucket = storage.bucket "my-todo-app"
1776
+ # post = bucket.post_object "avatars/heidi/400x400.png",
1777
+ # issuer: issuer,
1778
+ # signer: signer
1779
+ #
1780
+ # post.url #=> "https://storage.googleapis.com"
1781
+ # post.fields[:key] #=> "my-todo-app/avatars/heidi/400x400.png"
1782
+ # post.fields[:GoogleAccessId] #=> "0123456789@gserviceaccount.com"
1783
+ # post.fields[:signature] #=> "ABC...XYZ="
1784
+ # post.fields[:policy] #=> "ABC...XYZ="
1785
+ #
1676
1786
  def post_object path,
1677
1787
  policy: nil,
1678
1788
  issuer: nil,
1679
1789
  client_email: nil,
1680
1790
  signing_key: nil,
1681
- private_key: nil
1791
+ private_key: nil,
1792
+ signer: nil
1682
1793
  ensure_service!
1683
- signer = File::SignerV2.from_bucket self, path
1684
- signer.post_object issuer: issuer,
1685
- client_email: client_email,
1686
- signing_key: signing_key,
1687
- private_key: private_key,
1688
- policy: policy
1794
+ sign = File::SignerV2.from_bucket self, path
1795
+ sign.post_object issuer: issuer,
1796
+ client_email: client_email,
1797
+ signing_key: signing_key,
1798
+ private_key: private_key,
1799
+ signer: signer,
1800
+ policy: policy
1689
1801
  end
1690
1802
 
1691
1803
  ##
@@ -1703,17 +1815,29 @@ module Google
1703
1815
  # A {SignedUrlUnavailable} is raised if the service account credentials
1704
1816
  # are missing. Service account credentials are acquired by following the
1705
1817
  # steps in [Service Account Authentication](
1706
- # https://cloud.google.com/storage/docs/authentication#service_accounts).
1818
+ # https://cloud.google.com/iam/docs/service-accounts).
1707
1819
  #
1708
1820
  # @see https://cloud.google.com/storage/docs/xml-api/post-object
1709
1821
  #
1710
1822
  # @param [String] path Path to the file in Google Cloud Storage.
1711
1823
  # @param [String] issuer Service Account's Client Email.
1712
1824
  # @param [String] client_email Service Account's Client Email.
1713
- # @param [OpenSSL::PKey::RSA, String] signing_key Service Account's
1714
- # Private Key.
1715
- # @param [OpenSSL::PKey::RSA, String] private_key Service Account's
1716
- # Private Key.
1825
+ # @param [OpenSSL::PKey::RSA, String, Proc] signing_key Service Account's
1826
+ # Private Key or a Proc that accepts a single String parameter and returns a
1827
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1828
+ # @param [OpenSSL::PKey::RSA, String, Proc] private_key Service Account's
1829
+ # Private Key or a Proc that accepts a single String parameter and returns a
1830
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1831
+ # @param [OpenSSL::PKey::RSA, String, Proc] signer Service Account's
1832
+ # Private Key or a Proc that accepts a single String parameter and returns a
1833
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1834
+ #
1835
+ # When using this method in environments such as GAE Flexible Environment,
1836
+ # GKE, or Cloud Functions where the private key is unavailable, it may be
1837
+ # necessary to provide a Proc (or lambda) via the signer parameter. This
1838
+ # Proc should return a signature created using a RPC call to the
1839
+ # [Service Account Credentials signBlob](https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob)
1840
+ # method as shown in the example below.
1717
1841
  # @param [Integer] expires The number of seconds until the URL expires.
1718
1842
  # The default is 604800 (7 days).
1719
1843
  # @param [Hash] fields User-supplied form fields such as `acl`,
@@ -1733,6 +1857,11 @@ module Google
1733
1857
  #
1734
1858
  # @return [PostObject] An object containing the URL, fields, and values needed to upload files via html forms.
1735
1859
  #
1860
+ # @raise [SignedUrlUnavailable] If the service account credentials
1861
+ # are missing. Service account credentials are acquired by following the
1862
+ # steps in [Service Account Authentication](
1863
+ # https://cloud.google.com/iam/docs/service-accounts).
1864
+ #
1736
1865
  # @example
1737
1866
  # require "google/cloud/storage"
1738
1867
  #
@@ -1752,11 +1881,56 @@ module Google
1752
1881
  # post.fields["x-goog-date"] #=> "20200128T000000Z"
1753
1882
  # post.fields["x-goog-signature"] #=> "4893a0e...cd82"
1754
1883
  #
1884
+ # @example Using Cloud IAMCredentials signBlob to create the signature:
1885
+ # require "google/cloud/storage"
1886
+ # require "google/apis/iamcredentials_v1"
1887
+ # require "googleauth"
1888
+ #
1889
+ # # Issuer is the service account email that the Signed URL will be signed with
1890
+ # # and any permission granted in the Signed URL must be granted to the
1891
+ # # Google Service Account.
1892
+ # issuer = "service-account@project-id.iam.gserviceaccount.com"
1893
+ #
1894
+ # # Create a lambda that accepts the string_to_sign
1895
+ # signer = lambda do |string_to_sign|
1896
+ # IAMCredentials = Google::Apis::IamcredentialsV1
1897
+ # iam_client = IAMCredentials::IAMCredentialsService.new
1898
+ #
1899
+ # # Get the environment configured authorization
1900
+ # scopes = ["https://www.googleapis.com/auth/iam"]
1901
+ # iam_client.authorization = Google::Auth.get_application_default scopes
1902
+ #
1903
+ # request = {
1904
+ # "payload": string_to_sign,
1905
+ # }
1906
+ # resource = "projects/-/serviceAccounts/#{issuer}"
1907
+ # response = iam_client.sign_service_account_blob resource, request, {}
1908
+ # response.signed_blob
1909
+ # end
1910
+ #
1911
+ # storage = Google::Cloud::Storage.new
1912
+ #
1913
+ # bucket = storage.bucket "my-todo-app"
1914
+ # conditions = [["starts-with", "$acl","public"]]
1915
+ # post = bucket.generate_signed_post_policy_v4(
1916
+ # "avatars/heidi/400x400.png", expires: 10,
1917
+ # conditions: conditions, issuer: issuer, signer: signer
1918
+ # )
1919
+ #
1920
+ # post.url #=> "https://storage.googleapis.com/my-todo-app/"
1921
+ # post.fields["key"] #=> "my-todo-app/avatars/heidi/400x400.png"
1922
+ # post.fields["policy"] #=> "ABC...XYZ"
1923
+ # post.fields["x-goog-algorithm"] #=> "GOOG4-RSA-SHA256"
1924
+ # post.fields["x-goog-credential"] #=> "cred@pid.iam.gserviceaccount.com/20200123/auto/storage/goog4_request"
1925
+ # post.fields["x-goog-date"] #=> "20200128T000000Z"
1926
+ # post.fields["x-goog-signature"] #=> "4893a0e...cd82"
1927
+ #
1755
1928
  def generate_signed_post_policy_v4 path,
1756
1929
  issuer: nil,
1757
1930
  client_email: nil,
1758
1931
  signing_key: nil,
1759
1932
  private_key: nil,
1933
+ signer: nil,
1760
1934
  expires: nil,
1761
1935
  fields: nil,
1762
1936
  conditions: nil,
@@ -1764,17 +1938,18 @@ module Google
1764
1938
  virtual_hosted_style: nil,
1765
1939
  bucket_bound_hostname: nil
1766
1940
  ensure_service!
1767
- signer = File::SignerV4.from_bucket self, path
1768
- signer.post_object issuer: issuer,
1769
- client_email: client_email,
1770
- signing_key: signing_key,
1771
- private_key: private_key,
1772
- expires: expires,
1773
- fields: fields,
1774
- conditions: conditions,
1775
- scheme: scheme,
1776
- virtual_hosted_style: virtual_hosted_style,
1777
- bucket_bound_hostname: bucket_bound_hostname
1941
+ sign = File::SignerV4.from_bucket self, path
1942
+ sign.post_object issuer: issuer,
1943
+ client_email: client_email,
1944
+ signing_key: signing_key,
1945
+ private_key: private_key,
1946
+ signer: signer,
1947
+ expires: expires,
1948
+ fields: fields,
1949
+ conditions: conditions,
1950
+ scheme: scheme,
1951
+ virtual_hosted_style: virtual_hosted_style,
1952
+ bucket_bound_hostname: bucket_bound_hostname
1778
1953
  end
1779
1954
 
1780
1955
  ##
@@ -58,8 +58,13 @@ module Google
58
58
  ##
59
59
  # # SignedUrlUnavailable Error
60
60
  #
61
- # This is raised when File#signed_url is unable to generate a URL due to
62
- # missing credentials needed to create the URL.
61
+ # Raised by signed URL methods if the service account credentials
62
+ # are missing. Service account credentials are acquired by following the
63
+ # steps in [Service Account Authentication](
64
+ # https://cloud.google.com/iam/docs/service-accounts).
65
+ #
66
+ # @see https://cloud.google.com/storage/docs/access-control/signed-urls Signed URLs
67
+ #
63
68
  class SignedUrlUnavailable < Google::Cloud::Error
64
69
  end
65
70
  end
@@ -1442,7 +1442,7 @@ module Google
1442
1442
  # A {SignedUrlUnavailable} is raised if the service account credentials
1443
1443
  # are missing. Service account credentials are acquired by following the
1444
1444
  # steps in [Service Account Authentication](
1445
- # https://cloud.google.com/storage/docs/authentication#service_accounts).
1445
+ # https://cloud.google.com/iam/docs/service-accounts).
1446
1446
  #
1447
1447
  # @see https://cloud.google.com/storage/docs/access-control/signed-urls
1448
1448
  # Signed URLs guide
@@ -1467,10 +1467,22 @@ module Google
1467
1467
  # use the signed URL.
1468
1468
  # @param [String] issuer Service Account's Client Email.
1469
1469
  # @param [String] client_email Service Account's Client Email.
1470
- # @param [OpenSSL::PKey::RSA, String] signing_key Service Account's
1471
- # Private Key.
1472
- # @param [OpenSSL::PKey::RSA, String] private_key Service Account's
1473
- # Private Key.
1470
+ # @param [OpenSSL::PKey::RSA, String, Proc] signing_key Service Account's
1471
+ # Private Key or a Proc that accepts a single String parameter and returns a
1472
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1473
+ # @param [OpenSSL::PKey::RSA, String, Proc] private_key Service Account's
1474
+ # Private Key or a Proc that accepts a single String parameter and returns a
1475
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1476
+ # @param [OpenSSL::PKey::RSA, String, Proc] signer Service Account's
1477
+ # Private Key or a Proc that accepts a single String parameter and returns a
1478
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
1479
+ #
1480
+ # When using this method in environments such as GAE Flexible Environment,
1481
+ # GKE, or Cloud Functions where the private key is unavailable, it may be
1482
+ # necessary to provide a Proc (or lambda) via the signer parameter. This
1483
+ # Proc should return a signature created using a RPC call to the
1484
+ # [Service Account Credentials signBlob](https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob)
1485
+ # method as shown in the example below.
1474
1486
  # @param [Hash] query Query string parameters to include in the signed
1475
1487
  # URL. The given parameters are not verified by the signature.
1476
1488
  #
@@ -1496,7 +1508,12 @@ module Google
1496
1508
  # to create. Must be one of `:v2` or `:v4`. The default value is
1497
1509
  # `:v2`.
1498
1510
  #
1499
- # @return [String]
1511
+ # @return [String] The signed URL.
1512
+ #
1513
+ # @raise [SignedUrlUnavailable] If the service account credentials
1514
+ # are missing. Service account credentials are acquired by following the
1515
+ # steps in [Service Account Authentication](
1516
+ # https://cloud.google.com/iam/docs/service-accounts).
1500
1517
  #
1501
1518
  # @example
1502
1519
  # require "google/cloud/storage"
@@ -1556,6 +1573,40 @@ module Google
1556
1573
  # # Send the `x-goog-resumable:start` header and the content type
1557
1574
  # # with the resumable upload POST request.
1558
1575
  #
1576
+ # @example Using Cloud IAMCredentials signBlob to create the signature:
1577
+ # require "google/cloud/storage"
1578
+ # require "google/apis/iamcredentials_v1"
1579
+ # require "googleauth"
1580
+ #
1581
+ # # Issuer is the service account email that the Signed URL will be signed with
1582
+ # # and any permission granted in the Signed URL must be granted to the
1583
+ # # Google Service Account.
1584
+ # issuer = "service-account@project-id.iam.gserviceaccount.com"
1585
+ #
1586
+ # # Create a lambda that accepts the string_to_sign
1587
+ # signer = lambda do |string_to_sign|
1588
+ # IAMCredentials = Google::Apis::IamcredentialsV1
1589
+ # iam_client = IAMCredentials::IAMCredentialsService.new
1590
+ #
1591
+ # # Get the environment configured authorization
1592
+ # scopes = ["https://www.googleapis.com/auth/iam"]
1593
+ # iam_client.authorization = Google::Auth.get_application_default scopes
1594
+ #
1595
+ # request = {
1596
+ # "payload": string_to_sign,
1597
+ # }
1598
+ # resource = "projects/-/serviceAccounts/#{issuer}"
1599
+ # response = iam_client.sign_service_account_blob resource, request, {}
1600
+ # response.signed_blob
1601
+ # end
1602
+ #
1603
+ # storage = Google::Cloud::Storage.new
1604
+ #
1605
+ # bucket = storage.bucket "my-todo-app"
1606
+ # file = bucket.file "avatars/heidi/400x400.png", skip_lookup: true
1607
+ # url = file.signed_url method: "GET", issuer: issuer,
1608
+ # signer: signer
1609
+ #
1559
1610
  def signed_url method: "GET",
1560
1611
  expires: nil,
1561
1612
  content_type: nil,
@@ -1565,6 +1616,7 @@ module Google
1565
1616
  client_email: nil,
1566
1617
  signing_key: nil,
1567
1618
  private_key: nil,
1619
+ signer: nil,
1568
1620
  query: nil,
1569
1621
  scheme: "HTTPS",
1570
1622
  virtual_hosted_style: nil,
@@ -1574,30 +1626,32 @@ module Google
1574
1626
  version ||= :v2
1575
1627
  case version.to_sym
1576
1628
  when :v2
1577
- signer = File::SignerV2.from_file self
1578
- signer.signed_url method: method,
1579
- expires: expires,
1580
- headers: headers,
1581
- content_type: content_type,
1582
- content_md5: content_md5,
1583
- issuer: issuer,
1584
- client_email: client_email,
1585
- signing_key: signing_key,
1586
- private_key: private_key,
1587
- query: query
1629
+ sign = File::SignerV2.from_file self
1630
+ sign.signed_url method: method,
1631
+ expires: expires,
1632
+ headers: headers,
1633
+ content_type: content_type,
1634
+ content_md5: content_md5,
1635
+ issuer: issuer,
1636
+ client_email: client_email,
1637
+ signing_key: signing_key,
1638
+ private_key: private_key,
1639
+ signer: signer,
1640
+ query: query
1588
1641
  when :v4
1589
- signer = File::SignerV4.from_file self
1590
- signer.signed_url method: method,
1591
- expires: expires,
1592
- headers: headers,
1593
- issuer: issuer,
1594
- client_email: client_email,
1595
- signing_key: signing_key,
1596
- private_key: private_key,
1597
- query: query,
1598
- scheme: scheme,
1599
- virtual_hosted_style: virtual_hosted_style,
1600
- bucket_bound_hostname: bucket_bound_hostname
1642
+ sign = File::SignerV4.from_file self
1643
+ sign.signed_url method: method,
1644
+ expires: expires,
1645
+ headers: headers,
1646
+ issuer: issuer,
1647
+ client_email: client_email,
1648
+ signing_key: signing_key,
1649
+ private_key: private_key,
1650
+ signer: signer,
1651
+ query: query,
1652
+ scheme: scheme,
1653
+ virtual_hosted_style: virtual_hosted_style,
1654
+ bucket_bound_hostname: bucket_bound_hostname
1601
1655
  else
1602
1656
  raise ArgumentError, "version '#{version}' not supported"
1603
1657
  end
@@ -77,13 +77,21 @@ module Google
77
77
  end
78
78
 
79
79
  def determine_signing_key options = {}
80
- options[:signing_key] || options[:private_key] ||
81
- @service.credentials.signing_key
80
+ signing_key = options[:signing_key] || options[:private_key] ||
81
+ options[:signer] || @service.credentials.signing_key
82
+ raise SignedUrlUnavailable, error_msg("signing_key (private_key, signer)") unless signing_key
83
+ signing_key
82
84
  end
83
85
 
84
86
  def determine_issuer options = {}
85
- options[:issuer] || options[:client_email] ||
86
- @service.credentials.issuer
87
+ issuer = options[:issuer] || options[:client_email] || @service.credentials.issuer
88
+ raise SignedUrlUnavailable, error_msg("issuer (client_email)") unless issuer
89
+ issuer
90
+ end
91
+
92
+ def error_msg attr_name
93
+ "Service account credentials '#{attr_name}' is missing. To generate service account credentials " \
94
+ "see https://cloud.google.com/iam/docs/service-accounts"
87
95
  end
88
96
 
89
97
  def post_object options
@@ -99,8 +107,6 @@ module Google
99
107
  i = determine_issuer options
100
108
  s = determine_signing_key options
101
109
 
102
- raise SignedUrlUnavailable unless i && s
103
-
104
110
  policy_str = p.to_json
105
111
  policy = Base64.strict_encode64(policy_str).delete "\n"
106
112
 
@@ -119,18 +125,21 @@ module Google
119
125
  i = determine_issuer options
120
126
  s = determine_signing_key options
121
127
 
122
- raise SignedUrlUnavailable unless i && s
123
-
124
128
  sig = generate_signature s, signature_str(options)
125
129
  generate_signed_url i, sig, options[:expires], options[:query]
126
130
  end
127
131
 
128
132
  def generate_signature signing_key, secret
129
- unless signing_key.respond_to? :sign
130
- signing_key = OpenSSL::PKey::RSA.new signing_key
133
+ unencoded_signature = ""
134
+ if signing_key.is_a? Proc
135
+ unencoded_signature = signing_key.call secret
136
+ else
137
+ unless signing_key.respond_to? :sign
138
+ signing_key = OpenSSL::PKey::RSA.new signing_key
139
+ end
140
+ unencoded_signature = signing_key.sign OpenSSL::Digest::SHA256.new, secret
131
141
  end
132
- signature = signing_key.sign OpenSSL::Digest::SHA256.new, secret
133
- Base64.strict_encode64(signature).delete "\n"
142
+ Base64.strict_encode64(unencoded_signature).delete "\n"
134
143
  end
135
144
 
136
145
  def generate_signed_url issuer, signed_string, expires, query
@@ -43,6 +43,7 @@ module Google
43
43
  client_email: nil,
44
44
  signing_key: nil,
45
45
  private_key: nil,
46
+ signer: nil,
46
47
  expires: nil,
47
48
  fields: nil,
48
49
  conditions: nil,
@@ -50,8 +51,7 @@ module Google
50
51
  virtual_hosted_style: nil,
51
52
  bucket_bound_hostname: nil
52
53
  i = determine_issuer issuer, client_email
53
- s = determine_signing_key signing_key, private_key
54
- raise SignedUrlUnavailable unless i && s
54
+ s = determine_signing_key signing_key, private_key, signer
55
55
 
56
56
  now = Time.now.utc
57
57
  base_fields = required_fields i, now
@@ -82,12 +82,13 @@ module Google
82
82
  client_email: nil,
83
83
  signing_key: nil,
84
84
  private_key: nil,
85
+ signer: nil,
85
86
  query: nil,
86
87
  scheme: "https",
87
88
  virtual_hosted_style: nil,
88
89
  bucket_bound_hostname: nil
89
90
  raise ArgumentError, "method is required" unless method
90
- issuer, signer = issuer_and_signer issuer, client_email, signing_key, private_key
91
+ issuer, signer = issuer_and_signer issuer, client_email, signing_key, private_key, signer
91
92
  datetime_now = Time.now.utc
92
93
  goog_date = datetime_now.strftime "%Y%m%dT%H%M%SZ"
93
94
  datestamp = datetime_now.strftime "%Y%m%d"
@@ -192,28 +193,40 @@ module Google
192
193
  def determine_issuer issuer, client_email
193
194
  # Parse the Service Account and get client id and private key
194
195
  issuer = issuer || client_email || @service.credentials.issuer
195
- raise SignedUrlUnavailable, "issuer (client_email) missing" unless issuer
196
+ raise SignedUrlUnavailable, error_msg("issuer (client_email)") unless issuer
196
197
  issuer
197
198
  end
198
199
 
199
- def determine_signing_key signing_key, private_key
200
- signing_key = signing_key || private_key || @service.credentials.signing_key
201
- raise SignedUrlUnavailable, "signing_key (private_key) missing" unless signing_key
200
+ def determine_signing_key signing_key, private_key, signer
201
+ signing_key = signing_key || private_key || signer || @service.credentials.signing_key
202
+ raise SignedUrlUnavailable, error_msg("signing_key (private_key, signer)") unless signing_key
202
203
  signing_key
203
204
  end
204
205
 
206
+ def error_msg attr_name
207
+ "Service account credentials '#{attr_name}' is missing. To generate service account credentials " \
208
+ "see https://cloud.google.com/iam/docs/service-accounts"
209
+ end
210
+
205
211
  def service_account_signer signer
206
- signer = OpenSSL::PKey::RSA.new signer unless signer.respond_to? :sign
207
- # Sign string to sign
208
- lambda do |string_to_sign|
209
- sig = signer.sign OpenSSL::Digest::SHA256.new, string_to_sign
210
- sig.unpack("H*").first
212
+ if signer.is_a? Proc
213
+ lambda do |string_to_sign|
214
+ sig = signer.call string_to_sign
215
+ sig.unpack("H*").first
216
+ end
217
+ else
218
+ signer = OpenSSL::PKey::RSA.new signer unless signer.respond_to? :sign
219
+ # Sign string to sign
220
+ lambda do |string_to_sign|
221
+ sig = signer.sign OpenSSL::Digest::SHA256.new, string_to_sign
222
+ sig.unpack("H*").first
223
+ end
211
224
  end
212
225
  end
213
226
 
214
- def issuer_and_signer issuer, client_email, signing_key, private_key
227
+ def issuer_and_signer issuer, client_email, signing_key, private_key, signer
215
228
  issuer = determine_issuer issuer, client_email
216
- signing_key = determine_signing_key signing_key, private_key
229
+ signing_key = determine_signing_key signing_key, private_key, signer
217
230
  signer = service_account_signer signing_key
218
231
  [issuer, signer]
219
232
  end
@@ -337,11 +350,16 @@ module Google
337
350
  end
338
351
 
339
352
  def generate_signature signing_key, data
340
- unless signing_key.respond_to? :sign
341
- signing_key = OpenSSL::PKey::RSA.new signing_key
353
+ packed_signature = nil
354
+ if signing_key.is_a? Proc
355
+ packed_signature = signing_key.call data
356
+ else
357
+ unless signing_key.respond_to? :sign
358
+ signing_key = OpenSSL::PKey::RSA.new signing_key
359
+ end
360
+ packed_signature = signing_key.sign OpenSSL::Digest::SHA256.new, data
342
361
  end
343
- signature = signing_key.sign OpenSSL::Digest::SHA256.new, data
344
- signature.unpack("H*").first.force_encoding "utf-8"
362
+ packed_signature.unpack("H*").first.force_encoding "utf-8"
345
363
  end
346
364
  end
347
365
  end
@@ -483,7 +483,7 @@ module Google
483
483
  # A {SignedUrlUnavailable} is raised if the service account credentials
484
484
  # are missing. Service account credentials are acquired by following the
485
485
  # steps in [Service Account Authentication](
486
- # https://cloud.google.com/storage/docs/authentication#service_accounts).
486
+ # https://cloud.google.com/iam/docs/service-accounts).
487
487
  #
488
488
  # @see https://cloud.google.com/storage/docs/access-control/signed-urls
489
489
  # Signed URLs guide
@@ -511,10 +511,22 @@ module Google
511
511
  # use the signed URL.
512
512
  # @param [String] issuer Service Account's Client Email.
513
513
  # @param [String] client_email Service Account's Client Email.
514
- # @param [OpenSSL::PKey::RSA, String] signing_key Service Account's
515
- # Private Key.
516
- # @param [OpenSSL::PKey::RSA, String] private_key Service Account's
517
- # Private Key.
514
+ # @param [OpenSSL::PKey::RSA, String, Proc] signing_key Service Account's
515
+ # Private Key or a Proc that accepts a single String parameter and returns a
516
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
517
+ # @param [OpenSSL::PKey::RSA, String, Proc] private_key Service Account's
518
+ # Private Key or a Proc that accepts a single String parameter and returns a
519
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
520
+ # @param [OpenSSL::PKey::RSA, String, Proc] signer Service Account's
521
+ # Private Key or a Proc that accepts a single String parameter and returns a
522
+ # RSA SHA256 signature using a valid Google Service Account Private Key.
523
+ #
524
+ # When using this method in environments such as GAE Flexible Environment,
525
+ # GKE, or Cloud Functions where the private key is unavailable, it may be
526
+ # necessary to provide a Proc (or lambda) via the signer parameter. This
527
+ # Proc should return a signature created using a RPC call to the
528
+ # [Service Account Credentials signBlob](https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob)
529
+ # method as shown in the example below.
518
530
  # @param [Hash] query Query string parameters to include in the signed
519
531
  # URL. The given parameters are not verified by the signature.
520
532
  #
@@ -540,7 +552,12 @@ module Google
540
552
  # to create. Must be one of `:v2` or `:v4`. The default value is
541
553
  # `:v2`.
542
554
  #
543
- # @return [String]
555
+ # @return [String] The signed URL.
556
+ #
557
+ # @raise [SignedUrlUnavailable] If the service account credentials
558
+ # are missing. Service account credentials are acquired by following the
559
+ # steps in [Service Account Authentication](
560
+ # https://cloud.google.com/iam/docs/service-accounts).
544
561
  #
545
562
  # @example
546
563
  # require "google/cloud/storage"
@@ -575,6 +592,41 @@ module Google
575
592
  # issuer: issuer_email,
576
593
  # signing_key: key
577
594
  #
595
+ # @example Using Cloud IAMCredentials signBlob to create the signature:
596
+ # require "google/cloud/storage"
597
+ # require "google/apis/iamcredentials_v1"
598
+ # require "googleauth"
599
+ #
600
+ # # Issuer is the service account email that the Signed URL will be signed with
601
+ # # and any permission granted in the Signed URL must be granted to the
602
+ # # Google Service Account.
603
+ # issuer = "service-account@project-id.iam.gserviceaccount.com"
604
+ #
605
+ # # Create a lambda that accepts the string_to_sign
606
+ # signer = lambda do |string_to_sign|
607
+ # IAMCredentials = Google::Apis::IamcredentialsV1
608
+ # iam_client = IAMCredentials::IAMCredentialsService.new
609
+ #
610
+ # # Get the environment configured authorization
611
+ # scopes = ["https://www.googleapis.com/auth/iam"]
612
+ # iam_client.authorization = Google::Auth.get_application_default scopes
613
+ #
614
+ # request = {
615
+ # "payload": string_to_sign,
616
+ # }
617
+ # resource = "projects/-/serviceAccounts/#{issuer}"
618
+ # response = iam_client.sign_service_account_blob resource, request, {}
619
+ # response.signed_blob
620
+ # end
621
+ #
622
+ # storage = Google::Cloud::Storage.new
623
+ #
624
+ # bucket_name = "my-todo-app"
625
+ # file_path = "avatars/heidi/400x400.png"
626
+ # url = storage.signed_url bucket_name, file_path,
627
+ # method: "GET", issuer: issuer,
628
+ # signer: signer
629
+ #
578
630
  # @example Using the `headers` option:
579
631
  # require "google/cloud/storage"
580
632
  #
@@ -616,6 +668,7 @@ module Google
616
668
  client_email: nil,
617
669
  signing_key: nil,
618
670
  private_key: nil,
671
+ signer: nil,
619
672
  query: nil,
620
673
  scheme: "HTTPS",
621
674
  virtual_hosted_style: nil,
@@ -624,31 +677,32 @@ module Google
624
677
  version ||= :v2
625
678
  case version.to_sym
626
679
  when :v2
627
- signer = File::SignerV2.new bucket, path, service
628
-
629
- signer.signed_url method: method,
630
- expires: expires,
631
- headers: headers,
632
- content_type: content_type,
633
- content_md5: content_md5,
634
- issuer: issuer,
635
- client_email: client_email,
636
- signing_key: signing_key,
637
- private_key: private_key,
638
- query: query
680
+ sign = File::SignerV2.new bucket, path, service
681
+ sign.signed_url method: method,
682
+ expires: expires,
683
+ headers: headers,
684
+ content_type: content_type,
685
+ content_md5: content_md5,
686
+ issuer: issuer,
687
+ client_email: client_email,
688
+ signing_key: signing_key,
689
+ private_key: private_key,
690
+ signer: signer,
691
+ query: query
639
692
  when :v4
640
- signer = File::SignerV4.new bucket, path, service
641
- signer.signed_url method: method,
642
- expires: expires,
643
- headers: headers,
644
- issuer: issuer,
645
- client_email: client_email,
646
- signing_key: signing_key,
647
- private_key: private_key,
648
- query: query,
649
- scheme: scheme,
650
- virtual_hosted_style: virtual_hosted_style,
651
- bucket_bound_hostname: bucket_bound_hostname
693
+ sign = File::SignerV4.new bucket, path, service
694
+ sign.signed_url method: method,
695
+ expires: expires,
696
+ headers: headers,
697
+ issuer: issuer,
698
+ client_email: client_email,
699
+ signing_key: signing_key,
700
+ private_key: private_key,
701
+ signer: signer,
702
+ query: query,
703
+ scheme: scheme,
704
+ virtual_hosted_style: virtual_hosted_style,
705
+ bucket_bound_hostname: bucket_bound_hostname
652
706
  else
653
707
  raise ArgumentError, "version '#{version}' not supported"
654
708
  end
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Storage
19
- VERSION = "1.26.2".freeze
19
+ VERSION = "1.27.0".freeze
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-storage
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.26.2
4
+ version: 1.27.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-05-28 00:00:00.000000000 Z
12
+ date: 2020-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-cloud-core
@@ -298,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
298
298
  - !ruby/object:Gem::Version
299
299
  version: '0'
300
300
  requirements: []
301
- rubygems_version: 3.0.6
301
+ rubygems_version: 3.1.3
302
302
  signing_key:
303
303
  specification_version: 4
304
304
  summary: API Client library for Google Cloud Storage