|
1 |
| -import com.google.api.client.auth.oauth2.Credential; |
2 |
| -import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; |
3 |
| -import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver; |
4 |
| -import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; |
5 |
| -import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; |
6 |
| -import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; |
7 | 1 | import com.google.api.client.googleapis.json.GoogleJsonResponseException;
|
8 | 2 | import com.google.api.client.http.HttpHeaders;
|
9 |
| -import com.google.api.client.http.HttpTransport; |
10 | 3 | import com.google.api.client.http.InputStreamContent;
|
11 |
| -import com.google.api.client.json.JsonFactory; |
12 |
| -import com.google.api.client.json.jackson2.JacksonFactory; |
13 |
| -import com.google.api.client.util.store.DataStoreFactory; |
14 |
| -import com.google.api.client.util.store.FileDataStoreFactory; |
15 | 4 | import com.google.api.services.storage.Storage;
|
16 |
| -import com.google.api.services.storage.StorageScopes; |
17 | 5 | import com.google.api.services.storage.model.RewriteResponse;
|
18 | 6 |
|
19 | 7 | import java.io.IOException;
|
20 | 8 | import java.io.InputStream;
|
21 |
| -import java.io.InputStreamReader; |
22 |
| -import java.util.Collections; |
23 | 9 |
|
24 | 10 | /**
|
25 | 11 | * Demonstrates the use of GCS's CSEK features via the Java API client library
|
|
35 | 21 | **/
|
36 | 22 | class CustomerSuppliedEncryptionKeysSamples {
|
37 | 23 |
|
38 |
| - private static final java.io.File DATA_STORE_DIR = |
39 |
| - new java.io.File(System.getProperty("user.home"), ".store/storage_sample"); |
40 |
| - |
41 | 24 | // You can (and should) generate your own CSEK Key! Try running this from the command line:
|
42 | 25 | // python -c 'import base64; import os; print(base64.encodestring(os.urandom(32)))'
|
43 | 26 | // Also, these encryption keys are included here for simplicity, but please remember that
|
@@ -135,11 +118,11 @@ public static void uploadObject(
|
135 | 118 | httpHeaders.set("x-goog-encryption-algorithm", "AES256");
|
136 | 119 | httpHeaders.set("x-goog-encryption-key", base64CSEKey);
|
137 | 120 | httpHeaders.set("x-goog-encryption-key-sha256", base64CSEKeyHash);
|
138 |
| - |
| 121 | + |
139 | 122 | // Since our request includes our private key as a header, it is a good idea to instruct caches
|
140 | 123 | // and proxies not to store this request.
|
141 | 124 | httpHeaders.setCacheControl("no-store");
|
142 |
| - |
| 125 | + |
143 | 126 | insertObject.setRequestHeaders(httpHeaders);
|
144 | 127 |
|
145 | 128 | try {
|
@@ -189,11 +172,11 @@ public static void rotateKey(
|
189 | 172 | httpHeaders.set("x-goog-encryption-algorithm", "AES256");
|
190 | 173 | httpHeaders.set("x-goog-encryption-key", newBase64Key);
|
191 | 174 | httpHeaders.set("x-goog-encryption-key-sha256", newBase64KeyHash);
|
192 |
| - |
| 175 | + |
193 | 176 | // Since our request includes our private key as a header, it is a good idea to instruct caches
|
194 | 177 | // and proxies not to store this request.
|
195 | 178 | httpHeaders.setCacheControl("no-store");
|
196 |
| - |
| 179 | + |
197 | 180 | rewriteObject.setRequestHeaders(httpHeaders);
|
198 | 181 |
|
199 | 182 | try {
|
@@ -221,95 +204,23 @@ public static void main(String[] args) throws Exception {
|
221 | 204 | System.exit(1);
|
222 | 205 | }
|
223 | 206 | String bucketName = args[0];
|
224 |
| - // CSEK, like the JSON API, may be used only via HTTPS. |
225 |
| - HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); |
226 |
| - DataStoreFactory dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR); |
227 |
| - JsonFactory jsonFactory = JacksonFactory.getDefaultInstance(); |
228 |
| - Credential credential = authorize(jsonFactory, httpTransport, dataStoreFactory); |
229 |
| - Storage storage = |
230 |
| - new Storage.Builder(httpTransport, jsonFactory, credential) |
231 |
| - .setApplicationName("JavaCSEKApiSample") |
232 |
| - .build(); |
233 |
| - |
234 |
| - InputStream dataToUpload = new ArbitrarilyLargeInputStream(10000000); |
| 207 | + |
| 208 | + Storage storage = StorageFactory.getService(); |
| 209 | + InputStream dataToUpload = new StorageUtils.ArbitrarilyLargeInputStream(10000000); |
235 | 210 |
|
236 | 211 | System.out.format("Uploading object gs://%s/%s using CSEK.\n", bucketName, OBJECT_NAME);
|
237 | 212 | uploadObject(storage, bucketName, OBJECT_NAME, dataToUpload, CSEK_KEY, CSEK_KEY_HASH);
|
| 213 | + |
238 | 214 | System.out.format("Downloading object gs://%s/%s using CSEK.\n", bucketName, OBJECT_NAME);
|
239 | 215 | InputStream objectData =
|
240 | 216 | downloadObject(storage, bucketName, OBJECT_NAME, CSEK_KEY, CSEK_KEY_HASH);
|
241 |
| - readStream(objectData); |
| 217 | + StorageUtils.readStream(objectData); |
| 218 | + |
242 | 219 | System.out.println("Rotating object to use a different CSEK.");
|
243 | 220 | rotateKey(storage, bucketName, OBJECT_NAME, CSEK_KEY, CSEK_KEY_HASH,
|
244 | 221 | ANOTHER_CESK_KEY, ANOTHER_CSEK_KEY_HASH);
|
245 | 222 |
|
246 |
| - System.out.println(); |
247 |
| - } |
248 |
| - |
249 |
| - private static Credential authorize( |
250 |
| - JsonFactory jsonFactory, HttpTransport httpTransport, DataStoreFactory dataStoreFactory) |
251 |
| - throws Exception { |
252 |
| - |
253 |
| - InputStream clientSecretStream = |
254 |
| - CustomerSuppliedEncryptionKeysSamples.class |
255 |
| - .getResourceAsStream("client_secrets.json"); |
256 |
| - if (clientSecretStream == null) { |
257 |
| - throw new RuntimeException("Could not load secrets"); |
258 |
| - } |
259 |
| - |
260 |
| - // Load client secrets |
261 |
| - GoogleClientSecrets clientSecrets = |
262 |
| - GoogleClientSecrets.load(jsonFactory, new InputStreamReader(clientSecretStream)); |
263 |
| - |
264 |
| - // Set up authorization code flow |
265 |
| - GoogleAuthorizationCodeFlow flow = |
266 |
| - new GoogleAuthorizationCodeFlow.Builder( |
267 |
| - httpTransport, |
268 |
| - jsonFactory, |
269 |
| - clientSecrets, |
270 |
| - Collections.singleton(StorageScopes.DEVSTORAGE_FULL_CONTROL)) |
271 |
| - .setDataStoreFactory(dataStoreFactory) |
272 |
| - .build(); |
273 |
| - |
274 |
| - // Authorize |
275 |
| - Credential credential = |
276 |
| - new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user"); |
277 |
| - |
278 |
| - return credential; |
279 |
| - } |
280 |
| - |
281 |
| - /** |
282 |
| - * Reads the contents of an InputStream and does nothing with it. |
283 |
| - */ |
284 |
| - private static void readStream(InputStream is) throws IOException { |
285 |
| - byte inputBuffer[] = new byte[256]; |
286 |
| - while (is.read(inputBuffer) != -1) {} |
287 |
| - // The caller is responsible for closing this InputStream. |
288 |
| - is.close(); |
289 |
| - } |
290 |
| - |
291 |
| - /** |
292 |
| - * A helper class to provide input streams of any size. |
293 |
| - * The input streams will be full of null bytes. |
294 |
| - */ |
295 |
| - static class ArbitrarilyLargeInputStream extends InputStream { |
296 |
| - |
297 |
| - private long bytesRead; |
298 |
| - private final long streamSize; |
299 |
| - |
300 |
| - public ArbitrarilyLargeInputStream(long streamSizeInBytes) { |
301 |
| - bytesRead = 0; |
302 |
| - this.streamSize = streamSizeInBytes; |
303 |
| - } |
304 |
| - |
305 |
| - @Override |
306 |
| - public int read() throws IOException { |
307 |
| - if (bytesRead >= streamSize) { |
308 |
| - return -1; |
309 |
| - } |
310 |
| - bytesRead++; |
311 |
| - return 0; |
312 |
| - } |
| 223 | + System.out.println("Done"); |
313 | 224 | }
|
314 | 225 |
|
315 | 226 | }
|
0 commit comments