Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create signed URL V4 conformance tests #2250

Merged
merged 25 commits into from
Mar 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4dcfe96
Create signed URL V4 conformance tests
rsimion Mar 18, 2019
a66e66f
Cchanges to simplify the code
rsimion Mar 18, 2019
5599910
Some changes in the json file and integration test file
rsimion Mar 18, 2019
54ae86c
Reverted some changes
rsimion Mar 19, 2019
838663c
A lot of changes
rsimion Mar 19, 2019
e32549b
Merge branch 'master' into storage_branch
rsimion Mar 19, 2019
0aafd70
Merge branch 'master' into storage_branch
rsimion Mar 20, 2019
94d62f9
Major changes in both files
rsimion Mar 20, 2019
33a13da
Merge branch 'master' into storage_branch
rsimion Mar 21, 2019
656126a
Merge branch 'master' into storage_branch
rsimion Mar 21, 2019
cc49627
Made changes in the new integration test file
rsimion Mar 22, 2019
d9597ac
Removed throw
rsimion Mar 22, 2019
e725f49
Minor changes
rsimion Mar 22, 2019
1755b1e
Merge branch 'master' into storage_branch
rsimion Mar 24, 2019
35c10c8
Updated the json file and the integration test file
rsimion Mar 25, 2019
b0889b0
Merge branch 'master' into storage_branch
rsimion Mar 25, 2019
531584b
Merge branch 'master' into storage_branch
rsimion Mar 27, 2019
3b1923a
New changes in both, json and integration test files
rsimion Mar 27, 2019
ce7edd1
Fixing my mistake in the integration test file
rsimion Mar 27, 2019
51b7581
Cleaning up the clutter
rsimion Mar 27, 2019
2667b47
Merge branch 'master' into storage_branch
rsimion Mar 27, 2019
8316edb
Minor change of a comment
rsimion Mar 28, 2019
4118acc
More cleanup
rsimion Mar 28, 2019
4d831a4
Merge branch 'master' into storage_branch
rsimion Mar 28, 2019
307a7a2
Updated both files after #2350 was fixed
rsimion Mar 28, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions google/cloud/storage/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

set(storage_client_integration_tests
bucket_integration_test.cc
client_sign_url_integration_test.cc
curl_upload_request_integration_test.cc
curl_download_request_integration_test.cc
curl_request_integration_test.cc
Expand Down
12 changes: 12 additions & 0 deletions google/cloud/storage/tests/UrlSignerV4TestAccount.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"type": "service_account",
"project_id": "dummy-project-id",
"private_key_id": "ffffffffffffffffffffffffffffffffffffffff",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCsPzMirIottfQ2\nryjQmPWocSEeGo7f7Q4/tMQXHlXFzo93AGgU2t+clEj9L5loNhLVq+vk+qmnyDz5\nQ04y8jVWyMYzzGNNrGRW/yaYqnqlKZCy1O3bmnNjV7EDbC/jE1ZLBY0U3HaSHfn6\nS9ND8MXdgD0/ulRTWwq6vU8/w6i5tYsU7n2LLlQTl1fQ7/emO9nYcCFJezHZVa0H\nmeWsdHwWsok0skwQYQNIzP3JF9BpR5gJT2gNge6KopDesJeLoLzaX7cUnDn+CAnn\nLuLDwwSsIVKyVxhBFsFXPplgpaQRwmGzwEbf/Xpt9qo26w2UMgn30jsOaKlSeAX8\ncS6ViF+tAgMBAAECggEACKRuJCP8leEOhQziUx8Nmls8wmYqO4WJJLyk5xUMUC22\nSI4CauN1e0V8aQmxnIc0CDkFT7qc9xBmsMoF+yvobbeKrFApvlyzNyM7tEa/exh8\nDGD/IzjbZ8VfWhDcUTwn5QE9DCoon9m1sG+MBNlokB3OVOt8LieAAREdEBG43kJu\nyQTOkY9BGR2AY1FnAl2VZ/jhNDyrme3tp1sW1BJrawzR7Ujo8DzlVcS2geKA9at7\n55ua5GbHz3hfzFgjVXDfnkWzId6aHypUyqHrSn1SqGEbyXTaleKTc6Pgv0PgkJjG\nhZazWWdSuf1T5Xbs0OhAK9qraoAzT6cXXvMEvvPt6QKBgQDXcZKqJAOnGEU4b9+v\nOdoh+nssdrIOBNMu1m8mYbUVYS1aakc1iDGIIWNM3qAwbG+yNEIi2xi80a2RMw2T\n9RyCNB7yqCXXVKLBiwg9FbKMai6Vpk2bWIrzahM9on7AhCax/X2AeOp+UyYhFEy6\nUFG4aHb8THscL7b515ukSuKb5QKBgQDMq+9PuaB0eHsrmL6q4vHNi3MLgijGg/zu\nAXaPygSYAwYW8KglcuLZPvWrL6OG0+CrfmaWTLsyIZO4Uhdj7MLvX6yK7IMnagvk\nL3xjgxSklEHJAwi5wFeJ8ai/1MIuCn8p2re3CbwISKpvf7Sgs/W4196P4vKvTiAz\njcTiSYFIKQKBgCjMpkS4O0TakMlGTmsFnqyOneLmu4NyIHgfPb9cA4n/9DHKLKAT\noaWxBPgatOVWs7RgtyGYsk+XubHkpC6f3X0+15mGhFwJ+CSE6tN+l2iF9zp52vqP\nQwkjzm7+pdhZbmaIpcq9m1K+9lqPWJRz/3XXuqi+5xWIZ7NaxGvRjqaNAoGAdK2b\nutZ2y48XoI3uPFsuP+A8kJX+CtWZrlE1NtmS7tnicdd19AtfmTuUL6fz0FwfW4Su\nlQZfPT/5B339CaEiq/Xd1kDor+J7rvUHM2+5p+1A54gMRGCLRv92FQ4EON0RC1o9\nm2I4SHysdO3XmjmdXmfp4BsgAKJIJzutvtbqlakCgYB+Cb10z37NJJ+WgjDt+yT2\nyUNH17EAYgWXryfRgTyi2POHuJitd64Xzuy6oBVs3wVveYFM6PIKXlj8/DahYX5I\nR2WIzoCNLL3bEZ+nC6Jofpb4kspoAeRporj29SgesK6QBYWHWX2H645RkRGYGpDo\n51gjy9m/hSNqBbH2zmh04A==\n-----END PRIVATE KEY-----\n",
"client_email": "[email protected]",
"client_id": "000000000000000000000",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com"
}
122 changes: 122 additions & 0 deletions google/cloud/storage/tests/UrlSignerV4TestData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
[
{
"description": "Simple GET",
"bucket": "test-bucket",
"object": "test-object",
"method": "GET",
"expiration": 10,
"timestamp": "20190201T090000Z",
"expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=host&X-Goog-Signature=95e6a13d43a1d1962e667f17397f2b80ac9bdd1669210d5e08e0135df9dff4e56113485dbe429ca2266487b9d1796ebdee2d7cf682a6ef3bb9fbb4c351686fba90d7b621cf1c4eb1fdf126460dd25fa0837dfdde0a9fd98662ce60844c458448fb2b352c203d9969cb74efa4bdb742287744a4f2308afa4af0e0773f55e32e92973619249214b97283b2daa14195244444e33f938138d1e5f561088ce8011f4986dda33a556412594db7c12fc40e1ff3f1bedeb7a42f5bcda0b9567f17f65855f65071fabb88ea12371877f3f77f10e1466fff6ff6973b74a933322ff0949ce357e20abe96c3dd5cfab42c9c83e740a4d32b9e11e146f0eb3404d2e975896f74"
},

{
"description": "Simple PUT",
"bucket": "test-bucket",
"object": "test-object",
"method": "PUT",
"expiration": 10,
"timestamp": "20190201T090000Z",
"expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=host&X-Goog-Signature=8adff1d4285739e31aa68e73767a46bc5511fde377497dbe08481bf5ceb34e29cc9a59921748d8ec3dd4085b7e9b7772a952afedfcdaecb3ae8352275b8b7c867f204e3db85076220a3127a8a9589302fc1181eae13b9b7fe41109ec8cdc93c1e8bac2d7a0cc32a109ca02d06957211326563ab3d3e678a0ba296e298b5fc5e14593c99d444c94724cc4be97015dbff1dca377b508fa0cb7169195de98d0e4ac96c42b918d28c8d92d33e1bd125ce0fb3cd7ad2c45dae65c22628378f6584971b8bf3945b26f2611eb651e9b6a8648970c1ecf386bb71327b082e7296c4e1ee2fc0bdd8983da80af375c817fb1ad491d0bc22c0f51dba0d66e2cffbc90803e47"
},

{
"description": "POST for resumable uploads",
"bucket": "test-bucket",
"object": "test-object",
"method": "POST",
"expiration": 10,
"headers": {
"x-goog-resumable": "start"
},
"timestamp": "20190201T090000Z",
"expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=host%3Bx-goog-resumable&X-Goog-Signature=4a6d39b23343cedf4c30782aed4b384001828c79ffa3a080a481ea01a640dea0a0ceb58d67a12cef3b243c3f036bb3799c6ee88e8db3eaf7d0bdd4b70a228d0736e07eaa1ee076aff5c6ce09dff1f1f03a0d8ead0d2893408dd3604fdabff553aa6d7af2da67cdba6790006a70240f96717b98f1a6ccb24f00940749599be7ef72aaa5358db63ddd54b2de9e2d6d6a586eac4fe25f36d86fc6ab150418e9c6fa01b732cded226c6d62fc95b72473a4cc55a8257482583fe66d9ab6ede909eb41516a8690946c3e87b0f2052eb0e97e012a14b2f721c42e6e19b8a1cd5658ea36264f10b9b1ada66b8ed5bf7ed7d1708377ac6e5fe608ae361fb594d2e5b24c54"
},

{
"description": "Vary expiration and timestamp",
"bucket": "test-bucket",
"object": "test-object",
"method": "GET",
"expiration": 20,
"timestamp": "20190301T090000Z",
"expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190301%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190301T090000Z&X-Goog-Expires=20&X-Goog-SignedHeaders=host&X-Goog-Signature=9669ed5b10664dc594c758296580662912cf4bcc5a4ba0b6bf055bcbf6f34eed7bdad664f534962174a924741a0c273a4f67bc1847cef20192a6beab44223bd9d4fbbd749c407b79997598c30f82ddc269ff47ec09fa3afe74e00616d438df0d96a7d8ad0adacfad1dc3286f864d924fe919fb0dce45d3d975c5afe8e13af2db9cc37ba77835f92f7669b61e94c6d562196c1274529e76cfff1564cc2cad7d5387dc8e12f7a5dfd925685fe92c30b43709eee29fa2f66067472cee5423d1a3a4182fe8cea75c9329d181dc6acad7c393cd04f8bf5bc0515127d8ebd65d80c08e19ad03316053ea60033fd1b1fd85a69c576415da3bf0a3718d9ea6d03e0d66f0"
},

{
"description": "Vary bucket and object",
"bucket": "test-bucket2",
"object": "test-object2",
"method": "GET",
"expiration": 10,
"timestamp": "20190201T090000Z",
"expectedUrl": "https://storage.googleapis.com/test-bucket2/test-object2?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=host&X-Goog-Signature=36e3d58dfd3ec1d2dd2f24b5ee372a71e811ffaa2162a2b871d26728d0354270bc116face87127532969c4a3967ed05b7309af741e19c7202f3167aa8c2ac420b61417d6451442bb91d7c822cd17be8783f01e05372769c88913561d27e6660dd8259f0081a71f831be6c50283626cbf04494ac10c394b29bb3bce74ab91548f58a37118a452693cf0483d77561fc9cac8f1765d2c724994cca46a83517a10157ee0347a233a2aaeae6e6ab5e204ff8fc5f54f90a3efdb8301d9fff5475d58cd05b181affd657f48203f4fb133c3a3d355b8eefbd10d5a0a5fd70d06e9515460ad74e22334b2cba4b29cae4f6f285cdb92d8f3126d7a1479ca3bdb69c207d860"
},

{
"description": "Simple headers",
"bucket": "test-bucket",
"object": "test-object",
"headers": {
"foo": "foo-value",
"BAR": "BAR-value"
},
"method": "GET",
"expiration": 10,
"timestamp": "20190201T090000Z",
"expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=bar%3Bfoo%3Bhost&X-Goog-Signature=68ecd3b008328ed30d91e2fe37444ed7b9b03f28ed4424555b5161980531ef87db1c3a5bc0265aad5640af30f96014c94fb2dba7479c41bfe1c020eb90c0c6d387d4dd09d4a5df8b60ea50eb6b01cdd786a1e37020f5f95eb8f9b6cd3f65a1f8a8a65c9fcb61ea662959efd9cd73b683f8d8804ef4d6d9b2852419b013368842731359d7f9e6d1139032ceca75d5e67cee5fd0192ea2125e5f2955d38d3d50cf116f3a52e6a62de77f6207f5b95aaa1d7d0f8a46de89ea72e7ea30f21286318d7eba0142232b0deb3a1dc9e1e812a981c66b5ffda3c6b01a8a9d113155792309fd53a3acfd054ca7776e8eec28c26480cd1e3c812f67f91d14217f39a606669d"
},

{
"description": "Headers should be trimmed",
"bucket": "test-bucket",
"object": "test-object",
"headers": {
"leading": " xyz",
"trailing": "abc ",
"collapsed": "abc def"
},
"method": "GET",
"expiration": 10,
"timestamp": "20190201T090000Z",
"expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=collapsed%3Bhost%3Bleading%3Btrailing&X-Goog-Signature=1839511d6238d9ac2bbcbba8b23515b3757db35dfa7b8f9bc4b8b4aa270224df747c812526f1a3bcf294d67ed84cd14e074c36bc090e0a542782934a7c925af4a5ea68123e97533704ce8b08ccdf5fe6b412f89c9fc4de243e29abdb098382c5672188ee3f6fef7131413e252c78e7a35658825ad842a50609e9cc463731e17284ff7a14824c989f87cef22fb99dfec20cfeed69d8b3a08f00b43b8284eecd535e50e982b05cd74c5750cd5f986cfc21a2a05f7f3ab7fc31bd684ed1b823b64d29281e923fc6580c49005552ca19c253de087d9d2df881144e44eda40965cfdb4889bf3a35553c9809f4ed20b8355be481b92b9618952b6a04f3017b36053e15"
},

{
"description": "Header value with multiple inline values",
"bucket": "test-bucket",
"object": "test-object",
"headers": {
"multiple": " xyz , abc, def , xyz "
},
"method": "GET",
"expiration": 10,
"timestamp": "20190201T090000Z",
"expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=host%3Bmultiple&X-Goog-Signature=5cc113735625341f59c7203f0c2c9febc95ba6af6b9c38814f8e523214712087dc0996e4960d273ae1889f248ac1e58d4d19cb3a69ad7670e9a8ca1b434e878f59339dc7006cf32dfd715337e9f593e0504371839174962a08294586e0c78160a7aa303397888c8350637c6af3b32ac310886cc4590bfda9ca561ee58fb5b8ec56bc606d2ada6e7df31f4276e9dcb96bcaea39dc2cd096f3fad774f9c4b30e317ad43736c05f76831437f44e8726c1e90d3f6c9827dc273f211f32fc85658dfc5d357eb606743a6b00a29e519eef1bebaf9db3e8f4b1f5f9afb648ad06e60bc42fa8b57025056697c874c9ea76f5a73201c9717ea43e54713ff3502ff3fc626b"
},

{
"description": "Customer-supplied encryption key",
"bucket": "test-bucket",
"object": "test-object",
"headers":
{
"X-Goog-Encryption-Key": "key",
"X-Goog-Encryption-Key-Sha256": "key-hash",
"X-Goog-Encryption-Algorithm": "AES256"
},
"method": "GET",
"expiration": 10,
"timestamp": "20190201T090000Z",
"expectedUrl": "https://storage.googleapis.com/test-bucket/test-object?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=host%3Bx-goog-encryption-algorithm%3Bx-goog-encryption-key%3Bx-goog-encryption-key-sha256&X-Goog-Signature=278a1c5a3bad248637054a047014760353942433955871031ed08f515b54588654ad033e91f046ab202b68673030e117d1b786c325e870238b035ba75b3feed560a17aff9bab6bddebd4a31a52cb68b214e27d3b0bd886502c6b36b164306fe88b5a07c6063592afe746b2a5d205dbe90dd5386b94f0a78f75d9f53ee884e18f476e8fc2eb1dd910ce0b4ae1f5d7b09876ef9bf983f539c028429e14bad3c75dbd4ed1ae37856f6d6f8a1805eaf8b52a0d6fc993902e4c1ee8de477661f7b67c3663000474cb00e178189789b2a3ed6bd21b4ade684fca8108ac4dd106acb17f5954d045775f7aa5a98ebda5d3075e11a8ea49c64c6ad1481e463e8c9f11f704"
},

{
"description": "List Objects",
"bucket": "test-bucket",
"object": "",
"method": "GET",
"expiration": 10,
"timestamp": "20190201T090000Z",
"expectedUrl": "https://storage.googleapis.com/test-bucket?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=test-iam-credentials%40dummy-project-id.iam.gserviceaccount.com%2F20190201%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20190201T090000Z&X-Goog-Expires=10&X-Goog-SignedHeaders=host&X-Goog-Signature=6dbe94f8e52b2b8a9a476b1c857efa474e09944e2b52b925800316e094a7169d8dbe0df9c0ac08dabb22ac7e827470ceccd65f5a3eadba2a4fb9beebfe37f0d9bb1e552b851fa31a25045bdf019e507f5feb44f061551ef1aeb18dcec0e38ba2e2f77d560a46eaace9c56ed9aa642281301a9d848b0eb30749e34bc7f73a3d596240533466ff9b5f289cd0d4c845c7d96b82a35a5abd0c3aff83e4440ee6873e796087f43545544dc8c01afe1d79c726696b6f555371e491980e7ec145cca0803cf562c38f3fa1d724242f5dea25aac91d74ec9ddd739ff65523627763eaef25cd1f95ad985aaf0079b7c74eb5bcb2870a9b137a7b2c8e41fbe838c95872f75b"
}
]
155 changes: 155 additions & 0 deletions google/cloud/storage/tests/client_sign_url_integration_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// Copyright 2019 Google LLC
//
// 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.

#include "google/cloud/storage/client.h"
#include "google/cloud/storage/internal/nljson.h"
#include "google/cloud/storage/list_objects_reader.h"
#include "google/cloud/storage/testing/storage_integration_test.h"
#include "google/cloud/testing_util/assert_ok.h"
#include "google/cloud/testing_util/init_google_mock.h"
#include <gmock/gmock.h>
#include <fstream>

namespace nl = google::cloud::storage::internal::nl;
namespace google {
namespace cloud {
namespace storage {
inline namespace STORAGE_CLIENT_NS {
namespace {
using ::testing::HasSubstr;

// Initialized in main() below.
char const* account_file_name_;
char const* data_file_name_;

class ObjectIntegrationTest
: public google::cloud::storage::testing::StorageIntegrationTest {
protected:
// Converts ""20190201T090000Z",
// to "2019-02-01T09:00:00Z"
std::string TimestampToRfc3339(std::string ts) {
if (ts.size() != 16) {
return "";
}
return ts.substr(0, 4) + '-' + ts.substr(4, 2) + '-' + ts.substr(6, 2) +
'T' + ts.substr(9, 2) + ':' + ts.substr(11, 2) + ':' +
ts.substr(13, 2) + 'Z';
}

std::vector<std::pair<std::string, std::string>> ExtractHeaders(
nl::json j_obj) {
std::vector<std::pair<std::string, std::string>> headers;

// Check for the keys of the headers field
for (auto& x : j_obj["headers"].items()) {
// The keys are returned in alphabetical order by nlohmann::json, but
// the order does not matter when creating signed urls.
headers.emplace_back(x.key(), x.value());
}
return headers;
}
};

TEST_F(ObjectIntegrationTest, V4SignJson) {
// This is a dummy service account JSON file that is inactive. It's fine for
// it to be public.
std::string account_file = account_file_name_;
std::string data_file = data_file_name_;

std::ifstream ifstr(data_file);
ASSERT_TRUE(ifstr.is_open());

nl::json json_array = nl::json::parse(ifstr);
auto creds =
oauth2::CreateServiceAccountCredentialsFromJsonFilePath(account_file);

ASSERT_STATUS_OK(creds);
Client client(*creds);
StatusOr<std::string> actual;

for (auto const& j_obj : json_array) {
std::string const method_name = j_obj["method"];
std::string const bucket_name = j_obj["bucket"];
std::string const object_name = j_obj["object"];
std::string const date = TimestampToRfc3339(j_obj["timestamp"]);
auto const valid_for = std::chrono::seconds(j_obj["expiration"]);
std::string const expected = j_obj["expectedUrl"];

// Extract the headers for each object
std::vector<std::pair<std::string, std::string>> headers =
ExtractHeaders(j_obj);

if (headers.size() == 0) {
actual = client.CreateV4SignedUrl(
method_name, bucket_name, object_name,
SignedUrlTimestamp(internal::ParseRfc3339(date)),
SignedUrlDuration(valid_for),
AddExtensionHeader("host", "storage.googleapis.com"));
} else if (headers.size() == 1) {
actual = client.CreateV4SignedUrl(
method_name, bucket_name, object_name,
SignedUrlTimestamp(internal::ParseRfc3339(date)),
SignedUrlDuration(valid_for),
AddExtensionHeader("host", "storage.googleapis.com"),
AddExtensionHeader(headers.at(0).first, headers.at(0).second));
} else if (headers.size() == 2) {
actual = client.CreateV4SignedUrl(
method_name, bucket_name, object_name,
SignedUrlTimestamp(internal::ParseRfc3339(date)),
SignedUrlDuration(valid_for),
AddExtensionHeader("host", "storage.googleapis.com"),
AddExtensionHeader(headers.at(0).first, headers.at(0).second),
AddExtensionHeader(headers.at(1).first, headers.at(1).second));
} else if (headers.size() == 3) {
actual = client.CreateV4SignedUrl(
method_name, bucket_name, object_name,
SignedUrlTimestamp(internal::ParseRfc3339(date)),
SignedUrlDuration(valid_for),
AddExtensionHeader("host", "storage.googleapis.com"),
AddExtensionHeader(headers.at(0).first, headers.at(0).second),
AddExtensionHeader(headers.at(1).first, headers.at(1).second),
AddExtensionHeader(headers.at(2).first, headers.at(2).second));
} else {
EXPECT_LT(headers.size(), 4);
}
ASSERT_STATUS_OK(actual);
EXPECT_THAT(*actual, HasSubstr(bucket_name));
EXPECT_THAT(*actual, HasSubstr(object_name));
EXPECT_EQ(expected, *actual);
}
}

} // namespace
} // namespace STORAGE_CLIENT_NS
} // namespace storage
} // namespace cloud
} // namespace google

int main(int argc, char* argv[]) {
google::cloud::testing_util::InitGoogleMock(argc, argv);

// Make sure the arguments are valid.
if (argc != 3) {
std::string const cmd = argv[0];
auto last_slash = std::string(argv[0]).find_last_of('/');
std::cerr << "Usage: " << cmd.substr(last_slash + 1)
<< " <key-file-name> <all-file-name>\n";
return 1;
}

google::cloud::storage::account_file_name_ = argv[1];
google::cloud::storage::data_file_name_ = argv[2];

return RUN_ALL_TESTS();
}
Loading