@@ -38,6 +38,7 @@ const log = new DummyRequestLogger();
38
38
const splitter = constants . splitter ;
39
39
const canonicalID = 'accessKey1' ;
40
40
const authInfo = makeAuthInfo ( canonicalID ) ;
41
+ const authInfoOtherAcc = makeAuthInfo ( 'accessKey2' ) ;
41
42
const namespace = 'default' ;
42
43
const bucketName = 'bucketname' ;
43
44
const lockedBucket = 'objectlockenabledbucket' ;
@@ -2661,9 +2662,14 @@ describe('complete mpu with bucket policy', () => {
2661
2662
2662
2663
beforeEach ( done => {
2663
2664
cleanup ( ) ;
2665
+ sinon . spy ( metadataswitch , 'putObjectMD' ) ;
2664
2666
bucketPut ( authInfo , bucketPutRequest , log , done ) ;
2665
2667
} ) ;
2666
2668
2669
+ afterEach ( ( ) => {
2670
+ sinon . restore ( ) ;
2671
+ } ) ;
2672
+
2667
2673
it ( 'should complete with a deny on unrelated object as non root' , done => {
2668
2674
const bucketPutPolicyRequest = getPolicyRequest ( {
2669
2675
Version : '2012-10-17' ,
@@ -2730,6 +2736,96 @@ describe('complete mpu with bucket policy', () => {
2730
2736
done ( ) ;
2731
2737
} ) ;
2732
2738
} ) ;
2739
+
2740
+ it ( 'should set bucketOwnerId if requester is not destination bucket owner' , done => {
2741
+ const partBody = Buffer . from ( 'I am a part\n' , 'utf8' ) ;
2742
+ const bucketPutPolicyRequest = getPolicyRequest ( {
2743
+ Version : '2012-10-17' ,
2744
+ Statement : [
2745
+ {
2746
+ Effect : 'Allow' ,
2747
+ Principal : { AWS : `arn:aws:iam::${ authInfoOtherAcc . shortid } :root` } ,
2748
+ Action : [ 's3:*' ] ,
2749
+ Resource : `arn:aws:s3:::${ bucketName } /*` ,
2750
+ } ,
2751
+ ] ,
2752
+ } ) ;
2753
+ async . waterfall ( [
2754
+ next => bucketPutPolicy ( authInfo , bucketPutPolicyRequest , log , next ) ,
2755
+ ( corsHeaders , next ) => initiateMultipartUpload ( authInfoOtherAcc ,
2756
+ initiateRequest , log , next ) ,
2757
+ ( result , corsHeaders , next ) => parseString ( result , next ) ,
2758
+ ] ,
2759
+ ( err , json ) => {
2760
+ // Need to build request in here since do not have uploadId
2761
+ // until here
2762
+ assert . ifError ( err ) ;
2763
+ const testUploadId =
2764
+ json . InitiateMultipartUploadResult . UploadId [ 0 ] ;
2765
+ const md5Hash = crypto . createHash ( 'md5' ) . update ( partBody ) ;
2766
+ const calculatedHash = md5Hash . digest ( 'hex' ) ;
2767
+ const partRequest = new DummyRequest ( {
2768
+ bucketName,
2769
+ namespace,
2770
+ objectKey,
2771
+ headers : { host : `${ bucketName } .s3.amazonaws.com` } ,
2772
+ url : `/${ objectKey } ?partNumber=1&uploadId=${ testUploadId } ` ,
2773
+ query : {
2774
+ partNumber : '1' ,
2775
+ uploadId : testUploadId ,
2776
+ } ,
2777
+ // Note that the body of the post set in the request here does
2778
+ // not really matter in this test.
2779
+ // The put is not going through the route so the md5 is being
2780
+ // calculated above and manually being set in the request below.
2781
+ // What is being tested is that the calculatedHash being sent
2782
+ // to the API for the part is stored and then used to
2783
+ // calculate the final ETag upon completion
2784
+ // of the multipart upload.
2785
+ calculatedHash,
2786
+ socket : {
2787
+ remoteAddress : '1.1.1.1' ,
2788
+ } ,
2789
+ } , partBody ) ;
2790
+ objectPutPart ( authInfoOtherAcc , partRequest , undefined , log , err => {
2791
+ assert . ifError ( err ) ;
2792
+ const completeBody = '<CompleteMultipartUpload>' +
2793
+ '<Part>' +
2794
+ '<PartNumber>1</PartNumber>' +
2795
+ `<ETag>"${ calculatedHash } "</ETag>` +
2796
+ '</Part>' +
2797
+ '</CompleteMultipartUpload>' ;
2798
+ const completeRequest = {
2799
+ bucketName,
2800
+ namespace,
2801
+ objectKey,
2802
+ parsedHost : 's3.amazonaws.com' ,
2803
+ url : `/${ objectKey } ?uploadId=${ testUploadId } ` ,
2804
+ headers : { host : `${ bucketName } .s3.amazonaws.com` } ,
2805
+ query : { uploadId : testUploadId } ,
2806
+ post : completeBody ,
2807
+ actionImplicitDenies : false ,
2808
+ socket : {
2809
+ remoteAddress : '1.1.1.1' ,
2810
+ } ,
2811
+ } ;
2812
+ completeMultipartUpload ( authInfoOtherAcc ,
2813
+ completeRequest , log , err => {
2814
+ assert . ifError ( err ) ;
2815
+ sinon . assert . calledWith (
2816
+ metadataswitch . putObjectMD . lastCall ,
2817
+ bucketName ,
2818
+ objectKey ,
2819
+ sinon . match ( { bucketOwnerId : authInfo . canonicalId } ) ,
2820
+ sinon . match . any ,
2821
+ sinon . match . any ,
2822
+ sinon . match . any
2823
+ ) ;
2824
+ done ( ) ;
2825
+ } ) ;
2826
+ } ) ;
2827
+ } ) ;
2828
+ } ) ;
2733
2829
} ) ;
2734
2830
2735
2831
describe ( 'multipart upload in ingestion bucket' , ( ) => {
0 commit comments