mirror of
https://github.com/strapi/strapi.git
synced 2025-09-25 08:19:07 +00:00
Merge pull request #15861 from strapi/private-s3-bucket/only-sign-media-from-private-bucket
This commit is contained in:
commit
13d90f66d2
@ -0,0 +1,43 @@
|
||||
'use strict';
|
||||
|
||||
const { getBucketFromUrl } = require('../utils');
|
||||
|
||||
describe('Test for URLs', () => {
|
||||
test('Virtual hosted style', async () => {
|
||||
const url = 'https://bucket.s3.us-east-1.amazonaws.com/img.png';
|
||||
const { bucket } = getBucketFromUrl(url);
|
||||
expect(bucket).toEqual('bucket');
|
||||
});
|
||||
|
||||
describe('Path style', () => {
|
||||
test('No key', async () => {
|
||||
const url = 'https://s3.us-east-1.amazonaws.com/bucket';
|
||||
const { bucket } = getBucketFromUrl(url);
|
||||
expect(bucket).toEqual('bucket');
|
||||
});
|
||||
|
||||
test('With trailing slash', async () => {
|
||||
const url = 'https://s3.us-east-1.amazonaws.com/bucket/';
|
||||
const { bucket } = getBucketFromUrl(url);
|
||||
expect(bucket).toEqual('bucket');
|
||||
});
|
||||
|
||||
test('With key', async () => {
|
||||
const url = 'https://s3.us-east-1.amazonaws.com/bucket/img.png';
|
||||
const { bucket } = getBucketFromUrl(url);
|
||||
expect(bucket).toEqual('bucket');
|
||||
});
|
||||
});
|
||||
|
||||
test('S3 access point', async () => {
|
||||
const url = 'https://bucket.s3-accesspoint.us-east-1.amazonaws.com';
|
||||
const { bucket } = getBucketFromUrl(url);
|
||||
expect(bucket).toEqual('bucket');
|
||||
});
|
||||
|
||||
test('S3://', async () => {
|
||||
const url = 'S3://bucket/img.png';
|
||||
const { bucket } = getBucketFromUrl(url);
|
||||
expect(bucket).toEqual('bucket');
|
||||
});
|
||||
});
|
@ -8,6 +8,7 @@
|
||||
// Public node modules.
|
||||
const get = require('lodash/get');
|
||||
const AWS = require('aws-sdk');
|
||||
const { getBucketFromUrl } = require('./utils');
|
||||
|
||||
function assertUrlProtocol(url) {
|
||||
// Regex to test protocol like "http://", "https://"
|
||||
@ -66,6 +67,12 @@ module.exports = {
|
||||
* @returns {Promise<{url: string}>}
|
||||
*/
|
||||
getSignedUrl(file, customParams = {}) {
|
||||
// Do not sign the url if it does not come from the same bucket.
|
||||
const { bucket } = getBucketFromUrl(file.url);
|
||||
if (bucket !== config.params.Bucket) {
|
||||
return { url: file.url };
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const path = file.path ? `${file.path}/` : '';
|
||||
const fileKey = `${path}${file.hash}${file.ext}`;
|
||||
|
63
packages/providers/upload-aws-s3/lib/utils.js
Normal file
63
packages/providers/upload-aws-s3/lib/utils.js
Normal file
@ -0,0 +1,63 @@
|
||||
'use strict';
|
||||
|
||||
const ENDPOINT_PATTERN = /^(.+\.)?s3[.-]([a-z0-9-]+)\./;
|
||||
|
||||
/**
|
||||
* Parse the bucket name from a URL.
|
||||
* See all URL formats in https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-bucket-intro.html
|
||||
*
|
||||
* @param {string} fileUrl - the URL to parse
|
||||
* @returns {object} result
|
||||
* @returns {string} result.bucket - the bucket name
|
||||
* @returns {string} result.error - if any
|
||||
*/
|
||||
function getBucketFromUrl(fileUrl) {
|
||||
const uri = new URL(fileUrl);
|
||||
|
||||
// S3://<bucket-name>/<key>
|
||||
if (uri.protocol === 's3:') {
|
||||
const bucket = uri.host;
|
||||
|
||||
if (!bucket) {
|
||||
return { err: `Invalid S3 URI: no bucket: ${uri}` };
|
||||
}
|
||||
return { bucket };
|
||||
}
|
||||
|
||||
if (!uri.host) {
|
||||
return { err: `Invalid S3 URI: no hostname: ${uri}` };
|
||||
}
|
||||
|
||||
const matches = uri.host.match(ENDPOINT_PATTERN);
|
||||
if (!matches) {
|
||||
return { err: `Invalid S3 URI: hostname does not appear to be a valid S3 endpoint: ${uri}` };
|
||||
}
|
||||
|
||||
const prefix = matches[1];
|
||||
// https://s3.amazonaws.com/<bucket-name>
|
||||
if (!prefix) {
|
||||
if (uri.pathname === '/') {
|
||||
return { bucket: null };
|
||||
}
|
||||
|
||||
const index = uri.pathname.indexOf('/', 1);
|
||||
|
||||
// https://s3.amazonaws.com/<bucket-name>
|
||||
if (index === -1) {
|
||||
return { bucket: uri.pathname.substring(1) };
|
||||
}
|
||||
|
||||
// https://s3.amazonaws.com/<bucket-name>/
|
||||
if (index === uri.pathname.length - 1) {
|
||||
return { bucket: uri.pathname.substring(1, index) };
|
||||
}
|
||||
|
||||
// https://s3.amazonaws.com/<bucket-name>/key
|
||||
return { bucket: uri.pathname.substring(1, index) };
|
||||
}
|
||||
|
||||
// https://<bucket-name>.s3.amazonaws.com/
|
||||
return { bucket: prefix.substring(0, prefix.length - 1) };
|
||||
}
|
||||
|
||||
module.exports = { getBucketFromUrl };
|
Loading…
x
Reference in New Issue
Block a user