google-cloud-storage 1.26.2 → 1.27.0

Sign up to get free protection for your applications and to get access to all the features.
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