Skip to content

Commit 89d42a9

Browse files
committed
fix: handle destination encryption headers and prevent key interceptor conflicts during file copy operations
1 parent 168c927 commit 89d42a9

2 files changed

Lines changed: 53 additions & 23 deletions

File tree

handwritten/storage/src/file.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,20 +1386,18 @@ class File extends ServiceObject<File, FileMetadata> {
13861386
this.encryptionKeyHash;
13871387
}
13881388

1389-
let copiedKey = false;
13901389
if (
13911390
this.encryptionKey !== undefined &&
13921391
this.encryptionKey !== null &&
13931392
newFile.encryptionKey === undefined
13941393
) {
1395-
newFile.encryptionKey = this.encryptionKey;
1396-
newFile.encryptionKeyBase64 = this.encryptionKeyBase64;
1397-
newFile.encryptionKeyHash = this.encryptionKeyHash;
1398-
copiedKey = true;
1394+
newFile.setEncryptionKey(this.encryptionKey);
13991395
}
14001396

1401-
if (newFile.encryptionKey !== undefined && !copiedKey) {
1402-
this.setEncryptionKey(newFile.encryptionKey!);
1397+
if (newFile.encryptionKey !== undefined && newFile.encryptionKey !== null) {
1398+
headers['x-goog-encryption-algorithm'] = 'AES256';
1399+
headers['x-goog-encryption-key'] = newFile.encryptionKeyBase64;
1400+
headers['x-goog-encryption-key-sha256'] = newFile.encryptionKeyHash;
14031401
} else if (options.destinationKmsKeyName !== undefined) {
14041402
query.destinationKmsKeyName = options.destinationKmsKeyName;
14051403
delete options.destinationKmsKeyName;
@@ -1431,6 +1429,14 @@ class File extends ServiceObject<File, FileMetadata> {
14311429
delete options.preconditionOpts;
14321430
}
14331431

1432+
const originalGetRequestInterceptors = this.getRequestInterceptors;
1433+
this.getRequestInterceptors = () => {
1434+
return originalGetRequestInterceptors.call(this).filter(
1435+
interceptorFn =>
1436+
interceptorFn !== this.encryptionKeyInterceptor?.request
1437+
);
1438+
};
1439+
14341440
this.request(
14351441
{
14361442
method: 'POST',
@@ -1468,6 +1474,8 @@ class File extends ServiceObject<File, FileMetadata> {
14681474
callback!(null, newFile, resp);
14691475
},
14701476
);
1477+
1478+
this.getRequestInterceptors = originalGetRequestInterceptors;
14711479
}
14721480

14731481
/**

handwritten/storage/test/file.ts

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -596,9 +596,7 @@ describe('File', () => {
596596
});
597597

598598
it('should set correct headers when file is encrypted', done => {
599-
file.encryptionKey = {};
600-
file.encryptionKeyBase64 = 'base64';
601-
file.encryptionKeyHash = 'hash';
599+
file.setEncryptionKey('sourceKey');
602600

603601
const newFile = new File(BUCKET, 'new-file');
604602

@@ -607,29 +605,43 @@ describe('File', () => {
607605
'x-goog-copy-source-encryption-algorithm': 'AES256',
608606
'x-goog-copy-source-encryption-key': file.encryptionKeyBase64,
609607
'x-goog-copy-source-encryption-key-sha256': file.encryptionKeyHash,
608+
'x-goog-encryption-algorithm': 'AES256',
609+
'x-goog-encryption-key': file.encryptionKeyBase64,
610+
'x-goog-encryption-key-sha256': file.encryptionKeyHash,
610611
});
611612
done();
612613
};
613614

614615
file.copy(newFile, assert.ifError);
615616
});
616617

617-
it('should set encryption key on the new File instance', done => {
618+
it('should send destination encryption headers when destination file has an encryption key', done => {
618619
const newFile = new File(BUCKET, 'new-file');
619-
newFile.encryptionKey = 'encryptionKey';
620+
newFile.setEncryptionKey('destinationKey');
620621

621-
file.setEncryptionKey = (encryptionKey: {}) => {
622-
assert.strictEqual(encryptionKey, newFile.encryptionKey);
622+
file.request = (reqOpts: DecorateRequestOptions) => {
623+
assert.strictEqual(
624+
reqOpts.headers!['x-goog-encryption-algorithm'],
625+
'AES256'
626+
);
627+
assert.strictEqual(
628+
reqOpts.headers!['x-goog-encryption-key'],
629+
newFile.encryptionKeyBase64
630+
);
631+
assert.strictEqual(
632+
reqOpts.headers!['x-goog-encryption-key-sha256'],
633+
newFile.encryptionKeyHash
634+
);
623635
done();
624636
};
625637

626638
file.copy(newFile, assert.ifError);
627639
});
628640

629641
it('should not copy encryption key or send destination headers when destination file has null encryption key', done => {
630-
file.encryptionKey = 'sourceKey';
631-
file.encryptionKeyBase64 = 'sourceKeyBase64';
632-
file.encryptionKeyHash = 'sourceKeyHash';
642+
file.setEncryptionKey('sourceKey');
643+
const expectedSourceKeyBase64 = file.encryptionKeyBase64;
644+
const expectedSourceKeyHash = file.encryptionKeyHash;
633645

634646
const newFile = new File(BUCKET, 'new-file');
635647
newFile.setEncryptionKey(null);
@@ -645,11 +657,11 @@ describe('File', () => {
645657
);
646658
assert.strictEqual(
647659
reqOpts.headers!['x-goog-copy-source-encryption-key'],
648-
'sourceKeyBase64'
660+
expectedSourceKeyBase64
649661
);
650662
assert.strictEqual(
651663
reqOpts.headers!['x-goog-copy-source-encryption-key-sha256'],
652-
'sourceKeyHash'
664+
expectedSourceKeyHash
653665
);
654666

655667
assert.strictEqual(
@@ -665,7 +677,7 @@ describe('File', () => {
665677
undefined
666678
);
667679

668-
assert.strictEqual(file.encryptionKeyInterceptor, undefined);
680+
assert.notStrictEqual(file.encryptionKeyInterceptor, undefined);
669681

670682
done();
671683
};
@@ -674,9 +686,7 @@ describe('File', () => {
674686
});
675687

676688
it('should copy the source key to the destination file object if destination key is undefined', done => {
677-
file.encryptionKey = 'sourceKey';
678-
file.encryptionKeyBase64 = 'sourceKeyBase64';
679-
file.encryptionKeyHash = 'sourceKeyHash';
689+
file.setEncryptionKey('sourceKey');
680690

681691
const newFile = new File(BUCKET, 'new-file');
682692

@@ -689,6 +699,18 @@ describe('File', () => {
689699
reqOpts.headers!['x-goog-copy-source-encryption-key'],
690700
file.encryptionKeyBase64
691701
);
702+
assert.strictEqual(
703+
reqOpts.headers!['x-goog-encryption-algorithm'],
704+
'AES256'
705+
);
706+
assert.strictEqual(
707+
reqOpts.headers!['x-goog-encryption-key'],
708+
file.encryptionKeyBase64
709+
);
710+
assert.strictEqual(
711+
reqOpts.headers!['x-goog-encryption-key-sha256'],
712+
file.encryptionKeyHash
713+
);
692714
done();
693715
};
694716

0 commit comments

Comments
 (0)