mirror of
https://github.com/aljazceru/cyphernode.git
synced 2025-12-26 00:55:08 +01:00
added support for api key generation
This commit is contained in:
@@ -8,6 +8,7 @@ const path = require("path");
|
||||
const featureChoices = require(path.join(__dirname, "features.json"));
|
||||
const coinstring = require('coinstring');
|
||||
const Archive = require('./lib/archive.js');
|
||||
const ApiKey = require('./lib/apikey.js');
|
||||
|
||||
const uaCommentRegexp = /^[a-zA-Z0-9 \.,:_\-\?\/@]+$/; // TODO: look for spec of unsafe chars
|
||||
const userRegexp = /^[a-zA-Z0-9\._\-]+$/;
|
||||
@@ -163,6 +164,9 @@ module.exports = class extends Generator {
|
||||
return;
|
||||
}
|
||||
|
||||
// save auth key password to check if it changed
|
||||
this.auth_clientkeyspassword = this.props.auth_clientkeyspassword;
|
||||
|
||||
let prompts = [];
|
||||
for( let m of prompters ) {
|
||||
prompts = prompts.concat(m.prompts(this));
|
||||
@@ -173,12 +177,46 @@ module.exports = class extends Generator {
|
||||
});
|
||||
}
|
||||
|
||||
writing() {
|
||||
const configJsonString = JSON.stringify(this.props);
|
||||
|
||||
async configuring() {
|
||||
if( this.props.auth_recreatekeys || !this.props.auth_keys ) {
|
||||
delete this.props.auth_recreatekeys;
|
||||
const apikey = new ApiKey();
|
||||
|
||||
let configEntries = [];
|
||||
let clientInformation = [];
|
||||
|
||||
apikey.setId('001');
|
||||
apikey.setGroups(['watcher']);
|
||||
await apikey.randomiseKey();
|
||||
configEntries.push(apikey.getConfigEntry());
|
||||
clientInformation.push(apikey.getClientInformation());
|
||||
|
||||
apikey.setId('002');
|
||||
apikey.setGroups(['watcher','spender']);
|
||||
await apikey.randomiseKey();
|
||||
configEntries.push(apikey.getConfigEntry());
|
||||
clientInformation.push(apikey.getClientInformation());
|
||||
|
||||
apikey.setId('003');
|
||||
apikey.setGroups(['watcher','spender','admin']);
|
||||
await apikey.randomiseKey();
|
||||
configEntries.push(apikey.getConfigEntry());
|
||||
clientInformation.push(apikey.getClientInformation());
|
||||
|
||||
this.props.auth_keys = {
|
||||
configEntries: configEntries,
|
||||
clientInformation: clientInformation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async writing() {
|
||||
const configJsonString = JSON.stringify(this.props, null, 4);
|
||||
const archive = new Archive( this.destinationPath('config.7z'), this.configurationPassword );
|
||||
|
||||
if( !archive.writeEntry( 'config.json', configJsonString ) ) {
|
||||
console.log(chalk.bold.red( 'error! config archive was not written' ));
|
||||
console.log(chalk.bold.red( 'error! Config archive was not written' ));
|
||||
}
|
||||
|
||||
for( let m of prompters ) {
|
||||
@@ -192,6 +230,19 @@ module.exports = class extends Generator {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if( this.props.auth_keys && this.props.auth_keys.clientInformation ) {
|
||||
|
||||
if( this.auth_clientkeyspassword !== this.props.auth_clientkeyspassword ) {
|
||||
fs.unlinkSync( this.destinationPath('clientKeys.7z') );
|
||||
}
|
||||
|
||||
const archive = new Archive( this.destinationPath('clientKeys.7z'), this.props.auth_clientkeyspassword );
|
||||
if( !archive.writeEntry( 'keys.txt', this.props.auth_keys.clientInformation.join('\n') ) ) {
|
||||
console.log(chalk.bold.red( 'error! Client auth key archive was not written' ));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
install() {
|
||||
@@ -199,6 +250,10 @@ module.exports = class extends Generator {
|
||||
|
||||
/* some utils */
|
||||
|
||||
_clientAuthKeysArchiveExists() {
|
||||
return fs.existsSync( this.destinationPath('clientKeys.7z') );
|
||||
}
|
||||
|
||||
_assignConfigDefaults( props ) {
|
||||
props.derivation_path = this.props.derivation_path || '0/n';
|
||||
props.installer = this.props.installer || 'docker';
|
||||
|
||||
76
install/generator-cyphernode/generators/app/lib/apikey.js
Normal file
76
install/generator-cyphernode/generators/app/lib/apikey.js
Normal file
@@ -0,0 +1,76 @@
|
||||
const spawn = require('child_process').spawn;
|
||||
|
||||
module.exports = class ApiKey {
|
||||
constructor( id, groups, key, script ) {
|
||||
this.setId(id || '001');
|
||||
this.setGroups(groups || ['admin'] );
|
||||
this.setScript(script || 'eval ugroups_${kapi_id}=${kapi_groups};eval ukey_${kapi_id}=${kapi_key}' );
|
||||
this.setKey(key);
|
||||
}
|
||||
|
||||
setGroups( groups ) {
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
setId( id ) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
setScript( script ) {
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
setKey( key ) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
async randomiseKey() {
|
||||
try {
|
||||
|
||||
//const dd = spawn('/bin/dd if=/dev/urandom bs=32 count=1 | /usr/bin/xxd -pc 32');
|
||||
const dd = spawn("dd if=/dev/urandom bs=32 count=1 | xxd -pc32", [], {stdio: ['ignore', 'pipe', 'ignore' ], shell: true} );
|
||||
|
||||
const result = await new Promise( function(resolve, reject ) {
|
||||
|
||||
let result = '';
|
||||
dd.stdout.on('data', function( a,b,c) {
|
||||
let chunk = a.toString().trim();
|
||||
result += chunk;
|
||||
});
|
||||
|
||||
dd.stdout.on('end', function() {
|
||||
result = result.replace(/[^a-zA-Z0-9]/,'');
|
||||
resolve(result);
|
||||
});
|
||||
|
||||
dd.stdout.on('error', function(err) {
|
||||
console.log(err);
|
||||
reject(err);
|
||||
})
|
||||
});
|
||||
this.key = result;
|
||||
|
||||
} catch( err ) {
|
||||
console.log( err );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
getConfigEntry() {
|
||||
if( !this.key ) {
|
||||
return;
|
||||
}
|
||||
return `kapi_id="${this.id}";kapi_key="${this.key}";kapi_groups="${this.groups.join(',')}";${this.script}`;
|
||||
}
|
||||
|
||||
getClientInformation() {
|
||||
return `${this.id}=${this.key}`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//dd if=/dev/urandom bs=32 count=1 2> /dev/null | xxd -pc 32
|
||||
@@ -0,0 +1,37 @@
|
||||
const chalk = require('chalk');
|
||||
|
||||
const name = 'authentication';
|
||||
|
||||
const capitalise = function( txt ) {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1);
|
||||
};
|
||||
|
||||
const prefix = function() {
|
||||
return chalk.bold.red(capitalise(name)+': ');
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
name: function() {
|
||||
return name;
|
||||
},
|
||||
prompts: function( utils ) {
|
||||
// TODO: delete clientKeys archive when password chnages
|
||||
return [{
|
||||
type: 'password',
|
||||
name: 'auth_clientkeyspassword',
|
||||
default: utils._getDefault( 'auth_clientkeyspassword' ),
|
||||
message: prefix()+'Enter a password to protect your client keys with'+'\n',
|
||||
filter: utils._trimFilter,
|
||||
validate: utils._notEmptyValidator
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'auth_recreatekeys',
|
||||
default: false,
|
||||
message: prefix()+'Recreate auth keys?'+'\n'
|
||||
}];
|
||||
},
|
||||
templates: function( props ) {
|
||||
return [ 'keys.properties' ];
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
<%- auth_keys.configEntries.join('\n') %>
|
||||
Reference in New Issue
Block a user