0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-01-06 22:40:26 -05:00

Refactor storage, moves secret key generator to config file

This commit is contained in:
Juan Picado @jotadeveloper 2017-06-10 23:07:08 +02:00
parent ac456232bb
commit 1358d53dd9
No known key found for this signature in database
GPG key ID: 18AC54485952D158
2 changed files with 45 additions and 53 deletions

View file

@ -4,11 +4,10 @@
'use strict'; 'use strict';
const assert = require('assert'); const assert = require('assert');
const Crypto = require('crypto'); const _ = require('lodash');
const Error = require('http-errors'); const Error = require('http-errors');
const Crypto = require('crypto');
const minimatch = require('minimatch'); const minimatch = require('minimatch');
const Path = require('path');
const LocalData = require('./local-data');
const Utils = require('./utils'); const Utils = require('./utils');
const pkginfo = require('pkginfo')(module); // eslint-disable-line no-unused-vars const pkginfo = require('pkginfo')(module); // eslint-disable-line no-unused-vars
const pkgVersion = module.exports.version; const pkgVersion = module.exports.version;
@ -93,24 +92,6 @@ class Config {
assert.equal(typeof(config), 'object', 'CONFIG: it doesn\'t look like a valid config file'); assert.equal(typeof(config), 'object', 'CONFIG: it doesn\'t look like a valid config file');
assert(self.storage, 'CONFIG: storage path not defined'); assert(self.storage, 'CONFIG: storage path not defined');
// local data handler is linked with the configuration handler
self.localList = new LocalData(
Path.join(
Path.resolve(Path.dirname(self.self_path || ''), self.storage),
// FUTURE: the database might be parameterizable from config.yaml
'.sinopia-db.json'
)
);
// it generates a secret key
// FUTURE: this might be an external secret key, perhaps whitin config file?
if (!self.secret) {
self.secret = self.localList.data.secret;
if (!self.secret) {
self.secret = Crypto.pseudoRandomBytes(32).toString('hex');
self.localList.data.secret = self.secret;
self.localList.sync();
}
}
const users = { const users = {
'all': true, 'all': true,
@ -257,6 +238,21 @@ class Config {
} }
return {}; return {};
} }
/**
* Store or create whether recieve a secret key
* @param {String} secret
* @return {String}
*/
checkSecretKey(secret) {
if (_.isNil(secret) === false) {
return secret;
}
// it generates a secret key
// FUTURE: this might be an external secret key, perhaps whitin config file?
this.secret = Crypto.pseudoRandomBytes(32).toString('hex');
return this.secret;
}
} }
module.exports = Config; module.exports = Config;

View file

@ -1,12 +1,12 @@
'use strict'; 'use strict';
const _ = require('lodash');
const assert = require('assert'); const assert = require('assert');
const async = require('async'); const async = require('async');
const Error = require('http-errors'); const Error = require('http-errors');
const semver = require('semver'); const semver = require('semver');
const Crypto = require('crypto');
const _ = require('lodash');
const Stream = require('stream'); const Stream = require('stream');
const Search = require('./search'); const Search = require('./search');
const LocalStorage = require('./local-storage'); const LocalStorage = require('./local-storage');
const Logger = require('./logger'); const Logger = require('./logger');
@ -14,7 +14,6 @@ const MyStreams = require('./streams');
const Proxy = require('./up-storage'); const Proxy = require('./up-storage');
const Utils = require('./utils'); const Utils = require('./utils');
/** /**
* Implements Storage interface * Implements Storage interface
* (same for storage.js, local-storage.js, up-storage.js). * (same for storage.js, local-storage.js, up-storage.js).
@ -22,32 +21,14 @@ const Utils = require('./utils');
class Storage { class Storage {
/** /**
*
* @param {*} config * @param {*} config
*/ */
constructor(config) { constructor(config) {
this.config = config; this.config = config;
// we support a number of uplinks, but only one local storage this._setupUpLinks(this.config);
// Proxy and Local classes should have similar API interfaces
this.uplinks = {};
for (let p in config.uplinks) {
if (Object.prototype.hasOwnProperty.call(config.uplinks, p)) {
// instance for each up-link definition
this.uplinks[p] = new Proxy(config.uplinks[p], config);
this.uplinks[p].upname = p;
}
}
this.localStorage = new LocalStorage(config); this.localStorage = new LocalStorage(config);
// it generates a secret key this.localStorage.localList.data.secret = this.config.checkSecretKey(this.localStorage.localList.data.secret);
// FUTURE: this might be an external secret key, perhaps whitin config file?
if (!config.secret) {
config.secret = this.localStorage.localList.data.secret;
if (!config.secret) {
config.secret = Crypto.pseudoRandomBytes(32).toString('hex');
this.localStorage.localList.data.secret = config.secret;
this.localStorage.localList.sync(); this.localStorage.localList.sync();
}
}
// an instance for local storage // an instance for local storage
this.logger = Logger.logger.child(); this.logger = Logger.logger.child();
} }
@ -66,7 +47,6 @@ class Storage {
/** /**
* Check whether a package it is already a local package * Check whether a package it is already a local package
* @param {*} cb the callback method
* @return {Promise} * @return {Promise}
*/ */
const checkPackageLocal = () => { const checkPackageLocal = () => {
@ -85,7 +65,6 @@ class Storage {
/** /**
* Check whether a package exist in any of the uplinks. * Check whether a package exist in any of the uplinks.
* @param {*} cb the callback method
* @return {Promise} * @return {Promise}
*/ */
const check_package_remote = () => { const check_package_remote = () => {
@ -102,7 +81,7 @@ class Storage {
for (let i = 0; i < err_results.length; i++) { for (let i = 0; i < err_results.length; i++) {
// checking error // checking error
// if uplink fails with a status other than 404, we report failure // if uplink fails with a status other than 404, we report failure
if (err_results[i][0] != null) { if (_.isNil(err_results[i][0]) === false) {
if (err_results[i][0].status !== 404) { if (err_results[i][0].status !== 404) {
return reject(Error[503]('one of the uplinks is down, refuse to publish')); return reject(Error[503]('one of the uplinks is down, refuse to publish'));
} }
@ -116,7 +95,6 @@ class Storage {
/** /**
* Add a package to the local database * Add a package to the local database
* @param {*} cb callback method
* @return {Promise} * @return {Promise}
*/ */
const publish_package = () => { const publish_package = () => {
@ -212,7 +190,7 @@ class Storage {
Function removes a tarball from local storage. Function removes a tarball from local storage.
Tarball in question should not be linked to in any existing Tarball in question should not be linked to in any existing
versions, i.e. package version should be unpublished first. versions, i.e. package version should be unpublished first.
Used storages: local (write) Used storage: local (write)
* @param {*} name * @param {*} name
* @param {*} filename * @param {*} filename
* @param {*} revision * @param {*} revision
@ -266,7 +244,7 @@ class Storage {
rstream.abort(); rstream.abort();
rstream = null; // gc rstream = null; // gc
self.localStorage.getPackage(name, function(err, info) { self.localStorage.getPackage(name, function(err, info) {
if (!err && info._distfiles && info._distfiles[filename] != null) { if (!err && info._distfiles && _.isNil(info._distfiles[filename]) === false) {
// information about this file exists locally // information about this file exists locally
serve_file(info._distfiles[filename]); serve_file(info._distfiles[filename]);
} else { } else {
@ -275,7 +253,7 @@ class Storage {
if (err) { if (err) {
return readStream.emit('error', err); return readStream.emit('error', err);
} }
if (!info._distfiles || info._distfiles[filename] == null) { if (!info._distfiles || _.isNil(info._distfiles[filename])) {
return readStream.emit('error', err404); return readStream.emit('error', err404);
} }
serve_file(info._distfiles[filename]); serve_file(info._distfiles[filename]);
@ -604,6 +582,24 @@ class Storage {
}); });
} }
/**
* Set up the Up Storage for each link.
* @param {Object} config
* @private
*/
_setupUpLinks(config) {
// we support a number of uplinks, but only one local storage
// Proxy and Local classes should have similar API interfaces
this.uplinks = {};
for (let p in config.uplinks) {
if (Object.prototype.hasOwnProperty.call(config.uplinks, p)) {
// instance for each up-link definition
this.uplinks[p] = new Proxy(config.uplinks[p], config);
this.uplinks[p].upname = p;
}
}
}
/** /**
* Function gets a local info and an info from uplinks and tries to merge it * Function gets a local info and an info from uplinks and tries to merge it
exported for unit tests only. exported for unit tests only.
@ -616,7 +612,7 @@ class Storage {
// copy new versions to a cache // copy new versions to a cache
// NOTE: if a certain version was updated, we can't refresh it reliably // NOTE: if a certain version was updated, we can't refresh it reliably
for (let i in up.versions) { for (let i in up.versions) {
if (local.versions[i] == null) { if (_.isNil(local.versions[i])) {
local.versions[i] = up.versions[i]; local.versions[i] = up.versions[i];
} }
} }