From 376fcab2ca8a2908187bedec732fc99e1f1950c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20H=C3=B3ka?= Date: Thu, 31 May 2018 13:15:41 +0200 Subject: [PATCH] Add Azure Blob Storage support Signed-off-by: Adam Hoka --- README.md | 6 ++++-- config.json.example | 7 ++++++- lib/config/default.js | 6 +++++- lib/config/dockerSecret.js | 3 +++ lib/config/environment.js | 4 ++++ lib/config/index.js | 4 ++-- lib/web/imageRouter/azure.js | 35 +++++++++++++++++++++++++++++++++++ package.json | 1 + 8 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 lib/web/imageRouter/azure.js diff --git a/README.md b/README.md index f302802..ba04182 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,8 @@ There are some config settings you need to change in the files below. | `HMD_MINIO_ENDPOINT` | `minio.example.org` | Address of your Minio endpoint/instance | | `HMD_MINIO_PORT` | `9000` | Port that is used for your Minio instance | | `HMD_MINIO_SECURE` | `true` | If set to `true` HTTPS is used for Minio | +| `HMD_AZURE_CONNECTION_STRING` | no example | Azure Blob Storage connection string | +| `HMD_AZURE_CONTAINER` | no example | Azure Blob Storage container name (automatically created if non existent) | | `HMD_HSTS_ENABLE` | ` true` | set to enable [HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) if HTTPS is also enabled (default is ` true`) | | `HMD_HSTS_INCLUDE_SUBDOMAINS` | `true` | set to include subdomains in HSTS (default is `true`) | | `HMD_HSTS_MAX_AGE` | `31536000` | max duration in seconds to tell clients to keep HSTS status (default is a year) | @@ -261,7 +263,7 @@ There are some config settings you need to change in the files below. | `documentMaxLength` | `100000` | note max length | | `email` | `true` or `false` | set to allow email signin | | `allowEmailRegister` | `true` or `false` | set to allow email register (only applied when email is set, default is `true`. Note `bin/manage_users` might help you if registration is `false`.) | -| `imageUploadType` | `imgur`(default), `s3`, `minio` or `filesystem` | Where to upload image +| `imageUploadType` | `imgur`(default), `s3`, `minio`, `azure` or `filesystem` | Where to upload image | `minio` | `{ "accessKey": "YOUR_MINIO_ACCESS_KEY", "secretKey": "YOUR_MINIO_SECRET_KEY", "endpoint": "YOUR_MINIO_HOST", port: 9000, secure: true }` | When `imageUploadType` is set to `minio`, you need to set this key. Also checkout our [Minio Image Upload Guide](docs/guides/minio-image-upload.md) | | `s3` | `{ "accessKeyId": "YOUR_S3_ACCESS_KEY_ID", "secretAccessKey": "YOUR_S3_ACCESS_KEY", "region": "YOUR_S3_REGION" }` | When `imageuploadtype` be set to `s3`, you would also need to setup this key, check our [S3 Image Upload Guide](docs/guides/s3-image-upload.md) | | `s3bucket` | `YOUR_S3_BUCKET_NAME` | bucket name when `imageUploadType` is set to `s3` or `minio` | @@ -271,7 +273,7 @@ There are some config settings you need to change in the files below. | service | settings location | description | | ------- | --------- | ----------- | | facebook, twitter, github, gitlab, mattermost, dropbox, google, ldap, saml | environment variables or `config.json` | for signin | -| imgur, s3, minio | environment variables or `config.json` | for image upload | +| imgur, s3, minio, azure | environment variables or `config.json` | for image upload | | dropbox(`dropbox/appKey`) | `config.json` | for export and import | ## Third-party integration OAuth callback URLs diff --git a/config.json.example b/config.json.example index 6cd55ef..e07052b 100644 --- a/config.json.example +++ b/config.json.example @@ -114,6 +114,11 @@ "secretAccessKey": "change this", "region": "change this" }, - "s3bucket": "change this" + "s3bucket": "change this", + "azure": + { + "connectionString": "change this", + "container": "change this" + } } } diff --git a/lib/config/default.js b/lib/config/default.js index 68849d3..30ce209 100644 --- a/lib/config/default.js +++ b/lib/config/default.js @@ -56,7 +56,7 @@ module.exports = { heartbeatTimeout: 10000, // document documentMaxLength: 100000, - // image upload setting, available options are imgur/s3/filesystem + // image upload setting, available options are imgur/s3/filesystem/azure imageUploadType: 'filesystem', imgur: { clientID: undefined @@ -74,6 +74,10 @@ module.exports = { port: 9000 }, s3bucket: undefined, + azure: { + connectionString: undefined, + container: undefined + }, // authentication facebook: { clientID: undefined, diff --git a/lib/config/dockerSecret.js b/lib/config/dockerSecret.js index b9116cd..fd66ddf 100644 --- a/lib/config/dockerSecret.js +++ b/lib/config/dockerSecret.js @@ -22,6 +22,9 @@ if (fs.existsSync(basePath)) { accessKeyId: getSecret('s3_acccessKeyId'), secretAccessKey: getSecret('s3_secretAccessKey') }, + azure: { + connectionString: getSecret('azure_connectionString') + }, facebook: { clientID: getSecret('facebook_clientID'), clientSecret: getSecret('facebook_clientSecret') diff --git a/lib/config/environment.js b/lib/config/environment.js index 3dde478..810cb22 100644 --- a/lib/config/environment.js +++ b/lib/config/environment.js @@ -45,6 +45,10 @@ module.exports = { port: toIntegerConfig(process.env.HMD_MINIO_PORT) }, s3bucket: process.env.HMD_S3_BUCKET, + azure: { + connectionString: process.env.HMD_AZURE_CONNECTION_STRING, + container: process.env.HMD_AZURE_CONTAINER + }, facebook: { clientID: process.env.HMD_FACEBOOK_CLIENTID, clientSecret: process.env.HMD_FACEBOOK_CLIENTSECRET diff --git a/lib/config/index.js b/lib/config/index.js index bdba5e0..f10eadb 100644 --- a/lib/config/index.js +++ b/lib/config/index.js @@ -127,8 +127,8 @@ if (config.sessionSecret === 'secret') { } // Validate upload upload providers -if (['filesystem', 's3', 'minio', 'imgur'].indexOf(config.imageUploadType) === -1) { - logger.error('"imageuploadtype" is not correctly set. Please use "filesystem", "s3", "minio" or "imgur". Defaulting to "imgur"') +if (['filesystem', 's3', 'minio', 'imgur', 'azure'].indexOf(config.imageUploadType) === -1) { + logger.error('"imageuploadtype" is not correctly set. Please use "filesystem", "s3", "minio", "azure" or "imgur". Defaulting to "imgur"') config.imageUploadType = 'imgur' } diff --git a/lib/web/imageRouter/azure.js b/lib/web/imageRouter/azure.js new file mode 100644 index 0000000..cc98e5f --- /dev/null +++ b/lib/web/imageRouter/azure.js @@ -0,0 +1,35 @@ +'use strict' +const path = require('path') + +const config = require('../../config') +const logger = require('../../logger') + +const azure = require('azure-storage') + +exports.uploadImage = function (imagePath, callback) { + if (!imagePath || typeof imagePath !== 'string') { + callback(new Error('Image path is missing or wrong'), null) + return + } + + if (!callback || typeof callback !== 'function') { + logger.error('Callback has to be a function') + return + } + + var azureBlobService = azure.createBlobService(config.azure.connectionString) + + azureBlobService.createContainerIfNotExists(config.azure.container, { publicAccessLevel: 'blob' }, function (err, result, response) { + if (err) { + callback(new Error(err.message), null) + } else { + azureBlobService.createBlockBlobFromLocalFile(config.azure.container, path.basename(imagePath), imagePath, function (err, result, response) { + if (err) { + callback(new Error(err.message), null) + } else { + callback(null, azureBlobService.getUrl(config.azure.container, result.name)) + } + }) + } + }) +} diff --git a/package.json b/package.json index c31b3c8..b7420ce 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "async": "^2.1.4", "aws-sdk": "^2.7.20", "base64url": "^3.0.0", + "azure-storage": "^2.7.0", "blueimp-md5": "^2.6.0", "body-parser": "^1.15.2", "bootstrap": "^3.3.7",