mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Add Git access feature via SSH and Enhance SSH Key management
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
var fs = require('fs-extra');
|
||||
var when = require('when');
|
||||
var fspath = require("path");
|
||||
var os = require('os');
|
||||
|
||||
var gitTools = require("./git");
|
||||
var util = require("../util");
|
||||
@@ -680,6 +681,7 @@ function createProject(user, metadata) {
|
||||
if (metadata.git && metadata.git.remotes && metadata.git.remotes.origin) {
|
||||
var originRemote = metadata.git.remotes.origin;
|
||||
var auth;
|
||||
console.log('originRemote:', originRemote);
|
||||
if (originRemote.hasOwnProperty("username") && originRemote.hasOwnProperty("password")) {
|
||||
authCache.set(project,originRemote.url,username,{ // TODO: hardcoded remote name
|
||||
username: originRemote.username,
|
||||
@@ -688,6 +690,15 @@ function createProject(user, metadata) {
|
||||
);
|
||||
auth = authCache.get(project,originRemote.url,username);
|
||||
}
|
||||
else if (originRemote.hasOwnProperty("key_file") && originRemote.hasOwnProperty("passphrase")) {
|
||||
var key_file_name = (username === '_') ? os.hostname() + '_' + originRemote.key_file : username + '_' + originRemote.key_file;
|
||||
authCache.set(project,originRemote.url,username,{ // TODO: hardcoded remote name
|
||||
key_path: fspath.join(projectsDir, ".sshkeys", key_file_name),
|
||||
passphrase: originRemote.passphrase
|
||||
}
|
||||
);
|
||||
auth = authCache.get(project,originRemote.url,username);
|
||||
}
|
||||
return gitTools.clone(originRemote,auth,projectPath).then(function(result) {
|
||||
// Check this is a valid project
|
||||
// If it is empty
|
||||
|
@@ -45,7 +45,7 @@ var ResponseServer = function(auth) {
|
||||
parts.push(data.substring(0, m));
|
||||
data = data.substring(m);
|
||||
var line = parts.join("");
|
||||
console.log("LINE",line);
|
||||
console.log("LINE:",line);
|
||||
parts = [];
|
||||
if (line==='Username') {
|
||||
connection.end(auth.username);
|
||||
@@ -79,8 +79,54 @@ var ResponseServer = function(auth) {
|
||||
});
|
||||
}
|
||||
|
||||
var ResponseSSHServer = function(auth) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
server = net.createServer(function(connection) {
|
||||
connection.setEncoding('utf8');
|
||||
var parts = [];
|
||||
connection.on('data', function(data) {
|
||||
var m = data.indexOf("\n");
|
||||
if (m !== -1) {
|
||||
parts.push(data.substring(0, m));
|
||||
data = data.substring(m);
|
||||
var line = parts.join("");
|
||||
console.log("LINE:",line);
|
||||
parts = [];
|
||||
if (line==='The') {
|
||||
connection.end('yes');
|
||||
// server.close();
|
||||
} else if (line === 'Enter') {
|
||||
connection.end(auth.passphrase);
|
||||
// server.close();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
if (data.length > 0) {
|
||||
parts.push(data);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
var listenPath = getListenPath();
|
||||
|
||||
server.listen(listenPath, function(ready) {
|
||||
resolve({path:listenPath,close:function() { server.close(); }});
|
||||
});
|
||||
server.on('close', function() {
|
||||
// console.log("Closing response server");
|
||||
fs.removeSync(listenPath);
|
||||
});
|
||||
server.on('error',function(err) {
|
||||
console.log("ResponseServer unexpectedError:",err.toString());
|
||||
server.close();
|
||||
reject(err);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
ResponseServer: ResponseServer
|
||||
ResponseServer: ResponseServer,
|
||||
ResponseSSHServer: ResponseSSHServer
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@ var when = require('when');
|
||||
var exec = require('child_process').exec;
|
||||
var spawn = require('child_process').spawn;
|
||||
var authResponseServer = require('./authServer').ResponseServer;
|
||||
var sshResponseServer = require('./authServer').ResponseSSHServer;
|
||||
var clone = require('clone');
|
||||
var path = require("path");
|
||||
|
||||
@@ -41,6 +42,11 @@ function runGitCommand(args,cwd,env) {
|
||||
});
|
||||
|
||||
child.on('close', function(code) {
|
||||
console.log("===============================================================");
|
||||
console.log("stdout:", stdout);
|
||||
console.log("===============================================================");
|
||||
console.log("stderr:", stderr);
|
||||
console.log("===============================================================");
|
||||
if (code !== 0) {
|
||||
var err = new Error(stderr);
|
||||
err.stdout = stdout;
|
||||
@@ -49,6 +55,8 @@ function runGitCommand(args,cwd,env) {
|
||||
err.code = "git_auth_failed";
|
||||
} else if(/HTTP Basic: Access denied/.test(stderr)) {
|
||||
err.code = "git_auth_failed";
|
||||
} else if(/Permission denied \(publickey\)/.test(stderr)) {
|
||||
err.code = "git_auth_failed";
|
||||
} else if(/Connection refused/.test(stderr)) {
|
||||
err.code = "git_connection_failed";
|
||||
} else if (/commit your changes or stash/.test(stderr)) {
|
||||
@@ -56,9 +64,10 @@ function runGitCommand(args,cwd,env) {
|
||||
} else if (/CONFLICT/.test(err.stdout)) {
|
||||
err.code = "git_pull_merge_conflict";
|
||||
}
|
||||
|
||||
|
||||
|
||||
console.log("===============================================================");
|
||||
console.log('err:', err);
|
||||
console.log("===============================================================");
|
||||
|
||||
return reject(err);
|
||||
}
|
||||
resolve(stdout);
|
||||
@@ -78,6 +87,22 @@ function runGitCommandWithAuth(args,cwd,auth) {
|
||||
})
|
||||
}
|
||||
|
||||
function runGitCommandWithSSHCommand(args,cwd,auth) {
|
||||
return sshResponseServer(auth).then(function(rs) {
|
||||
var commandEnv = clone(process.env);
|
||||
commandEnv.SSH_ASKPASS = path.join(__dirname,"node-red-ask-pass.sh");
|
||||
commandEnv.DISPLAY = "dummy:0";
|
||||
commandEnv.NODE_RED_GIT_NODE_PATH = process.execPath;
|
||||
commandEnv.NODE_RED_GIT_SOCK_PATH = rs.path;
|
||||
commandEnv.NODE_RED_GIT_ASKPASS_PATH = path.join(__dirname,"authWriter.js");
|
||||
commandEnv.GIT_SSH_COMMAND = "ssh -i " + auth.key_path + " -F /dev/null";
|
||||
// console.log('commandEnv:', commandEnv);
|
||||
return runGitCommand(args,cwd,commandEnv).finally(function() {
|
||||
rs.close();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
function cleanFilename(name) {
|
||||
if (name[0] !== '"') {
|
||||
return name;
|
||||
@@ -331,7 +356,12 @@ module.exports = {
|
||||
}
|
||||
var promise;
|
||||
if (auth) {
|
||||
promise = runGitCommandWithAuth(args,cwd,auth);
|
||||
if ( auth.key_path ) {
|
||||
promise = runGitCommandWithSSHCommand(args,cwd,auth);
|
||||
}
|
||||
else {
|
||||
promise = runGitCommandWithAuth(args,cwd,auth);
|
||||
}
|
||||
} else {
|
||||
promise = runGitCommand(args,cwd)
|
||||
}
|
||||
@@ -362,7 +392,12 @@ module.exports = {
|
||||
args.push("--porcelain");
|
||||
var promise;
|
||||
if (auth) {
|
||||
promise = runGitCommandWithAuth(args,cwd,auth);
|
||||
if ( auth.key_path ) {
|
||||
promise = runGitCommandWithSSHCommand(args,cwd,auth);
|
||||
}
|
||||
else {
|
||||
promise = runGitCommandWithAuth(args,cwd,auth);
|
||||
}
|
||||
} else {
|
||||
promise = runGitCommand(args,cwd)
|
||||
}
|
||||
@@ -387,7 +422,12 @@ module.exports = {
|
||||
}
|
||||
args.push(".");
|
||||
if (auth) {
|
||||
return runGitCommandWithAuth(args,cwd,auth);
|
||||
if ( auth.key_path ) {
|
||||
return runGitCommandWithSSHCommand(args,cwd,auth);
|
||||
}
|
||||
else {
|
||||
return runGitCommandWithAuth(args,cwd,auth);
|
||||
}
|
||||
} else {
|
||||
return runGitCommand(args,cwd);
|
||||
}
|
||||
@@ -442,7 +482,12 @@ module.exports = {
|
||||
fetch: function(cwd,remote,auth) {
|
||||
var args = ["fetch",remote];
|
||||
if (auth) {
|
||||
return runGitCommandWithAuth(args,cwd,auth);
|
||||
if ( auth.key_path ) {
|
||||
return runGitCommandWithSSHCommand(args,cwd,auth);
|
||||
}
|
||||
else {
|
||||
return runGitCommandWithAuth(args,cwd,auth);
|
||||
}
|
||||
} else {
|
||||
return runGitCommand(args,cwd);
|
||||
}
|
||||
|
@@ -134,7 +134,7 @@ function getProject(user, name) {
|
||||
return Projects.get(name).then(function(project) {
|
||||
var result = project.toJSON();
|
||||
var projectSettings = settings.get("projects").projects;
|
||||
if (projectSettings[name].git && projectSettings[name].git.user[username]) {
|
||||
if (projectSettings[name] && projectSettings[name].git && projectSettings[name].git.user[username]) {
|
||||
result.git.user = projectSettings[name].git.user[username];
|
||||
}
|
||||
return result;
|
||||
|
Reference in New Issue
Block a user